Highcharts 可拖动注释如何逐步移动?

Highcharts draggable annotaion how to move by steps?

我想让注释移动一定的步长,而不是停在轴的两列之间。

例如x轴为[0, 10, 20, 30]。拖动注释时,我希望它的点直接从 {x: 10, y: 10000} 更改为 {x: 20, y: 10000} 而不是 x: 15。即使注释有点 到列而不是列之间。

我还需要获取当前注释点以便我可以更新一些其他元素。

我尝试了 的解决方案,但它不起作用。

这是我当前的代码。 CodePen

enter code here

编辑 1:
感谢@ppotaczek 的解决方案,注释现在可以逐步移动。这是更新后的代码 JSFiddle。需要细化的是当拖动注释的速度太快时,跟不上鼠标。是因为 Highcharts.redraw() 方法的性能问题,我们如何解决这个问题?

还有一个未解决的问题是->如何获取注解的当前点?注释对象似乎没有为此提供任何价值。我能想到的就是保留初始点的记录,然后每次将注释移动一步,更新记录。有没有更好的方法?

//this code can deal with vertical and horizontal annotations now.
Highcharts.Annotation.prototype.onDrag = function(e) {
if (
  this.chart.isInsidePlot(
    e.chartX - this.chart.plotLeft,
    e.chartY - this.chart.plotTop
  )
) {
  var translation = this.mouseMoveToTranslation(e),
    xAxis = this.chart.xAxis[0],
    yAxis = this.chart.yAxis[0],
    xStep = 1,
    yStep = 1000,
    pxStep = xAxis.toPixels(xStep) - xAxis.toPixels(0),
    pyStep = yAxis.toPixels(yStep) - yAxis.toPixels(0);

  if (!Highcharts.defined(this.potentialTranslation)) { //not defined
    this.potentialTranslation = 0;
  }

  if (this.options.draggable === 'x') {
    this.potentialTranslation += translation.x;
    translation.y = 0;
    if (Math.abs(this.potentialTranslation) >= Math.abs(pxStep)) {
      translation.x = (this.potentialTranslation > 0) ? pxStep : -pxStep;
      this.potentialTranslation = 0;
      //this.potentialTranslation = undefined;

      if (this.points.length) {
        this.translate(translation.x, translation.y);
      } else {
        this.shapes.forEach(function(shape) {
          shape.translate(translation.x, translation.y);
        });
        this.labels.forEach(function(label) {
          label.translate(translation.x, translation.y);
        });
      }
    }
  }
  if (this.options.draggable === 'y') {
    this.potentialTranslation += translation.y;
    translation.x = 0;
    if (Math.abs(this.potentialTranslation) >= Math.abs(pyStep)) {
      translation.y = (this.potentialTranslation > 0) ? -pyStep : pyStep;
      this.potentialTranslation = 0;

      if (this.points.length) {
        this.translate(translation.x, translation.y);
      } else {
        this.shapes.forEach(function(shape) {
          shape.translate(translation.x, translation.y);
        });
        this.labels.forEach(function(label) {
          label.translate(translation.x, translation.y);
        });
      }
    }
  }

  this.redraw(false);
  }
}

编辑 2: 再次感谢@ppotaczek! "mouse moving too fast" 问题现已解决。我应用了他的更新以及我关于如何将注释值放入 JSFiddle.

的想法

您可以覆盖Highcharts.Annotation.prototype.onDrag方法:

(function(H) {
    H.Annotation.prototype.onDrag = function(e) {
        if (
            this.chart.isInsidePlot(
                e.chartX - this.chart.plotLeft,
                e.chartY - this.chart.plotTop
            )
        ) {
            var translation = this.mouseMoveToTranslation(e),
                xAxis = this.chart.xAxis[0],
                step = 0.5,
                pxStep = xAxis.toPixels(step) - xAxis.toPixels(0);

            if (!H.defined(this.potentialTranslation)) {
                this.potentialTranslation = 0;
            }

            this.potentialTranslation += translation.x;

            if (Math.abs(this.potentialTranslation) >= pxStep) {
                translation.y = 0;
                translation.x = (this.potentialTranslation > 0) ? pxStep : -pxStep;
                this.potentialTranslation = 0;

                if (this.points.length) {
                    this.translate(translation.x, translation.y);
                } else {
                    this.shapes.forEach(function(shape) {
                        shape.translate(translation.x, translation.y);
                    });
                    this.labels.forEach(function(label) {
                        label.translate(translation.x, translation.y);
                    });
                }
            }

            this.redraw(false);
        }
    }
}(Highcharts));

现场演示: http://jsfiddle.net/BlackLabel/vmon2chx/

文档: https://www.highcharts.com/docs/extending-highcharts