在混淆了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 –