使用 NodeSize 的节点之间的 D3 树布局分离 [英] D3 Tree Layout Separation Between Nodes using NodeSize

查看:59
本文介绍了使用 NodeSize 的节点之间的 D3 树布局分离的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

现在我正在尝试分离我的矩形节点,因为它们如下图所示重叠:

我看了一下,发现 D3 提供了一个 nodeSizeseparation 方法,但由于某种原因它不起作用.

我发现这篇博文谈论的是问题,但他说

<块引用>

节点中不存在 size 属性,因此您可以使用任何属性来控制它们的大小.

但显然有一个 nodeSize 方法,所以我觉得我只是错误地使用了该方法和/或博客文章已过时.我想将我的节点塑造成矩形的大小并将它们均匀地间隔开,这样它们就不会相互重叠.有谁知道如何正确使用这些方法?关于这些方法的文档没有得到很好的解释,也没有产生任何区别.我也找不到很多例子,人们改变了树的 nodeSize 或需要对矩形对象进行分隔(有一些关于圆形对象的例子,但我觉得这太不同了......)

这是相关的代码.我会尝试准备一个 JSFiddle.

var margin = {top: 20, right: 120, bottom: 20, left: 120},高度 = 960 - margin.right - margin.left,宽度 = 800 - margin.top - margin.bottom,rectW = 70;rectH = 30;//bbox = NaN,最大文本长度 = 0;变量 i = 0,持续时间 = 750,根;//这里最初绘制的每个节点的路径//改为d.x, d.yvar 对角线 = d3.svg.diagonal().projection(function(d) { return [d.x+rectW/2, d.y+rectH/2];//.projection(function(d) { return [d.x+bbox.getBBox().width/2, d.y+bbox.getBBox().height/2];});var 树 = d3.layout.tree().nodeSize([30,70]).separation(function(a, b) { return (a.parent == b.parent ? 1 : 2); }).size([宽度, 高度]);var svg = d3.select("body").append("svg").attr("height","100%").attr("width","100%").call(d3.behavior.zoom().on("zoom", redraw)).append("g").attr("transform", "translate(" + margin.top + "," + margin.left + ")");

解决方案

UPDATE 05/04/2018:我的理解是 d3 已经改变了很多(变得更好),变得更多模块化的.对于那些正在寻找这个答案的人,这是使用旧版本的 d3(特别是 v3).

很多发现仍然与cluster.size()<下的>d3-hierarchy包/code> 和 cluster.nodeSize() 并且我计划可能更新我的示例以使用它.不过,作为历史参考,我不会触及底部.

<小时>

这是一个 jsFiddle:http://jsfiddle.net/augburto/YMa2y/>

更新并将示例移至 Codepen.该示例仍然存在于 jsFiddle 上,但 Codepen 似乎有一个更好的编辑器,并允许您轻松分叉.一旦我减少了其中的内容量,我也会尝试将示例直接添加到此答案中.

http://codepen.io/augbog/pen/LEXZKK

更新这个答案.我和我的朋友交谈,我们查看了 sizenodeSize

的源代码

 tree.size = function(x) {if (!arguments.length) 返回 nodeSize ?空:大小;nodeSize = (size = x) == null;返回树;};tree.nodeSize = 函数(x){if (!arguments.length) 返回 nodeSize ?大小:空;nodeSize = (size = x) != null;返回树;};

当您为树设置 size 时,您设置的是固定大小,以便树必须符合该宽度和高度.当您设置 nodeSize 时,树必须是动态的,因此它会重置树的大小.

当我在 nodeSize 之后指定 size 时,我几乎覆盖了我想要的东西哈哈...

底线:如果你想让 nodeSize 工作,你不能有一个固定的树大小.它将大小设置为 null.如果您要声明 nodeSize,请不要声明 size.

D3.js 实际上更新了文档.感谢这样做的人,因为现在更清晰了!

<块引用>

nodeSize 属性是 tree.size 独有的;环境tree.nodeSize 将 tree.size 设置为 null.

这就是我的树现在的样子.我还添加了缩放功能以及如何在矩形内居中文本.

Right now I am trying to separate my rectangle nodes because they overlap as shown in the picture below:

I took a look and found out that D3 offers a nodeSize and separation method but for some reason it did not work.

I found this blog post talking about the issue but he says

The size property doesn’t exist in nodes, so it will be whatever property you want to control the size of them.

but clearly there is a nodeSize method so I feel like I am simply using the method incorrectly and/or the blog post is out-of-date. I want to shape my nodes to be the size of the rectangle and space them out evenly so they do not overlap each other. Does anyone know how to use the methods properly? The documentation about these methods isn't explained very well and it isn't yielding any difference. I also couldn't find many examples where people changed the nodeSize of trees or needed separation for rectangular objects (there were some examples regarding circular ones but I feel that's too different...)

Here is the relevant code. I will try to prepare a JSFiddle.

var margin = {top: 20, right: 120, bottom: 20, left: 120},
    height = 960 - margin.right - margin.left,
    width = 800 - margin.top - margin.bottom,
    rectW = 70;
    rectH = 30;
    //bbox = NaN,
    maxTextLength = 0;

var i = 0,
    duration = 750,
    root;


//paths from each node drawn initially here
//changed to d.x, d.y
var diagonal = d3.svg.diagonal()
    .projection(function(d) { return [d.x+rectW/2, d.y+rectH/2];
    //.projection(function(d) { return [d.x+bbox.getBBox().width/2, d.y+bbox.getBBox().height/2]; 
});

var tree = d3.layout.tree()
    .nodeSize([30,70])
    .separation(function(a, b) { return (a.parent == b.parent ? 1 : 2); })
    .size([width, height]);

var svg = d3.select("body")
            .append("svg")
              .attr("height","100%").attr("width","100%")
              .call(d3.behavior.zoom().on("zoom", redraw))
              .append("g")
                .attr("transform", "translate(" + margin.top + "," + margin.left + ")");

解决方案

UPDATE 05/04/2018: It is my understanding d3 has changed a lot (for the better) to be a lot more modular. For those who are looking towards this answer, this was using a much older version of d3 (specifically v3).

A lot of the findings are still relevant for the d3-hierarchy package under cluster.size() and cluster.nodeSize() and I am planning to potentially update my example to use that. For historical reference though, I'm leaving the bottom untouched.


Here is a jsFiddle: http://jsfiddle.net/augburto/YMa2y/

EDIT: Updated and move the example to Codepen. The example still exists on jsFiddle but Codepen seems to have a nicer editor and allows you to easily fork. I'll also try to add the example directly to this answer once I've reduced the amount of content in it.

http://codepen.io/augbog/pen/LEXZKK

Updating this answer. I talked with my friend and we looked at the source for size and nodeSize

  tree.size = function(x) {
    if (!arguments.length) return nodeSize ? null : size;
    nodeSize = (size = x) == null;
    return tree;
  };

  tree.nodeSize = function(x) {
    if (!arguments.length) return nodeSize ? size : null;
    nodeSize = (size = x) != null;
    return tree;
  };

When you set a size for the tree, you are setting a fixed size so that the tree has to conform to that width and height. When you set a nodeSize, the tree has to be dynamic so it resets the size of the tree.

When I specified size after nodeSize, I was pretty much overriding what I wanted haha...

Bottom line: If you want nodeSize to work, you can't have a fixed tree size. It will set the size to null. Do not declare a size if you are declaring a nodeSize.

EDIT: D3.js actually updated the documentation. Thanks to whoever did that because it is way clearer now!

The nodeSize property is exclusive with tree.size; setting tree.nodeSize sets tree.size to null.

This is what my tree looks like now. I have also added zoom functionality as well as how to center text within the rectangle.

这篇关于使用 NodeSize 的节点之间的 D3 树布局分离的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆