javascript - D3 延迟添加链接

标签 javascript svg d3.js force-layout

我想在下面的 D3 图表中添加一些功能,以便在延迟 1 秒后添加每个链接及其对应的节点(即一次添加一个)。有什么办法吗?

数据来自加载一次的外部 JSON 文件(此处未显示)。这里,我们假设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>

最佳答案

使用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);
});

另外不要忘记更新刻度函数,如下所示。

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

关于javascript - D3 延迟添加链接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29624177/

相关文章:

javascript - sleep 没有在 async 函数中定义吗?

javascript - jQuery UI 可拖动捕捉标尺

javascript - 如何在 javascript/lodash 中将字符串数组转换为键控对象

html - 使用 css 自定义图像形状

html - D3截图转PDF

javascript - Ext.select 上的 Extjs 5.1 事件。无法在 Ext.dom.Fly 实例上使用 addListener()

css - 使用CSS动画填充SVG中的路径元素

javascript - 传单 Google map 和 d3 Voronoi 图叠加

javascript - 将 Javascript 对象转换为数字数组

javascript - 使用 d3js-wordcloud Angular 指令将 SVG 导出为 PNG