这两天遇到这样一个需求,在前端页面展示流程图,我之前没有做过类似的需求,就来找万能的度娘 了。流程图根据需求不同,展示的形式有所不同,但是本质还是一致的。经过百度搜索,我找到了几种方案,简单给大家介绍一下:
1.做能拖拽和编辑的流程图
推荐使用https://jsplumbtoolkit.com/demos.html,这个网站专门用于生成流程图,基本能满足你的所有需求
2.展示流程图,不对流程图做任何操作
(1)在html页面中使用dagre-d3,生成展示型流程图
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
g.type-current>rect {
fill: #1E9FFF;
}
g.type-success>rect {
fill: green;
}
g.type-fail>rect {
fill: red;
}
text {
font-weight: 300;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serf;
font-size: 14px;
}
.node rect {
stroke: #999;
fill: #fff;
stroke-width: 1.5px;
}
.edgePath path {
stroke: #333;
stroke-width: 1.5px;
}
</style>
</head>
<script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
<script src="http://cpettitt.github.io/project/dagre-d3/v0.3.0/dagre-d3.min.js"></script>
<script src=" http://d3js.org/d3.v3.min.js "></script>
<body>
<svg id="svg-canvas" width=700 height=300></svg>
</body>
<script>
var dataFlow = [{
id: 0,
label: '事项受理',
status: 'success',
target: 1,
back_target:null
},{
id: 1,
label: '初审',
status: 'success',
target: 2,
back_target:null
},{
id: 2,
label: '初审回复',
status: 'success',
target: 3,
back_target:null
},{
id: 3,
label: '事情打回',
status: 'fail',
target: 4,
back_target: 1
},{
id: 4,
label: '事项办结',
status: 'current',
target: null,
back_target:null
},{
id: 5,
label: '候审补正',
status: 'done',
target: null,
back_target:null
}]
// Create the input graph
var g = new dagreD3.graphlib.Graph()
.setGraph({})
.setDefaultEdgeLabel(function () { return {}; });
dataFlow && dataFlow.map((item, i) =>{
g.setNode(item.id, {
label: item.label,
class: "type-" + item.status,
// id: "status" + i
});
// Set up edges, no special attributes.
if(item.target && !item.back_target) {
g.setEdge(item.id,item.target, {})
}else if(item.back_target) {
console.log(1111111)
g.setEdge(item.id,item.target, {})
g.setEdge(item.id,item.back_target, {})
}
})
g.nodes().forEach(function (v) {
var node = g.node(v);
// Round the corners of the nodes
node.rx = node.ry = 5;
});
// Create the renderer
var render = new dagreD3.render();
// Set up an SVG group so that we can translate the final graph.
var svg = d3.select("svg"),
svgGroup = svg.append("g");
// Run the renderer. This is what draws the final graph.
render(d3.select("svg g"), g);
var xCenterOffset = (svg.attr("width") - g.graph().width) / 2;
svgGroup.attr("transform", "translate(" + xCenterOffset + ", 20)");
svg.attr("height", g.graph().height + 40);
</script>
</html>
在html文件中,通过改变节点的class名来显示不同的颜色,展示流程到达的节点
(2)在react项目中使用 dagre-d3生成流程图
在html文件中国我们可以直接通过script标签引入d3,dagre-d3的代码文件,但是在react项目中,我们就不能这样直接引入了,首先要先安装d3,dagre-d3的依赖包,css文件也要单独引入
import React, { Component } from 'react';
import * as d3 from 'd3';
import './Demo.css';
import * as dagreD3 from 'dagre-d3';
class Demo extends Component {
constructor(props) {
super(props);
this.state = {
dataFlow: [{
id: 0,
label: '事项受理',
status: 'success',
target: 1,
back_target: null
}, {
id: 1,
label: '初审',
status: 'success',
target: [3],
back_target: null
}, {
id: 2,
label: '初审回复',
status: 'success',
target: 3,
back_target: null
}, {
id: 3,
label: '事情打回',
status: 'fail',
target: 4,
back_target: 1
}, {
id: 4,
label: '事项办结',
status: 'current',
target: null,
back_target: null
}, {
id: 5,
label: '候审补正',
status: 'done',
target: null,
back_target: null
}]
}
}
componentDidMount() {
this.renderDag();
}
renderDag() {
const { dataFlow } = this.state;
// // Create the input graph
var g = new dagreD3.graphlib.Graph()
.setGraph({})
.setDefaultEdgeLabel(function () { return {}; });
dataFlow && dataFlow.map((item, i) => {
g.setNode(item.id, {
label: item.label,
class: "type-" + item.status,
});
if (item.target && !item.back_target) {
g.setEdge(item.id, item.target, {})
} else if (item.back_target) {
g.setEdge(item.id,item.target, {})
g.setEdge(item.id,item.back_target, {})
}
})
g.nodes().forEach(function (v) {
var node = g.node(v);
// Round the corners of the nodes
node.rx = node.ry = 5;
});
// // Create the renderer
var render = new dagreD3.render();
// // Set up an SVG group so that we can translate the final graph.
var svg = d3.select("svg"),
svgGroup = svg.append("g");
// // Run the renderer. This is what draws the final graph.
render(d3.select("svg g"), g);
console.log(svg,'111', svgGroup)
var xCenterOffset = (svg.attr("width") - g.graph().width) / 2;
svgGroup.attr("transform", "translate(" + xCenterOffset + ", 20)");
svg.attr("height", g.graph().height + 40);
}
//获取dom节点
setNodeTree = (nodeTree) => {
this.nodeTree = nodeTree;
this.nodeTree.background = "yellow";
}
//获取dom节点
setNodeTreeInner = (nodeTreeInner) => {
this.nodeTreeInner = nodeTreeInner;
}
render() {
return (
<svg ref={this.setNodeTree} id="svg-canvas" width= '700px' height='300px' >
<g ref={this.setNodeTreeInner} />
</svg>
)
}
}
export default Demo;
以上就是我在工作中的一点小心得,若有错误欢迎指正,希望可以和大家多多交流,提升技术。