有几个问题非常接近这个主题,但没有一个真正帮助我。
我一直在编程一个绘图库,我需要一个算法来垂直放置标签而不重叠。我已经在这个问题上纠结了几天了,并设法将其提炼为最基本的功能:
如果给定沿Y轴的一系列标签位置,例如,1 1 2 3 5 6 9
,以及上限和下限分别为10
和0
,我需要一种方法来分隔值以输出1 2 3 4 5 6 9
333467
应被234567
加权,以接近原始坐标。
这也应该反向工作,如果值在刻度的上端聚集,它们应该尽可能地分散(在溢出之前)
我不是在寻找一个明确的答案,但我希望在如何处理这个问题上得到一些帮助。我完全卡住了。
最后的思路是扫描所有可能发生碰撞的标签,并将它们定位为一个大块,对准所有Y坐标的中心。但如果有多组碰撞,这将不起作用。
编辑:为了把这个算法放在一个更大的背景下,看看这两个google chart API饼状图:1)顶部堆叠标签
2)底部堆叠标签
标签几乎是有弹性的,它们通过结合在一起并将它们的整个质量移动到它们的质量中心来避免碰撞
通过插入到有序集合中使标签集唯一。用y轴上界和下界之差除以集合中元素的数量。这是间距增量。按顺序遍历集合,每间隔增加一个标签。
嗯,经过一些思考和其他来源的建议,我想到了一个解决方案:
伪代码:
foreach labels as label
if label->collidesWith(labels->lowerLimit)
label->moveAwayFrom(labels->lowerLimit)
if label->collidesWith(labels->upperLimit)
label->moveAwayFrom(labels->upperLimit)
if label->collidesWith(label->previous)
label->moveAwayFrom(label->previous)
label->previous->moveAwayFrom(label)
if label->collidesWith(label->next)
label->moveAwayFrom(label->next)
label->next->moveAwayFrom(label)
endforeach
MoveAwayFrom每次移动1个像素。当这个函数多次运行时,它会重新调整标签,直到它们没有冲突。(实际上我调用了这个循环100次,还没有找到更智能的方法)