D3.js 力学图 点击节点新增节点

D3.js 力学图 点击节点新增节点

摘要

D3.js 力学图 点击节点新增节点

HTML


<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <script src="jquery-1.11.2.js"></script>
    <script src="d3.min.js" charset="utf-8"></script>
    <title></title>
    <style>
        circle {
            cursor: pointer;
        }
    </style>
</head>

<body style="height: 100%;">
<div class="container" style="padding-left: 0; width: 100%;">
    <div id="svg">
    </div>
</div>

<script>
    $(document).ready(function () {
        var height = document.body.clientHeight;
        var width = document.body.clientWidth;

        var nodes = [{'name': '0'},
            {'name': '1'},
            {'name': '2'},
            {'name': '3'},
            {'name': '4'},
            {'name': '5'},
            {'name': '6'}];
        var links = [{'source': 0, 'target': 1},
            {'source': 0, 'target': 2},
            {'source': 0, 'target': 3},
            {'source': 0, 'target': 4},
            {'source': 0, 'target': 5},
            {'source': 0, 'target': 6}];


        var color = d3.scale.category20();
        var edgeWidth = 2;
        var r = 30;
        var svg = d3.select("#svg").append("svg")
                .attr("width", width)
                .attr("height", height);

        var force = d3.layout.force()
                .nodes(nodes)
                .links(links)
                .size([width, height])
               .linkDistance(100)
                .friction(0.8)
               .charge(-1000)
                .start();

        force.on("tick", function (d) {
            //更新连线坐标
            svg_links.attr("x1", function (d) {
                return d.source.x;
            })
                    .attr("y1", function (d) {
                        return d.source.y;
                    })
                    .attr("x2", function (d) {
                        return d.target.x;
                    })
                    .attr("y2", function (d) {
                        return d.target.y;
                    });
            //更新节点坐标   cricle
            svg_nodes.attr("cx", function (d) {
                return d.x;
            })
                    .attr("cy", function (d) {
                        return d.y;
                    });
            svg_nodes.attr("transform", function (d) {
                return "translate(" + d.x + "," + d.y + ")";
            });
        });


//        var svg_links = svg.selectAll("svg:g").data(links);
//        var svg_nodes = svg.selectAll("svg:g").data(nodes);

        var svg_links = svg.append('svg:g').selectAll('link').data(links);
        var svg_nodes = svg.append('svg:g').selectAll('node').data(nodes);

        //边
        svg_links.enter()
                .append("line")
                .style("stroke", "#ccc")
                .style("stroke-width", 2);

        var g = svg_nodes.enter()
                .append("g")
                .call(force.drag);    //使得节点能够拖动

        g.append("circle")
                .attr("r", r)
                .style("fill", function (d, i) {
                    return color(i);
                })
                .on("click", function (d, i) {
                    update(i);
                    lastClick = i;
                });

        g.append("text")
                .attr("dx", function (d, i) {
                    return -16 * (nodes[i].name.length);
                })
                .attr("dy", 5)
                .attr("fill", "#fff")
                .attr("class", "cb-svg-text")
                .style("font-size", 16)
                .text(function (d, i) {
                    if (i == 0) {
                        return "点我";
                    }
                    return "";
                });

        var colorIndex = 8;

        //更新
        function update(i) {
            var count = Math.ceil(Math.random() * 5);
            for (var k = 0; k < count; k++) {
                nodes.push({'name': 'xxx'});
                links.push({'source': i, 'target': nodes.length - 1});
            }

            svg_links = svg_links.data(links);
            svg_links.enter()
                    .append("line")
                    .style("stroke", "#ccc")
                    .style("stroke-width", 2);
            svg_links.exit().remove();

            svg_nodes = svg_nodes.data(nodes);
            g = svg_nodes.enter()
                    .append("g");    //使得节点能够拖动

            g.append("circle")
                    .attr("r", r)
                    .style("fill", function () {
                        return color(colorIndex++);
                    })
                    .on("click", function (d, i) {
                        update(i);
                        lastClick = i;
                    })
                    .call(force.drag);
            svg_nodes.exit().remove();

            force.start();

        }


        //回车事件
//        $(document).keydown(function (e) {
//            if (e.which == 13) {
//                update(lastClick);
//            }
//        });


    });

</script>

</body>
</html>

效果图