Invert / recreate chart issue in Highcharts 3.0 - javascript

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!

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();

chart.js radar scaleShowLine for each scaleLine

I'm working on a radar chart and I would like to only show the last scaleline.
I found this post which could have helped me: Chart.js (Radar Chart) different scaleLineColor for each scaleLine but unfortunately, the answer is not working anymore (the jsfiddle link doesn't display anything).
I read parts of the chart.js documentation about gridLines option, then did some tests/changes on this code: [regular radar chart][2] without any result, would anyone know how to adjust it?
Thanks!
[2]: https://codepen.io/grayghostvisuals/pen/xmBpLenter code here
Here is a solution using the latest version of chart.js (v2.5.0). It uses the scale afterTickToLabelConversion callback property to overwrite the values that were set for the scale ticks (e.g. scale lines).
Since you only want to display the last line, you have to overwrite them by keeping the first tick value (which is never displayed) and only the last tick value (the last line). If you only wanted to display some other line then you would keep the first tick and only the other line that you want displayed.
Here is my implementation.
afterTickToLabelConversion: function(scaleInstance) {
// overwrite the ticks and keep the first (never shown) and last
var oldTicks = scaleInstance.ticks;
scaleInstance.ticks = [oldTicks[0], oldTicks[oldTicks.length - 1]];
// overwrite the numerical representation of the ticks and
// keep the first (never shown) and last
var oldTicksAsNumbers = scaleInstance.ticksAsNumbers;
scaleInstance.ticksAsNumbers = [oldTicksAsNumbers[0], oldTicksAsNumbers[oldTicksAsNumbers.length - 1]];
}
Here is a codepen example that shows an original radar chart and one using the approach described above so that you can see the difference.

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/

Highcharts - redraw() vs. new Highcharts.chart

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).

Categories

Resources