有很多问题与这个话题非常接近,但没有一个真正帮助过我。
我一直在编写图形库,我需要一种算法来垂直放置标签而不重叠。我已经坚持了几天,并设法将其提炼到最基本的功能:
如果沿着Y轴给出一系列标签位置,比如1 1 2 3 5 6 9
,分别是上限和下限10
和0
,我需要一种方法来分隔要输出的值1 2 3 4 5 6 9
333467
应234567
加权,以接近原始坐标。
这也应该倒退,如果价值在规模的上端聚集,它们应该尽可能地分散(在溢出之前)
我不是在寻找明确的答案,但我想在如何解决这个问题上提供一些帮助。我完全卡住了。
最后的思路是扫描所有标签以查找可能的碰撞,并将它们定位为一个大块,与所有Y坐标的中心对齐。但如果存在多组碰撞,这将无效。
编辑:要将此算法放在更大的上下文中,请查看这两个谷歌图表API饼图:
标签几乎是弹性的,它们通过连接在一起并将整个质量移动到质量中心来避免碰撞。
答案 0 :(得分:0)
通过插入有序集使标签集唯一。将y轴上限和下限之间的差除以集合中的元素数。这是你的间距增量。按顺序迭代集合并在每个间距增量处定位一个标签。
您没有说需要保留比例......
答案 1 :(得分:0)
嗯,经过其他来源的一些思考和建议后,我想出了一个解决方案:
伪代码:
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次,还没有找到一种方法来更加智能地进行)