【问题标题】:How to specify height and width of a d3 tree dynamically to allow it to take up all the space it needs如何动态指定 d3 树的高度和宽度以允许它占用所需的所有空间
【发布时间】:2018-06-10 20:37:16
【问题描述】:

d3 example

我正在关注链接中的示例。我想将高度和宽度指定为“无限”,可以这么说,因为我的 json 文件非常大并且节点重叠,因为树和 svg 元素的高度和重量都是固定的。我该怎么做呢?

【问题讨论】:

  • 你的意思是你的svg容器的尺寸吗?您是否尝试过径向树(bl.ocks.org/mbostock/4063550)?我认为这样更节省空间。
  • 是的,这就是我的意思。不仅是 svg 容器,还有树本身的尺寸。我更喜欢这种可折叠的树而不是放射状的树。
  • 一旦知道有多少节点或分支,您可以尝试动态设置 d3.tree() 布局的 size()。那就是使大小与节点数成正比。并相应地更新 svg 容器的大小。

标签: javascript d3.js svg


【解决方案1】:

我的算法看起来像这样:

  1. 将树大小设置为已知的常量大小。
  2. 从展开位置的所有子节点开始(即每个人都有.children 而不是._children)。
  3. 致电tree.nodes(root)
  4. 递归访问每个叶节点并确定最大 d.yd.x 值。
  5. 然后高度变为最大值d.y 乘以节点大小(圆半径)加上填充。
  6. 然后宽度变为最大d.x 乘以节点大小(圆半径)加上填充。
  7. 设置新的树大小、新的 SVG 大小,重新调用 tree.nodes(root) 并绘制。

【讨论】:

  • 我不明白第二点。 .chidren 而不是 ._children?
  • @user4790067,您链接到的代码通过将折叠节点存储为._children 来使用展开/折叠技巧。导致d3.tree 在计算布局时不考虑它们。为了使我的算法正常工作,必须考虑所有节点进行计算。
【解决方案2】:

我也遇到了同样的问题。我所做的是根据进出儿童的数量在click 上更新tree.size([height,width])。所以示例中的代码

// Toggle children on click.
function click(d) {
  if (d.children) {
    d._children = d.children;
    d.children = null;
  } else {
    d.children = d._children;
    d._children = null;
  }
  update(d);
}

变成

// Toggle children on click.
function click(d) {
    if (d.open) {
        if (d.children) {
            height = height - d.children.length * 20;
            d._children = d.children;
            d.children = null;
        } else {
            height = height - d._children.length * 20;
            d.children = d._children;
            d._children = null;
        }
    } else {
        if (d.children) {
            height = height + d.children.length * 20;
            d._children = d.children;
            d.children = null;
        } else {
            height = height + d._children.length * 20;
            d.children = d._children;
            d._children = null;
        }
    }
    d.open = !d.open;
    update(d);
}

}

由于其他原因,我需要open 属性,所以也许您可以在没有太多重复的情况下相处。关键点是更新height 全局变量基于孩子的数量被扩大或收缩。然后,在您的 update 函数中,您可以再次调用第一件事

tree = d3.tree().size([height, width]);

【讨论】:

    猜你喜欢
    • 2014-04-20
    • 2012-08-23
    • 2011-05-04
    • 2012-07-07
    • 2020-05-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多