气泡图标签放置算法?(最好是JavaScript)

气泡图标签放置算法?(最好是JavaScript),javascript,algorithm,visualization,labels,placement,Javascript,Algorithm,Visualization,Labels,Placement,我想自动放置100-200个气泡标签,以便满足以下要求: 标签不应重叠 标签最好不要与气泡重叠 标签应靠近气泡 应在一定程度上尊重首选标签位置(左上、左上、右下等) 字体大小可以不同 有什么有用的库/算法吗?(最好是JavaScript或PHP) (图像中的标签放置不符合这些要求) 这个怎么样 不幸的是,我认为很难在Javascript或PHP中找到现成的解决方案。但是,我确实认为您的问题可以分解为小个子问题(基于您的规则),以帮助您设计解决方案 我会确定你的哪些规则是最重要的。从您提供的图

我想自动放置100-200个气泡标签,以便满足以下要求:

  • 标签不应重叠
  • 标签最好不要与气泡重叠
  • 标签应靠近气泡
  • 应在一定程度上尊重首选标签位置(左上、左上、右下等)
  • 字体大小可以不同
有什么有用的库/算法吗?(最好是JavaScript或PHP)

(图像中的标签放置不符合这些要求)

这个怎么样


不幸的是,我认为很难在Javascript或PHP中找到现成的解决方案。但是,我确实认为您的问题可以分解为小个子问题(基于您的规则),以帮助您设计解决方案

我会确定你的哪些规则是最重要的。从您提供的图表来看,我认为规则#1和#2将在可读性方面提供最大的改进

为了根据这些规则确定放置位置,我将计算文本和气泡的边界容器,并测试交叉点。交叉点后,移动到没有交叉点的位置。如果找不到,请使用重叠最小的空间

这将允许您为左上角、右下角等创建加权放置启发式,以帮助将标签放置在“首选”位置

我试着用两个气泡和两个标签写出一小段布局算法,两个标签通常很接近,可能会重叠。如果你能将你的布局算法推广到这个小的子集上,你应该会有更多的气泡


此外,也许您可以使用kd树或其他空间分区数据结构的顺序来定位要避免的最近邻居

这可以表述为一个线性规划问题。您希望根据某些约束(您的需求)最大化或最小化函数(表示解决方案的“权重”或“优点”)。您需要将需求形式化为值。大概是这样的:

Variables:
x1 = 1 if Labels overlap, 0 otherwise
x2 = some measure of "how much" a label overlaps a bubble
x3 = distance from label to bubble //Label should be close to bubble
x4 = distance between ideal and actual label position
x5 = difference between actual and ideal font size


minimize x1 + 10*x2 + x3 + 20*x4 + 5*x5

subject to constraints:
    x1   = 0  // labels can never overlap
    x2   < /* maximum amount a label is allowed to overlap a bubble */
    ...
    x5   < 6 // font size does not vary by more than +/- 6 pts.
变量:
如果标签重叠,x1=1,否则为0
x2=标签与气泡重叠“多少”的某种度量
x3=标签到气泡的距离//标签应靠近气泡
x4=理想和实际标签位置之间的距离
x5=实际和理想字体大小之间的差异
最小化x1+10*x2+x3+20*x4+5*x5
受限制:
x1=0//标签不能重叠
x2
我创建了系数和约束,您可以使用它们根据哪些特征对您最重要来调整结果。系数增加需求的值(在这种情况下,
f4
的权重最大,因此它“最重要”。约束是不能违反的硬限制


由于这是一个众所周知的问题,您现在可以使用多种方法来解决它。单纯形算法很流行。关于这些问题,本文有整整一章。

我想您正在使用javascript、html和css?在任何情况下,都会想到两种方法

首先,将其表述为优化问题。您需要计算每个标签的理想位置。这将基于气泡的大小、所需位置(即顶部、底部、左侧、右侧)以及标签的大小(字体和长度)。然后你需要参数化你的坐标,例如进入一个2N个元素的列表,其中N是标签的数量。然后你需要在某个位置初始化标签(或者在使用遗传算法的情况下初始化群体)并应用一个优化算法,这将需要一个成本函数。这将基于一组标签位置离理想的距离,以及任何违反规则的情况,例如重叠


或者,把它变成一个物理问题。用一些刚性连接将每个标签与它的泡泡“连接”。给每个标签和泡泡一个排斥力,同时也增加一个全局的、更强的重力(在首选的上/左/右/下方向)。进行一次简短的物理模拟,直到达到平衡。数学应该不会太难。

也许可以使用以下帮助工具工具包:

    • 怎么样

      label.substring(0,数学sqrt(bubbleValueOrRadius))


      我在protovis.js的一个例子中发现了这一点。

      我认为如果你在工具中使用D3,你可以使用“基于力的”标签放置算法。该解决方案最初属于,但已经有一个现成的Javascript示例,在这里:

      我在Java中找到了一种解决此问题的方法,该方法实际有效,称为强制地图标记,是一种开源的学院体验


      这是文档+项目源代码:

      在涵盖一些方法方面非常好。我使用的是多焦点的force布局,因为它似乎是最好的整体方法。

      很好的问题。我会提供一个悬赏,但读图表中的“每1000人谋杀”会让我闭嘴,忘记“悬赏”这个词András,这张图片只是一张带有标签的散点图的插图。我从这里开始拍摄:。如果这不是一张合适的示例图片,我很抱歉-我没有太多注意绘制的实际指标。我认为这个问题的范围太广了。一个用d3.js构建的起点,使用相同的数据集:感谢链接到这篇优秀的论文。我已经通读了一遍,但可能很难使算法适应JavaScript和上面列出的标准。如果您有更多“适用”的资源可供共享,他们将不胜感激。@dani我同意此算法不会是e