将d3更新为v4后,节点位置出现问题

时间:2016-09-17 13:28:17

标签: d3.js

我想更新"修改部队布局" d3 v4的例子。工作示例是https://bl.ocks.org/mbostock/1095795

但是,当我这样做时,节点出现在左上角。我该如何纠正? 您可以在https://bl.ocks.org/stevescc/f964f8f4658bc11319765f83f67b7f9f

查看我的前叉

要查看我在fork中所做的更改,请参阅here。据我所知,我所做的唯一改变是由于改变为v4而引起的。

以下是完整性的完整index.html。

<!DOCTYPE html>
<meta charset="utf-8">
<style>

.link {
  stroke: #000;
  stroke-width: 1.5px;
}

.node {
  fill: #000;
  stroke: #fff;
  stroke-width: 1.5px;
}

.node.a { fill: #1f77b4; }
.node.b { fill: #ff7f0e; }
.node.c { fill: #2ca02c; }

</style>
<body>
<script src="//d3js.org/d3.v4.js"></script>
<script>

var width = 960,
    height = 500;

var color = d3.scaleOrdinal(d3.schemeCategory10);

var nodes = [],
    links = [];

var force = d3.forceSimulation()    
    .nodes(nodes)
    .force("link", d3.forceLink(links)
        .distance(120))
    .force("charge", d3.forceManyBody().strength(-400))
    .force("X", d3.forceX().x(width/2))
    .force("Y", d3.forceY().y(height/2))
    .on("tick", tick);

var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height);

var node = svg.selectAll(".node"),
    link = svg.selectAll(".link");

// 1. Add three nodes and three links.
setTimeout(function() {
  var a = {id: "a"}, b = {id: "b"}, c = {id: "c"};
  nodes.push(a, b, c);
  links.push({source: a, target: b}, {source: a, target: c}, {source: b, target: c});
  start();
}, 0);

// 2. Remove node B and associated links.
setTimeout(function() {
  nodes.splice(1, 1); // remove b
  links.shift(); // remove a-b
  links.pop(); // remove b-c
  start();
}, 3000);

// Add node B back.
setTimeout(function() {
  var a = nodes[0], b = {id: "b"}, c = nodes[1];
  nodes.push(b);
  links.push({source: a, target: b}, {source: b, target: c});
  start();
}, 6000);

function start() {
  link = link.data(force.force('link').links(), function(d) { return d.source.id + "-" + d.target.id; });
  link.enter().insert("line", ".node").attr("class", "link");
  link.exit().remove();

  node = node.data(force.nodes(), function(d) { return d.id;});
  node.enter().append("circle").attr("class", function(d) { return "node " + d.id; }).attr("r", 8);
  node.exit().remove();

  force.restart();
}

function tick() {
  node.attr("cx", function(d) { return d.x; })
      .attr("cy", function(d) { return d.y; })

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

</script>

2 个答案:

答案 0 :(得分:1)

将块更新(https://bl.ocks.org/mbostock/1095795)到d3 v4。 问题是输入的元素需要与现有元素合并(merge函数)。

答案 1 :(得分:0)

我首先会添加一个中心力或更好的x和y力作为d3.centeringForce修改位置而不是速度,然后在中心或附近添加节点。

这是一个例子: https://bl.ocks.org/tezzutezzu/cd04b3f1efee4186ff42aae66c87d1a7

为了清晰起见,我还更改了节点的创建/删除方式,并添加了一个访问器来选择添加/删除的节点。

更新: 在链接示例中,进入节点的位置与第一个节点相同。您可以通过以下方式修改代码中的函数来实现相同的结果:

function createNode(id) {
	var pos = nodes.length > 1 ? {x: nodes[0].x, y: nodes[0].y} : {x:width/2,y:height/2};
	return {id: id, x: pos.x, y:pos.y}
}