Highcharts - redraw() vs. new Highcharts.chart - javascript

I'm struggling to understand the correct way to update a highcharts chart. Supposing I have rendered a chart, and then I want to update it in some way. For instance, I may want to change the values of the data series, or I may want to enable dataLabels.
At the moment the only way I can figure out how to do this is to alter the chart options, and use new Highcharts.chart to tell highcharts to redraw.
However, I'm wondering whether this may be overkill and it might be possible to alter the chart 'in situ', without having to start from scratch with new Highcharts.chart. I notice there is a redraw() method, but I can't seem to get it to work.
Any help is very much appreciated.
Thanks,
Robin
Sample code is as follows and at the bottom there is a jsFiddle
$(document).ready(function() {
chartOptions = {
chart: {
renderTo: 'container',
type: 'area',
},
series: [{
data: [1,2,3]
}]
};
chart1 = new Highcharts.Chart(chartOptions);
chartOptions.series[0].data= [10,5,2];
chart1 = new Highcharts.Chart(chartOptions);
//The following seems to have no effect
chart1.series[0].data = [2,4,4];
chart1.redraw();
});​
http://jsfiddle.net/sUXsu/18/
[edit]:
For any future viewers of this question, it's worth noting there is no method to hide and show dataLabels. The following shows how to do it: http://jsfiddle.net/supertrue/tCF8Y/

chart.series[0].setData(data,true);
The setData method itself will call the redraw method

you have to call set and add functions on chart object before calling redraw.
chart.xAxis[0].setCategories([2,4,5,6,7], false);
chart.addSeries({
name: "acx",
data: [4,5,6,7,8]
}, false);
chart.redraw();

var newData = [1,2,3,4,5,6,7];
var chart = $('#chartjs').highcharts();
chart.series[0].setData(newData, true);
Explanation:
Variable newData contains value that want to update in chart. Variable chart is an object of a chart. setData is a method provided by highchart to update data.
Method setData contains two parameters, in first parameter we need to pass new value as array and second param is Boolean value. If true then chart updates itself and if false then we have to use redraw() method to update chart (i.e chart.redraw();)
http://jsfiddle.net/NxEnH/8/

#RobinL as mentioned in previous comments, you can use chart.series[n].setData(). First you need to make sure you’ve assigned a chart instance to the chart variable, that way it adopts all the properties and methods you need to access and manipulate the chart.
I’ve also used the second parameter of setData() and had it false, to prevent automatic rendering of the chart. This was because I have multiple data series, so I’ll rather update each of them, with render=false, and then running chart.redraw(). This multiplied performance (I’m having 10,000-100,000 data points and refreshing the data set every 50 milliseconds).

Related

ChartJS re-rendering bug

So I'm building a trading tool and am using chartJS for the charts. This is how my charts look now on the page:
So my problem is that when I change the time period of the chart, the chart shows randomly the old data mixed with the new one.
You can see the behaviour here: https://gifyu.com/image/vda5
For now I can't use the Big chart together with the small one on the same page because the big chart which has the timing period has also multiple AJAX calls so every time I click on "1W" for example, a new call is being made and the chart is drawn over.
Things I tried:
I know that for dynamic charts in chartJS I have to destroy the chart, so I'm using
if (window.chart !== undefined) window.chart.destroy();
and for the small charts I use an empty array and push the elements inside. Here is how I do it:
if ($(quoteDisplayEl).hasClass('quoteDisplay-light')) {
chartHandel.push(quoteChart);
} else {
window.chart = quoteChart;
}
so for the big chart I assign it to a global variable and the small one I push it to the empty array - that allows me to have multiple charts on one page.
But in order for the big chart to be destroyed I should destroy and re-render all charts from scratch (I guess) and I tried multiple was of achieving that with now luck.
Unfortunately the code is over 500 lines and has lots of variable data coming from APIs and DB thus I can't make a fiddle demo.
I prefer chart.update() over chart.destroy().
Here's a small, simple example how I usually update data.
I make one object per chart with labels (empty array) and data (empty array) and colors and all the stuff you need.
I fill these arrays with data I get (AJAX).
Optional: If I get all the data and need to filter it to show less data, I copy my object to keep all the data I got and have all the data I need now for my chart in another object
Make an updateChart() function which alters your displayed data or saved data from your backup object or use new data from a new AJAX request.
End your updateChart() with chart.update() (or whatever your chart is called).
Multiple charts shouldn't be a problem and you shouldn't have to destroy your chart.

Creating datapoints on mouseclick Chart.js

I am new to Chart.js and JavaScript. Currently working with a line chart, and now I want to add custom data points to a mouse click event (when I press somewhere on the data set, it takes the current value of the Y axis and using that value it creates a data point in that place). I took the code from http://www.chartjs.org/samples/latest/charts/line/basic.html and trying to modify it. Here is a link to my current chart:
https://i.stack.imgur.com/M9MF1.jpg
I am using the basic chart.bundle.js library, and used D3.js libraries for making data points draggable.
Trying to implement the creation of points per mouse click using the following code, but it seems that it's not good so far.
document.getElementById('canvas').onclick = function(e){
//getting value by pressing on dataset
value = chartInstance.scales[scale].getValueForPixel(e.clientY)
//trying to create dataPoint
myLineChart.points.push(new this.PointClass({
y: value;
strokeColor: this.datasets[datasetIndex].pointStrokeColor,
fillColor: this.datasets[datasetIndex].pointColor
}));
//after all updating my chart
chartInstance.Update(0)
};
Maybe anyone could explain more about this library and how it creates data points?
Every new point in the chart is data, so you need to add that point in the data (chartData.data.dataset[]) array. Instead of adding to the, myLineChart.points which i'm not sure why you have used you should add the data-point in the data array and the UI decorations such as colors are supposed to be specified in the chartOptions.scales.yAxes[] array. Therefore in order to add the point in the chart use:
// here i is the corresponding parameter for which you want to add the new point
chartInstance.data.datasets[i].push(value);
chartInstance.update();

Cannot read property 'info' of undefined

I am having an issue where I get the error in the title of this question when I create a chart like the one in this fiddle http://jsfiddle.net/w43m47hL/.
I get this problem when selecting a point.
this.select();
The problem occurs when performing these steps.
create the chart
click on a point to select it
destroy the chart
create the chart again
The size of the data set seems to have something to do with the problem. If you change 1500 to 15 you will see that you don't get this problem any more. However the data point that was selected is still selected after the chart is destroyed and created again. I would have thought that the point would not be selected since the chart was destroyed. How is the data point remembering that it was selected?
The issue is caused by keeping reference to "old" data array. During chart initialisation, you set the reference to data array, which is modified. So when you destroy chart, reference still exists. Use the copy of data ($.extend([],data)) in Highcharts objects.
series: [{
data: $.extend([], data)
}],
Example:
http://jsfiddle.net/nazr3det/

Why is the legend of my HighChart PieChart behaving irradically, when I update my series data?

I have a semi-circle donut piechart, which I have been successfully able to pass data to in runtime. Both the Legend, and the Tooltip has been working perfectly, and shown the correct data.
The tooltip has been showing both the amount, and a percentage value. The legend used to show an amount-value, but I was required to change it to percentages. I didn't expect that to be hard, but for some reason, the percentage value behaves very strangely. The first data in the series will always show the previous updated percentage. The others I can't even understand what are doing. They seem to be following a pattern of their previous value as well, but something seemingly related to the first data, seem to affect them. They do not even add up to a 100 percent.
I've been trying to figure out if there is some designated required order, or sequence to follow, when updating the series values, and the legend, but I can't figure it out. if I switch the this.percentage.toFixed(1) with this.y it works again, but then with amounts instead of percentages.
i have reproduced the error in a JSFiddle:
http://jsfiddle.net/kuF3q/
For this example, I have used the Math.random() to simulate new data, like this:
chart.series[0].data[0].update(Math.random());
chart.series[0].data[1].update(Math.random());
chart.series[0].data[2].update(Math.random());
chart.series[0].data[3].update(Math.random());
chart.series[0].data[4].update(Math.random());
chart.series[0].data[5].update(Math.random());
chart.series[0].data[6].update(Math.random());
Note the difference between the tooltip-values, and the legend values. Any ideas on what I am doing wrong?
I'm not sure why your example is going wrong, but you can get it working by using chart.series.setData like this:
function newData(){
var newData = [Math.random(),Math.random(),Math.random(),Math.random(),Math.random(),Math.random(),Math.random()];
chart.series[0].setData(newData);
}
http://jsfiddle.net/QwLR7/
Note, setData redraws the chart by default. http://api.highcharts.com/highcharts#Series.setData.
Here is your newData function :
function newData(){
chart.series[0].setData ( [3, 2, 4, 6, 12, 6, 5]);
chart.redraw(true);
}
Here is a JsFiddle : http://jsfiddle.net/S5q53/
With random value : http://jsfiddle.net/S5q53/1/

Invert / recreate chart issue in Highcharts 3.0

I'm working with an issue of missing series when inverting a chart with more than one serie. It worked before we upgraded to v3.0 of Highcharts. So the technique of "dynamically" inverting the chart, is to copy the previous charts options, change the inverted option, then creating a new chart with these options.
options = jQuery.extend(true, {}, chart.options);
options.chart.inverted = isInverted;
chart.destroy();
chart = new Highcharts.Chart(options);
This worked "nicely" before. But now it only keeps one serie. Tried all sorts of solutions, copying the serie object, and adding each serie to the new object, without luck because the copied object uses pointers.
Any takers ?
I finally found the reason:
the chart.options object didn't contain the series, just the series object contained them. The series had been added using Chart.addSeries(). Shouldn't this method also make a options.series object?
Anyways, pushed in a new object in the array, got the settings from chart.series, and voila!

Categories

Resources