是否可以添加垂直绘图线并显示与序列的交点?

时间:2019-04-14 15:53:47

标签: highcharts

我想知道是否有一种方法可以在图表上画一条线并显示与所有系列中的该线相交的值

为此,我为系列数据标签创建了一个格式化程序,如果每个标签的x值是绘图线的x值,它都会查找该标签,然后仅显示数据标签

plotOptions: {
                        series: {
                            dataLabels: {
                                enabled: true,
                                className: 'highcharts-data-label-box',
                                padding: 0,
                                formatter: function () {
                                    if (valuesToShow.indexOf(this.x) > -1) {
                                        return this.y;
                                    } else {
                                        return null;
                                    }
                                }
                            }
}

这是我的演示:     https://jsfiddle.net/rabigado/7wousgm5/118/

希望找到一种使用注释的方法或其他成本更低的方法来获得相同的结果。

1 个答案:

答案 0 :(得分:1)

可以使用Highcharts.SVGRenderer来创建自定义标签。但是,在重新绘制图表时,它需要附加的逻辑,因为标签会更改其位置,更困难的是,当极端情况发生变化时,dataGrouping会估计不同的值。

我设法做到了,您可以采用这种方法:

  1. point.events.click回调中从整个位置查找x位置 点组。您可以在chart.series.xData数组中找到它。 请注意,chart.series.processedXData具有当前在图表上呈现的值-按dataGrouping分组。
  2. 在x位置上绘制plotLine
  3. 使用chart.renderer.text为每个系列添加标签。保存 对创建的标签的引用。
  4. chart.events.render回调中
  5. 销毁现有的SVG元素 每个标签,并在dataGrouping更改它时以新位置和新值重新绘制它。

代码:

点击点时添加标签:

point: {
  events: {
    click(event) {
      var chart = this.series.chart,
        seriesLen = chart.series.length,
        x = this.x,
        pointIndex,
        pointIndexAbs,
        i,
        y,
        annotation,
        absX,
        plotLine;

      absX = chart.series[0].xData.reduce(
        (prev, curr, index) => {
          return Math.abs(curr - x) < Math.abs(prev - x) ? curr : prev;
        });

      plotLine = chart.xAxis[0].addPlotLine({
        color: "#000",
        width: 1,
        value: absX,
        id: absX
      });

      for (i = 0; i < seriesLen - 1; i++) {

        pointIndex = chart.series[i].processedXData.indexOf(x);

        if (pointIndex !== -1) {
          y = chart.series[i].processedYData[pointIndex];

          annotation = chart.renderer.text(
              y.toFixed(4).toString(),
              chart.xAxis[0].toPixels(absX) - 25,
              chart.yAxis[0].toPixels(y)
            )
            .css({
              fill: 'red',
              fontSize: '10px'
            })
            .attr({
              zIndex: 6
            })
            .add();

          chart.annotationColl.push({
            svgElem: annotation,
            x: absX,
            y: y,
            seriesIndex: i,
            plotLine: plotLine
          });
        }
      }

      return false;
    }
  }
}

在渲染事件上重画标签:

chart: {
  zoomType: 'xy',
  events: {
    render: function() {
      var chart = this,
        x,
        newX,
        newY,
        actualValue,
        absX,
        pointIndex,
        y;

      if (chart.annotationColl && chart.annotationColl.length) {

        chart.annotationColl.forEach(function(annotation, i) {
          if (annotation.svgElem) {
            annotation.svgElem.destroy();
          }

          absX = chart.series[0].processedXData.reduce(
            (prev, curr, index) => {
              return Math.abs(curr - annotation.x) < Math.abs(prev - annotation.x) ? curr : prev;
            });

          pointIndex = chart.series[annotation.seriesIndex].processedXData.indexOf(absX);
          y = chart.series[annotation.seriesIndex].processedYData[pointIndex];

          newX = chart.xAxis[0].toPixels(annotation.x) - 25;
          newY = chart.yAxis[0].toPixels(y);

          if (newX >= chart.plotLeft && newX < chart.plotLeft + chart.plotWidth - 35) {
            annotation.svgElem = chart.renderer.text(
                y.toFixed(4).toString(),
                newX,
                newY
              )
              .css({
                fill: 'red',
                fontSize: '10px'
              })
              .attr({
                zIndex: 6
              })
              .add();
          } else {
            annotation.svgElem = null;
          }
        });
      } else {
        chart.annotationColl = [];
      }

    }
  }
}

演示:

API参考: