Impossible to render multiple charts with chart.js - javascript

I'm trying to create multiple charts on a single page with Chart.js
I'm dynamically creating several canvas to host those charts.
The information concerning each charts are contained into JSON objects which are contained into 'allDatas'.
Note that the datas from allDatas are correctly formatted and each one have been tested, we can correctly create a Chart without any problem with them. It's the same for the canvas, they're all correct and we can display a chart in any of them. The problem occur when I'm trying to create multiple charts.
var displayDataviz = function(){
var datavizCanvas = document.querySelectorAll('.js-datavizCanvas');
for(var i=0; i<datavizCanvas.length;i++){
var canvas = datavizCanvas[i];
var data = allDatas[i];
data = data.replace(/"/g,'\"');
data = JSON.parse(data);
reCreateDataviz(canvas,data);
}
}
var reCreateDataviz = function(canvas, previousDataviz) {
console.log(canvas);
console.log(previousDataviz);
var myChart = new Chart(canvas, previousDataviz);
return myChart;
}
Here's what I obtain in the console, I logged the two objects so you can see that they're correct, and you can also see that the first chart (totally random) works fine.
I tried to create them manually and the same problem occurs.
Thanks for your help.

This reason why it­'s not working is because, you are storing all the chart instances to a single variable (myChart), which distorts all other chart instances, except one.
To resolve this ...
add another parameter to the reCreateDataviz function ( for instance -
chartID ), which will contain an unique id for each chart :
var reCreateDataviz = function(canvas, previousDataviz, chartID) {
...
}
then, declare the variable, that stores the chart instance, like this :
window['myChart' + chartID] = new Chart(canvas, previousDataviz);
and finally, when calling reCreateDataviz function inside the for loop, pass i as the third argument, like so :
...
reCreateDataviz(canvas, data, i);
...

Related

Update stock price in anychart without re-plotting whole chart

I am playing with the Anychart stock candlestick chart which is very nice, in order to update the chart I use a setInterval function but it re-plots the entire chart which sucks because if I am zooming or something it resets and starts over obviously. Is there a way I can just update last price from the database every couple seconds without re-plotting the whole chart?
Current setInterval function to load chart:
setInterval(function() {
$.get('chart_data.php', function(data) {
$(".main_cont").replaceWith(data);
});
}, 2000);
My chart_data variable:
$chart_data .= "{'x':'".$open_time."','open': ".$open.",'high': ".$high.",'low': ".$low.",'close': ".$close."},";
chart_data.php file:
anychart.onDocumentReady(function() {
// create a data table
var table = anychart.data.table('x');
// add data
table.addData([<?php echo $chart_data;?>]);
// add data
//table.addData([ {'x':'08/09/2020 10:11','open': 11000,'high': 10000,'low': 8000,'close': 8500}]);
// create a stock chart
var chart = anychart.stock(true);
// create a mapping
var mapping = table.mapAs({
'date': 'date',
'open': 'open',
'high': 'high',
'low': 'low',
'close': 'close',
'fill': 'fill'
});
var plot = chart.plot(0);
// add a series using the mapping
chart.plot(0).candlestick(mapping).name();
// set container id for the chart
chart.container('container');
var series = chart.plot(0).candlestick(mapping);
chart.scroller().xAxis(false);
// initiate chart drawing
chart.draw();
});
I would like to replace the setInterval function with something that just replaces the last price data from the database to move the candle up or down, if a new record is added then draw the new candle. I have the script to update the candle or add a new candle I just cannot find a way to do it without re-drawing the whole chart.
You can use the functions for manipulating data to alter the chart.
You can use JS to fetch new data every two seconds, and use addData() to replace the existing data. If that still causes a complete refresh, you'll have to compare the difference between two arrays to determine the difference between the current data and newly fetched data, and use the insert, delete and update methods as described in the docs to alter just the changed data. However, this may still may result in a complete refresh.
You would use AJAX (from JS) to request updated data from a PHP script. The data gets returned to your JS. It's probably easiest to send/receive data in JSON format via jQuery.getJSON.
There's no need to recreate the chart or even reapply the whole data. The AnyStock API provides all you need to update a part of the data. The series will be updated automatically.
For this purpose, you can use addData() function. It replaces all rows with duplicating keys by the last seen row with that key. It means that new points will be added to the table, points with already existing keys in the table will be overridden.
So, all you need is to manage keys and apply points according to your mapping. For details, check the following sample, that simulates exactly what you need - https://playground.anychart.com/Cplq7KMd

Getting empty array from getSelection() of Google Charts ColumnChart

I am creating various charts from data using Google Charts. I am using 2 pie charts (chart0 and chart1), which work fine, and when i use chart0.getSelection() and chart1.getSelection() I get a full array returned, and I can open the selected data perfectly into a dataTable. But when I use getSelection() on the ColumnChart, selection is an empty array with no data inside it. I cannot figure out why nothing is being returned.
var chart2 = new google.visualization.ColumnChart(document.getElementById('chart2Div'));
google.visualization.events.addListener(chart2, 'select', selectHandler2);
function selectHandler2() {
var selection = chart2.getSelection();
if (selection.length) {
doSomething();
}
}

Highcharts Line Chart - Hyperlink on a data point

I am working on an application to create Line Chart using the Highcharts API. This application involves plotting a Date vs. Time Line Chart.
I need to have dynamic hyperlinks, for all or some of the data points.
The data for this chart is being retrieved from a database table and converted into JSON. This JSON is then being parsed by JavaScript and converted into data array that can be consumed by the Highcharts API. There is some data manipulation being done in the JavaScript while converting the data from JSON to data array.
The Highcharts API accepts the input in data array format that comprises of [x, y] combinations.
As I need to have a dynamic hyperlink for all or some of the data points, I have created another array that comprises of the hyperlinks.
I am unable to retrieve the hyperlink URL from the array on the fly as a particular hyperlink is clicked by the user.
I tried using it they was it has been used in this fiddle, http://jsfiddle.net/awasM/1/
A snippet of my code is given below:
series: [{
name: 'Release',
data: dataArray,
URLs: urlArray,
point: {
events: {
click: function() {
var someURL = this.series.userOptions.URLs[this.x];
if (someURL != "undefined")
window.open(someURL);
}
}
}
}]
However, as in my case date (in Unix/Epoch time format) is on x-axis (and time on y-axis), so using the x-axis value does not work.
i hope you could match this code to fix something.
point: {
events: {
click: function() {
var pointObject = this;
var pointindex = pointObject.x;
var pointdata = pointObject.y;
var getIndexOfURL = this.series.userOptions.URLs[pointindex];
var getIndexOfData = this.series.userOptions.data[pointindex];
if (getIndexOfURL){
window.open('http://'+getIndexOfURL);
}
}
}
}

Redraw AmStockChart

I have several AmStockCharts on the page. Those are line graphs. The data gets fetched from MySQL DB in JSON format. If user clicks on a graph dot (a bullet) then a form gets showed up where user can modify the data and save it. In this case I would need to redraw the chart and I can't figure this out.
Here is the piece of code:
//drawing all charts there are
var chart;
$.getJSON('stats.php', function (data) { // get all data from all stats at once
var i=0;
for (chartData in data) {
i++;
chart = new AmCharts.AmStockChart();
var dataSet = new AmChart.DataSet();
dataSet.dataProvider = chartData;
// etc. etc. here are all the single graph parameters
$('#stats').append('<div id="chartdiv' + i + '"></div>');
chart.write("chartdiv" + i);
}
});
I get all charts drawn fine. But here are two problems then. First problem that I can't access them later as the 'chart' variable refers only to the last chart drawn. The second problem is that even if I try to redraw this last chart I get no result.
To redraw the chart I have tried the following:
function chart_redraw(stat) {
$.getJSON('stat.php?redraw=' + stat, function (data) { // get data for one particular stat
var dataSet = new AmCharts.DataSet();
dataSet.dataProvider = data;
...
chart.dataSets = [dataSet];
var stockPanel = new AmChart.StockPanel();
stockPanel.validateData();
chart.panels = [stockPanel];
chart.validateNow();
});
That didn't do anything, i.e. the chart does not get re-drawn.
The only thing I could do is to store the chart div in a hidden input at click event by:
function chartClick (event) {
var chartdiv = event.event.target.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.id
$('#chart_n').val(chartdiv);
...
}
and then use it to remove the chart from that div and crate new one at that place but it is much slower then the validateData() would be.
When data is changed, all you need to do is set new data for data set:
dataSet.dataProvider = yourDataArray;
and then call
stockChart.validateData();
However your code should also change panel/dataset, so It's a bit strange for me. Do you get any console errors? In case not, I'd need to see full working source of your case., but I hipe my suggestion will work.

Parameter passing between different JavaScript libraries

In my Application, I have a grid made in extjs, on click of every row I need to pass selected cell values of that row to another JavaScript library. So to do so, I am considering html as a bridge, if I can somehow get the value in html then I think passing rest won't be tough job. In this regard, I have couple of questions
Am I correct in the way of my thinking?
If so, can anyone suggest me how to pass parameters from extjs to html?
I am retrieving the cell values from Extjs grid using this code
var grid = Ext.getCmp('lineGridChart');
var selectedRecords= grid.getView().getSelectionModel().getSelection();
myWTN = selectedRecords[0].get('wtn');
myMOU = selectedRecords[0].get('avg');
myWING = selectedRecords[0].get('wing');
myPDU = selectedRecords[0].get('pdu');
I need to pass those values to d3 or a simple jquery.
You can use localstorage...
Or just:
myData = selectedRecords[0].getData();
Update:
myData = {
data: {},
set: function(data) {
myData.data = data;
// You jquery logik
}
};
myData.set(selectedRecords[0].getData());

Categories

Resources