d3.js沿着一条线的圆形包装

6
我有一个数据集,其中每个样本都有一个大小(0-1000)和一个值(等级1-5)。我想用不同大小的圆在一条线(域轴)上可视化数据,就像这样:http://www.nytimes.com/interactive/2013/05/25/sunday-review/corporate-taxes.html?_r=1&(请注意,即使具有相同的有效税率,圆圈也不重叠)。 例如数据如下:sample 1: size 300 value 3.2,sample 2: size 45 value 3.8,sample 3: size 4400 value 4.0,sample 5: size 233 value 0.2,sample 6: size 4000 value 4.2。如何使用圆圈在一条线上显示上述数据(大小决定直径,值决定大致位置),以便圆圈不重叠? 我一直在研究D3的打包布局,但据我所知,它不支持此功能。 有没有任何想法来解决这个问题?

如果是一条直线,你只需要将前面圆圈的直径相加即可得到新圆圈的位置。 - Lars Kotthoff
@LarsKotthoff:您能详细说明一下吗?(我更新了问题)? - jrydberg
2个回答

18

哦,这个确实有点难题...

如果您查看NYTimes图形的代码,则使用数据文件中的预计算坐标,因此那并没有什么用。

但是,在脚本顶部有一个未使用的变量声明,提示原始版本使用了d3.geom.quadtree来布置圆圈。 四叉树并不是一种布局方法;它用于创建相邻节点的搜索树,因此当您需要在给定区域中找到一个节点时,您不必搜索整个集合。 在这里可以看到示例

因此,四叉树可用于确定哪些数据点可能在x轴上重叠。 然后,您必须弄清楚需要偏移多少以避免重叠。 变量半径使这两个功能变得复杂...

我在此处实现了一个测试用例:http://fiddle.jshell.net/6cW9u/5/

装箱算法并不完美:我总是将新圆形添加到现有圆形的外部,而不测试它们是否可能更靠近地放置,因此有时会出现显着的额外空白。 (运行几次以了解可能性-请注意,我将x变量分布为随机正常值,r变量分布为随机均匀值。)我还曾在N = 100的一次迭代中使用递归方法时出现堆栈溢出- 明显随机分布对四叉树优化不足。

但它具有基本功能。 如果您无法理解我的代码注释的逻辑,请在此处留下评论。

--ABR

更新

在这里有一个新的fiddle: http://fiddle.jshell.net/6cW9u/8/

经过大量的重新排列,我让打包算法搜索现有气泡之间的间隙。为了展示小圆圈可以填补间隙,我已经切换了排序顺序(以便最大的圆圈首先添加),尽管我在代码注释中提到,这会降低四叉树搜索的效率。

还添加了各种装饰和转换,以便您清楚地看到圆圈的位置,并将r-scale设置为平方根,使数据中的值(更真实,并且是O.P.要求的)与面积(而不是半径)成比例。


太棒了!我还想补充一点,原始可视化实际上并没有准确地反映水平轴上的数据 - 如果你仔细查看提示中显示的数据,你会发现这一点。因此,位置被手动或自动调整,我们只看到硬编码的结果。 - VividD
我正在使用N=125运行fiddle,布局相当令人满意,甚至美观,但是似乎有一个错误(可能是你提到的同一个错误)会不时出现,并将几乎所有圆形放在轴上... - VividD
是的,当堆栈溢出时就会发生这种情况——你没有得到有效的y偏移量。这似乎与x值在四叉树的范围之外有关。因此,逻辑上应该根据实际数据范围设置四叉树范围。*(在我的更新版fiddle中,我作弊了,只使用了一个足够大的值,以使我的随机正常值超出它的概率非常小。)* - AmeliaBR
@AmeliaBR,我正在尝试将您的代码更新到v4,但是在quadroot方面遇到了问题。根始终未定义。 - Mike
@Mike 看了一下更改列表,也许你需要将初始的 quadroot = quadtree() 赋值更改为 quadroot = quadtree().root`? 或者在获得有效根节点之前,您需要添加第一个数据项吗?我很抱歉我还没有尝试过使用 quadtrees 和 D3v4 进行编程。 - AmeliaBR

3
D3的装箱布局在这里不是答案。它将圆圈螺旋式地放置在现有的组周围。这是我在逆向工程装箱布局算法:

enter image description here

我建议使用基于力导向布局的方法。这样,您可以给节点施加朝向重心的力,然后让重力发挥作用。
力导向布局(例如集群力导向布局I)通常是动画效果,因此您需要应用静态力导向布局
我已经将这种方法封装在示例块中,看起来像这样:

circles on a line in a static force layout


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接