Highcharts/Highstock:如何将工具提示位置移动到数据组的中心
请看一下这个:Highcharts/Highstock:如何将工具提示位置移动到数据组的中心,highcharts,Highcharts,请看一下这个: 图表中有一系列区域范围类型和强制数据分组,如下所示: 很明显,工具提示指向组中的最小y值。但是,我需要工具提示来引用数据组中心的值(我不是指平均值)。同样,对于垂直十字线底部的滑动“标题”(在示例中不可能看到差异,但实际上我使用了更细粒度的数据) 所需内容的手绘草图: 为了进行实验,我的JSFIDLE包含Highcharts Tooltip.定位器函数的包装。(或者,我可以在highcharts图表选项中引入一个部分tooltip.positioner,但我更喜欢在原始tool
图表中有一系列区域范围类型和强制数据分组,如下所示:
很明显,工具提示指向组中的最小y值。但是,我需要工具提示来引用数据组中心的值(我不是指平均值)。同样,对于垂直十字线底部的滑动“标题”(在示例中不可能看到差异,但实际上我使用了更细粒度的数据) 所需内容的手绘草图:
为了进行实验,我的JSFIDLE包含Highcharts Tooltip.定位器函数的包装。(或者,我可以在highcharts图表选项中引入一个部分tooltip.positioner,但我更喜欢在原始tooltip.positioner函数周围有一个包装器,以便保留它提供的所有功能,并且只修改所述的y定位)。
,我原以为当光标悬停在图表上时包装器会执行,但事实并非如此。我也试过用“”代替“定位器”,但运气不好
Highcharts.wrap(Highcharts.Tooltip.prototype, 'positioner', function (proceed, args) {
console.log("positioner wrapper executing"); // **** this does not run !!?? ***
// how can I get to the point? Is it args.point?
const start = args.point.dataGroup.start;
const length = args.point.dataGroup.length;
// index of the central point within the group:
const cidx = Math.floor((start + length / 2.0));
// get the that point from the series
const cx = args.point.series.xData[cidx];
const cy = args.point.series.yData[cidx];
// Here I want to call the original positioner function
// with the point coordinates { x: cx, y: cy }
// but I don't know how.
proceed.apply(this, Array.prototype.slice.call(arguments, 1));
});
$(function () {
// generate some data
const x0 = 2592000000;
const dx = 86400000;
const n = 900;
let data = [
[x0, 10, 20]
]; // initial value
for (i = 1; i < n - 1; i++) { // construct n values of [timestamp, random, random]
data[i] = [data[i - 1][0] + dx, 10 + Math.random() * 10, 20 + Math.random() * 10];
}
chart = new Highcharts.StockChart({
chart: {
renderTo: 'container',
},
series: [{
name: 'data',
data: data,
type: 'arearange',
dataGrouping: {
forced: true,
}
}]
});
});
Highcharts.wrap(Highcharts.Tooltip.prototype,'positioner',函数(继续,args){
console.log(“定位器包装器正在执行”);//****这不会运行***
//我怎么才能说到点子上呢?是args.point吗?
const start=args.point.dataGroup.start;
常量长度=args.point.dataGroup.length;
//组内中心点的索引:
常数cidx=数学楼层((起点+长度/2.0));
//从这一系列中获得这一点
常量cx=args.point.series.xData[cidx];
常数cy=args.point.series.yData[cidx];
//这里我想调用原始定位器函数
//点坐标为{x:cx,y:cy}
//但我不知道怎么做。
apply(这个,Array.prototype.slice.call(参数,1));
});
$(函数(){
//生成一些数据
常数x0=2592000000;
常数dx=86400000;
常数n=900;
让数据=[
[x0,10,20]
];//初始值
对于(i=1;i
编辑:我多次修改了文本和JSFIDLE代码,以澄清我的意图并避免JSFIDLE出现问题
我需要工具提示来引用数据组中心的值(我不是指平均值)
请注意,没有点,工具提示状态为点-在本例中,它们之间只是一条路径
好吧,我原以为包装器会在光标悬停在图表上时执行,但事实并非如此
查看此演示:,检查开发控制台并探索工具提示原型。您应该注意到,定位器
不存在,这就是包装器无法工作的原因
相反,我鼓励使用pointFormatter
回调来计算显示的值(高点和低点之间的平均值),并使用定位器
回调来设置点之间的工具提示位置
演示:
工具提示:{
指针格式化程序(){
让点=这个,
输出=`● ${point.series.name}:${(point.high+point.low)/2}
`;
返回输出
},
形状:“rect”,
定位器:功能(标签宽度、标签高度、点){
让chart=this.chart,
yAxis=chart.yAxis[0];
if(点isHeader){
返回{
x:point.plotX+chart.plotLeft-labelWidth/2,
y:点。情节
}
}否则{
设lowPxPos=point.plotY,
highPxPos=yAxis.toPixels(point.high)-chart.plotTop;
返回{
x:point.plotX+chart.plotLeft+10,
y:(高PXPOS+低PXPOS)/2-标签高度/2,
伊舍德尔:是的
};
}
},
},
API:
API:
编辑
根据评论-有一个最终的解决方案:谢谢,但是point.high和point.low之间的中间值对我的目的没有用处。我需要未分组序列数据中的可用信息。我需要访问位于分组数据中心X的特定点(在未分组数据系列中)的坐标。我想这需要访问该系列。这不可能吗?此外,正如我所说的,我更愿意使用包装器来保持原来的工具提示定位行为的其余部分,而不必重新实现这一点……让我们考虑一下这个基本演示:在这里,您可以访问该系列。你能告诉我你想说什么吗:
我需要未分组序列数据中的可用信息。我需要访问位于分组数据中心X的特定点(在未分组数据系列中)的坐标
是否要访问嵌套在某个分组范围内的数据?工具提示应在其悬停的数据组的中心索引处获取(X,y)参数。我的意思是在索引轮(point.dataGroup.start+point.dataGroup.length/2)。在我的新演示jsfiddle.net/jakobvinther/b27cdzrw中,在控制台中,您可以看到数据组的值被动态打印出来。也许我应该提到,该图表将在webapp中用于显示密集采样的信号。它使用series.arearange.data类型来指示动态范围(最小/最大),无论缩放级别如何。系列数据数组如下所示:[[x1,y1,y1],[x2,y2,y2],[x3,y3,y3],…];注意两个y值(假设为Yman
tooltip: {
pointFormatter() {
let point = this,
output = `<span style="color:${point.color}">●</span> ${point.series.name}: <b>${(point.high + point.low) / 2}</b><br/>`;
return output
},
shape: 'rect',
positioner: function(labelWidth, labelHeight, point) {
let chart = this.chart,
yAxis = chart.yAxis[0];
if (point.isHeader) {
return {
x: point.plotX + chart.plotLeft - labelWidth / 2,
y: point.plotY
}
} else {
let lowPxPos = point.plotY,
highPxPos = yAxis.toPixels(point.high) - chart.plotTop;
return {
x: point.plotX + chart.plotLeft + 10,
y: (highPxPos + lowPxPos) / 2 - labelHeight / 2,
isHeader: true
};
}
},
},