在混淆了this awesome example of @mbostck的代码后,我找到了一个解决方案,并将我的代码从树列布局重新编排到树布局。但是我将代码分为两部分:一部分是用ul
和li
HTML元素构建列表。另一部分是用一个大的svg画出路径。
所以第一部分的代码为以下几点:
// This is my HTML container element
var $treelistContainer = d3.select('#treelist');
var tree = d3.layout.tree();
var indent = 15,
nodeTree = 0;
var ul = $treelistContainer.append("ul").classed("treelist",true);
var nodes = tree.nodes(data);
var nodeEls = ul.selectAll("li.item").data(nodes);
//list nodes
var listEnter = nodeEls
.enter()
.append("li")
.attr("class", function(d) {
// set class to node and to leaf (for endpoints) or to root (for stem)
var output = 'item'+(d.parent ? d.children ? '' : ' leaf' : ' root');
// set class to even or to odd, based on its level;
output += ((d.depth % 2) === 0 ? ' even' : ' odd');
return output;
})
.attr("id", function(d,i){return "id"+i})
.style("opacity", 1)
.style("background-color", function(d) {
return colorgrey(d.depth);
})
.append("span").attr("class", "value")
.style("padding-left", function (d) {
return 20 + d.depth * indent + "px";
})
.html(function (d) { return d.name; });
即建立了项目的整个HTML列表。现在来看下一部分的魔力:你必须重新计算x
,y
。我还使用了一个名为nodeTree
的值来为每个层次结构分配一个自己的ID以为其选择不同的颜色。因此,这里的代码:
var nodeTree = 0;
var rootTop = d3.selectAll('li.item')
.filter(function(d,i) {
return i == 0;
})
.node()
.getBoundingClientRect()
.top;
nodes.forEach(function(n, i) {
// Get position of li element
var top = d3.selectAll('li.item')
.filter(function(d2,i2) {
return i2 == i;
})
.node()
.getBoundingClientRect()
.top;
n.x = top - rootTop;//i * 38;
n.y = n.depth * indent;
if (n.depth == 1) nodeTree++;
n.value = nodeTree;
});
下面我简单宣读了X,Y和值来计算它的对角线位置。之前,我必须建立容器和计算一些其他的东西
var width = $treelistContainer.node().getBoundingClientRect().width,
height = $treelistContainer.node().getBoundingClientRect().height,
i = 0,
id = 0,
margin = {top: 20, right: 10, bottom: 10, left: 15};
var diagonal = d3.svg.diagonal()
.projection(function(d) { return [d.y, d.x]; });
var svg = $treelistContainer
.append("svg")
.attr("width", width - margin.left - margin.right+"px")
.attr("height", height+"px")
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var link = svg.selectAll("path.link")
.data(tree.links(nodes))
.enter()
.insert("path", "g")
.attr("class", "link")
.attr("stroke", function(d) {
// Setting the color based on the hierarchy
console.log(d.target.value);
return color(d.target.value);
})
.attr("d", function(d,i) {
var source = {x: d.source.x, y: d.source.y};
var target = {x: d.target.x, y: d.target.y};
return diagonal({source: source, target: target});
});
这里是它的样子:https://www.dropbox.com/s/ysbszycoiost72t/result.png?dl=0
我会尝试通过改变插值类型,增加了一些小丰富多彩的节点圆圈进行优化和等等。
希望这会帮助别人。
这就是现在的样子:https://www.dropbox.com/s/2dia1jicjzpv0wt/treelist-vis.png?dl=0 –