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";
版本号很重要,会直接影响到效果能否正常展示,这里我在项目里面的版本号如下:
"d3": "^5.16.0",
"dagre-d3": "^0.6.4",
流程图的简单复杂度是根据数据动态生成,效果图如下:
配置项:
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
});
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,
});
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
})
完整代码:
提示:想要鼠标悬停或者是鼠标点击的时候要加点其他的样式直接在注释的方法里面写就好了
<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'></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'></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>
后端数据:
提示:edges是根据from和to进行区分从哪个节点到哪个节点的,nodes就是节点具体要展示的信息
版权声明:本文为weixin_45313093原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。