将一系列值隔开,使其不重叠
有几个问题与这个主题非常接近,但没有一个真正对我有帮助。
我一直在编写图形库,我需要一种算法来垂直放置标签而不重叠。我已经在这个问题上坚持了几天了,并设法将其提炼为最基本的函数:
如果给定沿 Y 轴的一系列标签位置,例如 1 1 2 3 5 6 9< /code>,以及上限和下限分别为
10
和 0
,我需要一种方法来分隔输出值 1 2 3 4 5 6 9
333467
应采用 234567
加权以接近原始坐标。
这也应该向后工作,如果值聚集在刻度的上端,它们应该尽可能分散(在溢出之前)
我不是在寻找明确的答案,但我想要一些关于如何进行的帮助来解决这个问题。我完全卡住了。
最后一个思路是扫描所有标签是否存在可能的碰撞,并将它们定位为一个大块,与所有 Y 坐标的中心对齐。但如果存在多组碰撞,这将不起作用。
编辑:要将此算法放在更大的上下文中,请查看这两个 google Chart API 饼图:
1) 顶部堆叠标签
2) 底部堆叠标签
标签几乎是有弹性的,它们通过连接在一起并将整个质量移动到质量中心来避免碰撞。
There have been a couple of questions very close to this topic, but none really helped me.
Ive been programming a graphing library, and I need an algorithm to vertically place labels without overlapping. I've been stuck on this for a couple of days now, and managed to distil it to the most basic function:
If given a series of label positions along the Y axis, say, 1 1 2 3 5 6 9
, and an upper and a lower limits 10
and 0
respectively, I need a way to space out the values to output 1 2 3 4 5 6 9
333467
should be 234567
weighted to be close to the original coordinates.
This should also work backwards, if values are bunched up at the upper end of the scale, they should be spread as much as possible (before overflowing)
I'm not looking for a definitive answer, but I'd like some help on how to approach this problem. Im completely stuck.
Last train of thought was to scan all labels for possible collisions and position them as one big block, aligning to the centre of all the Y coordinates. But this will not work if there are multiple sets of collisions.
EDIT: To put this algorithm in a bigger context, have a look at these two google chart API pie charts:
The labels are almost springy, they avoid collisions by joining together and moving their entire mass to the center of their mass.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
通过插入有序组来使标签组唯一。将 y 轴上限和下限之间的差除以集合中的元素数量。这是您的间距增量。按顺序迭代该集合,并在每个间距增量处放置一个标签。
你没有说需要保留秤......
Make the set of labels unique by inserting into an ordered set. Divide the difference between the y-axis upper and lower bound by the number of elements in the set. This is your spacing increment. Iterate over the set in order and position one label every spacing increment.
You didn't say anything about needing to preserve a scale...
好吧,经过一些思考和其他来源的建议,我想出了一个解决方案:
伪代码:
MoveAwayFrom 一次移动 1 个像素。当此函数多次运行时,它会重新调整标签,直到它们不发生碰撞。 (实际上我调用这个循环100次,还没有找到更智能的方法)
Well, After some thought and advice from other sources i came up with a solution:
Pseudocode:
MoveAwayFrom moves 1 pixel at a time. When this function is run multiple times it rejiggles the labels until none of them collide. (in reality im calling this loop 100 times, havent figured out a way to do it more inteligently)