d3.js沿着一条线包装

时间:2014-01-03 20:22:27

标签: d3.js visualization

我得到的数据集中每个样本的大小(0-1000)和值(1-5级)。我想用一条直线(域轴)的不同大小的圆圈来显示数据,就像:

http://www.nytimes.com/interactive/2013/05/25/sunday-review/corporate-taxes.html?_r=1&

(请注意,即使使用相同的有效税率,圆圈也不会重叠)

示例数据:

  • 样本1:尺寸300值3.2
  • 样本2:大小45值3.8
  • 样本3:大小4400值4.0
  • 样品5:尺寸233值0.2
  • 样本6:大小4000值4.2

如何使用一行中的圆圈显示上述数据(尺寸决定直径,决定线上的近似位置),以便圆圈不重叠?< / p>

我一直在关注D3的包装布局,但据我所知,它不支持开箱即用。有人对如何处理这个问题有任何想法吗?

2 个答案:

答案 0 :(得分:17)

噢,这个是个谜题......

如果您查看NYTimes图形的代码,它会在数据文件中使用预先计算的坐标,因此没有多大用处。

但是,脚本顶部有一个未使用的变量声明,暗示原始版本使用d3.geom.quadtree来布置圆圈。四叉树实际上不是布局方法;它用于创建相邻节点的搜索树,因此当您需要在给定区域中查找节点时,您不必搜索整个集合。 Example here

因此,四叉树可用于识别哪些数据点可能在x轴上相互重叠。然后你必须弄清楚你需要多少偏移它们以避免重叠。变量半径使两个函数复杂化......

我在这里实施了一个测试用例: http://fiddle.jshell.net/6cW9u/5/

打包算法并不完美:我总是将新的圆圈添加到现有圆圈的外部,而不测试它们是否可能更贴近,所以有时候当圆圈碰撞的边缘时,你会获得显着的额外空白相互进入。 (运行几次以了解可能性 - 请注意,我将x变量分布为随机正态和r变量分布为随机均匀。)我在一个递归方法中也有一个堆栈溢出N = 100的迭代 - 随机分布显然不能很好地分布为四叉树优化。

但它有基本的功能。如果您不能遵循我的代码注释的逻辑,请在此处发表评论。

- ABR

更新

这里的新小提琴:http://fiddle.jshell.net/6cW9u/8/

经过大量的重新安排后,我得到了打包算法来寻找现有气泡之间的差距。我已经切换了排序顺序(以便首先添加最大的圆圈)以展示如何在空白中添加小圆圈 - 尽管正如我在代码注释中提到的那样,这会降低四叉树搜索的效率。 / p>

还添加了各种装饰和过渡,以便您可以清楚地看到圆圈的定位方式,并将r标度设置为平方根,因此面积(非半径)与数据中的值成正比(即更现实,OP要求的是什么。)

答案 1 :(得分:1)

D3的包装布局不是这里的答案。它围绕现有组以螺旋方式放置圆圈。这是我对包装布局背后的算法进行逆向工程:

enter image description here

我建议采用基于force layout的方法。这样,你可以让你的节点向重力中心施力,然后让重力做它的事情。

强制布局(例如Clustered Force Layout I)通常是动画,因此您需要应用static force layout

我已经完成了这个方法in an example block,看起来像这样:

circles on a line in a static force layout