当前位置: 首页 > 知识库问答 >
问题:

树布局中父母n>1d3.js孩子

吴鸿彩
2023-03-14

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 +")"; });

有人有更好的解决方案吗?

共有1个答案

燕建中
2023-03-14

我不知道这是否正是你要找的。但这可能会有帮助。

达格

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。