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));
我想让注释移动一定的步长,而不是停在轴的两列之间。
例如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));