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.rhkb.cn/news/245244.html

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

相关文章

Javadoc的讲解使用

概述&#xff1a;JavaDoc 是用于生成 Java 代码文档的工具。通过编写 JavaDoc 注释&#xff0c;可以为代码中的类、接口、方法、字段等元素添加文档注释&#xff0c;这些注释将被 JavaDoc 工具解析并生成相应的 HTML 文档。 目录 讲解 使用 结果 讲解 下面是一些关于 Java…

MCU常用外设总线

目录 前言一、时钟与中断二、GPIO三、ADC四、定时器4.1 基本定时器4.2 通用定时器4.2.1 输入捕获4.2.2 输出比较 五、UART5.1 通讯的基本概念5.1.1 串行通讯与并行通讯5.1.2 全双工、半双工及单工通讯5.1.3 同步通讯与异步通讯5.1.4 通信速率 5.2 异步串口UART5.2.1 物理层5.2.…

如何使用iPhone或iPad上的二维码共享Wi-Fi密码?这里有详细步骤

你有没有想过在不泄露网络密码的情况下与客人共享你的家庭或工作Wi-Fi?你肯定不是第一个这样想的人,我们很高兴地通知你,多亏了以下这个的变通方法,你现在可以使用iPhone或iPad做到这一点。 通常,如果你想让其他人访问网络,你需要共享你的Wi-Fi密码。苹果通过引入与任何…

嵌入式-stm32-江科大-EXTI外部中断

文章目录 一&#xff1a;EXTI外部中断&#xff08;external interrupt&#xff09;1.1 STM32 中断系统1.2 STM32外部中断EXTI1.3 实验&#xff1a;对射式红外传感器计次1.31 编程感想 1.4 实验&#xff1a;旋转编码器计次1.41 编程感想 道友&#xff1a;没有永久的巅峰也没有永…

Influxdb系列(一)influxdb2.7.x的部署安装

一、influxdb的介绍 InfluxDB 是一种时序数据库&#xff0c;时序数据库通常被用在监控场景&#xff0c;比如运维和 IOT&#xff08;物联网&#xff09;领域。这类数据库旨在存储时序数据并实时处理它们。 比如。我们可以写一个程序将服务器上 CPU 的使用情况每隔 10 秒钟向 In…

JVM-初始JVM

什么是JVM JVM 全称是 Java Virtual Machine&#xff0c;中文译名 Java虚拟机。JVM 本质上是一个运行在计算机上的程序&#xff0c;他的职责是运行Java字节码文件。 Java源代码执行流程如下&#xff1a; JVM的功能 1 - 解释和运行 2 - 内存管理 3 - 即时编译 解释和运行 解释…

2024转行程序员的请注意:均月薪在40-70k

前言 2023年&#xff0c;对大多数行业来说都是不太好过的一年。 对程序员来说也是如此&#xff0c;很多粉丝朋友都在说android工作特别难找&#xff0c;一个岗位都是几千份简历…大家心里都是特别的焦虑&#xff0c;本以为2024年就业情况会有好转&#xff0c;但实际上并非如此…

《WebKit 技术内幕》学习之十三(1):移动WebKit

1 触控和手势事件 1.1 HTML5规范 随着电容屏幕的流行&#xff0c;触控操作变得前所未有的流行起来。时至今日&#xff0c;带有多点触控功能已经成为了移动设备的标准配置&#xff0c;基于触控的手势识别技术也获得巨大的发展&#xff0c;如使用两个手指来缩放应用的大小等。…

基于SSM的蛋糕甜品店管理系统(有报告)。Javaee项目。ssm项目。

演示视频&#xff1a; 基于SSM的蛋糕甜品店管理系统&#xff08;有报告&#xff09;。Javaee项目。ssm项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&#xff0c;通过Spring…

C++ 数论相关题目(欧拉函数、筛法求欧拉函数)

1、欧拉函数 给定 n 个正整数 ai &#xff0c;请你求出每个数的欧拉函数。 欧拉函数的定义 1∼N 中与 N 互质的数的个数被称为欧拉函数&#xff0c;记为 ϕ(N) 。 若在算数基本定理中&#xff0c;Npa11pa22…pamm &#xff0c;则&#xff1a; ϕ(N) Np1−1p1p2−1p2…pm−1p…

SpringBoot项目多数据源配置与MyBatis拦截器生效问题解析

在日常项目开发中&#xff0c;由于某些原因&#xff0c;一个服务的数据源可能来自不同的库&#xff0c;比如&#xff1a; 对接提供的中间库&#xff0c;需要查询需要的数据同步数据&#xff0c;需要将一个库的数据同步到另一个库&#xff0c;做为同步工具的服务对接第三方系统…

肺癌相关文献6

第十四篇 Classification of lung adenocarcinoma based on stemness scores in bulk and single cell transcriptomes IF&#xff1a;6.0 中科院分区:2区 生物学WOS分区&#xff1a;Q1被引次数&#xff1a; 4 背景&#xff1a;癌细胞具有无限期自我更新和增殖的能力[2]。在一…

JavaScript进阶:WebAPIs重点知识整理1

目录 1 DOM修改元素内容 2 DOM修改元素常见属性 3 修改元素样式属性 3.1 通过style修改元素样式 3.2 通过类名className修改元素样式 3.3 通过classList修改元素样式 4 操作表单元素属性 5 自定义属性 6 定时器 7 事件监听 7.1 点击事件 click 7.2 鼠mouseenter和移…

Laya3.0 相机使用

摄像机&#xff0c;是3D场景里边最经常使用的对象了。 官方文档&#xff1a;点击这里学习 1.投影 Projection 透视&#xff1a; 模拟人眼的视觉效果&#xff0c;近大远小。模拟物理世界的规律&#xff0c;将眼睛或相机抽象成一个点&#xff0c;此时视锥体内的物体投影到视平…

YOLO 自己训练一个模型

一、准备数据集 我的版本是yolov8 8.11 这个目录结构很重要 ultralytics-main | datasets|coco|train|val 二、训练 编写yaml 文件 # Train/val/test sets as 1) dir: path/to/imgs, 2) file: path/to/imgs.txt, or 3) list: [path/to/imgs1, path/to/imgs2, ..] path…

Java项目:基于SSM框架实现同城蔬菜配送管理系统(SSM+B/S架构+源码+数据库+毕业论文)

一、项目简介 本项目是一套ssm825基于SSM框架实现同城蔬菜配送管理系统&#xff0c;主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的Java学习者。 包含&#xff1a;项目源码、数据库脚本等&#xff0c;该项目附带全部源码可作为毕设使用。 项目都经过严格调试&…

【Web前端开发基础】CSS3之空间转换和动画

CSS3之空间转换和动画 目录 CSS3之空间转换和动画一、空间转换1.1 概述1.2 3D转换常用的属性1.3 3D转换&#xff1a;translate3d&#xff08;位移&#xff09;1.4 3D转换&#xff1a;perspective&#xff08;视角&#xff09;1.5 3D转换&#xff1a;rotate3d&#xff08;旋转&a…

集美大学“第15届蓝桥杯大赛(软件类)“校内选拔赛 D矩阵选数

经典的状态压缩DP int dp[15][(1<<14)10]; int a[15][15]; void solve() {//dp[i][st]考虑到了第i行 并且当前考虑完第i行以后的选择状态是st的所有方案中的最大值for(int i1;i<13;i)for(int j1;j<13;j)cin>>a[i][j];for(int i1;i<13;i){for(int j0;j<…

Web网页生成桌面应用

前言&#xff1a;网页生成桌面指的是将一个网页保存为桌面应用程序的形式&#xff0c;使得用户可以在桌面上直接打开该网页&#xff0c;而不必通过浏览器打开。这种桌面应用程序一般具有独立的窗口、菜单、工具栏等界面元素&#xff0c;能够提供更加方便快捷的使用体验。 实现…

宠物互联网医院系统

在数字时代&#xff0c;宠物医疗迎来了一场革新&#xff0c;动物互联网医院系统以其先进的技术和智能的特性成为宠物护理的领军者。本文将介绍宠物互联网医院系统的一些关键技术和代码示例&#xff0c;揭示这一科技奇迹的实现原理。 1. 远程医疗服务的实现 远程医疗服务是宠…