使用d3 v4重新创建可折叠力布局 [英] Recreating collapsible force layout using d3 v4
问题描述
我一直在尝试使用d3js v4创建一个Collapsible force布局,类似于下面的内容: https://mbostock.github.io/d3/talk/20111116/force-collapsible.html
I've been trying to create a Collapsible force layout using d3js v4, similar to this one: https://mbostock.github.io/d3/talk/20111116/force-collapsible.html
我已经能够创建布局本身。但不能更新它。
I've been able to create the layout itself. But not able to update it. Can anyone help?
这是我的js代码:
var width = 960,
height = 600;
var root = {
"name": "server1900",
"children": [{
"name": "server913",
"_children": null,
"children": [{
"name": "server948"
}, {
"name": "server946"
}]
}, {
"name": "server912",
"_children": null,
"children": [{
"name": "server984"
}, {
"name": "server983"
}]
}, {
"name": "server911",
"_children": null,
"children": [{
"name": "server999",
"_children": null,
"children": [{
"name": "server992"
}]
}]
}]
};
root = d3.hierarchy(root);
var i = 0;
var transform = d3.zoomIdentity;;
var nodeSvg, linkSvg, simulation, nodeEnter, linkEnter ;
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.call(d3.zoom().scaleExtent([1 / 2, 8]).on("zoom", zoomed))
.append("g")
.attr("transform", "translate(40,0)");
function zoomed() {
svg.attr("transform", d3.event.transform);
}
simulation = d3.forceSimulation()
.force("link", d3.forceLink().id(function(d) { return d.id; }))
.force("charge", d3.forceManyBody())
.force("center", d3.forceCenter(width / 2, height / 2))
.on("tick", ticked);
update();
function update() {
var nodes = flatten(root);
var links = root.links();
simulation
.nodes(nodes)
simulation.force("link")
.links(links);
linkSvg = svg.selectAll(".link")
.data(links, function(d) { return d.target.id; })
linkSvg.exit().remove();
linkSvg = linkSvg.enter()
.append("line")
.attr("class", "link");
nodeSvg = svg.selectAll(".node")
.data(nodes, function(d) { return d.id; })
nodeSvg.exit().remove();
nodeSvg = nodeSvg.enter()
.append("g")
.attr("class", "node")
.on("click", click)
.call(d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended))
nodeSvg.append("circle")
.attr("r", 4 )
.append("title")
.text(function(d) { return d.data.name; })
nodeSvg.append("text")
.attr("dy", 3)
.attr("x", function(d) { return d.children ? -8 : 8; })
.style("text-anchor", function(d) { return d.children ? "end" : "start"; })
.text(function(d) { return d.data.name; });
}
function ticked() {
linkSvg
.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; });
nodeSvg
.attr("transform", function(d) { return "translate(" + d.x + ", " + d.y + ")"; });
}
function click(d) {
if (d.children) {
d._children = d.children;
d.children = null;
update();
simulation.restart();
} else {
d.children = d._children;
d._children = null;
update();
simulation.restart();
}
}
function dragstarted(d) {
if (!d3.event.active) simulation.alphaTarget(0.3).restart()
simulation.fix(d);
}
function dragged(d) {
simulation.fix(d, d3.event.x, d3.event.y);
}
function dragended(d) {
if (!d3.event.active) simulation.alphaTarget(0);
simulation.unfix(d);
}
function flatten (root) {
// hierarchical data to flat data for force layout
var nodes = [];
function recurse(node) {
if (node.children) node.children.forEach(recurse);
if (!node.id) node.id = ++i;
else ++i;
nodes.push(node);
}
recurse(root);
return nodes;
}
line {
stroke: #666;
}
.node {
pointer-events: all;
}
circle {
stroke: none;
stroke-width: 40px;
}
.node text {
font: 8px sans-serif;
}
<script src="https://d3js.org/d3.v4.0.0-alpha.50.min.js"></script>
这是我的小提琴。 https://jsfiddle.net/t4vzg650/4/
感谢
推荐答案
我忘了在enter()之后合并旧节点。
I forgot to merge old nodes after enter().
link = svg.selectAll(".link").data(links, function(d) { return d.target.id; })
var linkEnter = link.enter().append("line").attr("class", "link");
link = linkEnter.merge(link);
感谢Mike Bostock帮助我解决这个问题。我认为d3 v4有一个问题,证明我没有完全读取更改:|
Thanks to Mike Bostock for helping me with this problem. I thought there was an issue with d3 v4, turns out I didn't read changes fully :|
有关详细信息,请参阅: https://github.com/d3/d3-force/issues/37
Refer this for more info: https://github.com/d3/d3-force/issues/37
固定小提琴: https://jsfiddle.net/t4vzg650/6/
这篇关于使用d3 v4重新创建可折叠力布局的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!