Highcharts dataLabels重叠时重新定位

时间:2017-02-14 12:16:56

标签: graph highcharts

我有一个Highcharts组件,用户可以在其中向图表添加注释,注释在分散系列中显示为dataLabel。但是,我注意到默认情况下allowOverlap只是删除了碰撞的dataLabel,我的问题是:是否可以使碰撞的dataLabels堆叠在一起?我认为既然allowOverlap: true可以检测到哪些是碰撞的,那么可能有办法利用这个?

这就是我的dataLabels现在的样子: Overlapping labels

这是我的目标: Stacking labels

希望有人可以帮助我找到一个聪明的解决方案,我确定知道我的想法!

顺便说一句,现在dataLabels通过将xAxis :{ max: value }除以1,5得到它们的xAxis位置。这只是将其平均定位在我的所有图表上,这些图表都具有不同的minmax值。可能值得一提。

1 个答案:

答案 0 :(得分:1)

可以覆盖应隐藏重叠标签的功能,并调整重叠标签的位置,如下所示:



$(function() {
  (function(H) {
    var each = H.each,
      UNDEFINED;

    H.Chart.prototype.hideOverlappingLabels = function(labels, rerun) {
      if (rerun === UNDEFINED ||
        rerun < 10) //infinity loop limit
      {
        var doTheRerun = false,
          len = labels.length,
          label, i, j, label1, label2,
          isIntersecting, pos1, pos2, parent1, parent2,
          padding,
          intersectRect = function(x1, y1, w1, h1, x2, y2, w2, h2) {
            return !(
              x2 > x1 + w1 ||
              x2 + w2 < x1 ||
              y2 > y1 + h1 ||
              y2 + h2 < y1
            );
          };
        for (i = 0; i < len; i++) {
          label = labels[i];
          if (label) {
            label.oldOpacity = label.opacity;
            label.newOpacity = 1;
          }
        }
        labels.sort(function(a, b) {
          return (b.labelrank || 0) - (a.labelrank || 0);
        });
        for (i = 0; i < len; i++) {
          label1 = labels[i];
          for (j = i + 1; j < len; ++j) {
            label2 = labels[j];
            if (label1 && label2 && label1.placed && label2.placed && label1.newOpacity !== 0 && label2.newOpacity !== 0) {
              pos1 = label1.alignAttr;
              pos2 = label2.alignAttr;
              parent1 = label1.parentGroup; // Different panes have different positions
              parent2 = label2.parentGroup;
              padding = 2 * (label1.box ? 0 : label1.padding); // Substract the padding if no background or border (#4333)
              isIntersecting = intersectRect(
                pos1.x + parent1.translateX,
                pos1.y + parent1.translateY,
                label1.width - padding,
                label1.height - padding,
                pos2.x + parent2.translateX,
                pos2.y + parent2.translateY,
                label2.width - padding,
                label2.height - padding
              );
              if (isIntersecting) {
                (label1.labelrank < label2.labelrank ? label1 : label2).addHeightOffset = true;
              }
            }
          }
        }

        each(labels, function(label) {
          var complete,
            newOpacity;
          if (label) {
            if (label.addHeightOffset && label.placed) {
              label.alignAttr.y -= label.height;
              label.addHeightOffset = false;
              doTheRerun = true;
            }
            label['attr'](label.alignAttr);
          }
        });
        if (doTheRerun) {
          rerun = (rerun || 0) + 1;
          H.Chart.prototype.hideOverlappingLabels(labels, rerun);
        }
      }
    };
  }(Highcharts))

  $('#container').highcharts({
    series: [{
      dataLabels: {
        enabled: true,
        format: 'The value that is important for this point is: {y}'
      },
      data: [1, 2, 1, 1, 2, 2, 2]
    }]
  });
});
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="http://code.highcharts.com/highcharts.js"></script>
<div id="container" style="height: 400px"></div>
&#13;
&#13;
&#13;

JSFiddle中的演示:http://jsfiddle.net/ozLtvwke/1/