d3.js树形布局是一个很棒的工具,但是它默认只允许孩子有一个单亲。我希望能够让孩子们有不止一个父母。我对树的默认行为提供的节点位置很满意。我想要的只是在默认树被计算出来之后,在没有孩子的父母和现有的孩子之间画出额外的对角线链接。我的脚本目前看起来像这样:
<script>
var h = 870,
w = 1200;
var dimcirc = [60,30,10,8];
var offsetL = 60;
var couleurs = [
"#a2a2ff",
"#87ff87",
"#ffc55c",
"#ff844d",
"#ffe452"];
var tree = d3.layout.tree()
.size([h-100, w-400])
.separation(function(a, b) { return (a.parent == b.parent ? 1 : 1.2); });
var diagonal = d3.svg.diagonal()
.projection(function(d) { return [d.y + offsetL, d.x]; });
var svg = d3.select("body").append("svg")
.attr("width", w)
.attr("height", h)
.append("g");
d3.json("donnees.json", function(error, root) {
if (error) throw error;
var nodes = tree.nodes(root),
links = tree.links(nodes);
var link = svg.selectAll(".link")
.data(links)
.enter().append("path")
.attr("class", "link")
.attr("d", diagonal);
var node = svg.selectAll(".node")
.data(nodes)
.enter().append("g")
.attr("class", function(d){return "niv_" + d.depth.toString();})
.classed("node", true)
.attr("transform", function(d) { return "translate(" + (d.y + offsetL).toString() + "," + d.x +")"; })
// Draw node circles
node.append("circle")
.attr("fill", function(d){
console.log(d.couleur);
if(d.couleur!=null){
return couleurs[d.couleur];
}
else {return couleurs[4];}
})
.attr("r", function(d){
return dimcirc[d.depth];
});
node.append("text")
.attr("dy", "0.31em")
//.attr("text-anchor", function(d) { return d.x < 180 ? "start" : "end"; })
.attr("transform", function(d){
return "translate(" + (dimcirc[d.depth] + 10).toString() + ")"
})
.text(function(d) { return d.name; })
.call(wrap, 230);
});
// Wrap text
function wrap(text, width) {
// A function to help wrap svg text.
}
</script>
我试图使用根对象将父节点的子节点复制到无子节点,但无济于事(根对象的结构对我来说非常晦涩难懂)。
感谢任何帮助。
PS :我知道一个类似的问题(d3.js具有相同父级的树节点),但是缺乏答案对我没有多大帮助或当然。
编辑
我已经设法得到我想要的:
1)识别感兴趣的节点:那些没有要连接到现有子节点的子节点,以及后者的父节点。
2) 从根对象中提取源(没有子节点的节点)和目标(要连接到此节点的子节点)的坐标。
3)使用与树创建的“标准”路径相同的对角线创建额外的路径。
下面是我添加的代码,用于获取每个路径的源和目标:
var link2 = [];
var loopLink2 = [{"a":0,"b":1, "c":0,"d":0},{"a":1,"b":1, "c":1,"d":0},{"a":3,"b":0, "c":2,"d":1}];
loopLink2.forEach(function(d){
var sourX = root.children[d.a].children[d.b].x;
var sourY = root.children[d.a].children[d.b].y;
root.children[d.c].children[d.d].children.forEach(function(d){
link2.push({"source":{"x":sourX,"y":sourY}, "target":{"x":d.x,"y":d.y}});
console.log(link2);
});
});
这里是实际创建路径的地方:
svg.selectAll(".link2")
.data(link2)
.enter().append("path")
.attr("class", "link2")
.attr("d", diagonal)
.attr("transform", function(d) { return "translate(0," + offsetT +")"; });
有人有更好的解决方案吗?
我不知道这是否正是你要找的。但这可能会有帮助。
达格
Dagre是一个使用d3绘制非循环图的库。您可以尝试修改它。这是github wiki。
家系
在这里,您可以找到创建家谱的出色答案 ,该家谱可以为一个孩子提供多个父母。如果结构无关紧要,这可能会满足您的要求。
我一直在将代码从JIT转换到D3,并使用树布局。我已从中复制了代码http://mbostock.github.com/d3/talk/20111018/tree.html使用我的树数据,但我想做更多。 在我的例子中,我想创建子节点,这些子节点合并回一个较低级别的父节点,我意识到这更像是一个有向图结构,但是希望树能够适应这一点(即注意子节点之间的公共id应该合并)。 因此,基本上,一棵树在从父母到
问题内容: 我有以下标记: 我希望将样式设置为“一个”和“三个”。 但是,标记也可以是: 我尝试使用以下CSS: 但是,正如预期的那样,这是每个样式的第一个子元素的样式。 如何更改CSS,以便可以定位属于的第1个和第3个? 问题答案: 您不能仅凭CSS选择器来做到这一点。和兄弟组合器仅限于共享其父代的子代/兄弟姐妹,正如其名称所暗示的那样,并且CSS选择器无法解释父子结构的这种变化,也没有类似选择
所以我正在使用 http://bl.ocks.org/mbostock/4339083 来创建一个可折叠的树,它工作得很好。 现在的问题是,我有一些节点具有相同的子节点,所以我想知道是否有任何方法可以将图形可视化,使两个父节点都扩展到同一个子节点? 所以基本上,当您扩展父节点时,它应该会自动扩展另一个父节点,导致相同的公共子节点,这在任何图中都可能吗?
树布局能够用莱因戈尔德-蒂尔福德算法产生一个整洁的树状结点-链接图。例如,树布局可以用来组织软件的包中类的层级结构。 像其他大多数布局一样,d3.layout.tree返回的是一个对象也是一个函数。也就是说:你可以像调用其他函数一样调用布局,并且这个布局函数有可以改变它的行为的附加方法。像D3里的其他类一样,布局遵循函数的链式模式,其中setter返回布局本身,允许在简单的语句中调用多个sette
问题内容: 我在 MySQL中* 有如下的 注释 表: * 用户可以添加 新的 注释,因为它们不是其他注释的子对象,所以将没有parent_id。用户还可以 回复 通过先前方法添加的评论,因此它们是主要评论的子级,例如在第二层级上。该 PARENT_ID 列表示父评论的ID,如果存在的话。如果注释没有父母,则默认 parent_id 为-1。 话虽如此,我想查询表中的所有注释,每个父项后跟其子级,
问题内容: 早上好, 我在工作中继承了一些旧代码,并且使用的是一种非常不寻常的设计模式。我在论坛上唯一可以找到的类似模式的参考资料是在这里。情况是原始设计者有一个泛型父类(不是抽象类),该类具有静态工厂方法,该方法直接引用子类。 这是这种编码样式的示例,可在旧版代码的多个地方找到: 其中Log4JLoggerFactory和LogBackLoggerFactory扩展了LoggerFactory。