Related
In ChartJS's pie and doughnut charts there is a legend option for every data that you can click to hide the data, this behavior changes with bar and line charts, when there is only a single legend option for the entire dataset, and when clicking it, it hides the entire dataset.
Is there any way to have a legend option for each data in bar/line charts?
Here's a example with a bar and a pie chart using the exact same configuration, you can see in the pie chart you can hide the slices individually, while in the bar chart you can only hide the entire dataset
var barCfg = {
type: 'bar',
data: {
labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
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
}]
}
};
var pieCfg = {
type: 'pie',
data: {
labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
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
}]
}
};
var barChart = new Chart(
document.getElementById('barChart').getContext('2d'), barCfg);
var pieChart = new Chart(
document.getElementById('pieChart').getContext('2d'), pieCfg);
JSFiddle
Looking at the ChartJS API it looks like hide(datasetIndex, dataIndex?) would be what you are looking for.
Hide is called when you click a legend (without dataIndex) to hide the dataset. When you call it with a dataIndex it behaves a little bit differently. Here is a fiddle to show what i mean: JSFiddle
chart onClick:
function chartOnClick(evt) {
let chart = evt.chart
const points = chart.getElementsAtEventForMode(evt, 'nearest', {}, true);
if (points.length) {
const firstPoint = points[0];
//var label = myChart.data.labels[firstPoint.index];
//var value = myChart.data.datasets[firstPoint.datasetIndex].data[firstPoint.index];
let datasetIndex = firstPoint.datasetIndex, index = firstPoint.index;
if (firstPoint.element.hidden != true) {
chart.hide(datasetIndex, index);
} else {
chart.show(datasetIndex, index);
}
}
}
options: { // chart options
onClick: chartOnClick
}
If that works for you, then great, but if you want it to disappear completely, then you would need to delete the data from the array like this:
chart.data.datasets[datasetIndex].data.splice(index, 1);
chart.update();
Just keep a copy of the original array with all the data. You would likely have a "restore" button somewhere, that would set the data back when you click it:
chart.data = myData;
chart.update();
Here is a fiddle with the latter behaviour: JSFiddle (lacking the restore button, but it should be very easy to add)
ChartJS's BarCharts expect your data to belong to a single category thats why you only one button to show/hide all bars.
You easily fix this by changing the structure of your data so that each value has its own label. Instead of,
datasets: [{
label: 'A',
data: [1, 2, 3]
}]
your data should look like,
datasets: [{
label: 'A',
data: [1]
},{
label: 'B',
data: [2]
},{
label: 'C',
data: [3]
}]
var barCfg = {
type: 'bar',
data: {
labels: ['Red'],
datasets: [{
label: 'Person 1',
data: [12],
backgroundColor: ['#FFC857']
}, {
label: 'Person 2',
data: [19],
backgroundColor: ['#E9724C']
},{
label: 'Person 3',
data: [3],
backgroundColor: ['#C5283D']
},{
label: 'Person 4',
data: [5],
backgroundColor: ['#481D24']
},{
label: 'Person 5',
data: [2],
backgroundColor: ['#ff1Dff']
},{
label: 'Person 6',
data: [3],
backgroundColor: ['#48ffff']
}]
}
};
var pieCfg = {
type: 'pie',
data: {
labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
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
}]
}
};
var barChart = new Chart(
document.getElementById('barChart').getContext('2d'), barCfg);
var pieChart = new Chart(
document.getElementById('pieChart').getContext('2d'), pieCfg);
<script src="https://cdn.jsdelivr.net/npm/chart.js#3.4.1/dist/chart.min.js"></script>
<canvas id="barChart"></canvas>
<canvas id="pieChart"></canvas>
JSFiddle fork just for the record: https://jsfiddle.net/pqva7yso/
It should look somehow like this:
I already have the chart, just the text is missing. Is there an option to get the text in the middle of the chart?
EDIT: An example of such a graph can be found here: https://jsfiddle.net/wt4260qf/1/
var ctx = document.getElementById("myChart");
var myChart = new Chart(ctx, {
type: 'doughnut',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
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: {
rotation: 1 * Math.PI,
circumference: 1 * Math.PI
}
});
Thanks to #DTul, I figured it out. The title configuration is here: https://www.chartjs.org/docs/latest/configuration/title.html.
I've added the following section:
title: {
display: true,
text: 'Custom Chart Title',
position: 'bottom'
}
to the options.
The whole example looks now like that:
var ctx = document.getElementById("myChart");
var myChart = new Chart(ctx, {
type: 'doughnut',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
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: {
rotation: 1 * Math.PI,
circumference: 1 * Math.PI,
title: {
display: true,
text: 'Custom Chart Title',
position: 'bottom'
}
}
});
The corresponding fiddle is here: https://jsfiddle.net/ktq8mb0z/
I used this instructions
How can I add some text in the middle of a half doughnut chart in Chart.JS?
some changes for text position and fontsize
var fontSizeToUse = 16;
var centerY = ((chart.chartArea.top + chart.chartArea.bottom) - 80);
http://jsfiddle.net/vencendor/e0c8rgbm/
half-doughnut, or how I call it, a speedometer graph, is now configured with degrees:
var chart = new Chart(canvas, {
type: 'doughnut',
data: ['400', '200'],
options: {
rotation: -90,
circumference: 180,
}
I did this in Chartjs version 3.5.1
I'm using Chart.js (http://www.chartjs.org/) and it's working fine, but I have too big X labels also with 45 degrees orientation (is auto adjusting).
I would like to reduce the size of that text, is it possible to do only for X axis?
thanks
Yes in the ticks.fontSize configuration you can do it only for the x-axis. For example
var ctx = document.getElementById("myChart");
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
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
}
}],
xAxes: [{
ticks: {
fontSize: 8
}
}]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.bundle.min.js"></script>
<canvas id="myChart" width="400" height="400"></canvas>
I'm trying to edit a chart but i can't.
I want to change the canvas height to a fix height. The chart start always with 1156px X 867. And i need to change also the heigh of each bar.
So, how can i change the size of canvas and how can i change the height of each bar.
I have this code:
var ctx = document.getElementById("chart");
var myChart = new Chart(ctx, {
type: 'horizontalBar',
data: {
labels: data['labels'],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
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
}
}]
}
}
});
html:
<canvas id="chartMentes" width="400" height="300"></canvas>
How can I change the size of canvas?
Usually, ChartJS displays chart in a responsive manner, meaning it won't take canvas's width and height (set by user) into consideration.
To get around this, you need to set responsive property to false in your chart options, like so ...
options: {
responsive: false,
...
}
Now, you could set canvas's width and height as per your requirement.
<canvas id="chartMentes" width="400" height="800"></canvas>
How can I change the height of each bar?
You can change the height of each bar by setting the barThickness property accordingly for y-axis in the chart options, like so ...
options: {
scales: {
yAxes: [{
barThickness: 10, //set that suits the best
...
}
ᴅᴇᴍᴏ
var ctx = document.getElementById("chartMentes").getContext('2d');
var myChart = new Chart(ctx, {
type: 'horizontalBar',
data: {
labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
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: {
responsive: false,
scales: {
yAxes: [{
barThickness: 10,
ticks: {
beginAtZero: true
}
}]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.5.0/Chart.min.js"></script>
<canvas id="chartMentes" width="300" height="200"></canvas>
I have the following script of drawing bar chart and I wanna add horizontal line on particular y dot. I was trying following example link and I just substituted Chart.types.Line.extend with Chart.types.Bar.extend
but as a result I'm getting can not read property extend of undefined
So can someone help to implement above example which in the link properly or suggest another decision
my source code without horizontal line
var ctx = document.getElementById("myChart");
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
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
},
}]
},
}
});
You can use Chart.js plugins to do that. Plugins let you handle specific events such as beforeUpdate or afterDraw and are also easy to implement :
Chart.pluginService.register({
afterDraw: function(chart) {
// Code here will be triggered ... after the drawing
}
});
An easy way to do it is to simply draw a line like you would you on a simple canvas element, after everything is drawn in your chart, using the lineTo method.
Here is a small example (and its related code) of how it would look like :
With the answer from #tektiv, your yAxis always starts at 0.
This is a working example without the use of yAxe.min, so
you can use it (for example, with beginAtZero:false) and the yAxe scales automatically with your data.
Line plugin:
var canvas = document.getElementById("barCanvas");
var ctx = canvas.getContext('2d');
Chart.pluginService.register({
afterDraw: function(chart) {
if (typeof chart.config.options.lineAt != 'undefined') {
var lineAt = chart.config.options.lineAt;
var ctxPlugin = chart.chart.ctx;
var xAxe = chart.scales[chart.config.options.scales.xAxes[0].id];
var yAxe = chart.scales[chart.config.options.scales.yAxes[0].id];
ctxPlugin.strokeStyle = "red";
ctxPlugin.beginPath();
lineAt = yAxe.getPixelForValue(lineAt);
ctxPlugin.moveTo(xAxe.left, lineAt);
ctxPlugin.lineTo(xAxe.right, lineAt);
ctxPlugin.stroke();
}
}
});
Chart:
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
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: {
lineAt: 14,
scales: {
yAxes: [{
ticks: {
beginAtZero:false
}
}]
},
}
});