我需要制作具有可拖动功能的“粘性布局”,并尝试在此链接上复制 Mike Bostock 的示例。因为作者在 D3 v3 中编写了该程序,所以我必须将他的代码“升级”到 D3 v4。这意味着必须相应地更改 d3-force 和 d3-drag 语句。虽然原始示例中的逻辑流程很容易理解,但我仍然无法制作自己的版本(参见下面的代码)。问题:经过一定时间(2 - 3 秒)后,节点被拖走,但链接未更新。
我最初的想法集中在拖动函数(.call(drag)),但后来我发现“tick”函数在上述时间后不再运行(我通过在tick中放置一个计数变量得到它函数,然后 console.log 它)。至此,我的脑海里一片空白,无法进一步探索。
问题出在哪里?
var width = 960,
height = 500;
var simulation = d3.forceSimulation()
.force("charge", d3.forceManyBody().strength(-100))
d3.forceX(width)
d3.forceY(height)
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
var drag = d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended);
var link = svg.selectAll(".link")
var node = svg.selectAll(".node")
d3.json("graph.json", function (error, graph) {
if (error) throw error;
simulation.nodes(graph.nodes)
.force("link", d3.forceLink(graph.links))
.on("tick", tick);
link = link.data(graph.links)
.enter().append("line")
.attr("class", "link");
node = node.data(graph.nodes)
.enter().append("circle")
.attr("class", "node")
.attr("r", 12)
.on("dblclick", dblclick)
.call(drag)
});
var count = 0;
function tick() {
count++;
console.log(count);
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 dblclick(d) {
d3.select(this).classed("fixed", d.fixed = false);
// console.log("Is clicking");
}
function dragstarted(d) {
d3.select(this).classed("fixed", d.fixed = true);
console.log("Is dragging");
}
function dragged(d) {
d3.select(this).attr("cx", d.x = d3.event.x).attr("cy", d.y = d3.event.y);
}
function dragended(d) {
d3.select(this).classed("active", false);
}