1

有几个问题非常接近这个主题,但没有一个真正帮助我。

我一直在编写一个图形库,我需要一种算法来垂直放置标签而不重叠。我已经坚持了几天了,并设法将其提炼为最基本的功能:

如果给定沿 Y 轴的一系列标签位置,例如 ,以及上限和1 1 2 3 5 6 9下限,我需要一种方法来分隔要输出的值1001 2 3 4 5 6 9

333467234567加权以接近原始坐标。

这也应该向后工作,如果值在刻度的上端聚集在一起,它们应该尽可能地分散(在溢出之前)

我不是在寻找明确的答案,但我想要一些关于如何解决这个问题的帮助。我完全卡住了。

最后的思路是扫描所有标签以查找可能的碰撞并将它们定位为一个大块,与所有 Y 坐标的中心对齐。但是如果有多组碰撞,这将不起作用。

编辑:为了把这个算法放在更大的背景下,看看这两个谷歌图表 API 饼图:

1)顶部堆叠标签

2)底部堆叠标签

标签几乎是有弹性的,它们通过连接在一起并将它们的整个质量移动到它们的质量中心来避免碰撞。

4

2 回答 2

0

通过插入有序集合使标签集唯一。将 y 轴上限和下限之间的差除以集合中的元素数。这是您的间距增量。按顺序遍历集合,并在每个间距增量处放置一个标签。

你没有说需要保留一个规模......

于 2011-04-27T12:44:02.670 回答
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 次,还没有找到更智能的方法)

于 2011-05-01T21:49:33.113 回答