antv g6实现系统拓扑图

2024-06-21 00:20
文章标签 实现 系统 antv g6 拓扑图

本文主要是介绍antv g6实现系统拓扑图,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1 背景

为例描述各个服务、redis、mysql等之间的联系及其健康状态,构建系统拓扑图,考虑 g6 更适合处理大量数据之间的关系,所以我们采用g6来绘制前端的图形。

g6提供的支持:

  • 节点/边类型多样,同样支持自定义
  • 对于节点的样式可以直接配置化处理
  • 丰富的事件体系,包括对节点/边/画布,以及时机事件的监听
  • 多种布局算法
  • 节点/边的数据,都是可以配置化的json对象

在线工具:g6示例

2 功能列表

节点:

  • 添加节点:除了id、style、type外,还包括一些业务需要的数据
  • 删除节点:除了删除该节点相对于画布的id外,还包括与之相关的业务数据
  • 节点状态:比如错误节点需要标红;非活跃节点需要标灰

边:

  • 添加边:除了id、style、type外,还包括一些业务需要的数据
  • 删除变:除了删除该边相对于画布的id外,还包括与之相关的业务数据
  • 修改边:主要是修改边所代表的业务信息,如果没有业务信息的话,这条边应该被删除

画布:

  • 用户自定义布局,比如需要保存用户拖拽节点后的节点位置坐标信息
  • dagre层次布局
  • 工具栏
  • 图例
  • 小地图
  • 触摸板放大缩小
  • 节点搜索

3 节点

3.1 渲染节点

渲染节点,包括自定义节点类型和样式。

自定义节点,该节点由rect和image组成,类似于矩形里面有icon:

// 其实可以不用自定义节点,可以使用circle类型的icon字段。但是这种方式,点击节点的时候,里面的icon会存在闪缩的情况
// https://g6.antv.antgroup.com/manual/middle/elements/nodes/built-in/circle#%E5%9B%BE%E6%A0%87-icon
G6.registerNode('drag-inner-image-node',{afterDraw(cfg, group) {const size = cfg?.size as number[];const width = size[0] - 20;const height = size[1] - 20;const imageShape = group?.addShape('image', {attrs: {x: -width / 2,y: -height / 2,width,height,img: cfg?.img,cursor: 'move',},// must be assigned in G6 3.3 and later versions. it can be any string you want, but should be unique in a custom item typename: 'image-shape',});// 启用拖拽imageShape?.set('draggable', true);},},'circle',
);

节点样式:

const DefaultNodeSelectedStyle = {lineWidth: 8,'text-shape': {// 点击后的文本样式,保持点击前一致fontWeight: 400,},
};export const NodeStyleMap = {default: {// 正常节点 - 样式设置style: {fill: GlobalLightBlueColor,stroke: GlobalBlueColor,lineWidth: 1,},// 状态样式,比如 selected点击状态stateStyles: {selected: {stroke: GlobalBlueColor,fill: GlobalLightBlueColor,shadowColor: GlobalBlueColor,...DefaultNodeSelectedStyle,},},},error: {// 异常节点style: {stroke: GlobalRedColor,fill: GlobalLightRedColor,lineWidth: 1,},stateStyles: {selected: {stroke: GlobalRedColor,fill: GlobalLightRedColor,shadowColor: GlobalRedColor,...DefaultNodeSelectedStyle,},},},
};

获取节点的渲染数据:

export const formatNodes = (nodes: MttkArchitectureNode[] = []) => {return nodes?.map((node) => {const { component, has_error, coordinates } = node;// 业务逻辑const middlewareType = getMiddlewareType(component) as MttkComponentType;const { id, label, wholeLabelName } = getNodeId(node);// 样式和iconconst nodeStyle = NodeStyleMap[has_error ? 'error' : 'default'];const img = has_error ? ErrorIconImageMap[middlewareType] : IconImageMap[middlewareType];return {...node,img,middlewareType,label,wholeLabelName, // 仅前端展示使用...nodeStyle,id, // 仅前端展示使用x: coordinates?.x, // 节点的位置坐标y: coordinates?.y, // 节点的位置坐标};});
};

3.2 删除节点

3.3 添加节点

4 边

4.1 渲染边

边的样式:

const DefaultEdgeSelectedStyle = {lineWidth: 4,shadowBlur: 10, // 阴影的模糊级别,数值越大越模糊
};export const EdgeStyleMap = {default: {// 正常边 - 样式设置style: {stroke: GlobalBlueColor,lineWidth: 1,lineDash: [0], // 如果[0]表示直线,需要覆盖一下创建边之后的虚线样式},// 状态样式,比如 selected点击状态stateStyles: {selected: {stroke: GlobalBlueColor,shadowColor: GlobalBlueColor,...DefaultEdgeSelectedStyle,},},},error: {// 异常边style: {stroke: GlobalRedColor,lineWidth: 1,},stateStyles: {selected: {stroke: GlobalRedColor,shadowColor: GlobalRedColor,...DefaultEdgeSelectedStyle,},},},
};

边的渲染数据:

export const formatEdges = (edges: MttkArchitectureEdge[] = [], nodes: MttkArchitectureNode[] = []) => {return edges?.map((edge) => {const { has_error } = edge;const edgeStyle = EdgeStyleMap[has_error ? 'error' : 'default'];const { id, fromId, toId } = getEdgeId(nodes, edge);return {...edge,source: fromId,target: toId,...edgeStyle,id,from: fromId, // 前端直接替换掉get接口返回的随机数idto: toId, // 前端直接替换掉get接口返回的随机数id};});
};

4.2 删除边

4.3 添加边

5 画布全局配置


export const LayoutMap = {[LayoutType.LR]: {// 从左到右type: 'dagre',ranksep: 70,controlPoints: true, // 是否保留布局连线的控制点rankdir: 'LR', // 可选,默认为图的中心nodesep: 10, // 可选},[LayoutType.TB]: {// 从上到下// type: 'dagre',// ranksep: 70,// controlPoints: true,rankdir: 'TB',},
};export const DefaultOptions = {layout: LayoutMap.LR,defaultNode: {type: 'drag-inner-image-node',size: [50, 50],style: { cursor: 'move' },label: 'node-label',labelCfg: {position: 'bottom',offset: 2,style: {fill: '#666',fontSize: 14,cursor: 'move',},},},defaultEdge: {type: 'polyline',style: {radius: 20, // 拐弯处的圆角弧度offset: 20, // 拐弯处距离节点最小距离endArrow: true,lineAppendWidth: 20, // 提升边的击中范围},},modes: {default: ['drag-canvas','drag-node',{type: 'create-edge',trigger: 'click', // 'click' by default. options: 'drag', 'click'key: 'shift', // undefined by default, options: 'shift', 'control', 'ctrl', 'meta', 'alt'edgeConfig: {// 有该交互创建出的边的配置项,可以配置边的类型、样式等style: {radius: 20, // 拐弯处的圆角弧度offset: 20, // 拐弯处距离节点最小距离endArrow: true,lineAppendWidth: 20, // 提升边的击中范围...EdgeStyleMap.default.style,lineDash: [5], // 设置线的虚线样式, 如果[0]表示直线},},shouldEnd: (e: any, self: any) => {const { item: toItem } = e;const { source: fromId, graph } = self;const toId = toItem._cfg.id;// 不允许创建自环边if (toId === fromId) {return false;}// 不允许创建已经存在的边const edges = graph.getEdges();if (edges.some((ed: any) => {const { source, target } = ed.getModel();return fromId === source && toId === target;})) {return false;}return true;},},{type: 'click-select',// 不允许节点被该交互选中。如果为true的话,会存在重复点击当前节点闪烁的情况,// 因为 已选中 > 再次点击,会默认给当前节点 selected status设置为false,我们再手动改为true的时候,就会存在闪烁selectNode: false,multiple: false, // 不允许多选},],},fitView: true, // 图是否自适应画布
};

6 图例

g6自带的图例不是很好自定义ui,虽然可以进行与节点/边数据联动的功能,所以考虑直接react实现。

// interface Props {
//   extendLegend?: React.ReactNode; // 扩展图例,比如错误的信息
// }
export const GraphNodeTypeConfigs = [{icon: IconImageMap[MttkComponentType.SERVICE],description: 'Service',key: MttkComponentType.SERVICE,},{icon: IconImageMap[MttkComponentType.MYSQL],description: 'MySQL',key: MttkComponentType.MYSQL,},{icon: IconImageMap[MttkComponentType.KAFKA],description: 'Kafka',key: MttkComponentType.KAFKA,},{icon: IconImageMap[MttkComponentType.REDIS],description: 'Redis',key: MttkComponentType.REDIS,},{icon: IconImageMap[MttkComponentType.UNKNOWN],description: 'Unknown',key: MttkComponentType.UNKNOWN,},
];export function LegendRow() {return (<>{GraphNodeTypeConfigs.map(({ icon, description }) => (<Row justify="start" align="middle" wrap={false} style={{ marginRight: 8 }}><img src={icon} style={{ width: 18, height: 18, marginRight: 4 }} />{description}</Row>))}</>);
}

7 工具栏

跟图例一样,考虑不太好自定义ui,所以直接react实现。

import { ZoomInOutlined, ZoomOutOutlined, FullscreenExitOutlined } from '@ant-design/icons';
import { Col, Row, Button } from 'antd';interface Props {onZoomIn: () => void; // 放大onZoomOut: () => void; // 缩小onFixCenter: () => void; // 回到中间
}export function Toolbar(props: Props) {const { onZoomIn, onZoomOut, onFixCenter } = props;return (<Col style={{ width: 30 }}><Row justify="center"><Button type="link" style={{ padding: 0 }} onClick={onZoomIn}><ZoomInOutlined /></Button></Row><Row justify="center"><Button type="link" style={{ padding: 0 }} onClick={onZoomOut}><ZoomOutOutlined /></Button></Row><Row justify="center"><Button type="link" style={{ padding: 0 }} onClick={onFixCenter}><FullscreenExitOutlined /></Button></Row></Col>);
}

这篇关于antv g6实现系统拓扑图的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1079681

相关文章

不懂推荐算法也能设计推荐系统

本文以商业化应用推荐为例,告诉我们不懂推荐算法的产品,也能从产品侧出发, 设计出一款不错的推荐系统。 相信很多新手产品,看到算法二字,多是懵圈的。 什么排序算法、最短路径等都是相对传统的算法(注:传统是指科班出身的产品都会接触过)。但对于推荐算法,多数产品对着网上搜到的资源,都会无从下手。特别当某些推荐算法 和 “AI”扯上关系后,更是加大了理解的难度。 但,不了解推荐算法,就无法做推荐系

基于人工智能的图像分类系统

目录 引言项目背景环境准备 硬件要求软件安装与配置系统设计 系统架构关键技术代码示例 数据预处理模型训练模型预测应用场景结论 1. 引言 图像分类是计算机视觉中的一个重要任务,目标是自动识别图像中的对象类别。通过卷积神经网络(CNN)等深度学习技术,我们可以构建高效的图像分类系统,广泛应用于自动驾驶、医疗影像诊断、监控分析等领域。本文将介绍如何构建一个基于人工智能的图像分类系统,包括环境

水位雨量在线监测系统概述及应用介绍

在当今社会,随着科技的飞速发展,各种智能监测系统已成为保障公共安全、促进资源管理和环境保护的重要工具。其中,水位雨量在线监测系统作为自然灾害预警、水资源管理及水利工程运行的关键技术,其重要性不言而喻。 一、水位雨量在线监测系统的基本原理 水位雨量在线监测系统主要由数据采集单元、数据传输网络、数据处理中心及用户终端四大部分构成,形成了一个完整的闭环系统。 数据采集单元:这是系统的“眼睛”,

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

hdu1043(八数码问题,广搜 + hash(实现状态压缩) )

利用康拓展开将一个排列映射成一个自然数,然后就变成了普通的广搜题。 #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#include<stdlib.h>#include<ctype.h>#inclu

嵌入式QT开发:构建高效智能的嵌入式系统

摘要: 本文深入探讨了嵌入式 QT 相关的各个方面。从 QT 框架的基础架构和核心概念出发,详细阐述了其在嵌入式环境中的优势与特点。文中分析了嵌入式 QT 的开发环境搭建过程,包括交叉编译工具链的配置等关键步骤。进一步探讨了嵌入式 QT 的界面设计与开发,涵盖了从基本控件的使用到复杂界面布局的构建。同时也深入研究了信号与槽机制在嵌入式系统中的应用,以及嵌入式 QT 与硬件设备的交互,包括输入输出设

JAVA智听未来一站式有声阅读平台听书系统小程序源码

智听未来,一站式有声阅读平台听书系统 🌟&nbsp;开篇:遇见未来,从“智听”开始 在这个快节奏的时代,你是否渴望在忙碌的间隙,找到一片属于自己的宁静角落?是否梦想着能随时随地,沉浸在知识的海洋,或是故事的奇幻世界里?今天,就让我带你一起探索“智听未来”——这一站式有声阅读平台听书系统,它正悄悄改变着我们的阅读方式,让未来触手可及! 📚&nbsp;第一站:海量资源,应有尽有 走进“智听

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

【Prometheus】PromQL向量匹配实现不同标签的向量数据进行运算

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi

让树莓派智能语音助手实现定时提醒功能

最初的时候是想直接在rasa 的chatbot上实现,因为rasa本身是带有remindschedule模块的。不过经过一番折腾后,忽然发现,chatbot上实现的定时,语音助手不一定会有响应。因为,我目前语音助手的代码设置了长时间无应答会结束对话,这样一来,chatbot定时提醒的触发就不会被语音助手获悉。那怎么让语音助手也具有定时提醒功能呢? 我最后选择的方法是用threading.Time