D3使用额外的父路径和兄弟路径来适应树结构的力布局

时间:2013-11-27 15:16:46

标签: javascript graph d3.js tree

D3是否提供了创建树的可能性,其中在同一级别的节点之间存在连接,但是也存在独立于不同级别的级别的路径(例如,级别2的节点3应该具有到节点6的可视链接等级4)。

我的意思是像这样闷闷不乐:

       (1)
   (2)_/ \_(3)
   /_(4)     \
      /_(5)__(6)

我认为这是一个“正常”的图形结构,但我必须将其自上而下与树相似。 也许http://bl.ocks.org/GerHobbelt/3683278将是一个很好的开始,但我怎么能告诉force-layout将节点可视化更像树一样清晰?

编辑: 我的数据如下:

{
 "name": "Root",
 "children": [
  {
   "name": "1",
   "children": [
    {
     "name": "2",
     "children": [
      {"name": "20"},
      {"name": "21"},
      {"name": "22"}
     ]
    },
    {
     "name": "3",
     "children": [
      {"name": "31",
         "children": [
          {"name": "300"},
          {"name": "301"},
          {"name": "302",
             "children": [
              {"name": "3020"},
              {"name": "3021"},
              {"name": "3022"}
             ]
          }
         ]
      },
      {"name": "32"},
      {"name": "33"},
      {"name": "34"}
     ]
    },
    {
     "name": "4",
     "children": [
      {"name": "41"},
      {"name": "41"}
     ]
    }
   ]
  }
 ]
}

我已经像这个树一样复制了这个例子:http://bl.ocks.org/mbostock/4339083

如何添加现在的个别链接?例如节点'2'和'3'之间? 我添加了

var dataset = {
                edges: [
                    {source: 2, target: 3}
                ]
            };

在复制的样本中,链接创建通过

完成
// Update the links…
              var link = vis.selectAll("path.link")
                  .data(tree.links(nodes), function(d) { return d.target.id; });

              // Enter any new links at the parent's previous position.
              link.enter().insert("svg:path", "g")
                  .attr("class", "link")
                  .attr("d", function(d) {
                    var o = {x: source.x0, y: source.y0};
                    return diagonal({source: o, target: o});
                  })
                .transition()
                  .duration(duration)
                  .attr("d", diagonal);

              // Transition links to their new position.
              link.transition()
                  .duration(duration)
                  .attr("d", diagonal);

              // Transition exiting nodes to the parent's new position.
              link.exit().transition()
                  .duration(duration)
                  .attr("d", function(d) {
                    var o = {x: source.x, y: source.y};
                    return diagonal({source: o, target: o});
                  })
                  .remove();

我不明白,我如何添加新的附加链接。有什么想法吗?

1 个答案:

答案 0 :(得分:1)

您可以使用常规树布局 - 它不限制节点之间的连接类型。基本的想法是绘制所有“普通”树链接,然后分别添加级别之间的链接。对于其中的每一个,您需要确定开始和结束节点位置并在它们之间画一条线。

首先,您需要解析其他边缘的坐标。

dataset.edges.forEach(function(e) {
  e.source = nodes[e.source];
  e.target = nodes[e.target];
});

然后,像对待其他链接一样绘制链接。

vis.selectAll("path.linkExtra").data(dataset.edges)
   .enter().append("path")
   .attr("class", "linkExtra")
   .attr("d", diagonal");