Handling data over lapping in chart.js - javascript

I need not to load the same type of data for different sections in one bar/pie chart. On load it shows relevant data but after that, when I load the data of subsequent sections is loaded then it shows irrelevant data or it shows previous sections data.
Demo link: http://coderstutor.com/ChartProb/
codepenLink: https://codepen.io/tumulalmamun/pen/eeVmVX
var chartList = [5,6];
function chart(){
var ctx = document.getElementById("myChart").getContext('2d');
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: ["Red", "Blue"],
datasets: [{
label: '# of Votes',
data: chartList,
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
],
borderColor: [
'rgba(255,99,132,1)',
'rgba(54, 162, 235, 1)',
],
borderWidth: 1
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero:true
}
}]
}
}
});
}
chart();
function addData(){
var i = 4;
var o = 8;
chartList = [];
chartList.push(i);
chartList.push(o);
chart();
}
</script>
</body>

Every time you update it, you're sort of like, creating a new chart over it. What you need to do is to destroy the chart before updating it.
myChart.destroy()
I updated your javascript code:
var chartList = [5,6];
var myChart;
function chart(){
var ctx = document.getElementById("myChart").getContext('2d');
if (myChart != undefined && typeof myChart == 'object' && typeof myChart.destroy == 'function') myChart.destroy()
myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: ["Red", "Blue"],
datasets: [{
label: '# of Votes',
data: chartList,
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
],
borderColor: [
'rgba(255,99,132,1)',
'rgba(54, 162, 235, 1)',
],
borderWidth: 1
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero:true
}
}]
}
}
});
}
chart();
function addData(){
var i = 4;
var o = 8;
chartList = [];
chartList.push(i);
chartList.push(o);
chart();
}

Related

Chart.js duration time graph

I'm trying to build a chart of the top 10 activities that take the most time to perform and I'm basing myself on the duration of each one.
I created an example in Google Spreadsheet to exemplify what i need.
I couldn't create a graph with 'hour' data, so I converted it to seconds. But I would like to display the hours on the X axis as in the image.
Here's my code:
enter link description here
<canvas id="myChart" height="200"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.5.0/Chart.min.js"></script>
<script>
var ctx = document.getElementById("myChart");
var myChart = new Chart(ctx, {
type: 'horizontalBar',
data: {
labels: ["Work", "Study", "Gym"],
datasets: [{
label: '# activities',
data: [30000, 9000, 5400],
time: ['08:20', '02:30', '01:30:00'],
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)'
],
borderColor: [
'rgba(255,99,132,1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)'
],
borderWidth: 1
}]
},
options: {
tooltips: {
callbacks: {
label: function(tooltipItem, data) {
return 'Duration ' + data['datasets'][0]['time'][tooltipItem['index']];
}
}
},
scales: {
xAxes: [{
ticks: {
min: 0,
max: 45000,
stepSize: 5000
}
}]
}
}
});
</script>
Any tips?
You can define a ticks.callback function on your x-axis as follows:
xAxes: [{
ticks: {
min: 0,
max: 45000,
stepSize: 7200,
callback: v => Number.isInteger(v / 3600) ? (v / 3600) + ':00:00' : ''
}
}]
Please take a look at your amended and runnable code below and see how it works.
var myChart = new Chart('myChart', {
type: 'horizontalBar',
data: {
labels: ["Work", "Study", "Gym"],
datasets: [{
label: '# activities',
data: [30000, 9000, 5400],
time: ['08:20', '02:30', '01:30:00'],
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)'
],
borderColor: [
'rgba(255,99,132,1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)'
],
borderWidth: 1
}]
},
options: {
tooltips: {
callbacks: {
label: function(tooltipItem, data) {
return 'Duration ' + data['datasets'][0]['time'][tooltipItem['index']];
}
}
},
scales: {
xAxes: [{
ticks: {
min: 0,
max: 45000,
stepSize: 7200,
callback: v => Number.isInteger(v / 3600) ? (v / 3600) + ':00:00' : ''
}
}]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.js"></script>
<canvas id="myChart" height="90"></canvas>

chartjs - bar graphs size not increasing

I'm having an issue in setting bars width using chart.js.
This is my code:
<script>
var endpoint = '/api/';
$.ajax({
method: "GET",
url: endpoint,
success: function (data) {
drawBarGraph(data, 'myChartBar');
console.log("drawing");
},
error: function (error_data) {
console.log(error_data);
}
})
function drawBarGraph(data, id) {
var labels = data.labels;
var chartLabel = data.chartLabel;
var chartdata = data.chartdata;
var ctx = document.getElementById(id).getContext('2d');
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: labels,
datasets: [{
barThickness: 0.9,
label: chartLabel,
data: chartdata,
backgroundColor: 'rgba(54, 162, 235, 0.2)',
borderColor: 'rgba(54, 162, 235, 0.2)',
borderWidth: 1
}]
},
options: {
scales: {
xAxes: [{
}],
yAxes: [{
ticks: {
beginAtZero: true
}
}]
}
}
});
}
</script>
I cannot increase the bar thickness.
I'm using Argon Dashboard with Django.
Is this an issue with theme's css?
What am I missing here?
Change this value
xAxes: [{
// Change this
barPercentage: 0.2
}]

Displaying Data on a Pie chart in ChartsJs

I was able to create this doughnut chart that displays data. However, now that I look at it, I would like add the number value of the foods (100,200,300) below, on a second line, instead of having next to the food item itself. Is there a way to do this? I was thinking that since this is a nested array, looping through it may work? Any thoughts?
var ctx = document.getElementById("myChart");
var myChart = new Chart(ctx, {
type: 'doughnut',
data: {
label1: [["Pizza: 100"], ["Hot Dogs: 200"], ["Burgers:300"]],
datasets: [{
label: '# of Votes',
data: [12, 19, 3],
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)'
],
borderColor: [
'rgba(255,99,132,1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)'
],
borderWidth: 1
}]
},
options: {
tooltips: {
callbacks: {
title: function(tooltipItem, data, label1, label2) {
return data ['label1'][tooltipItem[0]['index']];
},
label: function(tooltipItem, data) {
return data['datasets'][0]['data'][tooltipItem['index']];
},
afterLabel: function(tooltipItem, data) {
var dataset = data['datasets'][0];
var percent = Math.round((dataset['data'][tooltipItem['index']] / dataset["_meta"][0]['total']) * 100)
return '(' + percent + '%)';
}
},
backgroundColor: '#FFF',
titleFontSize: 16,
titleFontColor: '#0066ff',
bodyFontColor: '#000',
bodyFontSize: 14,
displayColors: false
}
}
});
<div>
<canvas id="myChart" height="100"></canvas>
<div id="chartjs-tooltip">
<table></table>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js">
</script>

Why is this Chart.js graph not showing the right colors?

I'm using Chart.js to show a bar graph from two datasets for every month to show the evolution of certain data. Now the problem is the way Chart.js is showing these bars.
var myChartIBM = new Chart(ctx1, {
type: 'bar',
plugins: [ChartDataLabels],
data: {
datasets: [{
label: "Número de entregas",
data: entregas,
backgroundColor: [
'rgba(255, 99, 132, 0.2)'
],
borderColor: [
'rgba(255, 99, 132, 1)'
],
borderWidth: 1
},
{
label: "Número de reversas",
data: reversas,
backgroundColor: [
'rgba(54, 162, 235, 0.2)'
],
borderColor: [
'rgba(54, 162, 235, 1)'
],
borderWidth: 1
}
]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero: true,
stepSize: 500
}
}],
xAxes: [{
type: 'time',
distribution: 'series',
offset: true,
ticks: {
source: 'data'
},
time: {
unit: 'month',
tooltipFormat: 'll'
}
}]
},
tooltips: {
mode: 'x', // optional
callbacks: {
title: function(tooltipItems, data) {
let tI = tooltipItems[0];
return data.datasets[tI.datasetIndex].data[tI.index].x;
}
}
},
plugins: {
datalabels: {
formatter: function(value, context) {
return value['y'];
}
}
},
responsive: true,
maintainAspectRatio: true
}
});
My doubt is why is it showing grey after the first dataset and what could I do to fix this. Maybe should I always add a zero?
This is the code on PHP side which generates the data:
$col_entregas = Device::select(DB::raw("count(serial) as cantidad, year(fecha_recepcion) as year, month(fecha_recepcion) as month"))->whereNotNull('fecha_recepcion')->whereNotNull('guia_recepcion')->groupBy('year', 'month')->orderBy('year', 'asc')->orderBy('month', 'asc')->get();
$col_reversas = Device::select(DB::raw("count(serial) as cantidad, year(fecha_reversa) as year, month(fecha_reversa) as month"))->whereNotNull('fecha_reversa')->whereNotNull('guia_reversa')->groupBy('year', 'month')->orderBy('year', 'asc')->orderBy('month', 'asc')->get();
$ar_entregas = [];
$ar_reversas = [];
$meses_grafico = [];
foreach($col_entregas as $entrega)
{
$fecha = $entrega->year . '-' . $entrega->month;
$meses_grafico[] = $fecha;
$ar_entregas[] = ["x" => $fecha,
"y" => $entrega->cantidad];
}
foreach($col_reversas as $reversa)
{
$fecha = $reversa->year . '-' . $reversa->month;
$ar_reversas[] = [
"x" => $fecha,
"y" => $reversa->cantidad];
}
So I had to add a foreach to add the same color to every entry in both arrays and that fixed the issue:
var colors_entregas = [];
var border_entregas = [];
entregas.forEach(function (el){
colors_entregas.push('rgba(255, 99, 132, 0.2)');
border_entregas.push('rgba(255, 99, 132, 1)');
});
var colors_reversas = [];
var border_reversas = [];
reversas.forEach(function (el){
colors_reversas.push('rgba(54, 162, 235, 0.2)');
border_reversas.push('rgba(54, 162, 235, 1)');
});
Inside every dataset:
data: entregas,
backgroundColor: colors_entregas,
borderColor: border_entregas,

Chart.js combine two pieces of data into one bar

I am using charts.js to display data. i have it set up and it is working.
However, I have read through all the documentation and cannot figure out how to solve what I want to achieve.
Currently, the data contains three numbers [12, 19, 3]. this is the number of actual goals scored. However, there is also a prediction as to the number of goals scored. This value is always going to be less based on the data I have. so the expected goals scored are [8, 11, 1]. these correspond with the first set.
Is there anyway to combine the two values in the same bar. So in the first bar, it would go to 8, as the expected number of goals, and then the top part of the bar would show the actual number of goals.
Here is my code below.
Hopefully my question makes sense
var ctx = document.getElementById("myChart");
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: ["Red", "Blue", "Yellow"],
datasets: [{
label: '# of Goals',
data: [12, 19, 3],
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)'
],
borderColor: [
'rgba(255,99,132,1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)'
],
borderWidth: 1
}]
},
options: {
responsive: false,
scales: {
yAxes: [{
ticks: {
beginAtZero:true
}
}]
}
}
});
var ctx = document.getElementById("myChart");
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: ["Red", "Blue", "Yellow"],
datasets: [{
label: '# of Likes',
data: [12, 19, 3],
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)'
],
borderColor: [
'rgba(255,99,132,1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)'
],
borderWidth: 1
}]
},
options: {
responsive: false,
scales: {
yAxes: [{
ticks: {
beginAtZero:true
}
}]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.1.4/Chart.bundle.min.js"></script>
<canvas id="myChart" width="400" height="400"></canvas>
Version 2 does support stacked bar charts.
https://jsfiddle.net/r71no58a/10/
scales: {
xAxes: [{
stacked: true,
}],
yAxes: [{
stacked: true,
ticks: {
beginAtZero: true
}
}]
}

Categories