Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Show gap of missing data with Highstock

Using Highstock to chart a sorted time serie: [[timestamp, value], ...]

The datasource is sampled at irregular intervals. As result the distances between two points (in the time axis) varies.

If two adjacent points are separated for more than 5 minutes I want to show a gap in the chart.

Using the gapSize option doesn't work, because it doesn't allows to specify the 'size' of the gap as a function of time.

Showing gaps is already a part of Highstock, I just need a way to specify it as a fixed amount of time (5 minutes). Ideas?

Btw, beside that the plot works great.

like image 924
Maximiliano Padulo Avatar asked May 08 '15 08:05

Maximiliano Padulo


Video Answer


2 Answers

Here's a slightly unclean way to "manipulate" gapSize to work so that it's value is the amount of milliseconds required to create a gap.

(function (H) {
    // Wrap getSegments to change gapSize functionality to work based on time (milliseconds)
    H.wrap(H.Series.prototype, 'getSegments', function (proceed) {
        var cPR = this.xAxis.closestPointRange;
        this.xAxis.closestPointRange = 1;

        proceed.apply(this, Array.prototype.slice.call(arguments, 1));

        this.xAxis.closestPointRange = cPR;
    });
}(Highcharts));

This utilizes that gapSize is only used within the getSegments function (see source), and it works based on the closestPointRange of the axis. It wraps the getSegments, sets closestPointRange to 1, calls the original method and then resets closestPointRange to its original value.

With the code above you could do gaps for 5 minutes like this:

plotOptions: {
    line: {
        gapSize: 300000 // 5 minutes in milliseconds
    }
}

See this JSFiddle demonstration of how it may work.

like image 147
Halvor Holsten Strand Avatar answered Oct 13 '22 00:10

Halvor Holsten Strand


Halvor Strand function wrapper did not work for me as long as getSegments is not part of highstock source code anymore to calculate that gap. Anyway, you can find an approximation to solve the problem combining this other topic and the previows answer like this:

(function(H) {
  H.wrap(H.Series.prototype, 'gappedPath', function(proceed) {
    var gapSize = this.options.gapSize,
      xAxis = this.xAxis,
      points = this.points.slice(),
      i = points.length - 1;

    if (gapSize && i > 0) { // #5008

      while (i--) {
        if (points[i + 1].x - points[i].x > gapSize) { // gapSize redefinition to be the real threshold instead of using this.closestPointRange * gapSize
          points.splice( // insert after this one
            i + 1,
            0, {
              isNull: true
            }
          );
        }
      }
    }
    return this.getGraphPath(points);
  });
}(Highcharts))

setting gapSize in plotOptions to the desired size (in ms) like Halvor said:

plotOptions: {
  line: {
    gapSize: 300000 // 5 minutes in milliseconds
  }
}
like image 43
ivan Avatar answered Oct 12 '22 22:10

ivan