Search code examples
angularhighchartsangular5angular6angular2-highcharts

The continuous update highcharts with more data plotting the continuity is not visible so we need that continuity in the centre of the graph


Issue: Currently I am trying to build a live stream graph which will display data in the range of 0.5 hour to 3 hours. So the graph updates continuously, but it updates at the extreme right side of the graph.

Requirement: My requirement is that I want to do the same thing, but it should be done at the centre of the graph. The live stream should be updated at the centre of the graph and right side should contain future time values with no data plotted against it.

I tried plotting null data against future timestamp values, but Stockchart does not accept such kind of data and displays nothing.

Here is a JSFiddle, the important part:

Highcharts.stockChart('container', {
 chart: {
        events: {
            load: function () {

                // set up the updating of the chart each second
                var series = this.series[0];
                setInterval(function () {
                    var x = (new Date()).getTime(), // current time
                        y = Math.round(Math.random() * 100);
                    series.addPoint([x, y], true, true);
                }, 1000);
                  var series1 = this.series[1];
                setInterval(function () {
                    var x = (new Date()).getTime(), // current time
                        y = Math.round(Math.random() * 100);
                    series1.addPoint([x, y], true, true);
                }, 1000);
                  var series2 = this.series[2];
                setInterval(function () {
                    var x = (new Date()).getTime(), // current time
                        y = Math.round(Math.random() * 100);
                    series2.addPoint([x, y], true, true);
                }, 1000);
            }
        }
    },

Solution

  • I tried plotting null data against future timestamp values, but Stockchart does not accept such kind of data and displays nothing.

    It happens because by default xAxis.ordinal = true it means that points are equally spaced in the chart regardless of the actual time or x distance between them. The solution is simple, set xAxis.ordinal = false and set axis extremes to show future time before the graph line. Check the demo and code posted below.

    var power = [],
      speed = [],
      torque = [],
    
      i = 0;
    let time = 1542278447000;
    for (i; i < 100; i += 1) {
      let torqueValue = Math.floor(Math.random() * (100 - 5 + 1)) + 5;
      let speedValue = Math.floor(Math.random() * (100 - 5 + 1)) + 5;
      powerValue = torqueValue * speedValue
      time = time + 1000
      torque.push([
        time, // the date
        torqueValue // the torque
      ]);
      speed.push([
        time, // the date
        speedValue // the speed
      ]);
      power.push([
        time, // the date
        powerValue // the power
      ]);
    }
    
    // create the chart
    Highcharts.stockChart('container', {
      chart: {
        events: {
          load: function() {
            var chart = this,
              multiplier,
              dataLength,
              x,
              y;
    
            setInterval(function() {
              chart.series.forEach(function(series) {
                multiplier = series.dataMax;
                dataLength = chart.series[0].xData.length;
                x = chart.series[0].xData[dataLength - 1] + 1000;
                y = Math.round(Math.random() * multiplier);
    
                series.addPoint([x, y], false, true);
              });
    
              chart.xAxis[0].setExtremes(null, x + 15000);
            }, 1000);
    
          }
        }
      },
      rangeSelector: {
        enabled: false,
        selected: 2
      },
      navigator: {
        enabled: false
      },
      scrollbar: {
        enabled: false
      },
    
      title: {
        text: ''
      },
      exporting: {
        enabled: false
      },
    
      subtitle: {
        text: ''
      },
    
      xAxis: {
        title: {
          text: 'Time'
        },
        ordinal: false
      },
    
      yAxis: [{
        opposite: false,
        startOnTick: true,
        endOnTick: true,
        labels: {
          align: 'left',
          x: -22
        },
        title: {
          text: 'Torque',
          x: -15
        },
        height: '30%',
        offset: 0,
        lineWidth: 2,
        resize: {
          enabled: true
        }
      }, {
        opposite: false,
        labels: {
          align: 'left',
          x: -22
        },
        title: {
          text: 'Speed',
          x: -15
        },
        top: '33%',
        height: '30%',
        offset: 0,
        lineWidth: 2
      }, {
        opposite: false,
        labels: {
          align: 'left',
          x: -22
        },
        title: {
          text: 'Power',
          x: -15
        },
        top: '66%',
        height: '30%',
        offset: 0,
        lineWidth: 2
      }],
    
      legend: {
        enabled: true
      },
      tooltip: {
        split: true
      },
    
      credits: {
        enabled: false
      },
    
      plotOptions: {
        series: {}
      },
    
      series: [{
        color: '#77787b',
        type: 'spline',
        name: 'Torque',
        id: 'Power',
        zIndex: 2,
        data: torque
      }, {
        color: '#335572',
        type: 'spline',
        name: 'Speed',
        id: 'Speed',
        data: speed,
        yAxis: 1
      }, {
        color: '#ee4650',
        type: 'spline',
        name: 'Power',
        id: 'Power',
        data: power,
        yAxis: 2
      }]
    });
    .header {
      padding: 20px 20px 10px 0px;
      width: 100%;
      display: flex;
      font-size: 16px;
      color: #5e5e5e;
      font-family: 'Montserrat Medium', 'Montserrat Regular', 'Montserrat'
    }
    
    span {
      width: 50%;
      font-family: 'Montserrat Medium', 'Montserrat Regular', 'Montserrat'
    }
    
    span:last-child {
      text-align: right;
    }
    <script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
    <script src="https://code.highcharts.com/stock/highstock.js"></script>
    <script src="https://code.highcharts.com/stock/modules/drag-panes.js"></script>
    <script src="https://code.highcharts.com/stock/modules/exporting.js"></script>
    <script src="https://code.highcharts.com/stock/indicators/indicators.js"></script>
    <script src="https://code.highcharts.com/stock/indicators/volume-by-price.js"></script>
    
    <div class='header'>
      <span>
      Date: 15/11/2018
      </span>
      <span>
      Thrust: 3079.21 N
      </span>
    </div>
    <div id="container" style="height: 500px; min-width: 310px"></div>

    Demo:

    API reference:



    ADDITION

    If you want to make it work with navigator enabled set the same extremes also on navigator xAxis and after that redraw the chart (chart.redraw()). Notice, that it will work correctly if you have navigator.adaptToUpdatedData = false.

    Code:

      chart: {
        events: {
          load: function() {
            var chart = this,
                offset = 15000,
              multiplier,
              dataLength,
              x,
              y,
              min,
              max;
    
            setInterval(function() {
              chart.series.forEach(function(series) {
                multiplier = series.dataMax;
                dataLength = chart.series[0].xData.length;
                x = chart.series[0].xData[dataLength - 1] + 1000;
                y = Math.round(Math.random() * multiplier);
    
                series.addPoint([x, y], false, true);
              });
    
              min = chart.xAxis[0].userMin || null;
              min = min < chart.xAxis[0].dataMin ? null : min;
    
              max = x + offset;
    
              chart.xAxis[0].setExtremes(min, max, false);
              chart.navigator.xAxis.setExtremes(min, max, false);
              chart.redraw();
            }, 1000);
    
          }
        }
      }
    

    Demo:

    API reference: