Canvas.js chart not updating with new data - javascript

I'm using CanvasJS to create a line graph based on some numbers coming in from my Myo. When new data comes in, the graph doesn't update. Since I don't populate the graph with initial data points, it stays empty forever.
My code: Here

Try this way.
Lets say:
var myChart = new CanvasJS.Chart(...);
Then to update chart data use:
myChart.options.data[0].dataPoints = YOUR_DATA_ARRAY;
myChart.render();
Worked for me, as I didn't find any 'update' method in documentation.

Related

Getting access to already created Chart.js chart

I have created a BarChart with angular-chart like this:
<canvas id="bar"
chart-data="ctrl.barChartData"
chart-options="ctrl.barChartOptions"
chart-labels="ctrl.barChartLabels"
chart-series="ctrl.barChartSeries"
chart-click="ctrl.chartClick"
class="chart chart-bar">
</canvas>
I have wrote a chartClick function based on some example and looks like this:
vm.chartClick = function(evt){
var myBarChart = //how I can obtain a access to my created bar chart?
var activePoints = myBarChart.getPointsAtEvent(evt);
console.log("active: "+activePoints);
}
My question is: how can I obtain an access to chart I have created and assign it to myBarChart?
I have found solution for Highcharts however I can't find it for Chart.js
UPDATE:
Based on link provided by #IBarros I have manage to wrote following few lines of code:
$scope.$on('chart-create', function (event, chart) {
//console.log(chart);
myBarChart = chart;
});
I have 2 charts - one pie chart, one bar chart. What is more the event can be emitted multiple times for each chart so as a result I have a 7 charts printed into console. My next question is: how to find out what chart is a bar chart I'm looking for?
The reason why the event is fired 7 times was explained in this issue: How to get chart instance? #464
If options or other optional attributes are set after the data is set
the chart will be destroyed and recreated. This logic is what allows
the chart to be automatically updated everytime something changes in
the chart settings.
When that happens you should just update the reference on your side.
To figure out which chart object is the one you want, just look for the chart directive id (or chart type) in the chart object.
Example:
Use an object as an associative array
$scope.myCharts = {};
Save object reference in the associative array
$scope.$on('chart-create', function (event, chart) {
console.log(chart.chart.canvas.id);
console.log(chart.chart.config.type);
//If id is the same, reference will be updated
$scope.myCharts[chart.chart.canvas.id] = chart;
});
Access chart object by its directive id
console.log($scope.myCharts[id]);

Adding data points to existing graph with Dygraphs

I have an existing graph created with Dygraphs based on a JavaScript array. I also have a process that generates new values, say once per second, as JavaScript array.
Is it possible to add the new values to the existing graph? I'd like to avoid redrawing the whole graph each time a new value is created.
var data = [[1,99,42],[2,98,52]]
var graph = new Dygraph(element, data, {});
// now graph is created and visible
// how to add newPoint to existing graph?
var newPoint = [3,100,20];
You can use option file for all kinds of data, not just for CSV files.
data.push(newPoint);
graph.updateOptions({file: data});

Chart.js replace all data

im having a issue with Chart.js.
Firts, I set a data, and then when a parameter change, I want rebind the entire chart.
This work, but its like the chart with the old data still behind the new one.
first ->
chart.Line(data, options);
in a event ->
chart.Line(newdata, options);
I saw this solution
chart.js load totally new data
but I dont like this way. Im in a angular directive context, so it's not the best aproach.
I tried without results
.update( ), .removeData( ), .clear(), .destroy(), etc
here its my current directive
http://plnkr.co/edit/qn2UUyznonKm6zgEi8FW?p=catalogue
Any Idea ?
You are creating a new chart, that's why you end up with the old chart behind the new one.
One simple option that I've used:
Remove the old chart from the canvas that you are using for the chart:
$('#canvas').replaceWith('<canvas id="canvas"></canvas>');
And now create the chart with the new data in the same canvas
var ctxChart = document.getElementById("canvas").getContext("2d");
window.myChart = new Chart(ctxChart).Line(newdata, options);
Hope it helps!
For those of you wondering the same thing with Pie charts, doesn't look like there's a given public method that works but you can use an easy workaround by removing the data yourself:
var pieChart = new Chart(ctx).Doughnut(undefined, pieChartOptions);
pieChart.segments.splice(0, pieChart.segments.length);
Seems to work ok, wish they would just add a remove all method or make the clear actually work.
You are right, using the .update() function is the correct way to do this. I just answered the question on the other one you referenced but wanted to provide it here as well.
No need to delete the existing chart or do something like removing the canvas element to later append a new one. That works.. but isn't necessary.
Working CodePen: https://codepen.io/vpolston/pen/KKRoEBY
Video walkthrough: https://www.youtube.com/watch?v=Ac5pzmHO3_A
Firstly if you want to know the why then I would recommend doing a console.log(myChart) of your chart object. You'll see all kinds of properties that can be updated by simply assigning it a new value and then calling the myChart.update() on your chart.
Let's say you have a chart that you called myChart when you instantiated it.. this part:
const myChart = new Chart('myChart', {}
The variable name is important. To update the dataset you silo down into what you saw when you console.log'd the chart. So your dataset would be
myChart.config.data.datasets[0].data
Just assign that a new value like this:
const newDatasArray = [1,52,23,23,48];
myChart.config.data.datasets[0].data = newDatasArray;
and then for the labels if you needed to change those:
const newLabelsArray = ["Jan", "Feb", "Mar", "Apr", "May"];
myChart.config.data.labels = newLabelsArray;
And then finally call the update function with myChart.update();
You'll see the chart update to use the new dataset and/or labels.
Hopefully that gives a bit more insight into properly updating a chart. If you have a further question let me know and I'd be glad to try to help.
Thanks,
VP

Google Annotation Chart Duplicates Itself

I haven't seen this problem with other Google charts before but I am using the Annotation Chart and every time the data is updated the following lines are called which duplicates the chart object in the DOM as a sibling of the parent:
var chart = new google.visualization.AnnotationChart(document.getElementById('chart_' + this.display.displayDivId));
chart.draw(data, options);
This more or less makes sense based on the code but how can I prevent the new method from firing and instead create a chart object out of the existing DOM element and then call the .draw() method on that object?
Is this possible? The only other thing I can think of would be to clear the existing one from the DOM first, and then proceed w/ the logic I illustrated above.
Any thoughts/suggestions would be much appreciated.

Dynamically pass series in jqplot line chart

I have used jqplot line chart.
I have get data from php page using ajax.In some condition I will display specific series.So
How to pass series dynamically in jqplot line chart and also set legend of series ?
I have manually write code for above requirement.I have apply click event on legend series and draw graph as per click on legend.
I have also change y-axis value as per select/deselect series legend.
I originally tried the answer posted by #sdespont, but due to additional properties that need to be in place for the series, it wasn't working properly. I was able to get this working by doing the following:
plot1.data = data;
plot1.replot( data );
data is a 3D array of the same makeup as you would pass in when creating the plot. If I did either part without doing the other, it wouldn't refresh properly, but the combination of the two seems to do the trick. Refreshing the plot in this fashion would dynamically add or remove any series I added to the data array.
Hope that helps.
You could add or remove series by playing with plot1.series array.
Here is a good jsfiddle : jsfiddle.net/fracu/HrZcj
The idea is to create an array with data
myNewSerie = Array();
x = (new Date()).getTime();
y = Math.floor(Math.random() * 100);
myNewSerie.push([x, y]);
Then add it to the graph using the next available slot
plot1.series[plot1.series.length] = myNewSerie
And finally redraw using plot1.replot();
Check out the updateSeries function in the end of the fiddle
Not tested, but should work
I had the same problem recently. "replot" works but is veeerrryyy slow. I used "jQPlot.drawSeries" which is blazingly fast. Just give your new series data to jQPlot as usual and call jQPlot.drawSeries({}, <nr of your series from 0...xxx)
My realtime chart with 800 values runs with >> 60 FPS on my PC and also very fast on my mobiles.

Categories