Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Update chartistjs with new data?

I can reanimate the chart using a setTimeout (at the bottom, on the created event) by using chart.update.bind(chart).

Can anyone suggest a way I can pass new data into that chart object? Maybe with a prototype method? Or Should I just create a whole new chart object and redraw it?

Ultimately I just want a chart that changes data automatically with a nice animation, primarily for aesthetic purposes.

var chart = new Chartist.Line('.ct-chart-main', {
  labels: ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'],
  series: [
    [1, 4, 5, 12, 4, 3, 2, 4, 5, 1]
  ]
}, {
  low: 0,
  showArea: true,
  fullWidth: true,
  width: '600px',
  height: '250px',
  lineSmooth: Chartist.Interpolation.cardinal({
    tension: 1
  })
});

chart.on('created', function() {
  if(window.__exampleAnimateTimeout) {
    clearTimeout(window.__exampleAnimateTimeout);
    window.__exampleAnimateTimeout = null;
  }
  window.__exampleAnimateTimeout = setTimeout(chart.update.bind(chart), 5000);
});

chart.on('draw', function(data) {
    if(data.type === 'point') {
        var circle = new Chartist.Svg('circle', {
      cx: [data.x], cy:[data.y], r:[5],
    }, 'ct-circle');
    data.element.replace(circle);
    }
  if(data.type === 'line' || data.type === 'area') {

    data.element.animate({
      d: {
        begin: 2000 * data.index,
        dur: 1000,
        from: data.path.clone().scale(1, 0).translate(0, data.chartRect.height()).stringify(),
        to: data.path.clone().stringify(),
        easing: Chartist.Svg.Easing.easeOutQuint
      }
    });
  }
});

chart.on('created', function() {
  if(window.__exampleAnimateTimeout) {
    clearTimeout(window.__exampleAnimateTimeout);
    window.__exampleAnimateTimeout = null;
  }
  window.__exampleAnimateTimeout = setTimeout(chart.update.bind(chart), 5000);
});
like image 731
Michael Joseph Aubry Avatar asked Apr 18 '15 19:04

Michael Joseph Aubry


2 Answers

You should be able to update your chart with the following:

chart.update(newData)

like image 99
brianrhea Avatar answered Sep 17 '22 20:09

brianrhea


Here is an example of how I was able to pass new data to an example chart: Note, this uses recursion to demonstrate the concept, to use the function standalone remove the setTimout line.

function updateChart(chart,data,point,length) {
 if(data.series[0].length >= length) {
    data.series[0].shift();
  }
  data.series[0].push(point);
  chart.update(data);
  setTimeout(() => { updateChart(chart,data,getRandomInt(20),length) }, 1000);
}

Entire demo code:

<!DOCTYPE html>
<html>

  <head>
    <style>
      html,
      body {
        margin: 50px;
        padding: 20;
      }

      h2 {
        text-align: center;
      }

    </style>
    <link rel="stylesheet" href="//cdn.jsdelivr.net/chartist.js/latest/chartist.min.css">
    <script src="//cdn.jsdelivr.net/chartist.js/latest/chartist.min.js"></script>
  </head>

  <body>
    <h2>
      Chartist.js Updating with New Data
    </h2>
    <div class="ct-chart ct-perfect-fourth"></div>
  </body>

</html>

<script>

var data = {
    series: [[5, 4, 3, 7, 5, 10]]
};

function getRandomInt(max) {
  return Math.floor(Math.random() * Math.floor(max));
}

function updateChart(chart,data,point,length) {
 if(data.series[0].length >= length) {
    data.series[0].shift();
  }
  data.series[0].push(point);
  chart.update(data);
  setTimeout(() => { updateChart(chart,data,getRandomInt(20),length) }, 1000);
}

// We are setting a few options for our chart and override the defaults
var options = {
  // Don't draw the line chart points
  showPoint: true,
  // Disable line smoothing
  lineSmooth: false,
  // X-Axis specific configuration
  axisX: {
    // We can disable the grid for this axis
    showGrid: true,
    // and also don't show the label
    showLabel: true
  },
  // Y-Axis specific configuration
  axisY: {
    // Lets offset the chart a bit from the labels
    offset: 60,
    // The label interpolation function enables you to modify the values
    // used for the labels on each axis. Here we are converting the
    // values into million pound.
    labelInterpolationFnc: function(value) {
      return '$' + value + 'm';
    }
  }
};

// All you need to do is pass your configuration as third parameter to the chart function

var cid = new Chartist.Line('.ct-chart', data, options);

 
setTimeout(() => { updateChart(cid, data, getRandomInt(20), 10) }, 1000);

</script>
like image 21
ljboone Avatar answered Sep 18 '22 20:09

ljboone