打印区域外的Highcharts批注放置不正确

打印区域外的Highcharts批注放置不正确,highcharts,Highcharts,我希望将注释放置在y轴上,但不在打印区域之外。应使用与打印线相同高度的连接件(详图索引)放置这些线 但是,这些设置在那里无法正常工作(请参见图-红色)。路线应为水平“右侧”和垂直“居中”。使右侧的连接器位于轴上 距离给出了错误的结果。如果激活此选项,注释将跳转到另一个位置。它似乎对垂直位移有效。 我当前的解决方法是,添加一个标注作为css样式。但这不是我们要走的路 谢谢 默认情况下,MaikHighcharts注释使用callout符号(Highcharts.SvgRender.protot

我希望将注释放置在y轴上,但不在打印区域之外。应使用与打印线相同高度的连接件(详图索引)放置这些线

但是,这些设置在那里无法正常工作(请参见图-红色)。路线应为水平“右侧”和垂直“居中”。使右侧的连接器位于轴上

距离给出了错误的结果。如果激活此选项,注释将跳转到另一个位置。它似乎对垂直位移有效。 我当前的解决方法是,添加一个标注作为css样式。但这不是我们要走的路

谢谢
默认情况下,Maik

Highcharts注释使用
callout
符号(
Highcharts.SvgRender.prototype.symbols.callout
),该符号不是为此用途而设计的。但是,您可以对其进行修改,使其符合您的需要。检查我的包装张贴在下面和演示它

Highcharts.svgrender.prototype.symbols.callout上的包装器方法:

(function(H) {
  H.SVGRenderer.prototype.symbols.callout = function(x, y, w, h, options) {
    var arrowLength = 6,
      halfDistance = 6,
      r = Math.min((options && options.r) || 0, w, h),
      safeDistance = r + halfDistance,
      anchorX = options && options.anchorX,
      anchorY = options && options.anchorY,
      path;

    path = [
      'M', x + r, y,
      'L', x + w - r, y, // top side
      'C', x + w, y, x + w, y, x + w, y + r, // top-right corner
      'L', x + w, y + h - r, // right side
      'C', x + w, y + h, x + w, y + h, x + w - r, y + h, // bottom-rgt
      'L', x + r, y + h, // bottom side
      'C', x, y + h, x, y + h, x, y + h - r, // bottom-left corner
      'L', x, y + r, // left side
      'C', x, y, x, y, x + r, y // top-left corner
    ];

    // Anchor on right side
    if (anchorX && anchorX > w) {

      // Chevron
      if (
        anchorY > y + safeDistance &&
        anchorY < y + h - safeDistance
      ) {
        path.splice(13, 3,
          'L', x + w, anchorY - halfDistance,
          x + w + arrowLength, anchorY,
          x + w, anchorY + halfDistance,
          x + w, y + h - r
        );

        // Simple connector
      } else {
        path.splice(13, 3,
          'L', x + w, h / 2,
          anchorX, anchorY,
          x + w, h / 2,
          x + w, y + h - r
        );
      }

      // Anchor on left side
    } else if (anchorX && anchorX < 0) {

      // Chevron
      if (
        anchorY > y + safeDistance &&
        anchorY < y + h - safeDistance
      ) {
        path.splice(33, 3,
          'L', x, anchorY + halfDistance,
          x - arrowLength, anchorY,
          x, anchorY - halfDistance,
          x, y + r
        );

        // Simple connector
      } else {
        path.splice(33, 3,
          'L', x, h / 2,
          anchorX, anchorY,
          x, h / 2,
          x, y + r
        );
      }

    } else if ( // replace bottom
      anchorY &&
      anchorY > h &&
      anchorX > x + safeDistance &&
      anchorX < x + w - safeDistance
    ) {
      path.splice(23, 3,
        'L', anchorX + halfDistance, y + h,
        anchorX, y + h + arrowLength,
        anchorX - halfDistance, y + h,
        x + r, y + h
      );

    } else if ( // replace top
      anchorY &&
      anchorY < 0 &&
      anchorX > x + safeDistance &&
      anchorX < x + w - safeDistance
    ) {
      path.splice(3, 3,
        'L', anchorX - halfDistance, y,
        anchorX, y - arrowLength,
        anchorX + halfDistance, y,
        w - r, y
      );
    } else { // add to support right arrows
        path.splice(13, 3,
          'L', x + w, anchorY - halfDistance,
          x + w + arrowLength, anchorY,
          x + w, anchorY + halfDistance,
          x + w, y + h - r
        );
    }

    return path;
  }
})(Highcharts);
演示:

Api参考:

感谢您的调出功能。这将允许我删除css解决方案。不幸的是,它并不能解决水平和垂直对齐不能正常工作的实际问题。我希望
垂直对齐:“middle”
将注释居中。您仍然必须指定距离:-10
。与
align:'right'
对齐的水平对齐也存在同样的问题。在您的示例中,必须明确指定
x:-55
。因为我不知道框有多宽(不同的文本),所以容易出错。不过,谢谢你的回答和例子!Maikher是一个修订的视图不幸的是,Highcharts注释
align
verticalAlign
只能在图表绘图区域内正常工作。您试图实现的是注释功能之外的功能。因此,根据您的需要,您可以使用svgrender、plotLines.lables(带有css样式)或注释创建这些绘图线批注,这些批注具有我在答案(答案的编辑部分)中发布的解决方法。
(function(H) {
  H.SVGRenderer.prototype.symbols.callout = function(x, y, w, h, options) {
    var arrowLength = 6,
      halfDistance = 6,
      r = Math.min((options && options.r) || 0, w, h),
      safeDistance = r + halfDistance,
      anchorX = options && options.anchorX,
      anchorY = options && options.anchorY,
      path;

    path = [
      'M', x + r, y,
      'L', x + w - r, y, // top side
      'C', x + w, y, x + w, y, x + w, y + r, // top-right corner
      'L', x + w, y + h - r, // right side
      'C', x + w, y + h, x + w, y + h, x + w - r, y + h, // bottom-rgt
      'L', x + r, y + h, // bottom side
      'C', x, y + h, x, y + h, x, y + h - r, // bottom-left corner
      'L', x, y + r, // left side
      'C', x, y, x, y, x + r, y // top-left corner
    ];

    // Anchor on right side
    if (anchorX && anchorX > w) {

      // Chevron
      if (
        anchorY > y + safeDistance &&
        anchorY < y + h - safeDistance
      ) {
        path.splice(13, 3,
          'L', x + w, anchorY - halfDistance,
          x + w + arrowLength, anchorY,
          x + w, anchorY + halfDistance,
          x + w, y + h - r
        );

        // Simple connector
      } else {
        path.splice(13, 3,
          'L', x + w, h / 2,
          anchorX, anchorY,
          x + w, h / 2,
          x + w, y + h - r
        );
      }

      // Anchor on left side
    } else if (anchorX && anchorX < 0) {

      // Chevron
      if (
        anchorY > y + safeDistance &&
        anchorY < y + h - safeDistance
      ) {
        path.splice(33, 3,
          'L', x, anchorY + halfDistance,
          x - arrowLength, anchorY,
          x, anchorY - halfDistance,
          x, y + r
        );

        // Simple connector
      } else {
        path.splice(33, 3,
          'L', x, h / 2,
          anchorX, anchorY,
          x, h / 2,
          x, y + r
        );
      }

    } else if ( // replace bottom
      anchorY &&
      anchorY > h &&
      anchorX > x + safeDistance &&
      anchorX < x + w - safeDistance
    ) {
      path.splice(23, 3,
        'L', anchorX + halfDistance, y + h,
        anchorX, y + h + arrowLength,
        anchorX - halfDistance, y + h,
        x + r, y + h
      );

    } else if ( // replace top
      anchorY &&
      anchorY < 0 &&
      anchorX > x + safeDistance &&
      anchorX < x + w - safeDistance
    ) {
      path.splice(3, 3,
        'L', anchorX - halfDistance, y,
        anchorX, y - arrowLength,
        anchorX + halfDistance, y,
        w - r, y
      );
    } else { // add to support right arrows
        path.splice(13, 3,
          'L', x + w, anchorY - halfDistance,
          x + w + arrowLength, anchorY,
          x + w, anchorY + halfDistance,
          x + w, y + h - r
        );
    }

    return path;
  }
})(Highcharts);
  chart: {
    events: {
      render: function() {
        var chart = this,
          annotations = chart.annotations[0],
          options = annotations.userOptions,
          labels = options.labels,
          arrowWidth = 6,
          bbox;

        labels.forEach(function(label, i) {
          if (label.point.x === 0) {
            bbox = annotations.labels[i].getBBox();
            label.point.x = -(bbox.width / 2 + arrowWidth);
            label.distance = -bbox.height / 2;
          }
        });

        chart.removeAnnotation('annotations-id');
        chart.addAnnotation(options);
      }
    }
  }