javascript - 如何在 D3.js 中更改径向树的根

标签 javascript d3.js tree

我在 D3.js 中的径向树出现问题

我想将选定的节点(单击时)放在径向树的中心,并使整个树重新适应这个新设置。在我的更新函数中,我可以将根设置为所选节点:

root = source; 

但是,这仅显示所选节点和子节点,但我希望将父节点(及其子节点)放在所选节点的顶部,将所选节点的子节点放在其底部。

我尝试的是从父级的子级数组中删除选定的节点。然后将这个更改的父节点推送为所选节点的子节点,但这会产生递归错误。

var index = source.parent.children.indexOf(source);
source.parent.children.splice(0, 1);
source.parent.parent = source;
source.children.push(source.parent);

完整代码here

如果有任何帮助或指示,我将不胜感激。

谢谢

最佳答案

这是一个负责重新排列的递归函数:

function makeRoot(source) {
   if (!source.parent) return; //nothing to do if source is already root

   makeRoot(source.parent); //flip the higher branches recursively so that the parent becomes root of the tree 

   var index = source.parent.children.indexOf(source);
   source.parent.children.splice(index, 1);  //corrected here: you need to remove the right element from the children list
   source.parent.parent = source;
   source.children.push(source.parent);
   delete source.parent; //added: now that the original parent is linked, make source the root of the tree
}

我不知道如何强制将原始节点的子节点绘制到南方,其余的绘制到北方。首先要做的就是知道每个节点必须位于哪一侧(这很简单:默认情况下所有节点都在“北”,然后从访问子树,在调用 makeRoot 之前,并告诉它们为“南”)。但在那之后,我对 d3 中的树布局不够熟悉,无法强制执行“北/南”约束。

<小时/>

更新南北方向,您可以尝试以下操作:

  • 保留指向所选节点的原始父节点的指针oldParent=source.parent
  • 布局完成后,在更新 svg 之前,计算 offsetX= 90- oldParent.x (父位置和北轴之间的差异 - 注意:我不确定大约北轴为 90°,但它应该是 0、90、180 或 270 之一..全部尝试一下;) )
  • 将所有节点移动 offsetX 量(保持 Angular 在 0 到 359 之间):

    nodes.forEach(function(d) {
        d.x = (d.x + offsetX) % 360;
    });
    
  • 然后你可以更新 svg:整个树应该旋转,以便原始父节点指向北......这应该足以获得你想要的视觉效果。

<小时/>

更新#2另一种进行南北对齐的方法。

请参阅此处的 fiddle :https://jsfiddle.net/qo4w0ktn/4/

这个想法是计算原始子节点中最左边和最右边叶子的 Angular ,然后旋转整个图,直到这两个 Angular 平均值指向南方。这意味着您需要跟踪树中的“原始”子级,这是通过我的 d.real_children 属性完成的。函数 leftmostLeafrightmostLeaf 很简单(参见 fiddle )。

  function rotateSouth(source, nodes) {
    var lx = leftmostLeaf(source);
    var rx = rightmostLeaf(source);

    if (lx>rx) rx += 360; //this happens if the interval overlap angle 0

    var offsetX= 180- (lx+rx)/2; //the median point (=(lx+rx)/2) should be pushed south (=180)

    nodes.forEach(function(d) {
      d.x = (d.x + offsetX) % 360; //rotate every node by the same offset
    });  
  }

关于javascript - 如何在 D3.js 中更改径向树的根,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36864983/

相关文章:

c# - 在状态转换中产生最短路径

javascript - 使用 jsTree XML 模块

javascript - 将项目插入JavaScript中的多维树状结构

javascript - 带有 JSONP 的主干 js

Javascript 不会加载到 ajax div 中

javascript - 抑制 d3plus 方框和晶须绘图中的极端异常值

javascript - 使用 d3.create 创建和附加分离元素

javascript - 如何在 Javascript 中解析非英文文本日期?

javascript - meteor :如何在CSS选择器中使用多个类

d3.js - 为什么域不使用D3中的d3.max(data)?