antv/g6绘制数据流向图

antv/g6绘制数据流向图

  • 前言
    • 接口模拟数据
    • html
    • ts
    • 页面效果

前言

在业务开发中需要绘制数据流向图,由于echarts关系图的限制以及需求的特殊要求,转而使用antv/g6实现,本文以代码的方式实现数据流向需求以及节点分组,版本"@antv/g6": “^4.8.24”,

本文主要列出关键性的代码,并非全部代码

接口模拟数据

getCenterFlowG6ApiV2(data = {}) {return new Promise((resolve) => {let nodes: any = []for (let i = 1; i <= 14; i++) {let node: any = { id: "node-" + i, label: "node-" + i }if (i % 3 === 0) {node.class = "c0"} else if (i % 3 === 1) {node.class = "c1"} else if (i % 3 === 2) {node.class = "c2"}nodes.push(node)}const res = {"resultStat": "0","failCode": null,"mess": "获取流向成功","callBack": null,"data": {nodes: [{id: "4",label: "业务数据库A",comboId:"group0",imgType:"14","pointNodeDetail": {"nodeName": "武汉关","nodeTypeName": "应用安全域","areaName": "武汉关","areaIpScope": "160.1.1.1-255.255.255.255","areaBelong": "tanzhi","areaType": "办公网接入域"},}, {id: "8",label: "业务数据库B",comboId:"group1",imgType:"10"},{id: "10",label: "主机166.10.1.1",comboId:"group2"},{id: "12",label: "主机161.19.1.4",comboId:"group4"}, {id: "14",label: "业务数据库B",comboId:"group3"}],edges: [{eid: "4-8",source: "4",target: "8",},{eid: "8-4",source: "8",target: "4",},{eid: "10-4",source: "10",target: "4",},{eid: "10-8",source: "10",target: "8",},{eid: "12-8",source: "12",target: "8",style:{stroke: 'red', // 线的颜色}},{eid: "4-14",source: "4",target: "14",}],combos: [{id:'group0',label:'信息中心',collapsed: true,// 初始时,收起,不展示内部节点style:{fill: "r(0.5,0.5,0.9) 0.6:#f8fcff 1:#3b97f1",opacity: 0.2}},{id:'group1',label:'数据分析中心',parentId:'group0',collapsed: true,style:{fill:"#FCCBAE"}},{id:'group2',label:'数据采集',collapsed: true,style:{fill:"#ECF7CF"}},{id:'group3',label:'业务办公区',parentId:'group0',collapsed: true,style:{fill:"#CECFD1"}},{id:'group4',label:'某地海关',collapsed: true,style:{fill:"#D1E9FF"}}]},"redirectURL": null,"total": null}resolve(res)})}

html

<div class="echart-box"><div class="chart1" id="charts1" *ngIf="chartData.data != null && !pageLoading" ></div>
</div>  

ts


import G6 from "@antv/g6"import equipment from "../../../../assets/equipment.png"
import equipmentE from "../../../../assets/equipmentE.png"
import equipmentY from "../../../../assets/equipmentY.png"
import application from "../../../../assets/application.png"
import assetsE from "../../../../assets/assetsE.png"
import assetsY from "../../../../assets/assetsY.png"
import assets from "../../../../assets/assets.png"
import domain from "../../../../assets/domain.png"
import domainE from "../../../../assets/domainE.png"
import domainY from "../../../../assets/domainY.png"
import warning from "../../../../assets/warning.png"
import warningY from "../../../../assets/warningY.png"import clusterAsset from "../../../../assets/clusterAsset.png"
import clusterAssetY from "../../../../assets/clusterAssetY.png"
import clusterAssetR from "../../../../assets/clusterAssetR.png"
import belongCenterY from "../../../../assets/belongCenterY.png"
import belongCenter from "../../../../assets/belongCenter.png"
import belongCenterR from "../../../../assets/belongCenterR.png"
import netDomain from "../../../../assets/netDomain.png"
import netDomainR from "../../../../assets/netDomainR.png"
import netDomainY from "../../../../assets/netDomainY.png"
import groupIcon from "../../../../assets/chart/img/g6/群组_02.png";/*** 加载流向图*/getDataFlow() {this.pageLoading = truethis.apiService.getCenterFlowG6ApiV2(removeNullProperty({...this.q})).then((res: resType) => {console.log(res);if (res.resultStat === "0") {this.chartData.data = this.transformData(res.data)console.log(this.chartData.data);setTimeout(() => {this.initG6DataFlow(this.chartData.data)}, 300);}this.pageLoading = false}).catch(err => {this.pageLoading = false})}initG6DataFlow(data) {let rectWidth = 800let rectHeight = 600const eContainer = document.getElementById("charts1")if (eContainer) {if (data.nodes.length < 100) {eContainer.style.height = '100%'  // 600pxeContainer.style.minHeight = '600px'  // 600pxeContainer.style.width = '100%'  // 800px} else {eContainer.style.height = '1080px'eContainer.style.width = '1920px'}const rectObject = eContainer.getBoundingClientRect()rectWidth = rectObject.right - rectObject.leftrectHeight = rectObject.bottom - rectObject.top;console.log(rectObject);console.log(rectWidth, rectHeight);}const graph = new G6.Graph({container: 'charts1', // String | HTMLElement,必须,在 Step 1 中创建的容器 id 或容器本身width: rectWidth - 10, // Number,必须,图的宽度height: rectHeight - 10, // Number,必须,图的高度fitView: false, // 将图适配到画布fitViewPadding: 50, // 画布四周留白宽度// 必须将 groupByTypes 设置为 false,带有 combo 的图中元素的视觉层级才能合理groupByTypes: false,fitCenter: true,linkCenter: false,//autoPaint: true,layout: {type: 'comboCombined',spacing: 20,comboPadding: 5},modes: {// 允许拖拽画布、放缩画布、拖拽节点,default: ['drag-canvas','zoom-canvas',{type: 'drag-node',onlyChangeComboSize: true,},{type: "drag-combo",enableDelegate: false,onlyChangeComboSize: true,},{type: 'collapse-expand-combo',trigger: 'click',relayout: false, // 收缩展开后,不重新布局},{type: 'tooltip', // 提示框formatText(model) {// 提示框文本内容const text = 'label: ' + model.label + '<br/> class: ' + model.class;return text;},shouldUpdate: e => {return true;}},{type: 'edge-tooltip', // 边提示框formatText(model) {// 边提示框文本内容const text ='source: ' +model.source +'<br/> target: ' +model.target +'<br/> weight: ' +(model.weight || "");return text;},shouldUpdate: e => {return true;}}],},defaultNode: {// 默认状态下的节点配置size: 30,// 节点样式配置style: {fill: 'steelblue', // 节点填充色stroke: '#666', // 节点描边色lineWidth: 2, // 节点描边粗细},// 节点上的标签文本配置labelCfg: {// 节点上的标签文本样式配置style: {fill: '#333', // 节点标签文字颜色stroke: '#fff',},position:"bottom"},},defaultEdge: {// 默认状态下的边配置style: {//opacity: 0.6, // 边透明度lineWidth: 4, // 线宽stroke: '#D6ECF3', // 线的颜色//endArrow: true,// 默认箭头endArrow: { // 自定义终点箭头path: G6.Arrow.vee(5, 10, 10), // 使用内置箭头路径函数,参数为箭头的 宽度、长度、偏移量(默认为 0,与 d 对应)d: 10}},// 边上的标签文本配置labelCfg: {autoRotate: true, // 边上的标签文本根据边的方向旋转refY: 10,},},defaultCombo: {collapsed: true,padding:5,labelCfg:{"style": {"fontSize": 12,"fill": "r(0.5,0.5,0.1)  0:#ffffff 1:#555555","opacity": 1,"stroke": "#fff","lineWidth": 1,"fontFamily": "微软雅黑","text": "信息中心"},"position": "top"},collapsedSubstituteIcon: { // 群组收起时的图标show: true,img: groupIcon,height: 30,width: 30,},},// 节点不同状态下的样式集合nodeStateStyles: {// 鼠标 hover 上节点,即 hover 状态为 true 时的样式hover: {fill: 'lightsteelblue',},// 鼠标点击节点,即 click 状态为 true 时的样式click: {stroke: '#000',lineWidth: 3,},},// 边不同状态下的样式集合edgeStateStyles: {// 鼠标点击边,即 click 状态为 true 时的样式click: {stroke: 'steelblue',},},});if (this.chartData.instance) {this.chartData.instance.destroy()}this.chartData.instance = graphgraph.data(data); // 读取 Step 2 中的数据源到图上graph.render(); // 渲染图graph.get('canvas').set('localRefresh', false)// 监听鼠标进入节点graph.on('node:mouseenter', (e) => {const nodeItem = e.item;// 设置目标节点的 hover 状态 为 truegraph.setItemState(nodeItem, 'hover', true);});// 监听鼠标离开节点graph.on('node:mouseleave', (e) => {const nodeItem = e.item;// 设置目标节点的 hover 状态 falsegraph.setItemState(nodeItem, 'hover', false);});// 监听鼠标点击节点graph.on('node:click', (e) => {console.log(e);this.pointNodeDetail = e.item._cfg.model.pointNodeDetail// 先将所有当前有 click 状态的节点的 click 状态置为 falseconst clickNodes = graph.findAllByState('node', 'click');clickNodes.forEach((cn) => {graph.setItemState(cn, 'click', false);});const nodeItem = e.item;// 设置目标节点的 click 状态 为 truegraph.setItemState(nodeItem, 'click', true);});// 监听鼠标点击节点graph.on('edge:click', (e) => {// 先将所有当前有 click 状态的边的 click 状态置为 falseconst clickEdges = graph.findAllByState('edge', 'click');clickEdges.forEach((ce) => {graph.setItemState(ce, 'click', false);});const edgeItem = e.item;// 设置目标边的 click 状态 为 truegraph.setItemState(edgeItem, 'click', true);});}/*** 对接口数据进行加工*/transformData(data) {for (let i = 0; i < data.nodes.length; i++) {let node = data.nodes[i]console.log(node);if (!node.style) {node.style = {}}switch (node.class // 根据节点数据中的 class 属性配置图形) {case 'c0': {node.type = 'circle'; // class = 'c0' 时节点图形为 circlebreak;}case 'c1': {debuggernode.type = 'rect'; // class = 'c1' 时节点图形为 rectnode.size = [35, 20]; // class = 'c1' 时节点大小break;}case 'c2': {node.type = 'ellipse'; // class = 'c2' 时节点图形为 ellipsenode.size = [35, 20]; // class = 'c2' 时节点大小break;}}if(node.imgType){this.transNodeImg(node)}}return data}/*** 根据类型设置image图标* @param node */transNodeImg(node) {node.type = 'image'; node.size = 30switch (node.imgType // 根据节点数据中的 class 属性配置图形) {case '1': {node.img = domainbreak;}case '2': {node.img = equipmentbreak;}case '3': {node.img = assetsbreak;}case '4': {node.img = applicationbreak;}case '5': {node.img = domainYbreak;}case '6': {node.img = equipmentYbreak;}case '7': {node.img = assetsYbreak;}case '8': {node.img = warningYbreak;}case '9': {node.img = domainEbreak;}case '10': {node.img = equipmentEbreak;}case '11': {node.img = assetsEbreak;}case '12': {node.img = warningbreak;}case '13': {node.img = clusterAssetbreak;}case '14': {node.img = belongCenterbreak;}case '15': {node.img = belongCenterbreak;}case '16': {node.img = netDomainbreak;}case '17': {node.img = clusterAssetYbreak;}case '18': {node.img = belongCenterYbreak;}case '19': {node.img = belongCenterYbreak;}case '20': {node.img = netDomainYbreak;}case '21': {node.img = clusterAssetRbreak;}case '22': {node.img = belongCenterRbreak;}case '23': {node.img = belongCenterRbreak;}case '24': {node.img = netDomainRbreak;}}}

页面效果

image.png

image.png

image.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/644660.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

从零学习开发一个RISC-V操作系统(四)丨RISC-V汇编语言编程

本篇文章的内容 一、RISC-V汇编语言简介1.1 RISC-V 汇编语言的基本格式1.2 RISC-V 汇编指令操作对象1.3 RISC-V 汇编指令编码格式1.4 RISC-V 汇编指令分类 二、RISC-V汇编语言详解2.1 add 加法指令2.2 sub 减法指令 本系列是博主参考B站课程学习开发一个RISC-V的操作系统的学习…

linux条件判断练习

1.实现自动生成相应的压缩包 1.写一个脚本&#xff0c;完成如下功能 传递一个参数给脚本&#xff0c;此参数为gzip、bzip2或者xz三者之一&#xff1b; (1) 如果参数1的值为gzip&#xff0c;则使用tar和gzip归档压缩/etc目录至/backups目录中&#xff0c;并命名为/backups/etc-…

PPP协议原理介绍+报文分析+配置指导-RFC1661

个人认为&#xff0c;理解报文就理解了协议。通过报文中的字段可以理解协议在交互过程中相关传递的信息&#xff0c;更加便于理解协议。 因此本文将在PPP协议报文的基础上进行介绍。 关于PPP协议基本原理&#xff0c;可参考RFC1661-The Point-to-Point Protocol (PPP)。 关于P…

【JavaEE】文件操作 —— IO

文件操作 —— IO 1. 文件的属性 文件内容文件大小文件路径文件名称 2. 文件的管理 采用树形结构进行管理。 3. 文件路径 分为两种&#xff1a;相对、绝对路径。 相对路径&#xff1a;相对于当前位置的路径&#xff0c;以“./xxx.xxx”为标志绝对路径&#xff1a;以从盘符…

手动导入jar包到Maven的解决方案(简单有效!)

想要导入一个jar包到项目中&#xff0c;这个jar包在Maven中没有可以尝试以下方式。 第一步 先找到你maven的本地仓库&#xff0c;我的仓库就在这里&#xff0c;你可以根据你安装的maven找到你的目录 第二步 根据坐标创建文件夹。 这个依赖modbus4j.jar&#xff0c;Maven远…

PyQt ------ QTextEditor

PyQt ------ QTextEditor 引言正文示例1------进阶示例 引言 这里给大家介绍一下 PyQt6 中的 QTextEditor 组件用法。 正文 QTextEditor 可以进行多行字符串输出的组件。 想要获取 QTextEditor 组件中当前存放的字符串&#xff0c;需要使用&#xff1a; QTextEditor.toPla…

《GreenPlum系列》GreenPlum初级教程-GreenPlum详细入门教程

文章目录 GreenPlum详细入门教程第一章 GreenPlum介绍1.MPP架构介绍2.GreenPlum介绍3.GreenPlum数据库架构4.GreenPlum数据库优缺点 第二章 GreenPlum单节点安装1.Docker创建centos容器1.1 拉取centos7镜像1.2 创建容器1.3 进入容器1.4 容器和服务器免密操作1.4.1 生成密钥1.4.…

idea创建公用依赖包项目

创建parent项目 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/POM/…

服务器管理平台(6)- Utils

Utils 本篇为服务器管理平台的结篇&#xff0c;讲述一些必要的Util&#xff0c;如钉钉告警、安全加密、远程登录等功能的实现 1、钉钉告警 1.1、SQL配置告警规则 逻辑磁盘容量已使用比例超过90% 超过30天未登录 字段名称字段类型解释Idint自增IDTablestring监测表名Metri…

matlab appdesigner系列-常用18-表格

表格&#xff0c;常用来导入外部表格数据 示例&#xff1a; 导入外界excel数据&#xff1a;data.xlsx 姓名年龄城市王一18长沙王二21上海王三56武汉王四47北京王五88成都王六23长春 操作步骤如下&#xff1a; 1&#xff09;将表格拖拽到画布上 2&#xff09;对app1右键进行…

GPSR路由算法的MATLAB实现

GPSR基于节点地理位置路由信息&#xff0c;采用贪婪策略和右手准则的结合在邻居节点中选择下一跳节点进行数据转发。节点在进行路由选择时&#xff0c;只需知道自己、邻居和目标节点的地理位置信息&#xff0c;无需维护全局网络的链路状态&#xff0c;这在很大程度上降低了网络…

高质量简历模板网站,免费、免费、免费

你们在制作简历时&#xff0c;是不是基本只关注两件事&#xff1a;简历模板&#xff0c;还有基本信息的填写。 当你再次坐下来更新你的简历时&#xff0c;可能会发现自己不自觉地选择了那个“看起来最好看的模板”&#xff0c;填写基本信息&#xff0c;却没有深入思考如何使简历…

基于 Docker 部署 Pingvin Share 文件共享平台

一、Pingvin Share 介绍 Pingvin Share 简介 Pingvin Share 是自托管文件共享平台&#xff0c;是 WeTransfer 的替代方案。 Pingvin Share 特点 在 2 分钟内启动您的实例使用可通过链接访问的文件创建共享没有文件大小限制&#xff0c;只有你的磁盘是你的限制设置共享到期时间…

C++11新特性:final/override控制

override关键字 用于显式标识一个成员函数&#xff08;通常是虚函数&#xff09;是在派生类中重写&#xff08;覆盖&#xff09;了基类中的虚函数。这有助于提高代码的可读性&#xff0c;同时在编译时提供了检查&#xff0c;确保派生类中的函数确实是在基类中有对应的虚函数。…

GZ036 区块链技术应用赛项赛题第3套

2023年全国职业院校技能大赛 高职组 “区块链技术应用” 赛项赛卷&#xff08;3卷&#xff09; 任 务 书 参赛队编号&#xff1a; 背景描述 新能源作为新兴领域&#xff0c;产业呈现碎片化与复杂化的特性&#xff0c;逐渐出现管理困难、供应链金融、可信监管与数…

论文阅读_训练大模型用于角色扮演

英文名称: Character-LLM: A Trainable Agent for Role-Playing 中文名称: 角色-LLM&#xff1a;训练Agent用于角色扮演 文章: [https://arxiv.org/abs/2310.10158](https://arxiv.org/abs/2310.10158) 作者: Yunfan Shao, Linyang Li, Junqi Dai, Xipeng Qiu 机构: 复旦大学…

军事智能中的深度强化学习不同于传统的深度强化学习

在军事智能中&#xff0c;“诡”和“诈”是两个最重要的概念。 “诡”变指的是智能体通过采取一些不可预测或复杂的变化策略来获得优势。诡变可能包括逃避对手的观察或引诱对手采取不利的行动。智能体可以使用诡变来欺骗对手&#xff0c;使其做出错误的决策或暴露其策略。 “诈…

【第七在线】智能商品计划:重塑服装行业的供应链管理

在当今快速变化的市场环境中&#xff0c;供应链管理已成为企业成功的关键因素之一。尤其在服装行业&#xff0c;供应链的效率、灵活性和透明度直接影响着企业的竞争力和盈利能力。随着技术的发展&#xff0c;智能商品计划正逐渐成为重塑供应链管理的强大工具。 一、智能商品计划…

什么是JMeter?我们为什么要用JMeter做性能测试

什么是JMeter&#xff1f;我们为什么要用JMeter做性能测试 什么是JMeter&#xff1f;为什么选择JMeterJMeter的优点JMeter是如何工作的 什么是JMeter&#xff1f; Apache JMeter TM是纯Java开源软件&#xff0c;最初由Apache软件基金会的Stefano Mazzocchi开发&#xff0c;旨在…

如何在Linux上部署Docker容器

一、什么是docker&#xff1f; Docker 是一个开源的应用容器引擎&#xff0c;让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中&#xff0c;然后发布到任何流行的 Linux或Windows 机器上&#xff0c;也可以实现虚拟化。容器是完全使用沙箱机制&#xff0c;相互之间不…