I am plotting a number of highcharts dynamically in a loop and pushing each highchart to an array. So that while clicking on an external button, I can export the charts. But while pushing charts to array, only the last entry is properly set with options.
i had a reference to a fiddle that suggests to clone the options. [https://jsfiddle.net/ndb21y1w/][2]
https://www.highcharts.com/forum/viewtopic.php?t=38574
The fiddle have same series data plotted on all the charts. How to solve this if the data is different for each chart populated. Thanks for any help in advance.
Adding more clarity to question :
The data is populated dynamically in loop. My code logic is like:
counter i;
setInterval(function() {
//logic to populated data...
//It is a multiline chart, so three sets of arrays are populated.
//filling data1[], data2[] and data3[] .
drawChart(data1, data2, data3);
if(condition true) clearInterval();
i++;
});
drawChart(data1, data2, data3) {
var chart = new Highcharts.Chart({
title: {
text: "title",
},
xAxis: {
categories: [1,2,3,4...],
},
series: [{
type: 'line',
data: data1,
}, {
type: 'line',
data: data2,
}, {
type: 'line',
data: data3,
},
});
chartArray.push(chart);
}
This chartArray is where I mentioned to get the last entry only properly.
To create a chart you have to pass an HTML element that will be a chart container. In your code that what's missing. Check the demo I have prepared to reproduce this issue: https://jsfiddle.net/BlackLabel/c60y1t2v/
Code:
var chartArray = [],
counter = 1,
dataArr = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
],
containers = document.getElementById('containers');
function drawChart(data) {
var cnt = document.createElement('div'),
cntId = 'container' + counter++,
chart;
cnt.setAttribute('id', cntId);
containers.appendChild(cnt);
chart = new Highcharts.Chart(cntId, {
title: {
text: "title",
},
xAxis: {
categories: [1, 2, 3, 4],
},
series: [{
type: 'line',
data: data,
}]
});
return chart;
}
dataArr.forEach(function(data) {
var chart = drawChart(data);
chartArray.push(chart);
});
You need to define options each time you use a new chart. Reinitialize the OriginalOptions every time you create a new chart.
const options = [...Array(5)].map(() => {
const originalOptions = {
series: [{
data: [], // some random data
type: 'column'
}]
}
return Object.assign(originalOptions)
})
Fiddle
Updated:
For dynamically repopulating the chart, you have to initialize an empty chart and then add new series + redraw whenever your data is populated.
Your redraw function will look something like this:
var i = 0;
var data = [];
var chart = new Highcharts.Chart('container',{
series: []
});
var interval = setInterval(function() {
i++;
data[i] = [i*10 + 1, i*10+2, i*10+3];
drawChart(data[i]);
if(i > 2) clearInterval(interval);
},1000);
function drawChart(data) {
var series = {
type: 'line',
data: data
}
chart.addSeries(series, false);
chart.redraw();
}
See Updated Fiddle
To Print HTML as PDF you can use this software "wkhtmltopdf"
in Linux you need to use this command :
sudo apt-get install wkhtmltopdf
There are many library based on "wkhtmltopdf" in many languages so you can use it.
Library for PHP : https://github.com/mikehaertl/phpwkhtmltopdf
Store chart options in Array then map over to Initialize Highchart for each options.
var chartArray = [];
function drawChart(data1, data2, data3, i) {
// Create container for charts
const el = document.createElement('div');
document.body.appendChild(el).setAttribute("id", "container"+i);
// Create charts
var chart = new Highcharts.chart(el, {
series: [{
type: 'line',
data: data1,
}, {
type: 'line',
data: data2,
}, {
type: 'line',
data: data3,
}]
});
chartArray.push(chart);
console.log(chartArray);
}
var counter = 0;
var delayTime = 2000;
var timer = setInterval(function(){
var data1 = [30, 70, 50];
var data2 = [40, 70, 60];
var data3 = [10, 90, 20];
drawChart(data1, data2, data3, counter);
if(counter == 2){
clearInterval(timer);
}
counter++;
},delayTime);
<script src="https://code.highcharts.com/highcharts.js"></script>
Related
My chart isnt refreshing when i click search. My chart works and shows the data only when i search and resize the window. I tried moving my chart function inside my search function but it gives me an error. Is there another approach to this? my code is:
$(`#stock-search`).click(function(){
var searchValue = $('#stock-name').val();
$.getJSON(`https://sandbox.iexapis.com/stable/stock/${searchValue}/chart/1m?token=demo`,
function(data){
console.log(data);
for (x = 0; x < 22; x++){
const time = data[`${x}`].label;
xlabel.push(time);
const value = data[`${x}`].high;
ydata.push(value);
console.log(value);
console.log(time);
}
});
});
const ctx = document.getElementById('myChart').getContext('2d');
const xlabel= [];
const ydata= [];
const myChart = new Chart(ctx, {
type: 'line',
data: {
labels: xlabel,
datasets: [{
label: "Highs of the month",
data: ydata,
borderWidth: 1
}]
},
options: {
scales: {
yAxes: [{
ticks: {
callback: function(value, index, values) {
return '$' + value;
}
}
}]
}
}
});
You may want to look at this Question though while a bit dated does seems to provide numerous ways to accomplish your goal:
chart.js load totally new data
I am trying to create a pie chart in JavaScript. I would like this chart to display in the legend only the labels that are non zero.
Does anyone have any ideas how this can be done?
Here is the code I have so far. Currently the legend of the pie chart shows all possible 12 Labels, even though 8 of these have zero value. "Data" will eventually be filled from a database and therefore it is important that this is an automated process.
var ctx = document.getElementById("myPieChart");
var myPieChart = new Chart(ctx, {
type: 'pie',
data: {
labels: ["Astronomica", "Deuteronic", "Floral", "Galactic","Celestrial","Heliosphere","Jupiter","Interstella","Koronis","Eclipse,"Borealis","Lunatic"],
datasets: [{
data: [12.21, 15.58, 11.25, 8.32],
backgroundColor: ['#007bff', '#dc3545', '#ffc107', '#28a745'],
}],
},
});
You can manage data before use they.
var ctx = document.getElementById("myPieChart");
var input_lables = ["Astronomica" , "Deuteronic", "Floral", "Galactic", "Celestrial", "Heliosphere", "Jupiter", "Interstella","Koronis", "Eclipse", "Borealis", "Lunatic"];
var input_values = [12.21, 15.58, 11.25, 8.32];
var output_lables = [];
var output_values = [];
for(var i=0;i<input_lables.length;i++){
if(!values[i]){
output_lables.push(input_lables[i]);
output_values.push(input_values[i]);
}
}
var myPieChart = new Chart(ctx, {
type: 'pie',
data: {
labels: output_lables,
datasets: [{
data: output_values,
backgroundColor: ['#007bff', '#dc3545', '#ffc107', '#28a745'],
}],
},
});
if you went to automatic it just enough make a function like this code.
According with the documentation you can use the filter parameter in the label
http://www.chartjs.org/docs/latest/configuration/legend.html
and you can make a validation to validate the data and if it is 0 you can return false
Filter a legend Item with Chartjs.org V2.7
I need help to add a text after the data that shows the graph, the code I have is the following:
var ctx = document.getElementById("chart-area");
var myChart = new Chart(ctx, {
type: 'pie',
data: {
labels: ["label1", "label2", "label3", "label4"],
datasets: [{
data: [ 10, 20, 30, 40 ]
}]
}
}
It shows me the information like this:
label1: 10
But i need to add text after that, something like:
label1: 10 Mb
Please, I don't know how to add it, I already tried several ways
ChartJs does not provide any format label feature you have to play with it.
Initialize chart configuration with empty array then update it when you pushing data.
From this reference https://github.com/chartjs/Chart.js/issues/2738
here is fiddle link: http://jsfiddle.net/qsnpsxz5/7/
chart.config.data.labels.push("A label");
chart.config.data.labels.push("A label2");
chart.config.data.datasets[0].data.push(10);
chart.config.data.datasets[0].data.push(20);
chart.update();
Try using this script
var ctx = document.getElementById("chart-area");
var myChart = new Chart(ctx, {
type: 'pie',
data: {
labels: ["label1", "label2", "label3", "label4"],
datasets: [
{ data: [ 10, 20, 30, 40 ] }
]
},
options: {
tooltips: {
enabled: true,
callbacks: {
label: function(tooltipItem, data) {
var label = data.datasets[tooltipItem.datasetIndex].label;
var val = data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index];
return label + ' : ' + val + ' Mb';
}
}
}
}
});
I am using the Chart.js lib to make charts.
I have a json array that I am getting from a database.
Here is the console log of it: Data
I need to get the address, speed, and speed limit for every element in the list and use it in a chart.
My current code is as follows:
function ShowChart() {
var popCanvas = document.getElementById("speedLimitsChart");
console.dir(speeddata);
var labels = speeddata.map(function (e) {
return e.Adress;
});
var speed = speeddata.map(function (e) {
return e.Speed;
});
var speedlimits = speeddata.map(function (e) {
return e.SpeedLimits;
});
console.dir(labels);
var barChart = new Chart(popCanvas, {
type: 'bar',
data: {
datasets: [{
label: 'Speed',
data: speed,
backgroundColor: '#1E90FF'
}, {
label: 'Speed Limits',
data: speedlimits,
backgroundColor: '#B22222',
type: 'line'
}],
},
labels: labels
});
}
But in the result I only have the first element in my chart, and there are no labels.
Here is the output screen: Chart
I checked speed, speedlimits and labels and all of them have 2 elements. Can you please advise where my problem might be?
I found where is my problem
I need to write labels inside of data
Like this
var barChart = new Chart(popCanvas, {
type: 'bar',
data: {
labels: labels ,
datasets: [{
label: 'Speed',
data: speed,
backgroundColor: '#1E90FF'
}, {
label: 'Speed Limits',
data: speedlimits,
backgroundColor: '#B22222',
type: 'line'
}],
},
});
I want to do so the chart value increases itself by 1 each second. How can I achieve that? I tried setting a counter variable and then increasing it every second but it didn't work dynamically for some reason.
var myChart = new Chart(ctx, {
type: 'line',
data: {
datasets: [{
label: 'Crash line',
data: [0, 1], //1 here needs to be increased so the graphs grows up
backgroundColor: [
'rgba(108, 170, 91, 0.2)'
],
borderColor: [
'rgba(255,99,132,1)'
],
borderWidth: 1
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
}
}
});
Check out this chart.js documention and chart.js update documention.
You need to use the chart.update method as so:
var options = //chart.js option object
var ctx = document.getElementById('chartJSContainer').getContext('2d');
var chart = new Chart(ctx, options);
var somefunc = function(chart){
var chartDatasetLength = chart.data.datasets[0].data.length;
for(var i = 0; i < chartDatasetLength; i++){
chart.data.datasets[0].data[i] += 1;
}
chart.update();
}
setInterval(somefunc, 1000, chart);
A working jsfiddle demo.