HighCharts Keep Vertical Line on Click Event

2019-08-03 02:39发布

Using this example: http://jsfiddle.net/gh/get/jquery/1.7.2/highslide-software/highcharts.com/tree/master/samples/stock/demo/candlestick-and-volume/

When you hover over points on the chart, you get a nice vertical line showing you which point you're currently on. I want to modify the click event so that the vertical line stays when I hover away after a click. Changing the line color would be ideal on click, but not necessary.

If I click another point I'd want to remove any previous lines. Any ideas on how I could accomplish this?

2条回答
ゆ 、 Hurt°
2楼-- · 2019-08-03 03:26

The above solution like I said, is really cool, but is kind of a hack (getting the path of the crosshair) into the implementation details of highcharts, and may stop working in future releases, may not be totally cross browser (esp since <IE8 do not support SVG, the adding path may still work as it should be handled by highchart's add path method, but getting the crosshair's path may not work, I may be wrong, am an SVG noob). So here I give you the alternate solution of dynamically adding plotLines. PlotLines also allow some additional features like dashStyles, label etc.

get the axis and x value of point clicked (may not exactly overlap the crosshair)

            var xValue = evt.xAxis[0].value;
            var xAxis = evt.xAxis[0].axis;

Or

EDIT If you want to have the plotLine at the location of the crosshair and not the click position, you can use following formula (No direct API to get this, obtained from source code hence may stop working if code changes)

            var chart = this;
            var index = chart.inverted ? chart.plotHeight + chart.plotTop - evt.chartY : evt.chartX - chart.plotLeft;
            var xValue = chart.series[0].tooltipPoints[index].x;

Add plotline

           xAxis.addPlotLine({
                value: xValue,
                width: 1,
                color: 'red',
                //dashStyle: 'dash',                   
                id: myPlotLineId
            });

You can cleanup existing plotline

            $.each(xAxis.plotLinesAndBands,function(){
                if(this.id===myPlotLineId)
                {
                    this.destroy();
                }
            });

OR

            try {
                xAxis.removePlotLine(myPlotLineId);
            } catch (err) {}

Putting the pieces together

   var myPlotLineId="myPlotLine";
   ...
           var chart=this;
           index = chart.inverted ? chart.plotHeight + chart.plotTop - evt.chartY : evt.chartX - chart.plotLeft;
           var xValue =  chart.series[0].tooltipPoints[index];

           // var xValue = evt.xAxis[0].value; // To use mouse position and not crosshair's position
           var xAxis = evt.xAxis[0].axis;

            $.each(xAxis.plotLinesAndBands,function(){
                if(this.id===myPlotLineId)
                {
                    this.destroy();
                }
            });
            xAxis.addPlotLine({
                value: xValue,
                width: 1,
                color: 'red',
                //dashStyle: 'dash',                   
                id: myPlotLineId
            });
   ...

Add plot lines at click position @ jsFiddle
Persist crosshair/cursor as plot lines on click @ jsFiddle

查看更多
三岁会撩人
3楼-- · 2019-08-03 03:41

You can do it in several ways

Highchart has a very cool renderer that allows you to add various graphics to the chart. One of the options is to add a path I will be illustrating the same here.

We shall reuse the path of the crosshair and add the same to the chart with some additional styles like color you mentioned. The path of the crosshair can be optained as this.tooltip.crosshairs[0].d this is in string form and can be easily converted to an array using the Array.split() function

click: function() {
    this.renderer.path(this.tooltip.crosshairs[0].d.split(" ")).attr({
        'stroke-width': 2,
         stroke: 'red'
  }).add();
}

This will accomplish adding the line. You can store the returned object into a global variable and then when you are about to add another such line, you can destroy the existing one by calling Element.destroy()

 var line;
 ...
 chart:{
    events: {
        click: function() {

            if (line) {
                line.destroy();
            }
            line = this.renderer.path(this.tooltip.crosshairs[0].d.split(" ")).attr({
                'stroke-width': 2,
                stroke: 'red'
            }).add();

        }
    }
...

Persist tooltip / crosshair on click @ jsFiddle

Assuming you don't have much meta data to be shown along with the line, this is the easiest (or the coolest :) ) approach. You can also attach meta data if you want to using the renderer's text object etc.

An alternate way could be adding vertical plotLines to the xAxis

UPDATE

Refer my other solution to this question, that would work with zoom,scroll,etc

查看更多
登录 后发表回答