antv/g6绘制数据流向图

这篇具有很好参考价值的文章主要介绍了antv/g6绘制数据流向图。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

在业务开发中需要绘制数据流向图,由于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 = true
        this.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 = 800
        let rectHeight = 600
        const eContainer = document.getElementById("charts1")
        if (eContainer) {
            if (data.nodes.length < 100) {
                eContainer.style.height = '100%'  // 600px
                eContainer.style.minHeight = '600px'  // 600px
                eContainer.style.width = '100%'  // 800px
            } else {
                eContainer.style.height = '1080px'
                eContainer.style.width = '1920px'
            }

            const rectObject = eContainer.getBoundingClientRect()
            rectWidth = rectObject.right - rectObject.left
            rectHeight = 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 = graph
        graph.data(data); // 读取 Step 2 中的数据源到图上
        graph.render(); // 渲染图
        graph.get('canvas').set('localRefresh', false)
        // 监听鼠标进入节点
        graph.on('node:mouseenter', (e) => {
            const nodeItem = e.item;
            // 设置目标节点的 hover 状态 为 true
            graph.setItemState(nodeItem, 'hover', true);
        });
        // 监听鼠标离开节点
        graph.on('node:mouseleave', (e) => {
            const nodeItem = e.item;
            // 设置目标节点的 hover 状态 false
            graph.setItemState(nodeItem, 'hover', false);
        });
        // 监听鼠标点击节点
        graph.on('node:click', (e) => {
            console.log(e);
            this.pointNodeDetail = e.item._cfg.model.pointNodeDetail
            // 先将所有当前有 click 状态的节点的 click 状态置为 false
            const clickNodes = graph.findAllByState('node', 'click');
            clickNodes.forEach((cn) => {
                graph.setItemState(cn, 'click', false);
            });
            const nodeItem = e.item;
            // 设置目标节点的 click 状态 为 true
            graph.setItemState(nodeItem, 'click', true);
        });
        // 监听鼠标点击节点
        graph.on('edge:click', (e) => {
            // 先将所有当前有 click 状态的边的 click 状态置为 false
            const clickEdges = graph.findAllByState('edge', 'click');
            clickEdges.forEach((ce) => {
                graph.setItemState(ce, 'click', false);
            });
            const edgeItem = e.item;
            // 设置目标边的 click 状态 为 true
            graph.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' 时节点图形为 circle
                    break;
                }
                case 'c1': {
                    debugger
                    node.type = 'rect'; // class = 'c1' 时节点图形为 rect
                    node.size = [35, 20]; // class = 'c1' 时节点大小
                    break;
                }
                case 'c2': {
                    node.type = 'ellipse'; // class = 'c2' 时节点图形为 ellipse
                    node.size = [35, 20]; // class = 'c2' 时节点大小
                    break;
                }
            }
            if(node.imgType){
                this.transNodeImg(node)
            }


        }

        return data
    }
    
    /**
     * 根据类型设置image图标
     * @param node 
     */
    transNodeImg(node) {
        node.type = 'image'; 
        node.size = 30
        switch (
        node.imgType // 根据节点数据中的 class 属性配置图形
        ) {
            case '1': {
                node.img = domain
                break;
            }
            case '2': {
                node.img = equipment
                break;
            }
            case '3': {
                node.img = assets
                break;
            }
            case '4': {
                node.img = application
                break;
            }
            case '5': {
                node.img = domainY
                break;
            }
            case '6': {
                node.img = equipmentY
                break;
            }
            case '7': {
                node.img = assetsY
                break;
            }
            case '8': {
                node.img = warningY
                break;
            }
            case '9': {
                node.img = domainE
                break;
            }
            case '10': {
                node.img = equipmentE
                break;
            }
            case '11': {
                node.img = assetsE
                break;
            }
            case '12': {
                node.img = warning
                break;
            }
            case '13': {
                node.img = clusterAsset
                break;
            }
            case '14': {
                node.img = belongCenter
                break;
            }
            case '15': {
                node.img = belongCenter
                break;
            }
            case '16': {
                node.img = netDomain
                break;
            }
            case '17': {
                node.img = clusterAssetY
                break;
            }
            case '18': {
                node.img = belongCenterY
                break;
            }
            case '19': {
                node.img = belongCenterY
                break;
            }
            case '20': {
                node.img = netDomainY
                break;
            }
            case '21': {
                node.img = clusterAssetR
                break;
            }
            case '22': {
                node.img = belongCenterR
                break;
            }
            case '23': {
                node.img = belongCenterR
                break;
            }
            case '24': {
                node.img = netDomainR
                break;
            }

        }
    }

页面效果

antv/g6绘制数据流向图,前端,angular.js

antv/g6绘制数据流向图,前端,angular.js

antv/g6绘制数据流向图,前端,angular.js文章来源地址https://www.toymoban.com/news/detail-822085.html

到了这里,关于antv/g6绘制数据流向图的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 可视化—AntV G6实现节点连线及展开收缩分组

    AntV 是蚂蚁金服全新一代数据可视化解决方案,主要包含数据驱动的高交互可视化图形语法G2,专注解决流程与关系分析的图表库 G6、适于对性能、体积、扩展性要求严苛的场景。 demo使用 数字 模拟真实的节点及分组数据。 combo 内的 nodes 亦是使用 随机数 生成,节点之前的

    2024年02月16日
    浏览(62)
  • AntV G6 的坑之——从卡掉渣到满帧需要几步

    AntV G6 是一款图可视化与分析开源引擎。《AntV G6 的坑之——XXX》系列文章持续更新中,总结常见问题及神坑解决方案。任何问题可在 GitHub Issue 中提问,求 GitHub Star ⭐️https://github.com/antvis/g6 原文链接:https://g6.antv.antgroup.com/manual/faq/performance-opt 在面对复杂数据的图可视分析

    2024年02月16日
    浏览(65)
  • vue2中实现Antv g6 流程图 以及自定义节点

    本案例 antv g6版本: \\\"@antv/g6\\\": \\\"^3.4.8\\\", 效果: 1.引入antv g6和echarts差不多 一定记得给盒子设置宽高 初学者一个,以上如有问题或者错误,多谢指出

    2024年02月13日
    浏览(54)
  • 使用antv/G6在vue项目中开发较复杂样式流程图

    设计师提供了一版样式较复杂的流程图,我搜了一些常用的vue-super-flow和vue-x6-flow等都只支持简单的样式。之前自己写过纯展示流程图不涉及太多交互,感觉还是找一个成熟的插件开发更适合,也方便其他同事参考,所以最后选择了用antv/G6自己个性化开发,总结了使用antv/G6在

    2023年04月09日
    浏览(108)
  • 前端框架之争:Vue.js vs. React.js vs. Angular

    🎉欢迎来到Web前端专栏~前端框架之争:Vue.js vs. React.js vs. Angular ☆* o(≧▽≦)o *☆嗨~我是IT·陈寒🍹 ✨博客主页:IT·陈寒的博客 🎈该系列文章专栏:架构设计 📜其他专栏:Java学习路线 Java面试技巧 Java实战项目 AIGC人工智能 数据结构学习 🍹文章作者技术和水平有限,如果

    2024年02月07日
    浏览(91)
  • 如何基于G6进行双树流转绘制?

    业务背景:CRM系统随着各业务条线对线索精细化分配的诉求逐渐增加,各个条线的流向规则会越来越复杂,各个条线甚至整个CRM的线索流转规则急需一种树形的可视化的图来表达。 技术背景:在开发之前考虑了三种方案,原生canvas、fabric以及G6,三种方案各有优劣势 原生ca

    2024年02月07日
    浏览(29)
  • 如何使用前端框架(React、Angular、Vue.js等)?该如何选择?

    聚沙成塔·每天进步一点点 前端入门之旅:探索Web开发的奇妙世界 欢迎来到前端入门之旅!感兴趣的可以订阅本专栏哦!这个专栏是为那些对Web开发感兴趣、刚刚踏入前端领域的朋友们量身打造的。无论你是完全的新手还是有一些基础的开发者,这里都将为你提供一个系统而

    2024年02月07日
    浏览(56)
  • G6绘制树形图(自定义节点、自定义边、自定义布局)

    在 registerNode 中定义所有的节点 为了使用内置的布局方式,选择参数为 ‘tree-node’ 树节点类型,数据格式可以存在children子节点,效果自动生成子树 cfg 可以拿到数据,如cfg.id、cfg.name 使用 group.addShape(‘rect’, {}) 定义节点 rect 配置参数:https://antv-g6.gitee.io/zh/docs/api/shapeProp

    2024年02月05日
    浏览(34)
  • Vue使用AntV X6绘制流程图(组态呈现)

    先上几个网址 AntV | 蚂蚁数据可视化 AntV X6 图编辑引擎 AntV X6文档 AntV X6 API AntV X6图表示例 上面是一些用到的网址,先说下我项目中的需求,就是要自己绘制出一个我们想要的图,组态化呈现出来,然后这个图中会有很多节点,每个节点都会有自己的状态 ,状态会实时改变,

    2024年02月06日
    浏览(63)
  • K8S基础理论,核心组件,数据流向详解

    目录 第一章.k8s概述 1.1.什么是云原生 1.2.什么是K8S 1.3.K8S的优势 1.4.K8S的功能 1.5.K8S 的特性: 1.6.Kubernetes 集群架构与组件 第二章.K8S的核心组件 2.1.Master 组件 2.2.配置存储中心 2.3.Node 组件 第三章.Kubernetes 核心概念 3.1.Pod 3.2.Pod 控制器 3.3.Label 3.4.Label 选择器(Label selector) 3.5.S

    2024年02月03日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包