Pushing data from json to Chart.js labels and data - javascript

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'
}],
},
});

Related

How to set action on slice-click Doughnut in Chart.js

I've been trying to add chart.js to my Django Project, which worked pretty fine so far. I made a doughnut-chart with two slices. Now i want to have each of those slices to have seperate actions on click, like for example redirecting to new side.
These are my chart settings:
var config = {
type: 'doughnut',
data: {
datasets: [{
data: {{ data|safe }}, // Error because django and js are being mixed
backgroundColor: [
'#ff0000', '#008000'
],
label: 'Population'
}],
labels: {{ labels|safe }}
},
options: {
responsive: true
}
};
And this is the rendering and my function to make the actions on click:
window.onload = function() {
var ctx = document.getElementById('pie-chart').getContext('2d');
var myPieChart = new Chart(ctx, config);
$('#myChart').on('click', function(event) {
var activePoints = myPieChart.getElementsAtEvent(event)
if(activePoints[0]){
console.log("Helo 1")
}
else {
console.log("helo 2")
}
})
};
I saw my solution on other pages, but it doesn't work at all. Am I missing something? If yes could you please help?
getElementAtEvent has been replaced with chart.getElementsAtEventForMode in Chart.js v3 (see 3.x Migration Guide).
Please take a look at below runnable code and see how it works now:
const pieChart = new Chart("myChart", {
type: 'pie',
data: {
labels: ["Red", "Blue", "Yellow"],
datasets: [{
data: [8, 5, 6],
backgroundColor: ["#FF6384", "#36A2EB", "#FFCE56"],
}]
},
options: {
onClick: evt => {
var elements = pieChart.getElementsAtEventForMode(evt, 'index', { intersect: true }, false);
var index = elements[0].index;
console.log(pieChart.data.labels[index] + ': ' + pieChart.data.datasets[0].data[index]);
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.9.1/chart.min.js"></script>
<canvas id="myChart"></canvas>

Counting string to plot a graph using chart.js and angular

I am trying to create a bar chart in angular using chart.js and angular.
I want to display the disaters vs area. with the type of disaster ( earthquake, hurricane, storm...etc) on the x-axis and area (as in location) on the y-axis.
However, the area data is string and does not work when trying to plot a bar graph as it requires numbers.
I am reading the data as follows:
ngOnInit(): void {
this.chartService.noOfEqu().subscribe((res) => {
let area = res.map((res) => res.area);
let disaster = res.map((res) => res.disasterNature);
new Chart('disasterCanvas', {
type: 'bar',
data: {
labels: disaster,
datasets: [
{
data: area,
label: 'area',
backgroundColor: '#A121D5',
},
],
},
options: {
plugins: {
legend: {
display: true,
},
},
scales: {
x: {
ticks: {
display: true,
},
},
y: {
ticks: {
display: true,
},
},
},
},
});
});
}
}
Where let area = res.map((res) => res.area); is the area variable.
I want to know what is the best way to structure the data to be entered into the graph.
The disaster data that is logged is:
and the area data :
How can i structure the area such that it counts how much areas that a disaster has occured and plot it on the bar chart?
Thank you in advance...if there is anything i can clarify please let me know in the comments
Also is there another way to display this data besides tallying the string data?
You need to add a labels array to the scale and set the type to category to use string data:
const options = {
type: 'bar',
data: {
labels: ["Earthquake", "Tornade", "Flood"],
datasets: [{
label: '# of Votes',
data: ['Paris', 'Berlin', 'London'],
backgroundColor: 'pink'
}]
},
options: {
scales: {
y: {
type: 'category',
reverse: true,
labels: ['', 'London', 'Paris', 'Berlin']
}
}
}
}
const ctx = document.getElementById('chartJSContainer').getContext('2d');
new Chart(ctx, options);
<body>
<canvas id="chartJSContainer" width="600" height="400"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.7.1/chart.js"></script>
</body>

Chart JS Displays Only Bigger Dataset But Has Both Datasets?

fairly new to JS and I have a strange issue with chart JS bar chart.
<script>
$(document).ready(function() {
var bar = document.getElementById("chart-bar-11").getContext('2d');
var data1 = {
labels: ["Yesterday"],
datasets: [{
label: "Win",
data: [{{ gam }}],
borderColor: '#4099ff',
backgroundColor: '#4099ff',
hoverborderColor:'#4099ff',
hoverBackgroundColor: '#4099ff',
}, {
label: "Lose",
data: [{{ results }}],
borderColor: '#0e9e4a',
backgroundColor: '#0e9e4a',
hoverborderColor:'#0e9e4a',
hoverBackgroundColor: '#0e9e4a',
}]
};
var myBarChart = new Chart(bar, {
type: 'bar',
data: data1,
options: {
barValueSpacing: 20
}
});
});
</script>
I have a simplke bar chart, but here is a screen shot of current behavior, super confused how this chart shows it has both datasets but will only display the larger dataset?
Ended up finding the options needed in another Chart JS post, this is what I was missing.
var myBarChart = new Chart(bar, {
type: 'bar',
data: data1,
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
}
}
});
It appears he "beginAtZero" is what was missing. This now works as expected.

charts js, doughnut chart not rendering tooptips correctly

i have a multilevel donut chart but it is not rendering correctly here is code
the problem is, onmouseover on all green parts it says objects, on all grey parts it says products, solution i would like is, on outer ring it should say products, in middle objects, and inner most should be materials, grey areas should just show number. here is a jsfiddle of the problem
Code:
var op=93;
var ap=99;
var mp=66;
var ctx = new Chart(myChart, {
type: 'doughnut',
data: {
labels: ['Objects', 'Products', 'Materials'],
datasets: [{
label: 'Objects',
data: [op, 100 - op],
backgroundColor: ['#006a4e','#eeeeee'],
hoverOffset: 4
},{
label: 'Products',
data: [ap, 100 - ap],
backgroundColor: ['#2e856e', '#eeeeee'],
hoverOffset: 4
},
{
label: 'Materials',
data: [mp, 100 - mp],
backgroundColor: ['#5ca08e', '#eeeeee'],
hoverOffset: 4
}
]
},
options: {
//cutoutPercentage: 40,
height: 200,
width:200
}
});
You can achieve that fairly simple with Chart.JS 2.7.2. Add labels to each dataset like this:
data: {
labels: ['Existing', 'Non'],
datasets: [
{
labels: ['Objects', 'Non-objects'],
...
}, {
labels: ['Products', 'Non-products'],
...
},
{
labels: ['Materials', 'Non-materials'],
...
}
]
}
And add the following label tooltip callback:
tooltips: {
callbacks: {
label: function(tooltipItem, data) {
var dataset = data.datasets[tooltipItem.datasetIndex];
var index = tooltipItem.index;
return dataset.labels[index] + ": " + dataset.data[index];
}
}
}
Demo: https://jsfiddle.net/adelriosantiago/fxd6vops/3/
I am sure it is possible with Chart.JS > 3.0 too but I have no idea how since quite a few things changed in the structure.
I had a same problem which took a lot of time but what worked in the end was importing these elements and initialising them ..
import { Chart as ChartJS, ArcElement, Tooltip, Legend } from 'chart.js';
ChartJS.register(ArcElement, Tooltip, Legend);
these are the elements that helps make the entire chart. you can't skip them

How to pass series to plot options in highcharts

I am trying to update the series data option for 'pie' type chart:
I am using exporting buttons to display options to change chart type, all other chart types work well except pie which needs a different format of series data.
exporting: {
buttons: {
lineButton: {
text: 'line',
onclick: function () {
for(i=0;i<this.series.length;i++) {
this.series[i].update({
type: "line"
});
}
}
},
barButton: {
text: 'bar',
onclick: function () {
for(i=0;i<this.series.length;i++) {
this.series[i].update({
type: "column"
});
}
}
},
pieButton: {
text: 'pie',
onclick: function () {
var pieSeries = [];
$.each(category_totals, function(j, k) {
pieSeries.push( { name: j , y: k } );
});
for(i=0;i<this.series.length;i++) {
this.series[i].remove();
}
this.series = [{
name: title,
colorByPoint: true,
data: pieSeries
}];
this.series[0].update({
type: "pie"
});
}
}
}
...
And I get this error: Uncaught TypeError: this.series[0].update is not a function
The problem is that you sequentially remove the series from the chart, after each call the chart is redrawn and by the end of the for loop the chart doesn't have any series. When you do
this.series = [{
name: title,
colorByPoint: true,
data: pieSeries
}]
you are modifying the javascript object and therefore update method is not available when you try to do
this.series[0].update({
type: "pie"
});
because you are trying to call Highcharts method on a generic javascript object.
What you should do is
this.addSeries({
name: title,
colorByPoint: true,
data: pieSeries,
type: 'pie'
})
Also, a suggestion: pass argument false to remove method so that it it doesn't redraw every time. Just redraw when you add the new series.
So above call would look like
this.addSeries({
name: title,
colorByPoint: true,
data: pieSeries,
type: 'pie'
}, true)
1.
for(i=0;i<this.series.length;i++) {
this.series[i].remove();
}
The code above will not remove series items: see here
2.
The correct way to add series is:
this.addSeries({...});
3.
Final working code:
...
pieButton: {
text: 'pie',
onclick: function () {
var pieSeries = [];
$.each(category_totals, function(j, k) {
pieSeries.push( { name: j , y: k } );
});
while(this.series.length > 0) {
this.series[0].remove(true);
}
this.addSeries({
name: title,
colorByPoint: true,
data: pieSeries,
type: 'pie'
});
// As Rahul Sharma pointed out in comments above,
// you can pass the "type" option to
// addSeries method, making this call redundant
// this.series[0].update({
// type: "pie"
// });
}
}
...

Categories

Resources