Creating categories with different widths in chart.js - javascript

I'm creating a line diagram using chart.js, and my X axis is of type category (which, in my case, makes absolute sense). Now, chart.js creates all categories with the same width, which I guess is a reasonable default.
However, I would like to have categories of different width, e.g.: The first category should be 3 times as wide as the second one, and the third one should be 2 times as wide as the second one, essentially rendering something such as:
| | | |
| | | |
| | | |
A B C
Is this possible? If so, how?

Have you tried using: dataset.barPercentage?
I used scale 1.0 to represent 3.0 and made the other ones relative to that scale.
var ctx = document.getElementById('myChart').getContext('2d');
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: ['Red', 'Blue', 'Yellow'],
datasets: [{
label: '# of Votes',
data: [3, 4, 2],
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,
barPercentage: [
1.0,
0.333,
0.667
]
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.css" rel="stylesheet" />
<canvas id="myChart" width="400" height="200"></canvas>

Related

Multiple Charts in one page with Laravel & Chartjs

I'm trying to display two charts in one page. I'm expecting like 1 doughnut and 1 pie.
Here's my view snippets:
First Chart
<div class="card-body d-flex flex-center flex-column" style="width: 381px; height:350px;">
<!-- Find the JS file for the following chart at: src/js/charts/echarts/bandwidth-saved.js-->
<!-- If you are not using gulp based workflow, you can find the transpiled code at: public/assets/js/theme.js-->
<canvas id="pengeluaran" width="350"></canvas>
</div>
Second Chart
<div class="card-body d-flex flex-center flex-column" style="width: 381px; height:350px;">
<!-- Find the JS file for the following chart at: src/js/charts/echarts/bandwidth-saved.js-->
<!-- If you are not using gulp based workflow, you can find the transpiled code at: public/assets/js/theme.js-->
<canvas id="sponsorship" width="350"></canvas>
</div>
I tried the solution at Two charts in a page not working, using Chart.js 3.1.1 cdn in Laravel 8.x framework & Multiple charts in one page - Chartjs, but it's seems doesn't work for me. I tried to implement it, but only the first chart is displaying on the page.
It's displays the error "Failed to create chart: can't acquire context from the given item", I double check everything and I can't find what's cause of the error.
Here's the javascript file:
<script>
const ctx1 = document.getElementById('pengeluaran');
const ExpensesLabel = ['Rewards', 'Bantuan', 'Others'];
const ExpensesData = {
labels :ExpensesLabel,
datasets: [{
label: 'Sebaran Pengeluaran untuk Anak',
data: [300, 50, 100],
backgroundColor: [
"rgb(255, 99, 132, 0.2)", "rgb(54, 162, 235, 0.2)",
"rgb(255, 206, 86, 0.2)",
],
borderColor: [
"rgb(255, 99, 132, 1)", "rgb(54, 162, 235, 1)",
"rgb(255, 206, 86, 1)",
],
hoverOffset: 4,
borderWidth: 1,
}]};
const options1 = {
responsive: true,
maintainAspectRatio: true,
layout: {
padding: 10
}
};
new Chart(ctx1, {
type: 'doughnut',
data: ExpensesData,
options: options1
});
</script>
Second Charts
<script>
const ctx2 = document.getElementById('sponsorship');
const SponsorLabel = ['TK','SD','SMP','SMA-K / Kuliah'];
const SponsorData = {
labels : SponsorLabel,
datasets: [{
label: 'Sebaran Penerimaan Hadiah Sponsor',
data: [300, 50, 100, 90],
backgroundColor: [
"rgb(255, 99, 132, 0.2)", "rgb(54, 162, 235, 0.2)",
"rgb(255, 206, 86, 0.2)", "rgb(75, 192, 192, 0.2)",
],
borderColor: [
"rgb(255, 99, 132, 1)", "rgb(54, 162, 235, 1)",
"rgb(255, 206, 86, 1)", "rgb(75, 192, 192, 1)",
],
hoverOffset: 4,
borderWidth: 1
}]
};
const options2 = {
responsive: true,
maintainAspectRatio: true,
layout: {
padding: 10
}
};
new Chart(ctx2, {
type: 'pie',
data: SponsorData,
options: options2,
});
</script>
Is there anything I missed? Any help would be appreciated! Thanks
Sorry for late reply. The fix was it was conflicting id naming with other div in the blade file. So I had to rename the second chart canvas id to different name. The code above works perfectly though, as explained and tested by FiddlingAway in the comment section.
<canvas id="sponsorship-charts" width="350"></canvas>

chart.js random weird problems

this to me makes absolutely no logical sense.
my graph.js was working until it randomly just stopped after passing local storage as a prop. i refactored to make the prop passed in completely unrelated to the local storage... which still shouldn't matter.
for some reason every single number i put into the data field works EXCEPT when i put in props.score/number or ANYTHING reassigned that number. ive never seen anything like it. when i console log number is is 82. it is a number (it is blue in the console) yet when i put it into chart.js it just won't appear.
what the heck is going on?!
this feels like typing 2+2 into a calculator and getting 5. i literally have no idea i have now been trying to figure this out for maybe 4 hours with absolutely no answer. once again...
this error just happened randomly today my app was working fine prior to this...?!
did chart.js change something as of yesterday?
is this a random bug ?
i have never run into such a problem after backtracking for so long. makes no sense.
import {useEffect} from 'react'
import Chart from 'chart.js';
import './BreakDown.css'
const LineChart = (props) => {
const number=props.score ***i am trying to get props.score into the chart js data point.
console.log(number) ****this console logs 82
const newNumber=10+number
console.log(newNumber) ***this console logs 92
useEffect(()=>{
var ctx = document.getElementById('myLineChart');
var myChart = new Chart(ctx, {
type: 'line',
responsive:true,
data: {
labels: ['X', 'IQ', 'X'],
datasets: [{
label: 'Your Score',
data: [0,newNumber,0], ***no matter what i do plug in in either of these numebnrs here doesn't work.
backgroundColor: [
'rgba(54, 80, 235, 0.2)',
'rgba(54, 80, 235, 0.2)',
'rgba(54, 162, 235, 0.2)'
],
borderColor: [
'rgba(255, 99, 132, 1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
],
borderWidth: 1,
},
{
label: 'Average',
data: [0, 100, 0],
backgroundColor: [
'rgba(54, 162, 235, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(54, 80, 235, 0.2)',
],
borderColor: [
'rgba(255, 99, 132, .5)',
'rgba(255, 99, 132, .5)',
'rgba(255, 99, 132, .5)',
],
borderWidth: 1
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero: false,
suggestedMin: 70,
suggestedMax: 160,
stepSize: 10
}
}]
}
}
});
},[])
return (
<div >
<canvas id="myLineChart" width="650" height="400"></canvas>
</div>
)
}
export default LineChart
to make things EVEN more bizarre if i plug in newNumber into the chart it gives me 10 in this case EVEN though console.logging newNumber gives me 92... HUH?!
Your code works fine on the first render for me. I am not 100% sure from your description what you think is going wrong, but 1 problem I see is that useEffect will only run once due to the [] in the second parameter.
If your prop.score updates, useEffect() won't run again, which means your chart won't update.
The main change I did below was add props.score in the array for useEffect, this tells useEffect to run again if props.score changes. You can read more about this in the useEffect docs
import React, { useEffect } from 'react'
import Chart from 'chart.js';
const LineChart = (props) => {
const number = props.score //***i am trying to get props.score into the chart js data point.
console.log(number) //****this console logs 82
const newNumber = 10 + number
console.log(newNumber) //***this console logs 92
useEffect(() => {
var ctx = document.getElementById('myLineChart');
var myChart = new Chart(ctx, {
type: 'line',
responsive: true,
data: {
labels: ['X', 'IQ', 'X'],
datasets: [{
label: 'Your Score',
data: [0, newNumber, 0],
backgroundColor: [
'rgba(54, 80, 235, 0.2)',
'rgba(54, 80, 235, 0.2)',
'rgba(54, 162, 235, 0.2)'
],
borderColor: [
'rgba(255, 99, 132, 1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
],
borderWidth: 1,
},
{
label: 'Average',
data: [0, 100, 0],
backgroundColor: [
'rgba(54, 162, 235, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(54, 80, 235, 0.2)',
],
borderColor: [
'rgba(255, 99, 132, .5)',
'rgba(255, 99, 132, .5)',
'rgba(255, 99, 132, .5)',
],
borderWidth: 1
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero: false,
suggestedMin: 70,
suggestedMax: 160,
stepSize: 10
}
}]
}
}
});
}, [props.score])
return (
<div >
<canvas id="myLineChart" width="650" height="400"></canvas>
</div>
)
}
export default LineChart

Trying to insert another label for a piechart in ChartsJS

I created this piechart using chartsjs. As of now, if you run the snippet, I am able to display my labels the following way:
Uno\Company 1
19
(56%)
However, I would love to display Company text underneath, so that it can be displayed like this:
Uno
Company1
19
(56%)
I tried creating a separate array: label2: ["Company1", "Company2", "Company3"]
Then in the callback, I added a new function, which i thought would give me the other label beneath, but no luck. Here is the code I used for that:
title2: function(tooltipItem, data, label2){
return data['label2'][tooltipItem[0]['index']]
}
Can anyone help me out?
var ctx = document.getElementById("myChart");
var myChart = new Chart(ctx, {
type: 'doughnut',
data: {
label1: ["Uno\\Company1", "Dos\\Company2", "Tres\\Company3"],
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>
Simply change label1 from an array of strings to an array of arrays:
label1: [["Uno", "Company1"], ["Dos", "Company2"], ["Tres", "Company3"]]
Chart.js will treat separate array items as separate lines.

How to create a chart with chartjs.org with data from an array?

I try to create a website with a bar-chart on it. I like to use ChartJs.
There are some good examples, but I don't know how to visualise the data if the data is an array.
var myArray = [{
year: '2016',
value: 5
},
{
year: '2017',
value: 9
},
{
year: '2018',
value: 4
}
];
How do I loop throu myArray to create a bar chart like this one in the example?
var ctx = document.getElementById('myChart').getContext('2d');
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: ['2016', '2017', '2018'],
datasets: [{
label: '# of Votes',
data: [5, 9, 4],
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
'rgba(75, 192, 192, 0.2)',
'rgba(153, 102, 255, 0.2)',
'rgba(255, 159, 64, 0.2)'
],
borderColor: [
'rgba(255, 99, 132, 1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
'rgba(153, 102, 255, 1)',
'rgba(255, 159, 64, 1)'
],
borderWidth: 1
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
}
}
});
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<canvas id="myChart" width="400" height="400"></canvas>
Thanks for your help!
Best, Marius
You can map your array of objects, getting only the value you need.
I did it by var values = myArray.map((x) => x.value) and then using values as the value to the data property inside chart options.
For the labels, you can use the same logic, but with x.year.
Below code represents an example:
var myArray = [{
year: '2016',
value: 5
},
{
year: '2017',
value: 9
},
{
year: '2018',
value: 4
}
];
//FILTER THE VALUES
var values = myArray.map((x) => x.value)
var ctx = document.getElementById('myChart').getContext('2d');
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: ['2016', '2017', '2018'],
datasets: [{
label: '# of Votes',
data: values,
borderWidth: 1,
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)'
],
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
}
}
});
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<canvas id="myChart" width="300" height="150"></canvas>
If, for some reason (browser maybe), you cant use arrow functions, then go with:
var values = myArray.map(function(x) {return x.value})

Using Chart.js - The X axis labels are not all showing

I'm using Chart.js for my pie/bar charts and on the line and the bar chart all of the 'x' axis labels are not all showing for some reason, however in the pie chart they are:
Code below has been used and the 'type' has just been altered for the type of graph I wished to use:
var ctx = document.getElementById("my3Chart");
var mylineChart = new Chart(ctx, {
type: 'bar',
data: {
labels: ["Time Management", "Career Coach", "Stress & Wellbeing", "Note Taking", "Exam Prep", "Presentations"],
datasets: [{
label: 'Module Tracker',
data: [6, 4, 2, 0, 3, 1],
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
'rgba(75, 192, 192, 0.2)',
'rgba(153, 102, 255, 0.2)',
'rgba(255, 159, 64, 0.2)'
],
borderColor: [
'rgba(255,99,132,1)'
],
borderWidth: 1
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero:true
}
}]
}
}
});
I've tested your code in a fiddle with Chart.js 2.0 for both bar/line and it looks fine. Chart takes in x-axis labels with:
labels: ["Time Management", "Career Coach", "Stress & Wellbeing", "Note Taking", "Exam Prep", "Presentations"]
The reason you can't see all your x-axis labels is that the width's are too thin. You can fix this by either expanding your width, or rotating your labels to be vertical instead.
400px width example: https://jsfiddle.net/swcy2opv/
Rotated labels example: https://jsfiddle.net/swcy2opv/1/

Categories

Resources