无需拖动即可将节点移动到某个位置
Move a node to a certain position withou dragging
我使用 D3.js,我希望在单击按钮后节点移动到特定位置 (1; 1000)。
onclick 函数如下所示:
var node = svg.append("g")
.attr("class", "nodes")
.selectAll("circle")
.data(nodes)
.enter().append("circle")
.attr("r", 8)
.attr("fill", (d, i) => colours[i % 2])
.style("stroke", "#000")
button.on("click", function(d) {
nodes[1].x = 1;
nodes[1].y = 1000;
nodes[1].px = 1;
nodes[1].py = 1000;
nodes[1].fixed = true; };
我的问题是这不能正常工作。有人可以帮助我吗?
非常感谢!
看起来您只为该节点设置了 'data'。然后需要将该数据应用于相关 DOM 元素的属性。如果没有看到更多您的代码,我不知道答案,但是例如使用 "translate" 移动 "g" 元素,或使用其 "cx" 和 "cy" 属性进行循环。
您必须重新加热模拟。在 v4 中:
simulation.alpha(0.8).restart();
//value here------^
//between 0 and 1
这里有一个demo,点击按钮将第一个节点的位置设置到左上角(同样,我使用的是v4):
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) {
nodes[1].fx = 20;
nodes[1].fy = 30;
simulation.alpha(0.8).restart();
})
<script src="https://d3js.org/d3.v4.js"></script>
<button>Click me</button>
<br>
我使用 D3.js,我希望在单击按钮后节点移动到特定位置 (1; 1000)。
onclick 函数如下所示:
var node = svg.append("g")
.attr("class", "nodes")
.selectAll("circle")
.data(nodes)
.enter().append("circle")
.attr("r", 8)
.attr("fill", (d, i) => colours[i % 2])
.style("stroke", "#000")
button.on("click", function(d) {
nodes[1].x = 1;
nodes[1].y = 1000;
nodes[1].px = 1;
nodes[1].py = 1000;
nodes[1].fixed = true; };
我的问题是这不能正常工作。有人可以帮助我吗?
非常感谢!
看起来您只为该节点设置了 'data'。然后需要将该数据应用于相关 DOM 元素的属性。如果没有看到更多您的代码,我不知道答案,但是例如使用 "translate" 移动 "g" 元素,或使用其 "cx" 和 "cy" 属性进行循环。
您必须重新加热模拟。在 v4 中:
simulation.alpha(0.8).restart();
//value here------^
//between 0 and 1
这里有一个demo,点击按钮将第一个节点的位置设置到左上角(同样,我使用的是v4):
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) {
nodes[1].fx = 20;
nodes[1].fy = 30;
simulation.alpha(0.8).restart();
})
<script src="https://d3js.org/d3.v4.js"></script>
<button>Click me</button>
<br>