I am using highcharts to display a bar chart of my data which i am getting from a json file.
I tried following highcharts example for a bar chart for some reason mine is not displaying anything on the chart nor giving me an error.
This is how i am loading my json data for labels and data values - i am returning the data that i want but the issue with display:
chartLabel: any[] = [];
chartValue: any[] = [];
this.serviceFile.getData().subscribe(
data => {
this.result = data;
this.result.forEach(graph =>{
this.chartLabel.push(graph.labelName);
this.chartValue.push(graph.value);
})
});
HTML:
<chart [options]="options"></chart>
chart options:
this.options = {
chart: {
type: 'bar',
margin: 75
},
xAxis: {
categories: this.chartLabel,
title: {
text: null
}
},
yAxis: {
min: 0,
labels: {
overflow: 'justify'
}
},
plotOptions: {
bar: {
dataLabels: {
enabled: true
}
}
},
series: [{
data: this.chartValue
}]
};
I am not sure if the way i created the arrays of my json data are appropriate for the highcharts chart.
I noticed in my console.log the way the data prints out is different which i believe is the cause of the problem and maybe some light on this matter will help:
printout for this.chartValue:
(3)[12,34,54]
what this should look like is:
12,34,54
Related
I have apex chart in angular that is receiving input from a parent component. See code below
`
#Input() labels: string[] = [];
#Input() series: number[] = [];
constructor() {}
ngOnInit(): void {
this.chartOptions = {
series: this.series,
chart: {
type: 'donut',
width: 200,
},
dataLabels: {
enabled: false,
},
colors: ['#197254', '#62DAB3', '#E2F96F'],
legend: {
show: false,
},
labels: this.labels,
tooltip: {
enabled: false,
},
//dont show data label
plotOptions: {
pie: {
donut: {
size: '80%',
labels: {
show: false,
},
},
},
},
};
}
The series is gotten from the parent after it makes network request.
`
<app-piechart id="pie" [labels]="['Monthly', 'Quaterly', 'Anually']" [series]="[stats.activeSubscriber.subscriptionTypeAggregate.monthly.count, stats.activeSubscriber.subscriptionTypeAggregate.quarterly.count, stats.activeSubscriber.subscriptionTypeAggregate.annually.count]"></app-piechart>
`If i pass random value to the component directly, the pie chart renders well but if i pass in variable into the arrays, it shows like the image below
enter image description here
Please assit
If i pass random value to the component directly, the pie chart renders well but if i pass in variable into the arrays, it shows like the image below
enter image description here
And i confirmed the variables is in the pie chart component using the angular extension on chrome.
I have fixed the issue.
Apparently i was passing string into the series array
like ['1', '2',...]
instead of [1, 2, ..]
I want to display a bar chart - each bar is a user/student. And for each student, there will be an xAxis label displaying the students name
The below code is a VueJS computed property and called chartData
My data array for the bar chart is an array of objects. Here is how i generate it
let dataRow = this.responses.map((d) => {
return {
label: d.user.name,
data: [d.grade],
}
});
Here is how I generate my labels
let users = [];
this.responses.map((d) => {
users.push(d.user.name)
});
I then return on object with an array of labels and datasets with data being an array of objects
return {
labels: users,
datasets: [{
data: dataRow
}],
}
Here is how I render the chart:
{
extends: Bar,
props: ["chartdata"],
data() {
return {
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
yAxes: [{
ticks: {
beginAtZero: true,
max: 100
}
}],
},
}
}
},
mounted() {
this.renderChart(this.chartdata, this.options)
}
}
Issue: Nothing displays and there are no errors
The bar chart only seems to work when the data in the datasets is not an array of object like:
testData: {
labels: ['test', 'test', 'test'],
datasets: [{
data: [65, 59, 80],
}]
}
After Sayf-Eddine comment, i have managed to achieve this:
I changed how i returned the chartdata like:
return {
labels: users,
datasets: dataRow
}
However, all bars are mapping to the first label
After Vitaliy Rayets comment i figured out what was wrong
i needed to return the data row like:
let dataRow = this.responses.map((d) => {
return {
label: d.user.name,
y: [d.grade],
}
});
**I changed the property 'data' to 'y' **
I'm using html, css and javascript for the project. The server is set up locally including node, express and highcharts.
In my html i have a div container, that i'm referencing in my highcharts function. The data i'm using in the highchart come from a csv file. I wrote a simple getData function, that parses the data into an array. And at the top of the highchartsfunction, i'm using await getData, so the chart can only be rendered after getting the data for it. All functions are async. On that one page i'm having seven charts, all constructed using the syntax following below, each with its own getData function and div container.
Two problems:
Problem No.1:
The charts are not getting displayed until i refresh the page and often times i even have to refresh it several times, till every chart is getting shown at a time (Like 20 times). The functions are all executed, i checked that in the console.
Problem No.2:
I would like to write this dynamically, as i want to have multiple pages on my website, each using its own csv file, but basically the same code.
*Edit:
From time to time i receive: "Error: Highcharts error #13: www.highcharts.com/errors/13/" in the console, but as i keep refreshing it changes the line/js it is referencing to. It always is the part of the highcharts function, in which i give it its container Highcharts.chart('hammerchart', {. I checked this error and what it sais is basically, that the script can't find a container with the #id. Which i don't understand as im using "DOMContentLoaded". I tried the "load" event instead, which solved the error #13, but ended up in no chart getting displayed at all without any error message.
*Edit2:
Until now i only used firefox to view my website. I checked Chrome aswell and here i don't have any error message, but it also never shows any of the charts aswell at all.
If someone could help me out here, i would be really happy, as i tried to fix this for days now with no success. I'm also open for suggestions, regarding the handling of my data. Thank you veeeery much in advance!!
Code:
CSV Data sample
2015,2.5,7.2,1.6,6.5,2.2
2016,3.5,7.6,2.6,9.3,1.2
2017,2.5,7.2,1.6,6.5,2.2
2018,3.5,7.6,2.6,9.3,1.2
2019,2.5,7.2,1.6,6.5,2.2
HTML
<div id="hammerchart">
</div>
CSS
#hammerchart{
width:49%;
height: 500px;
margin:0.5%;
margin-top:50px;
flex: 1 1 600px;
}
Javascript - first declaration of the arrays, then my parsing function, splitting the csv by linebreaks and commas. Then i'm using parseFloat(), so that i don't have strings in it. In the highcharts function i'm using await getData and DOMContentloaded, to make sure both html and my data are ready.
const years = [];
const columntwos = [];
const columnthrees = [];
const columnfours = [];
const columnfives = [];
const columnsixs = [];
async function getDataone() {
const response = await fetch('/javascripts/hammerchart.CSV');
const data = await response.text();
const table = data.split('\n');
table.forEach(row => {
const columns = row.split(',');
const year = columns[0];
years.push(year);
const columntwo = columns[1];
columntwos.push(parseFloat(columntwo));
const columnthree = columns[2];
columnthrees.push(parseFloat(columnthree));
const columnfour = columns[3];
columnfours.push(parseFloat(columnfour));
const columnfive = columns[4];
columnfives.push(parseFloat(columnfive));
const columnsix = columns[5];
columnsixs.push(parseFloat(columnsix));
});
};
async function hammerchart() {
await getDataone();
document.addEventListener('DOMContentLoaded', () => {
Highcharts.chart('hammerchart', {
chart: {
zoomType: 'xy'
},
title: {
text: 'Data'
},
subtitle: {
text: ''
},
credits: {
text: 'highcharts',
},
xAxis: [{
categories: years,
plotBands: [{ // visualize
from: 4.5,
to: 6,
color: 'rgba(68, 170, 213, .2)'
}],
crosshair: true
}],
yAxis: [{ // Primary yAxis
labels: {
format: '{value}$',
style: {
color: Highcharts.getOptions().colors[1]
}
},
title: {
text: 'Amount in $',
style: {
color: Highcharts.getOptions().colors[1]
}
}
}, { // Secondary yAxis
title: {
text: 'Ratio in %',
style: {
color: Highcharts.getOptions().colors[0]
}
},
labels: {
format: '{value} %',
style: {
color: Highcharts.getOptions().colors[0]
}
},
opposite: true
}],
tooltip: {
shared: true
},
legend: {
layout: 'vertical',
align: 'left',
x: 120,
verticalAlign: 'top',
y: 100,
floating: true,
backgroundColor:
Highcharts.defaultOptions.legend.backgroundColor || // theme
'rgba(255,255,255,0.25)'
},
series: [{
name: 'columntwo',
type: 'areaspline',
data: columntwos,
tooltip: {
valueSuffix: '$'
}
}, {
name: 'columnthree',
type: 'areaspline',
data: columnthrees,
tooltip: {
valueSuffix: '$'
}
}, {
name: 'columnfour',
type: 'areaspline',
data: columnfours,
tooltip: {
valueSuffix: '$'
}
}, {
name: 'columnfive',
type: 'column',
data: columnfives,
tooltip: {
valueSuffix: '$'
}
}, {
name: 'columnsix',
type: 'spline',
yAxis: 1,
data: columnsixs,
tooltip: {
valueSuffix: '%'
}
}]
});
});
};
hammerchart();
Hey all i am using javascript with ApexCharts to draw a chart and this chart gets its data from firebase but each time the data is changed in firebase instead of replacing the chart or updating it it appends new chart under it
this is the code
function dailyTracking(){
var query = firebase.database().ref('Facilities').on('value', function(snapshot) {
var options = {
chart: {
height: 380,
width: "100%",
type: "bar",
stacked: false
},
series: [
{
name: "Library",
data: snapshotToArray(snapshot.child('Library'))
},
{
name: "Canteen",
data: [5]
},
{
name: "Free Lab",
data: [42]
}
],
xaxis: {
labels: {
formatter: function (value, timestamp) {
return new Date() // The formatter function overrides format property
},
}
}
};
var chart = new ApexCharts(document.querySelector("#chart"), options);
chart.render();
query.off();
return snapshotToArray(snapshot);});}
I managed to solve it by adding this line
document.getElementById('chart').innerHTML = '';
before rendering the chart
Try not to wrap the chart.render() call in the event. Render the chart once and call the update event when you get new data by calling chart.updateSeries()
I was having some trouble when trying to dynamically populate bar chart in chart.js. I have two arrays, one for label, one for its price and both of them are already populated with the sorted data from firebase. Here is my code:
var ctx = document.getElementById('brandChart').getContext("2d");
var data = {
labels: [],
datasets: [{
data: [],
backgroundColor: [
"#424242",
]
}]
};
var options = {
layout: {
padding: {
top: 5
}
},
responsive: true,
legend: {
display: true,
position: 'bottom',
// disable legend onclick remove slice
onClick: null
},
animation: {
animateScale: true,
animateRotate: true
},
};
var opt = {
type: "horizontalBar",
data: data,
options: options
};
if (brandChart) brandChart.destroy();
brandChart = new Chart(ctx, opt);
// dynamically populate chart
for(var i = 0; i < labelData.length; i++){
brandChart.config.data.labels.push(labelData[i]);
}
for(var i = 0; i < priceData.length; i++){
brandChart.config.data.datasets[0].data.push(priceData[i]);
}
brandChart.update();
I managed to show all of them in bar chart, however, the result as such:
It is kind of squeeze between each labels if there are too many categories. Also, only the first bar has the color & the legends shown undefined. Any ideas how to solve these?
ɪꜱꜱᴜᴇ #1 - ꜱᴏʟᴜᴛɪᴏɴ
Add a callback for y-axis ticks, in your chart options :
options: {
scales: {
yAxes: [{
ticks: {
callback: function(t, i) {
if (!(i % 2)) return t;
}
}
}]
},
...
}
this will only show every other label on y-axis.
ɪꜱꜱᴜᴇ #2 - ꜱᴏʟᴜᴛɪᴏɴ
This is because, you have only one color in your backgroundColor array. If you want different color for each bar, then you need to populate this array with multiple color values.
Edit: as it seems form your updated question, you already kind of got the idea.
ɪꜱꜱᴜᴇ #3 - ꜱᴏʟᴜᴛɪᴏɴ
Define the label property for your dataset , like so :
datasets: [{
label: 'Legend Title', //<- define this
data: [],
backgroundColor: ["#424242", ]
}]