Chart.js replace all data - javascript

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

Related

D3 multiline chart on update crosses axis

I am trying to plot a multiline d3 chart. I have created a method which should take a new dataset and try to plot it in the same d3 frame for new data update changes (possibly filters).
The first draw works fine but the next draw (mocked data: which is a slice of the previous data and few manipulated values) is not showing correct is crossing the x axis.
[See Image below]
Also the starting origin is missing a tick which should also be 2010 in this example
I also want to create few more lines if there is more datapoints in the future which should be dynamic. Current model is {date, actual, projected}, More expected is mean or difference which will only be shown on trigger.
Any help would be appreciated.
Here is a Stackblitz https://stackblitz.com/edit/angular-rhr39p
References:
Animated line chart: http://bl.ocks.org/atmccann/8966400
Multiline chart: https://bl.ocks.org/larsenmtl/e3b8b7c2ca4787f77d78f58d41c3da91
Dataset updates: https://bl.ocks.org/d3noob/7030f35b72de721622b8
Please keep just one problem per question here at Stack Overflow. This answer will deal with problem #1, consider asking separate questions for the other problems.
The issue here is just your enter/update methodology, that is not correct and. Stick with the idiomatic D3, which is along these lines:
const update = this.svg.selectAll('.records')
.data(records);
const enter = update.enter().append('g')
.attr('class', 'records');
Then, you append new paths using enter and update those paths using update.
You can also ditch the groups and create enter/update/exit selections for the paths directly. That will make your code simpler.
Here is the forked code: https://stackblitz.com/edit/angular-lyd79t?file=src%2Fapp%2Flinechart%2Flinechart.component.ts

Canvas.js chart not updating with new data

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.

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.

jqplot custom legends

I try to create legends for jqPlot but they will just show the max and min values for y slope. Just like 'Max: 16 Min:2', but I can't figure out how. E.g, I tried giving labels as
var labels = [{'Max':16}, {'Min':2}];
But nothing seems to be working. Do you know any quick method or I should create my own special renderer for this?
Thanks.
ufucuk.
I had the same problem and I solved it doing the following:
$("#hereGoesMyMinValue").text($("#myGraphId").
children(".jqplotxaxis").children(":first").text());
//first value shown
$("#hereGoesMyMaxValue").text($("#myGraphId").
children(".jqplot-xaxis").children(":last").text());
//last value shown
Note that this will be done only once. Here explains how to sync them
By the way, you also can do the following:
var title=$("#selecting_period").children(".jqplot-title").text();
var coolTitle=
title+": Showing "+ $("#myGraphId").children(".jqplot-xaxis").
children(":first").text()+" to "+$("#myGraphId").
children(".jqplot-xaxis").children(":last").text();
$("#myGraphId").children(".jqplot-title").text(coolTitle);

Categories