Highcharts/Highstock: How to move the tooltip position to the center of a dataGroup

淺唱寂寞╮ 提交于 2021-01-28 08:00:34

问题


Please have a look at this: https://jsfiddle.net/jakobvinther/9u5wdmhp/

The chart has a series with arearange type and forced dataGrouping, looking like this:

Obviously the tooltip is pointing at the minimum y-value in the group. However, I need the tooltip to refer to the value in the center of the dataGroup (I don't mean the average). Likewise for the sliding "header" at the bottom of the vertical crosshair (it is impossible to see the difference in the example, but I use much more fine-grained data in reality).

A hand-made sketch of what is wanted:

To experiment, my jsfiddle includes a wrapper of the Highcharts Tooltip.positioner function. (Alternatively I could have introduced a section tooltip.positioner in the highcharts chart options, but I prefer to have a wrapper around the original Tooltip.positioner function in order to keep all the functionality it provides, and only modify the y-positioning as described).
Well, I had expected the wrapper to execute when the cursor hovers over the chart, but it does not. I also tried with 'TooltipPositionerCallbackFunction' instead of 'positioner' without luck.

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,
            }
        }]
    });
});

EDITS: I have modified the text and jsfiddle code several times to clarify my intentions and avoid problems with the jsfiddle.


回答1:


I need the tooltip to refer to the value in the center of the dataGroup (I don't mean the average)

Notice that there is no point, tooltips states to the point - low in this case, between them, is just a path.

Well, I had expected the wrapper to execute when the cursor hovers over the chart, but it does not.

Look into this demo: https://jsfiddle.net/BlackLabel/aer86jgb/, check the dev console and explore the tooltip prototype. You should notice that the positioner doesn't exist there, that's why your wrapper doesn't work.

Instead of that, I encourage to use the pointFormatter callback to calculate the displayed value (the average between the high and low points) and the positioner callback to set the tooltip position between the points.

Demo: https://jsfiddle.net/BlackLabel/opzgsL4t/

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
      };
    }
  },
},

API: https://api.highcharts.com/highcharts/tooltip.pointFormatter

API: https://api.highcharts.com/highcharts/tooltip.positioner


EDIT

According to the comments - there is a final solution: http://jsfiddle.net/BlackLabel/b7ogdayt/



来源:https://stackoverflow.com/questions/64358169/highcharts-highstock-how-to-move-the-tooltip-position-to-the-center-of-a-datagr

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!