简体   繁体   English

D3延迟添加链接

[英]D3 add link with delay

I want to add some functionality to the D3 graph below, such that each link and its corresponding nodes are added after a delay of 1 second (ie one at a time). 我想在下面的D3图中添加一些功能,以便在1秒的延迟后(即一次)添加每个链接及其对应的节点。 Is there any way to do that? 有什么办法吗?

The data come from an external JSON file (not shown here) that is loaded once. 数据来自加载一次的外部JSON文件(此处未显示)。 Here, we assume that the JSON file will not change over time, so it's just enough if we parse the JSON file once at the beginning. 在这里,我们假设JSON文件不会随时间变化,因此如果我们在开始时解析一次JSON文件就足够了。

      <!DOCTYPE html>
            <meta charset="utf-8">
            <style>

            .link {
              stroke: #ccc;
            }

            .node text {
              pointer-events: none;
              font: 10px sans-serif;
            }

            </style>
            <body>

            <script src="http://d3js.org/d3.v3.min.js"></script>
            <script>

            //Constants for the SVG
            var width = 2480,
                height = 2880;

            //Set up the colour scale
            var color = d3.scale.category10();

            //Set up the force layout


            var force = d3.layout.force()
                .charge(-100)
                .linkDistance(300)
                .size([width, height]);

            //Append a SVG to the body of the html page. Assign this SVG as an object to svg
            var svg = d3.select("body").append("svg")
                .attr("width", width)
                .attr("height", height);

            //Read the data from the mis element 
            d3.json("data.json", function(error, graph) {
              force
                  .nodes(graph.nodes)
                  .links(graph.links)
                  .start();



            //Create all the line svgs but without locations yet
            var link = svg.selectAll(".link")
                .data(graph.links)
                .enter().append("line")
                .attr("class", "link")
                .style("stroke-width", function (d) {
                return Math.sqrt(d.value);
            });

            //Do the same with the circles for the nodes - no 
            //Changed
            var node = svg.selectAll(".node")
                .data(graph.nodes)
                .enter().append("g")
                .attr("class", "node")
                .call(force.drag);

            node.append("circle")
                .attr("r", 8)
                .style("fill", function (d) {
                return color(d.group);
            })

            node.append("text")
                  .attr("dx", 10)
                  .attr("dy", ".35em")
                  .text(function(d) { return d.name });
            //End changed


            //Now we are giving the SVGs co-ordinates - the force layout is generating the co-ordinates which this code is using to update the attributes of the SVG elements
            force.on("tick", function () {
                link.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;
                });

                //Changed

                d3.selectAll("circle").attr("cx", function (d) {
                    return d.x;
                })
                    .attr("cy", function (d) {
                    return d.y;
                });

                d3.selectAll("text").attr("x", function (d) {
                    return d.x;
                })
                    .attr("y", function (d) {
                    return d.y;
                });

                //End Changed

            });

            });

            </script>

Use setTimeOut method. 使用setTimeOut方法。

graph.links.forEach(function(d, i) {
    setTimeout(function() {
        var nodes = graph.nodes.filter(function(n,i){
            return d.source.index==i || d.target.index==i
        });
        nodes.forEach(function(node){
            var nodeG = container.append("g")
                .datum(node)
                .attr("class", "node")
                .attr("cx", function(d) {
                    return d.x;
                })
                .attr("cy", function(d) {
                    return d.y;
                })
                .call(drag);
            nodeG.append("circle")
                .attr("r", function(d) {
                    return d.weight * 2 + 12;
                })
                .style("fill", function(d) {
                    return color(1 / d.rating);
                });
        });
        container.append("line")
            .datum(d)
            .attr("class", "link")
            .style("stroke-width", function(d) {
                return Math.sqrt(d.value);
            });   
       force.resume();  //Restarts the force simulation.  
    }, 1000 * i);
});

Also don't forget to update the tick function as shown below. 同样不要忘记更新滴答功能,如下所示。

force.on("tick", function() {
     container.selectAll(".link")
              .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; });

     container.selectAll(".node")
              .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
});

Working JSFiddle 工作中的JSFiddle

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM