Search code examples
highchartsmousemovetouchstarttouchmove

Capturing touch events (touchstart and touchmove) in addition to mousemove for synchronising highcharts


I have been building a basic webpage which displays data from a weather station with multiple synchronised highcharts, with the help of others here and here I have been able to implement a fully working version for mouse based systems (windows etc), how do I adapt the code below to also capture the touchstart and touchmove events:

//catch mousemove event and have all charts' crosshairs move along indicated values on x axis

function syncronizeCrossHairs(chart) {
  var container = $(chart.container),
    offset = container.offset(),
    x;

  container.mousemove(function(evt) {
    x = evt.clientX - chart.plotLeft - offset.left;
    //remove old plot line and draw new plot line (crosshair) for this chart
    var xAxis1 = chart1.xAxis[0],
      points = [],
      points1 = [],
      points2 = [],
      points3 = [],
      points4 = [],
      e = chart1.pointer.normalize(evt); // Find coordinates within the chart   

    chart1.series.forEach(s => {
      var point = s.searchPoint(e, true)
      if (point) {
        point.setState();
        points.push(point)
      }
    })

    if (points) {
      var number = 0;
      Highcharts.each(points, function(p, i) {
        if (!p.series.visible) {
          points.splice(i - number, 1);
          number++;
        }
      })
      if (points.length) {
        chart1.tooltip.refresh(points); // Show the tooltip
      }
    }

    xAxis1.removePlotLine("myPlotLineId");
    xAxis1.addPlotLine({
      value: chart.xAxis[0].translate(x, true),
      width: 1,
      id: "myPlotLineId"
    });

    /*----- second chart ------*/
    var xAxis2 = chart2.xAxis[0];

    chart2.series.forEach(s => {
      var point = s.searchPoint(e, true)
      if (point) {
        point.setState();
        points1.push(point)
      }
    })

    if (points1[0]) {
      var number = 0;
      Highcharts.each(points1, function(p, i) {
        if (!p.series.visible) {
          points1.splice(i - number, 1);
          number++;
        }
      })
      if (points1.length) {
        chart2.tooltip.refresh(points1); // Show the tooltip
      }
    }

    xAxis2.removePlotLine("myPlotLineId");
    xAxis2.addPlotLine({
      value: chart.xAxis[0].translate(x, true),
      width: 1,
      id: "myPlotLineId"
    });

    /*----- third chart ------*/
    var xAxis3 = chart3.xAxis[0];

    chart3.series.forEach(s => {
      var point = s.searchPoint(e, true)
      if (point) {
        point.setState();
        points2.push(point)
      }
    })

    if (points2[0]) {
      var number = 0;
      Highcharts.each(points1, function(p, i) {
        if (!p.series.visible) {
          points2.splice(i - number, 1);
          number++;
        }
      })
      if (points2.length) {
        chart3.tooltip.refresh(points2); // Show the tooltip
      }
    }

    xAxis3.removePlotLine("myPlotLineId");
    xAxis3.addPlotLine({
      value: chart.xAxis[0].translate(x, true),
      width: 1,
      id: "myPlotLineId"
    });

    //if you have other charts that need to be syncronized - update their crosshair (plot line) in the same way in this function.                   
  });
}

Thanks


Solution

  • Base on this example from official Highcharts demo base https://www.highcharts.com/demo/synchronized-charts I was able to wrap similar pattern to your code.

    Demo: http://jsfiddle.net/BlackLabel/mnLzbe1s/

      ['mousemove', 'touchmove', 'touchstart'].forEach(function(eventType) {
        var container = $(chart.container),
          offset = container.offset(),
          x;
        container[0].addEventListener(eventType,
          (function(evt) {
            x = evt.clientX - chart.plotLeft - offset.left;
            //remove old plot line and draw new plot line (crosshair) for this chart
            var xAxis1 = chart1.xAxis[0],
              points = [],
              points1 = [],
              points2 = [],
              points3 = [],
              e = chart1.pointer.normalize(evt); // Find coordinates within the chart
    
           ...
           })
         )
      })