carlcraig/tc-angular-chartjs

Dynamic update of graph

Closed this issue · 12 comments

Is it possible to update the data dynamically without re-rendering the whole graph from scratch?

This is something we could potentially do, but it is a little complicated. Currently the directive will destroy/create the chart whenever the scope changes.

Chart.js takes the inital data, and creates new objects on the chart object, so they loose some of the structure that we have in $scope.data

Example:

  $scope.data = {
      labels: [1, 2, 3, 4, 5, 6, 7],
      datasets: [
          {
              fillColor: "rgba(220,220,220,0.2)",
              strokeColor: "rgba(220,220,220,1)",
              pointColor: "rgba(220,220,220,1)",
              pointStrokeColor: "#fff",
              data: [65, 59, 80, 81, 56, 55, 40]
          }
      ]
   }

// Chart.js is using this data we provide, and creating new objects 
// on the chart object for these points.
// e.g. the first point on a line chart could be accessed
myLineChart.datasets[0].points[0].value; // should be 65
// to change we could do:
myLineChart.datasets[0].points[0].value = 10;
myLineChart.update(); // would update without destroying/recreating the chart.

There is no way for us to reload the $scope.data into the chart, without either:

  • looping through the whole dataset and updating each point/segment on the chart.js object (like in example above
  • destroying the chart, and re-creating it.

Chart.js allows us to add/remove/update data (one point at a time, i have not seen any way to bulk update).

It could be interesting to concept a "live update" style feature.
Potentially we could analyze the difference between $scope.data and try to add/remove/update accordingly?

Currently you can retrieve the Chart.js object from the directive like this:

$scope.chart = null;
<canvas tc-chartjs chart-type="line" chart-data="data" chart-options="options" chart="chart">
</canvas>

The chart="variable" will force the app to update that variable with the chart.js object when it is created.

You would want to run some watch on chart variable to know when it is created:

$scope.$watch("chart", function( new, old ) {
   // do something
}

I think, this would be a nice thing for us to solve.

Potentially we should look at a way of analyzing the differences in oldValue and newValue when the $scope.data is updated, so that we can add/remove/update points without destroying the original chart.

+1 for this feature

+1 for this feature!

+1 I'm playing with this now if I come up with something Ill make a gist or PR.

Also +1

Have to add my +1 - pretty keen for this

🎱

I will take a look at some solution for this when i have time. If anyone else has some ideas on how to solve this, feel free to put together a PR, or some examples.

This is pretty crucial. Destroying the chart and re-creating almost seems more expensive than updating data points under the hood, especially in a UI where interaction and graphs are very frequent.

Another +1 from me. It feels very odd not to have this feature as it kind of goes against the angular-mentality.

Closing, as opened new issue for implementing this #43 can move any further discussion to that issue.