我正在寻找一个解决方案,将一个D3.js层次结构树创建为一个树状列表,就像在MindNode 2中一样(参见:https://www.dropbox.com/s/6cjs1ma9n4yex3w/mindnode-treelist.png?dl=0)。
如您所见,有四种不同的路径:
⏋
形曲线(父节点)├
形状的结尾⎿
形状的结尾,用于层次结构级别中的最后一个节点叶。我发现这个例子似乎是一个良好的开端:http://bl.ocks.org/thehogfather/0e48ec486abbd5be17d7
我现在的问题是:我现在该怎么办?我想为每个节点附加一个svg容器,根据相关条件获取相关路径。另一个解决方案是一个巨大的svg及其所有路径 - 但这可能是错误的方式,因为 - 如图所示 - 一些节点有更多的文本必须包含在li
- 元素内
任何解决方案?打开问题?例子:-)?
答案 0 :(得分:1)
在混淆了this awesome example of @mbostck的代码之后,我找到了一个解决方案并将我的代码从treelist布局重写为树形布局。但我将代码分为两部分:一部分是使用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
我将尝试通过更改插值类型,添加一些小的彩色节点圆等来优化它。
希望这会对某人有所帮助。