代码之家  ›  专栏  ›  技术社区  ›  singmotor

在d3中设置节点间数据运动的动画

  •  1
  • singmotor  · 技术社区  · 6 年前

    我有一个d3v4力定向图。为了简单起见,我们假设 this .

    该图显示了流(如powergrid)。我希望能够动画每个链接,以显示从目标到源的流(移动虚线,气泡等)。

    有人知道怎么做吗?

    1 回复  |  直到 6 年前
        1
  •  2
  •   Xavier Guihot    6 年前

    这里是迈克的“Les Mixy Rable”力有向图的一种稍加修改的版本,其中线条由冲刺组成,其偏移周期性地递增(受 this post ):

    var svg = d3.select("svg"),
        width = +svg.attr("width"),
        height = +svg.attr("height");
    
    var color = d3.scaleOrdinal(d3.schemeCategory20);
    
    var simulation = d3.forceSimulation()
        .force("link", d3.forceLink().id(function(d) { return d.id; }))
        .force("charge", d3.forceManyBody())
        .force("center", d3.forceCenter(width / 2, height / 2));
    
    d3.json("https://gist.githubusercontent.com/mbostock/4062045/raw/5916d145c8c048a6e3086915a6be464467391c62/miserables.json", function(error, graph) {
      if (error) throw error;
    
      var link = svg.append("g")
          .attr("class", "links")
        .selectAll("line")
        .data(graph.links)
        .enter().append("line")
          .attr("stroke-width", function(d) { return Math.sqrt(d.value); });
    
      var node = svg.append("g")
          .attr("class", "nodes")
        .selectAll("circle")
        .data(graph.nodes)
        .enter().append("circle")
          .attr("r", 5)
          .attr("fill", function(d) { return color(d.group); })
          .call(d3.drag()
              .on("start", dragstarted)
              .on("drag", dragged)
              .on("end", dragended));
    
      node.append("title")
          .text(function(d) { return d.id; });
    
      simulation
          .nodes(graph.nodes)
          .on("tick", ticked);
    
      simulation.force("link")
          .links(graph.links);
    
      var lines = d3.selectAll('line');
    
      var offset = 1; 
      setInterval(function() {
        lines.style('stroke-dashoffset', offset);
        offset += 1; 
      }, 50);
    
      function ticked() {
        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; });
    
        node
            .attr("cx", function(d) { return d.x; })
            .attr("cy", function(d) { return d.y; });
      }
    });
    
    function dragstarted(d) {
      if (!d3.event.active) simulation.alphaTarget(0.3).restart();
      d.fx = d.x;
      d.fy = d.y;
    }
    
    function dragged(d) {
      d.fx = d3.event.x;
      d.fy = d3.event.y;
    }
    
    function dragended(d) {
      if (!d3.event.active) simulation.alphaTarget(0);
      d.fx = null;
      d.fy = null;
    }
    .links line {
      stroke: #999;
      stroke-opacity: 0.6;
    }
    
    .nodes circle {
      stroke: #fff;
      stroke-width: 1.5px;
    }
    
    line {
      opacity: 0.5;
      stroke-dasharray: 10, 4;
    }
    <svg width="960" height="600"></svg>
    <script src="https://d3js.org/d3.v4.min.js"></script>

    创建图形后,我们可以开始定期更新虚线偏移:

    var lines = d3.selectAll('line');
    
    // Updates the offset of dashes every 50ms:
    var offset = 1;
    setInterval( function() {
      lines.style('stroke-dashoffset', offset);
      offset += 1; 
    }, 50);
    

    下面是与虚线关联的css:

    line {
      opacity: 0.5;
      stroke-dasharray: 10, 4;
    }