前端使用dagre-d3生成流程图的那些事儿

这两天遇到这样一个需求,在前端页面展示流程图,我之前没有做过类似的需求,就来找万能的度娘 了。流程图根据需求不同,展示的形式有所不同,但是本质还是一致的。经过百度搜索,我找到了几种方案,简单给大家介绍一下:

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;
 

以上就是我在工作中的一点小心得,若有错误欢迎指正,希望可以和大家多多交流,提升技术。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

------------------ 
作者:娜娜的小幸福 
来源:CSDN 
原文:https://blog.csdn.net/nn1523713/article/details/87722959 
版权声明:本文为博主原创文章,转载请附上博文链接!

 

 

 

 

 

 

 

 

 

 

 

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页