Cannot read property 'info' of undefined - javascript

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/

Related

Unable to create custom indicator

Checked all the samples in here: https://www.anychart.com/products/anystock/gallery/Stock_Technical_Indicators/?theme=darkEarth All are calculated by any chart functions. indicatorPlot is getting members like .adl etc..
Also checked the sample here with setCalculationFunction: https://www.anychart.com/blog/2018/03/14/custom-technical-indicators-javascript-stock-charts/
Is there a way to "map indicatorPlot" with a csv values like drawing the main graph? Or is datatable can store indicator values to show underneath the chart like oscilators.
The main question is: Is there a way to display a custom oscillator under the chart feeded with values from csv, json etc.. ?
Yes, in this case, the indicator is a usual series that is based on your data. Simply create a series from your data, provide the desired name and that's it.

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

in d3js how can I filter data by clicking on stack bar

I'm trying to filter data by clicking on certain rect bar in a stacked bar. This stack bar is a two dimention graph, the horizontal index is years, and the vertical index different product revenues, I want to filter by certain product in certain year. means when I click on a rect bar of the whole graph, the data should get filtered by certain year and certain product.
my code is :
metrics.on("click", function(d,i,j){
d3.select(this)
.style("fill","lightcoral")
.style("stroke","red");
fdata =rawdata.filter(function(d){return (d[xvalue]==_seriesA[i])&&(d[yvalue]==_seriesB[j])});
});
but the weird thing is the value of j is always undefined, although if I attach a title to it :
metrics.append("title").text(
function(d,i,j) {
return i + ' - '+j ;
});
the value of j will get printed correctly, is there anything special about the 'on' click function? why I cannot get the value of j? any help will be appreciated....this is triving me crazy for the whole night...
According to the documentation, the second argument to .on() is a function that takes two arguments, not three. Similarly, it shouldn't work in your second example either.
I think you're getting confused about the distinction between the data and how it is rendered. The .on() function will get you the data. The scales you have created somewhere in your code take that data and map it to x and y coordinates in your graph (or you use the data directly without scales). In the .on() function, you use the data in exactly the same way you used it when you created the graph to start with. That is, the data item (d in your code) contains the data for the specific position that you're highlighting.

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