Reputation: 1400
This is what I'm working with:
var data =
{
name: "flare",
children: [
{name: "analytics", children:[{name: "testera1"},{name: "testera1"},{name: "testera1"},{name: "testera1"},{name: "testera1"}]},
{name: "analytics", children:[{name: "testera1"},{name: "testera1"},{name: "testera1"},{name: "testera1"},{name: "testera1"}]},
{name: "analytics", children:[{name: "testera1"},{name: "testera1"},{name: "testera1"},{name: "testera1"},{name: "testera1"}]},
{name: "analytics", children:[{name: "testera1"},{name: "testera1"},{name: "testera1"},{name: "testera1"},{name: "testera1"}]},
{name: "analytics", children:[{name: "testera1"},{name: "testera1"},{name: "testera1"},{name: "testera1"},{name: "testera1"}]},
{name: "analytics", children:[{name: "testera1"},{name: "testera1"},{name: "testera1"},{name: "testera1"},{name: "testera1"}]},
{name: "analytics", children:[{name: "testera1"},{name: "testera1"},{name: "testera1"},{name: "testera1"},{name: "testera1"}]},
{name: "analytics", children:[{name: "testera1"},{name: "testera1"},{name: "testera1"},{name: "testera1"},{name: "testera1"}]},
]
};
var width = 960,
height = 500,
root;
var force = d3.layout.force()
.linkDistance(80)
.charge(-120)
.gravity(.05)
.size([width, height])
.on("tick", tick);
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
var link = svg.selectAll(".link"),
node = svg.selectAll(".node");
root = data;
update();
function update() {
var nodes = flatten(root),
links = d3.layout.tree().links(nodes);
// Restart the force layout.
force
.nodes(nodes)
.links(links)
.start();
// Update links.
link = link.data(links, function(d) { return d.target.id; });
link.exit().remove();
link.enter().insert("line", ".node")
.attr("class", "link");
// Update nodes.
node = node.data(nodes, function(d) { return d.id; });
node.exit().remove();
var nodeEnter = node.enter().append("g")
.attr("class", "node")
.on("click", click)
.call(force.drag);
nodeEnter.append("circle")
.attr("r", function(d) { return Math.sqrt(d.size) / 10 || 4.5; });
nodeEnter.append("text")
.attr("dy", ".35em")
.text(function(d) { return d.name; });
node.select("circle")
.style("fill", color);
}
function tick() {
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("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
}
function color(d) {
return d._children ? "#3182bd" // collapsed package
: d.children ? "#c6dbef" // expanded package
: "#fd8d3c"; // leaf node
}
// Toggle children on click.
function click(d) {
if (d3.event.defaultPrevented) return; // ignore drag
if (d.children) {
d._children = d.children;
d.children = null;
} else {
d.children = d._children;
d._children = null;
}
update();
}
// Returns a list of all nodes under the root.
function flatten(root) {
var nodes = [], i = 0;
function recurse(node) {
if (node.children) node.children.forEach(recurse);
if (!node.id) node.id = ++i;
nodes.push(node);
}
recurse(root);
return nodes;
}
.node circle {
cursor: pointer;
stroke: #3182bd;
stroke-width: 1.5px;
}
.node text {
font: 10px sans-serif;
pointer-events: none;
text-anchor: middle;
}
line.link {
fill: none;
stroke: #9ecae1;
stroke-width: 1.5px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<script src="//d3js.org/d3.v3.min.js"></script>
Basically, everything works fine, except this will start with all children expanded, but I need it to load with collapsed children. I've tried to run
function collapse(d) {
if (d.children) {
d._children = d.children;
d._children.forEach(collapse);
d.children = null;
}
But it didn't help. I've tried to collapse them with:
function collapseAll(){
root.children.forEach(collapse);
collapse(root);
update(root);
}
Didn't work neither.
Upvotes: 0
Views: 549
Reputation: 428
The implementation of your collapse
function seems to be correct. In your collapseAll
function however you're calling collapse
for each child of the root node, and also for the root node itself, thus recursing over the tree twice.
Here's a working fiddle.
Notice that the update
function must be called once before collapsing the nodes, so that they are drawn.
Upvotes: 2