尝试在D3中获取树布局,以使子节点与子节点更加靠近。这是代码:
var margin = {
top: 20,
right: 120,
bottom: 20,
left: 120
},
width = 960 - margin.right - margin.left,
height = 800 - margin.top - margin.bottom;
var i = 0,
duration = 750,
rectW = 185,
rectH = 45;
var tree = d3.layout.tree()
.nodeSize([200, 40]);
var diagonal = d3.svg.diagonal()
.projection(function (d) {
return [d.x + rectW / 2, d.y + rectH / 2];
});
var svg = d3.select("#body").append("svg").attr("width", 1000).attr("height", 1000)
.call(zm = d3.behavior.zoom().scaleExtent([0,1]).on("zoom", redraw))
.append("g")
.attr("transform", "translate(" + 30 + "," + 20 + ")");
//necessary so that zoom knows where to zoom and unzoom from
zm.translate([350, 20]);
root.x0 = width / 2;
root.y0 = 0;
update(root);
d3.select("#body").style("height", "800px");
function update(source) {
// Compute the new tree layout.
var nodes = tree.nodes(root).reverse(),
links = tree.links(nodes);
// Normalize for fixed-depth.
nodes.forEach(function (d) {
d.y = (d.depth * 120);
});
// Update the nodes…
var node = svg.selectAll("g.node")
.data(nodes, function (d) {
return d.id || (d.id = ++i);
});
// Enter any new nodes at the parent's previous position.
var nodeEnter = node.enter().append("g")
.attr("class", "node")
.attr("transform", function (d) {
return "translate(" + source.x0 + "," + source.y0 + ")";
})
.on("click", click);
// Add rectangles to nodes
nodeEnter.append("rect")
.attr("width", function (d) {
return rectW;
//return d._children ? "lightsteelblue" : "#fff";
})
.attr("height", rectH)
.attr("class", function (d) {
return "rect-" + d.state;
});
// Add text to nodes
nodeEnter.append("text")
.attr("x", rectW / 2)
.attr("y", rectH / 2)
.attr("dy", ".35em")
.attr("text-anchor", "middle")
.text(function (d) {
return d.name;
});
// Transition nodes to their new position.
var nodeUpdate = node.transition()
.duration(duration)
.attr("transform", function (d) {
return "translate(" + d.x + "," + d.y + ")";
});
nodeUpdate.select("rect")
.attr("width", rectW)
.attr("height", rectH)
.attr("class", function (d) {
return "rect-" + d.state;
});
nodeUpdate.select("text")
.style("fill-opacity", 1);
// Update the links…
var link = svg.selectAll("path.link")
.data(links, function (d) {
return d.target.id;
});
// Enter any new links at the parent's previous position.
link.enter().insert("path", "g")
.attr("class", function (d) {
return "link " + d.target.dest;
})
.attr("x", rectW / 2)
.attr("d", function (d) {
var o = {
x: source.x0,
y: source.y0
};
return diagonal({
source: o,
target: o
});
});
// Transition links to their new position.
link.transition()
.duration(duration)
.attr("d", diagonal);
// Transition exiting nodes to the parent's new position.
link.exit().transition()
.duration(duration)
.attr("d", function (d) {
var o = {
x: source.x,
y: source.y
};
return diagonal({
source: o,
target: o
});
}).remove();
// Update the link labels…
var linkLabel = svg.selectAll("text.link-label")
.data(links, function (d) {
return d.target.id;
});
// Enter any new links at the parent's previous position.
linkLabel.enter().insert("text", "path")
.text(function (d) {
return (d.target.state !== "open") ? null : "If " + d.target.dest;
})
.attr("class", function (d) {
return "link-label " + d.target.dest;
})
.attr("x", function (d) {
return d.target.x + rectW / 2;
})
.attr("y", function (d) {
return d.target.y + rectH * 2 - 30;
})
.attr('text-anchor', 'middle')
.style("fill-opacity", 0);;
// Transition link labels
linkLabel.transition()
.delay(duration)
.style("fill-opacity", 1);
// Stash the old positions for transition.
nodes.forEach(function (d) {
d.x0 = d.x;
d.y0 = d.y;
});
}
// Toggle children on click.
function click(d) {
return false;
if (d.children) {
d._children = d.children;
d.children = null;
} else {
d.children = d._children;
d._children = null;
}
update(d);
}
//Redraw for zoom
function redraw() {
//console.log("here", d3.event.translate, d3.event.scale);
svg.attr("transform",
"translate(" + d3.event.translate + ")"
+ " scale(" + d3.event.scale + ")");
}
Here is a jsbin上述代码。我希望看到的是海军色的“节点1”和“节点2”更接近,同时保留没有子节点的节点之间的距离(灰色节点)。
这可能,我该怎么做?
答案 0 :(得分:6)
我找到了答案。这是分离方法。这让我得到了我想要的东西:
tree.separation(function separation(a, b) {
return a.parent == b.parent ? 1 : 1.5;
});