使用d3.v3插件繪制出svg圖


眾所周知,這個插件使用的svg技術,而IE8(包括IE8)之前的瀏覽器是不支持svg的

接下來看代碼吧

從后台獲取到帶id和父id的目錄數據[json格式]

var module = requestUrl('/Home/ModuleList', null);
module = eval("(" + module + ")");

 

 再將json拼成需要的svg格式

//svg圖數據
    var treeData = null;
 //如果左側菜單目錄不為空
    if (module.total != 0) {
        var json = "[";
        //循環第一層
        for (var i = 0; i < module.total; i++) {
            //根節點
            var root = module.rows[i].PARENTID;
            //如果為第一層
            if (module.rows[i].LEVEL == '1') {
                json += "{";
                json += "'name': '" + module.rows[i].MODULE + "(" + module.rows[i].MODULEID +")',";
                json += "'parent':'信息管理系統(0)','value': 10,'children': [";
                //當前的模塊ID
                var moduleId = module.rows[i].MODULEID;
                var parentId = null;
                for (var j = 0; j < module.total; j++) {

                    //如果為第二層
                    if (module.rows[j].LEVEL == '2') {
                        //獲取第二層父ID
                        parentId = module.rows[j].PARENTID;
                        var moduleId_children = module.rows[j].MODULEID;
                        //如果第二層父ID等於第一層模塊ID
                        if (moduleId == parentId) {
                            json += "{";
                            json += "'name':'" + module.rows[j].MODULE + "(" + module.rows[j].MODULEID+")',";
                            json += "'parent': '" + module.rows[i].MODULE + "','value': 10,'children': [";

                            for (var k = 0; k < module.total; k++) {
                                if (module.rows[k].LEVEL == '3') {
                                    parentId = null;
                                    parentId = module.rows[k].PARENTID;
                                    if (moduleId_children == parentId) {
                                        json += "{";
                                        json += "'name': '" + module.rows[k].MODULE + "(" + module.rows[k].MODULEID +")','value': 5";
                                        json += "},";
                                    }
                                }
                            }
                            json += "]},";
                        }
                    }
                }
                json += "]},";
            }
        }

        json += "]";
        //svg數據[json]
        treeData = [{
            "name": "信息管理系統(0)",
            "parent": "root",
            "value": 10,
            "children": eval("(" + json + ")")
        }];

 

  接下來是繪制svg圖的代碼:

// ************** Generate the tree diagram  *****************
    //定義樹圖的全局屬性(寬高)
    var margin = { top: 10, right: 120, bottom: 20, left: 400 },
        width = 1200 - margin.right - margin.left,
        height = 600 - margin.top - margin.bottom;

    var i = 0,
        duration = 750,//過渡延遲時間
        root;

    var tree = d3.layout.tree()//創建一個樹布局
        .size([height, width]);

    var diagonal = d3.svg.diagonal()
        .projection(function (d) { return [d.y, d.x]; });//創建新的斜線生成器

    //聲明與定義畫布屬性
    var svg = d3.select("body").append("svg")
        .attr("width", width + margin.right + margin.left)
        .attr("height", height + margin.top + margin.bottom)
        .append("g")
        .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

    root = treeData[0];//treeData為上邊定義的節點屬性
    root.x0 = height / 2;
    root.y0 = 0;

    update(root);

    d3.select(self.frameElement).style("height", "750px");

    function update(source) {

        // Compute the new tree layout.計算新樹圖的布局
        var nodes = tree.nodes(root).reverse(),
            links = tree.links(nodes);

        // Normalize for fixed-depth.設置y坐標點,每層占180px
        nodes.forEach(function (d) { d.y = d.depth * 180; });

        // Update the nodes…每個node對應一個group
        var node = svg.selectAll("g.node")
            .data(nodes, function (d) { return d.id || (d.id = ++i); });//data():綁定一個數組到選擇集上,數組的各項值分別與選擇集的各元素綁定

        // Enter any new nodes at the parent's previous position.新增節點數據集,設置位置
        var nodeEnter = node.enter().append("g")  //在 svg 中添加一個g,g是 svg 中的一個屬性,是 group 的意思,它表示一組什么東西,如一組 lines , rects ,circles 其實坐標軸就是由這些東西構成的。
            .attr("class", "node") //attr設置html屬性,style設置css屬性
            .attr("transform", function (d) { return "translate(" + source.y0 + "," + source.x0 + ")"; })
            .on("click", click);

        //添加連接點---此處設置的是圓圈過渡時候的效果(顏色)
        // nodeEnter.append("circle")
        //   .attr("r", 1e-6);//d 代表數據,也就是與某元素綁定的數據。

        nodeEnter.append("path")
            .style("stroke-width", "2px")
            .style("stroke", "#EB5409")
            .style("fill", "white")
            .attr("d", d3.svg.symbol()
                .size(function (d) {
                    if
                    (d.value <= 9) { return "400"; } else if
                    (d.value >= 9) { return "400"; }
                })
                .type(function (d) {
                    if
                    (d.value <= 9) { return "triangle-up"; } else if
                    (d.value >= 9) { return "circle"; }
                }))
            .attr('class', function (d) {
                if (d.value <= 9) {
                    return 'bling';
                } else {
                    return 'fill_normal';
                }
            });

        //添加標簽
        nodeEnter.append("text")
            .attr("x", function (d) { return d.children || d._children ? -13 : 13; })
            .attr("dy", ".35em")
            .attr("text-anchor", function (d) { return d.children || d._children ? "end" : "start"; })
            .text(function (d) { return d.name; })
            .style("fill-opacity", 1e-6);

        // Transition nodes to their new position.將節點過渡到一個新的位置-----主要是針對節點過渡過程中的過渡效果
        //node就是保留的數據集,為原來數據的圖形添加過渡動畫。首先是整個組的位置
        var nodeUpdate = node.transition()  //開始一個動畫過渡
            .duration(duration)  //過渡延遲時間,此處主要設置的是圓圈節點隨斜線的過渡延遲
            .attr("r", 10)
            .attr("transform", function (d) { return "translate(" + d.y + "," + d.x + ")"; });
        //更新連接點的填充色
        // nodeUpdate.select("circle")
        // .attr("r", 10)
        // .attr('class',function(d){
        //   if(d.value <= 9){
        //     return 'bling';
        //   }else{
        //     return 'fill_normal';
        //   }
        // });
        nodeUpdate.select("path")
            .style("stroke-width", "2px")
            .style("stroke", "#EB5409")
            .style("fill", "white")
            .attr("d", d3.svg.symbol()
                .size(function (d) {
                    if
                    (d.value <= 9) { return "400"; } else if
                    (d.value >= 9) { return "400"; }
                })
                .type(function (d) {
                    if
                    (d.value <= 9) { return "triangle-up"; } else if
                    (d.value >= 9) { return "circle"; }
                }))
            .attr('class', function (d) {
                if (d.value <= 9) {
                    return 'bling';
                } else {
                    return 'fill_normal';
                }
            });

        nodeUpdate.select("text")
            .style("fill-opacity", 1);

        // Transition exiting nodes to the parent's new position.過渡現有的節點到父母的新位置。
        //最后處理消失的數據,添加消失動畫
        var nodeExit = node.exit().transition()
            .duration(duration)
            .attr("transform", function (d) { return "translate(" + source.y + "," + source.x + ")"; })
            .remove();

        nodeExit.select("circle")
            .attr("r", 1e-6);

        nodeExit.select("text")
            .style("fill-opacity", 1e-6);

        // Update the links…線操作相關
        //再處理連線集合
        var link = svg.selectAll("path.link")
            .data(links, function (d) { return d.target.id; });

        // Enter any new links at the parent's previous position.
        //添加新的連線
        link.enter().insert("path", "g")
            .attr("class", "link")
            .attr("d", function (d) {
                var o = { x: source.x0, y: source.y0 };
                return diagonal({ source: o, target: o });  //diagonal - 生成一個二維貝塞爾連接器, 用於節點連接圖.
            })
            .style("stroke", function (d) {
                //d包含當前的屬性console.log(d)
                return '#ccc';
            });

        // Transition links to their new position.將斜線過渡到新的位置
        //保留的連線添加過渡動畫
        link.transition()
            .duration(duration)
            .attr("d", diagonal);

        // Transition exiting nodes to the parent's new position.過渡現有的斜線到父母的新位置。
        //消失的連線添加過渡動畫
        link.exit().transition()
            .duration(duration)
            .attr("d", function (d) {
                var o = { x: source.x, y: source.y };
                return diagonal({ source: o, target: o });
            })
            .remove();

        // Stash the old positions for transition.將舊的斜線過渡效果隱藏
        nodes.forEach(function (d) {
            d.x0 = d.x;
            d.y0 = d.y;
        });

    }

    //定義一個將某節點折疊的函數
    //Toggle children on click.切換子節點事件
    function click(d) {
        if (d.children) {
            d._children = d.children;
            d.children = null;
        } else {
            d.children = d._children;
            d._children = null;
        }
        update(d);
    }

    // 定義菜單選項
    var userMenuData = [
        [
            {
                text: "添加",
                func: function () {
                    // id為節點id
                    var id = $(this).children("text").html();
                    id = id.substring(id.indexOf("(") + 1, id.indexOf(")"));
                    showDialog(id);
                }
            },
            {
                text: "修改",
                func: function () {
                    var id = $(this).children("text").html();
                    id = id.substring(id.indexOf("(") + 1, id.indexOf(")"));
                    showEditDialog(id);
                }
            },
            {
                text: "禁用",
                func: function () {
                    var id = $(this).children("text").html();
                    id = id.substring(id.indexOf("(") + 1, id.indexOf(")"));
                   
                }
            },
            {
                text: "刪除",
                func: function () {
                    var id = $(this).children("text").html();
                    id = id.substring(id.indexOf("(") + 1, id.indexOf(")"));
                    deleteAppModule(id);
                }
            }
        ]
    ];
    // 事件監聽方式添加事件綁定
    $("g").smartMenu(userMenuData, {
        name: "chatRightControl",
        container: "g.node"
    });

 

  效果如下圖:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM