D3.js静态力布局不适用于路径?

时间:2017-06-10 19:27:36

标签: javascript d3.js force-layout

我尝试更改此示例https://bl.ocks.org/mbostock/1667139以使用路径而不是行,但它不起作用。 我尝试使用这样的自己的滴答功能:

target_link_libraries()

我不知道,如果我遗漏某些东西或静态力布局,就不能使用路径。 强制布局,路径正常工作

1 个答案:

答案 0 :(得分:1)

来自docs(加粗矿井):

  

simulation.tick()

     

将当前的alpha增加(alphaTarget - alpha)×alphaDecay;   然后调用每个注册的力量,传递新的alpha;然后   通过速度×velocityDecay递减每个节点的速度;最后   通过速度递增每个节点的位置。

     

此方法不会调度事件;事件只发送   自动启动模拟时的内部计时器   创建或通过调用simulation.restart。蜱虫的自然数量   模拟开始时是⌈log(alphaMin)/ log(1 -   alphaDecay)⌉;默认情况下,这是300。

     

此方法可与simulation.stop结合使用进行计算   静态力布局。对于大图,静态布局应该是   在Web worker中计算,以避免冻结用户界面。

由于它不调度事件,因此永远不会调用或使用您的tick函数。相反,只需更换一行并设置您的路径一次:

<!DOCTYPE html>
<svg width="960" height="500"></svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
  var svg = d3.select("svg"),
    width = +svg.attr("width"),
    height = +svg.attr("height"),
    g = svg.append("g").attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

  var n = 100,
    nodes = d3.range(n).map(function(i) {
      return {
        index: i
      };
    }),
    links = d3.range(n).map(function(i) {
      return {
        source: i,
        target: (i + 3) % n
      };
    });

  var simulation = d3.forceSimulation(nodes)
    .force("charge", d3.forceManyBody().strength(-80))
    .force("link", d3.forceLink(links).distance(20).strength(1).iterations(10))
    .force("x", d3.forceX())
    .force("y", d3.forceY())
    .stop();

  var loading = svg.append("text")
    .attr("dy", "0.35em")
    .attr("text-anchor", "middle")
    .attr("font-family", "sans-serif")
    .attr("font-size", 10)
    .text("Simulating. One moment please…");

  // Use a timeout to allow the rest of the page to load first.
  d3.timeout(function() {
    loading.remove();

    // See https://github.com/d3/d3-force/blob/master/README.md#simulation_tick
    for (var i = 0, n = Math.ceil(Math.log(simulation.alphaMin()) / Math.log(1 - simulation.alphaDecay())); i < n; ++i) {
      simulation.tick();
    }

    g.append("g")
      .attr("stroke", "#000")
      .attr("stroke-width", 1.5)
      .selectAll("line")
      .data(links)
      .enter().append("path")
      .attr("d", function(d) {
        var x1 = d.source.x,
          y1 = d.source.y,
          x2 = d.target.x,
          y2 = d.target.y,
          dx = x2 - x1,
          dy = y2 - y1,
          dr = Math.sqrt(dx * dx + dy * dy),

          // z uzla do ineho uzla
          drx = dr,
          dry = dr,
          xRotation = 0,
          largeArc = 0,
          sweep = 1;

        //do sameho seba
        if (x1 === x2 && y1 === y2) {
          xRotation = -45;
          largeArc = 1;
          drx = 30;
          dry = 30;
          x2 = x2 + 1;
          y2 = y2 + 1;
        }

        return "M" + x1 + "," + y1 + "A" + drx + "," + dry + " " + xRotation + "," + largeArc + "," + sweep + " " + x2 + "," + y2;
      });

    g.append("g")
      .attr("stroke", "#fff")
      .attr("stroke-width", 1.5)
      .selectAll("circle")
      .data(nodes)
      .enter().append("circle")
      .attr("cx", function(d) {
        return d.x;
      })
      .attr("cy", function(d) {
        return d.y;
      })
      .attr("r", 4.5);


  });
</script>

对评论的回应:

要将圆圈和文字附加为“节点”,我会创建一个g的位置,然后将圆圈和文字放入其中:

  var g = node
    .selectAll(".node")
    .data(nodes)
    .enter()
    .append("g")
    .attr("transform", function(d){
      return "translate(" + d.x + "," + d.y + ")";
    });

  g.append("circle")
    .attr("class", "node")
    .attr("stroke", "#fff")
    .attr("r", 28);

  g.append("text")
    .text("test");