当前位置:   article > 正文

vue利用dagre-d3/dagre实现动态流程图_vue实现动态流图

vue实现动态流图

vue利用dagre-d3/dagre实现动态流程图:

实现动态流程图效果

例如:
项目场景:示例:实时监控项目请求接口数据,这期间数据是从网页到服务器或者到数据库等等的过程,想要一个可以直接清晰了解过程的流程图


安装

必须要安装这两个依赖,可以不用在main.js里面全局安装,放在自己需要的vue文件里面局部引入就好了

官网地址:
dagre: https://github.com/dagrejs/dagre
dagre-d3: https://github.com/dagrejs/dagre-d3

import dagreD3 from "dagre-d3";
import * as d3 from "d3";
  • 1
  • 2

版本号很重要,会直接影响到效果能否正常展示,这里我在项目里面的版本号如下:

"d3": "^5.16.0",
"dagre-d3": "^0.6.4",
  • 1
  • 2

流程图的简单复杂度是根据数据动态生成,效果图如下:


配置项:

graph配置

g.setGraph({
   rankdir:'LR', //默认'TB'  设置 node 节点的延伸排列方向,它有4个值: TB, BT, LR, 或者 RL 可选,默认是’TB’(从上到下)
   align:'DL',  //node节点的对齐方式
   nodesep: 100,  //相同层级中节点的间距  默认 50
   edgesep:100,  //一个节点同事有多条连接线之间的间距  默认10
   ranksep: 50,   //相邻层级之间的间距  默认50
   marginx:50,   //图整体与画布的左右间距。默认 0
   marginy:100  //图整体与画布的上下间距。默认 0
});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

node配置

			g.setNode(node.id, {
                id: node.id,
                // label: node.title,
                label:labelVal,
                labelType:'html',  
                shape: 'rect',  //节点形状,可以设置rect(长方形),circle,ellipse(椭圆),diamond(菱形) 四种形状,还可以使用render.shapes()自定义形状
                style: this.boxStyle,  //节点样式,可设置节点的颜色填充、节点边框
                labelStyle: 'fill: #515a6e;',  //节点标签样式, 可设置节点标签的文本样式(颜色、粗细、大小)
                rx: 5,  // 设置圆角
                ry: 5,  // 设置圆角
                paddingBottom: 15,
                paddingLeft: 10,
                paddingRight: 10,
                paddingTop: 5,
            });
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

edge配置

				g.setEdge(edge.from, edge.to, {
                    label: edge.label,  //边标签
                    style: 'stroke: #515a6e; fill: none; stroke-width: 2px',  // 连线样式
                    arrowheadStyle: 'fill: #515a6e;stroke: #515a6e;',  //箭头样式,可以设置箭头颜色
                    arrowhead: 'normal',  //箭头形状,可以设置 normal,vee,undirected 三种样式,默认为 normal
                })
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

完整代码:

提示:想要鼠标悬停或者是鼠标点击的时候要加点其他的样式直接在注释的方法里面写就好了

<template>
    <div>
        <svg class="dagre" style="width:600px;height:150px">
            <g class="container"></g>
        </svg>
    </div>
</template>
<script>
import dagreD3 from  'dagre-d3';
import * as d3 from  'd3';
import {getTraceGraphV2,detailV2} from '@/services/monitoringStationApi'
export default {
  name: 'dagre',
  props:{
    needTraceId:{
        type:String,
        require:true
    }
  },
  data() {
    return {
        nodes: [],
        edges: [],
        boxStyle:'fill:#fff;stroke:#515a6e',
        boxStyles:''
    };
  },
  watch:{
    needTraceId:{
        handler(val) {
            if (val) {
                getTraceGraphV2(data).then(res=>{
                    if(res.data.graphView){
                        this.nodes = res.data.graphView.nodes
                        this.edges = res.data.graphView.edges
                        this.draw();
                    }
                })
            }
        },
        deep: true,
        immediate: true,
    },
  },
  mounted() {
    
  },
  methods: {
    // 绘制简单的流程图
    draw() {
        // 创建 Graph 对象
        const g = new dagreD3.graphlib.Graph().setGraph({
                    rankdir: 'LR', // 流程图从下向上显示,默认'TB',可取值'TB'、'BT'、'LR'、'RL'
                  }).setDefaultEdgeLabel(function() { return {}; });
 
        // Graph添加节点
        this.nodes.forEach(node => {
            if(node.icon =="server"){
                var labelVal = "<div class='labelContent'>" + 
                                "<span class='iconfont' style='width:50px;height:50px'>&#xe639;</span>"+ " "+
                                "<span class='labelTitle'>" + node.title + "</span>" + "<br/>" +
                                "<span class='subTitle'>" + node.subTitle + "</span>"
            }else{
                var labelVal = "<div class='labelContent'>" + 
                                "<span class='iconfont' style='width:50px;height:50px'>&#xe61e;</span>"+ " "+
                                "<span class='labelTitle'>" + node.title + "</span>" + "<br/>" +
                                "<span class='subTitle'>" + node.subTitle + "</span>"
            }
            
            g.setNode(node.id, {
                id: node.id,
                // label: node.title,
                label:labelVal,
                labelType:'html',
                shape: 'rect',  //节点形状,可以设置rect(长方形),circle,ellipse(椭圆),diamond(菱形) 四种形状,还可以使用render.shapes()自定义形状
                style: this.boxStyle,  //节点样式,可设置节点的颜色填充、节点边框
                labelStyle: 'fill: #515a6e;',  //节点标签样式, 可设置节点标签的文本样式(颜色、粗细、大小)
                rx: 5,  // 设置圆角
                ry: 5,  // 设置圆角
                paddingBottom: 15,
                paddingLeft: 10,
                paddingRight: 10,
                paddingTop: 5,
            });
        });
 
        // Graph添加节点之间的连线
        if(this.nodes.length > 1) {
            this.edges.forEach(edge => {
                g.setEdge(edge.from, edge.to, {
                    //边标签
                    label: edge.label,
                    style: 'stroke: #515a6e; fill: none; stroke-width: 2px',  // 连线样式
                    arrowheadStyle: 'fill: #515a6e;stroke: #515a6e;',  //箭头样式,可以设置箭头颜色
                    arrowhead: 'normal',  //箭头形状,可以设置 normal,vee,undirected 三种样式,默认为 normal
                })
            });
        }
 
        // 获取要绘制流程图的绘图容器
        const container = d3.select('svg.dagre').select('g.container');
        // 创建渲染器
        const render = new dagreD3.render();
        // 在绘图容器上运行渲染器绘制流程图
        render(container, g);
 
        // 拖拽缩放
        const svg = d3.select('svg.dagre');
        let zoom = d3.zoom().scaleExtent([0.5, 2]).on('zoom', current => {
          container.attr('transform', current.transform);
        });
        svg.call(zoom);
 
        
        // // 鼠标悬停显示隐藏tooltip
        // const that = this;
        // const tooltipBox = that.$refs.tooltip;
        // container.on('mouseover', e => {
        //   that.currentNode = that.nodes.filter(item => item.id === Number(e.target.__data__))[0];
        //   tooltipBox.style.display = 'block';
        //   tooltipBox.style.top = e.clientY + 5 + 'px';
        //   tooltipBox.style.left = e.clientX + 'px';
        // }).on('mouseout', function () {
        //   tooltipBox.style.display = 'none';
        // })
        
        //鼠标点击节点样式变化
        svg.selectAll("g.node").on('click', function (id, index) {
            console.log(id,index,'12444122222')
        // 选中样式变化
            this.boxStyle = 'fill:#fff;stroke:#2894ff'
            const val = index 
            // for (i = 0; i < array.length; i++) {
                d3.select();
            // }
            //     d3.select(this.children[0]).style("stroke","dodgerblue").style("stroke-width", "2.5px")
            // if (operation != null) {
            //     operation.nodeClick(id,index,array)
            // }
        })
        return g;
    },
  },
};
</script>
<style>
.container{
    background-color: aqua;
}
</style>


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152

后端数据:

提示:edges是根据from和to进行区分从哪个节点到哪个节点的,nodes就是节点具体要展示的信息

在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/563036
推荐阅读
相关标签
  

闽ICP备14008679号