【问题标题】:Moving all nodes the same time including links?同时移动所有节点,包括链接?
【发布时间】:2017-12-08 11:21:57
【问题描述】:

在 D3.js 中,我使用 force-layout 将所有节点向右移动,代码如下。但是当调用该函数时,只有节点移动,文本和链接保持不变。这里究竟缺少什么?是函数内部必须调用的tick()函数吗?

  function(){ d3.select(".nodes").attr("transform", "translate(200,0)");

                simulation.alpha(0.8).restart();


};

        simulation
                    .nodes(nodes)
                    .on("tick", function(d)
                    {

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

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



                    }

                    );

                simulation.force("link")
                    .links(links);

              });

【问题讨论】:

    标签: javascript d3.js nodes force-layout


    【解决方案1】:

    您的函数仅移动包含节点的 g。它不会更新附加到节点的基础数据(d.x 和 d.y)。因此,虽然它们在视觉上移动,但这并不是因为力(或您的代码)更新了 d.x 或 d.y 值。

    【讨论】:

      【解决方案2】:

      正如@TomShanley 在his answer 中所说,您只是在翻译包含<g> 的元素。

      不要那样做。将节点移动到固定位置的惯用方法是设置fxfy,或者使用forceYforceY(都在D3 v4 中)。

      这是一个使用forceX 的演示。首先,我们移除center 力,然后我们将forceX 设置为右侧的位置:

      simulation.force("center", null)
      simulation.force("toRight", d3.forceX(360).strength(0.8))
      

      这里是演示,点击按钮移动节点、链接和文本:

      var width = 400;
      var height = 300;
      
      var svg = d3.select("body")
        .append("svg")
        .attr("width", width)
        .attr("height", height);
      
      var nodes = [{
        name: "foo",
        color: "blue"
      }, {
        name: "bar",
        color: "green"
      }, {
        name: "baz",
        color: "red"
      }, {
        name: "foofoo",
        color: "yellow"
      }, {
        name: "foobar",
        color: "blue"
      }, {
        name: "foobaz",
        color: "green"
      }, {
        name: "barfoo",
        color: "red"
      }, {
        name: "barbar",
        color: "yellow"
      }, {
        name: "barbaz",
        color: "blue"
      }];
      
      var links = [{
        "source": 0,
        "target": 1
      }, {
        "source": 0,
        "target": 2
      }, {
        "source": 0,
        "target": 3
      }, {
        "source": 1,
        "target": 3
      }, {
        "source": 1,
        "target": 4
      }, {
        "source": 2,
        "target": 5
      }, {
        "source": 3,
        "target": 6
      }, {
        "source": 1,
        "target": 7
      }, {
        "source": 6,
        "target": 8
      }, {
        "source": 0,
        "target": 7
      }, {
        "source": 2,
        "target": 6
      }, {
        "source": 3,
        "target": 8
      }];
      
      var simulation = d3.forceSimulation()
        .force("link", d3.forceLink())
        .force("charge", d3.forceManyBody().strength(-50))
        .force("center", d3.forceCenter(width / 2, height / 2))
        .force("collide", d3.forceCollide(function(d) {
          return d.r + 1;
        }));
      
      var link = svg.selectAll(null)
        .data(links)
        .enter()
        .append("line")
        .style("stroke", "#ccc")
        .style("stroke-width", 1);
      
      var node = svg.selectAll(null)
        .data(nodes)
        .enter()
        .append("circle")
        .attr("r", function(d) {
          return d.r = 10;
        })
        .attr("stroke", "gray")
        .attr("stroke-width", "2px")
        .attr("fill", function(d) {
          return d.color
        })
        .call(d3.drag()
          .on("start", dragstarted)
          .on("drag", dragged)
          .on("end", dragended));;
      
      var text = svg.selectAll(null)
        .data(nodes)
        .enter()
        .append("text")
        .attr("pointer-events", "none")
        .style("fill", "black")
        .attr("dy", "-1em")
        .attr("dx", "-1em")
        .text(function(d) {
          return d.name;
        });
      
      simulation.nodes(nodes);
      simulation.force("link")
        .links(links);
      
      simulation.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;
          })
      
        node.attr("cx", function(d) {
          return d.x
        }).attr("cy", function(d) {
          return d.y
        });
      
        text.attr("x", function(d) {
          return d.x
        }).attr("y", 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;
      }
      
      d3.select("button").on("click", function(d) {
        simulation.force("center", null)
        simulation.force("toRight", d3.forceX(360).strength(0.8))
        simulation.alpha(0.8).restart();
      })
      <script src="https://d3js.org/d3.v4.js"></script>
      <button>Click me</button>
      <br>

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-01-15
        • 2014-07-23
        • 1970-01-01
        • 1970-01-01
        • 2019-07-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多