關於D3畫流程圖-節點懸浮提示信息和節點形狀的設置

最近開發項目需要根據後臺數據動態畫出流程圖,因此瞭解折磨了一點點D3,官網資料和案例好像比較少說明,經過這些天的挖地三尺地找網上資料,終於折磨出了一點點東西。以下是本人這裏的一個小demo,希望對有需要的朋友有幫助吧。(例子有點粗糙,僅是爲了有個效果而已,實際中應根據數據來正確規範的顯示流程圖)

<!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;
        }

        #tooltip {
            position: absolute;
            width: 150px;
            height: auto;
            padding: 5px;
            background-color: white;
            border: 1px solid #ccc;
            -webkit-border-radius: 10px;
            -moz-border-radius: 10px;
            border-radius: 10px;
            font-style: 12px;
            -webkit-box-shadow: 4px 4px 10px rbga(0, 0, 0, 0.4);
            -moz-box-shadow: 4px 4px 10px rbga(0, 0, 0, 0.4);
            box-shadow: 4px 4px 10px rbga(0, 0, 0, 0.4);
            pointer-events: none;
        }

        #tooltip.hidden {
            display: none;
        }

        #tooltip p {
            margin: 0;
            font-family: sans-serif;
            font-size: 16px;
            line-height: 20px;
        }
    </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> -->

<!--V4版本支持鼠標放大縮小-->
<script src="https://d3js.org/d3.v4.min.js" charset="utf-8"></script>
<script src="https://cdn.bootcss.com/dagre-d3/0.6.3/dagre-d3.js"></script>
<script src="https://code.jquery.com/jquery-1.9.1.min.js"></script>

<body>
    <div id="tooltip" class="hidden">
        <p><strong>提示:</strong></p>
        <p><span id="tooltip_value"></span></p>
    </div>

    <svg id="svg-canvas" width=1000></svg>
</body>
<script>
    
    var dataFlow = [
    {
            id: 0,
            label: '開始',
            status: 'start',
            target: 1,
            back_target: null,
            description: '',
            x: 206,
            y: 60
        },
        {
            id: 1,
            label: '事項受理',
            status: 'success',
            target: 2,
            back_target: null,
            description: 'title666',
            x: 206,
            y: 60
        }, {
            id: 2,
            label: '初審',
            status: 'success',
            target: 3,
            back_target: null,
            description: 'tit677657',
            lineTitle:'是',
            x: 326,
            y: 60
        }, {
            id: 3,
            label: '初審回覆',
            status: 'success',
            target: 4,
            back_target: null,
            description: 'title22111',
            lineTitle:'否',
            x: 266,
            y: 100
        }, {
            id: 4,
            label: '事情打回',
            status: 'fail',
            target: 5,
            back_target: 2,
            description: 'title1111',
            x: 200,
            y: 100
        }, {
            id: 5,
            label: '事項辦結',
            status: 'current',
            target: 7,
            back_target: null,
            description: 'title222',
            x: 383,
            y: 100
        }, {
            id: 6,
            label: '候審補正',
            status: 'done',
            target: null,
            back_target: null,
            description: 'title33333',
            x: 100,
            y: 200
        }, {
            id: 7,
            label: '結束',
            status: 'end',
            target: null,
            back_target: null,
            description: '',
            x: 100,
            y: 200
        }
    ]

    var g = new dagreD3.graphlib.Graph()
        .setGraph({ rankdir: 'LR' })//流程圖方向:LR(左右),RL,TB(上下),BT
        .setDefaultEdgeLabel(function () { return {}; });

    var render = new dagreD3.render();

    var svg = d3.select("svg"),
        svgGroup = svg.append("g");

    //添加鼠標滾輪放大縮小事件
    var zoom = d3.zoom().on("zoom", function () {
        svgGroup.attr("transform", d3.event.transform);
    });
    svg.call(zoom);

    dataFlow && dataFlow.map((item, i) => {
        let shape, fill;
        if(item.back_target!=null){
            shape = 'diamond';
        }else if(item.status=='start'||item.status=='end'){
            shape = 'ellipse';
        }else{
            shape = 'rect';
        }

        if(item.status=='success'){
            fill = 'green';
        }else if(item.status=='fail'){
            fill = 'red';
        }else if(item.status=='current'){
            fill = '#1E9FFF';
        }else{
            fill = 'white';
        }

        g.setNode(item.id, {//畫節點
            label: item.label,
            // class: "type-" + item.status,
            shape:shape,//形狀:circle,ellipse,cross,diamond,square,star,triangle,wye
            style: "stroke-width:2px;fill: "+fill+";",//節點樣式
            description: item.description,
            rx: 5,//矩形節點圓角度
            ry: 5,
            // x: item.x,//座標無效???
            // y: item.y,
            // width: 20,
            // height: 100,
            // id: "status" + i
        });
        if (item.target && !item.back_target) {//畫線
            g.setEdge(item.id, item.target, {
                label:item.lineTitle?item.lineTitle:'',
                style: "stroke: #0fb2cc; fill: none;",//線樣式
                arrowheadStyle: "fill: #0fb2cc;stroke: #0fb2cc;",//箭頭樣式
                arrowhead: 'vee' //箭頭形狀樣式
            })
        } 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);
        // node.rx = node.ry = 5;//控制節點圓角度
        // node.style = "fill: #14ff00;width:100px";//節點顏色
    // });

    render(svgGroup, g);//繪製圖表

    d3.select("body").style("background-color", "#ef9934");//整個頁面背景色

    //鼠標懸停節點事件
    svgGroup.selectAll("g.node").on('mouseover', function (v) {
        //顯示提示信息方案一:更新提示條位置和值
        d3.select("#tooltip")
            .attr("style", "left:" + g.node(v).x + "px" + ";top:" + g.node(v).y + "px")
            .select("#tooltip_value")
            .text("規則描述:" + g.node(v).description);
        //顯示提示條
        d3.select("#tooltip").classed("hidden", false);

        //顯示提示信息方案二:
        // d3.select(this).attr("fill", "#f34848").append("title").text(function (d) {
        //     return "規則描述:" + g.node(v).description;
        // }).attr("id", "tooltip");
    });
    svgGroup.selectAll("g.node").on('mouseout', function (v) {
        //顯示提示信息方案一:隱藏提示條
        d3.select("#tooltip").classed("hidden", true);

        //顯示提示信息方案二:
        // d3.select(this).attr("fill", "rgb(0,0," + (v * 10) + ")");
        // d3.select("#tooltip").remove();
    });


    //節點文字超出寬度時,隱藏並顯示省略號,無效???
    // svgGroup.selectAll("g.node").attr("style", "width:10px;height:100px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;");

    //添加title屬性後,鼠標hover時無效???
    // svgGroup.selectAll("g.node").attr("title", function (v) { return g.node(v).description })
    // //     .each(function (v) { $(this).tipsy({ gravity: "w", opacity: 1, html: true }); });

    var xCenterOffset = (svg.attr("width") - g.graph().width) / 2;
    svgGroup.attr("transform", "translate(" + xCenterOffset + ", 100)");//整個流程圖的位置在界面中,左右上下居中顯示

    // var initialScale = 0.75;
    // svg.call(zoom.transform, d3.zoomIdentity.translate((svg.attr("width") - g.graph().width * initialScale) / 2, 20).scale(initialScale));
    svg.attr("height", 400);

</script>

</html>

效果圖如下:

另外,本人最近還在折磨D3流程圖的座標位置、節點上的文字超出寬度時隱藏顯示省略號的問題,各網友要是有相關知識,有方法的,是否可以分享下呢?

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章