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

标签 javascript d3.js force-layout

我正在尝试更改此示例 https://bl.ocks.org/mbostock/1667139使用路径而不是线,但它不起作用。 我尝试使用自己的刻度函数,如下所示:

function tick() {
            link.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;
        });     
}

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

最佳答案

来自docs (加粗我的):

simulation.tick()

Increments the current alpha by (alphaTarget - alpha) × alphaDecay; then invokes each registered force, passing the new alpha; then decrements each node’s velocity by velocity × velocityDecay; lastly increments each node’s position by velocity.

This method does not dispatch events; events are only dispatched by the internal timer when the simulation is started automatically upon creation or by calling simulation.restart. The natural number of ticks when the simulation is started is ⌈log(alphaMin) / log(1 - alphaDecay)⌉; by default, this is 300.

This method can be used in conjunction with simulation.stop to compute a static force layout. For large graphs, static layouts should be computed in a web worker to avoid freezing the user interface.

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

<!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");

关于javascript - D3.js 静态力布局不适用于路径?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44477260/

相关文章:

代表节点的 Svg 图像,在力有向图中改变节点大小

javascript - 卡住力定向网络图并在 D3 中可拖动

javascript - TypeError : this. 元素为空,Rails with Judge gem

javascript - 检查字符串中的空格

javascript - 类似 jQuery 的配置传递

javascript - 为 D3 中的动态数据生成工具提示

d3.js - 将缩放行为从v3更新到v5

javascript - 下划线绑定(bind) vs jQuery.proxy vs native 绑定(bind)

javascript - 以负值开头的 d3.js bar

javascript - 在 d3 力布局中移动固定节点