I'm working with chart.js and need to make a legend on horizontalBar, but isn't working because my data have 5 values and on legend label is showing only one and the value is "undefined", this undefined value control all chart colors.
Here is my code:
horizontalMeters = new Chart("chartHorizontalBar", {
type: "bar",
data: {
labels: ["red", "blue", "green"],
datasets: [{
backgroundColor: ["red", "blue", "green"],
data: [123, 321, 213]
}]
},
options: {
indexAxis: 'y',
plugins: {
legend: {
display: true,
position: "right",
}
},
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.7.0/chart.min.js"
integrity="sha512-TW5s0IT/IppJtu76UbysrBH9Hy/5X41OTAbQuffZFU6lQ1rdcLHzpU5BzVvr/YFykoiMYZVWlr/PX1mDcfM9Qg=="
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/chartjs-plugin-datalabels/2.0.0-rc.1/chartjs-plugin-datalabels.min.js"
integrity="sha512-+UYTD5L/bU1sgAfWA0ELK5RlQ811q8wZIocqI7+K0Lhh8yVdIoAMEs96wJAIbgFvzynPm36ZCXtkydxu1cs27w=="
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<canvas id="chartHorizontalBar"></canvas>
I'm using chart.js v3.7 and a datalabels plugin v2.0, i don't know if this plugin and version have a conflict, but i make a Doughnot Chart with the same CDN's and that one works
The code:
doughnotQualities = new Chart("chartDoughnutBar", {
type: "doughnut",
data: {
labels: ["red", "blue", "green"],
datasets: [{
backgroundColor: ["red", "blue", "green"],
data: [123, 321, 213]
}]
},
options: {
plugins: {
legend: {
display: true,
position: "right"
},
},
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.7.0/chart.min.js"
integrity="sha512-TW5s0IT/IppJtu76UbysrBH9Hy/5X41OTAbQuffZFU6lQ1rdcLHzpU5BzVvr/YFykoiMYZVWlr/PX1mDcfM9Qg=="
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/chartjs-plugin-datalabels/2.0.0-rc.1/chartjs-plugin-datalabels.min.js"
integrity="sha512-+UYTD5L/bU1sgAfWA0ELK5RlQ811q8wZIocqI7+K0Lhh8yVdIoAMEs96wJAIbgFvzynPm36ZCXtkydxu1cs27w=="
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<canvas id="chartDoughnutBar"></canvas>
That's the difference between charts:
Does anyone know how to solve this?
It shows undefined since it takes the label of the dataset, for doughnut and pie charts chart.js overrides the legend generator to use the labels array instead.
You can use multiple datasets with null values and then set the skipNull options to true like so:
Chart.register(ChartDataLabels)
horizontalMeters = new Chart("chartHorizontalBar", {
type: "bar",
data: {
labels: ["red", "blue", "green"],
datasets: [{
backgroundColor: "red",
label: "red",
data: [123, null, null]
}, {
backgroundColor: "blue",
label: "blue",
data: [null, 321, null]
}, {
backgroundColor: "green",
label: "green",
data: [null, null, 213]
}]
},
options: {
indexAxis: 'y',
skipNull: true,
plugins: {
legend: {
display: true,
position: "right",
}
},
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.7.0/chart.min.js" integrity="sha512-TW5s0IT/IppJtu76UbysrBH9Hy/5X41OTAbQuffZFU6lQ1rdcLHzpU5BzVvr/YFykoiMYZVWlr/PX1mDcfM9Qg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/chartjs-plugin-datalabels/2.0.0-rc.1/chartjs-plugin-datalabels.min.js" integrity="sha512-+UYTD5L/bU1sgAfWA0ELK5RlQ811q8wZIocqI7+K0Lhh8yVdIoAMEs96wJAIbgFvzynPm36ZCXtkydxu1cs27w==" crossorigin="anonymous"
referrerpolicy="no-referrer"></script>
<canvas id="chartHorizontalBar"></canvas>
Edit:
To use the datalabels plugin you will need to register it either inline or globally as in my example.
This answer explains how to solve the problem with a vertical bar chart.
The code needs to be slightly adapted to also work for a horizontal bar chart.
Please take a look at the following code and see how it could be done in your case.
new Chart('myChart', {
type: 'bar',
plugins: [{
afterInit: chart => {
let dataset = chart.data.datasets[0];
chart.data.datasets = chart.data.labels.map((l, i) => ({
label: l,
data: [{ x: dataset.data[i], y: i }],
backgroundColor: dataset.backgroundColor[i],
categoryPercentage: 1
}));
chart.data.labels = undefined;
},
beforeLayout: chart => {
chart.options.scales.y1.labels = chart.data.datasets.filter((ds, i) => !chart.getDatasetMeta(i).hidden).map(ds => ds.label);
}
}],
data: {
labels: ['Red', 'Blue', 'Green'],
datasets: [{
data: [123, 321, 213],
backgroundColor: ['red', 'blue', 'green']
}]
},
options: {
indexAxis: 'y',
maintainAspectRatio: false,
plugins: {
legend: {
position: 'right'
},
tooltip: {
callbacks: {
title: () => null
}
}
},
scales: {
y: {
display: false
},
y1: {
offset: true
}
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.7.0/chart.min.js"></script>
<canvas id="myChart"></canvas>
In your dataset object, just add label:''. This will remove the undefined interpulated string.
Related
I want to add datalabels to the top of each bar and color them in black and make it in bigger font. Like this:
my chart with necessary labels
But all that I tried don't change the chart.
I add chartjs and charts-plugin-datalabels:
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.8.0/chart.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/chartjs-plugin-datalabels/2.0.0/chartjs-plugin-datalabels.js"></script>
Chart creating function:
function bars_chart(data, period) {
Chart.register(ChartDataLabels)
document.querySelector('#chartContainer').innerHTML = '<canvas id="bar-chart-horizontal"></canvas>'
var chartConfig = {
type: 'bar',
data: {
labels: period,
datasets: data
},
options: {
responsive: true,
plugins: {
dataLabels: {
font: {
color: "#000000",
size: 25
},
color: "#000000"
},
legend: {
position: 'top',
},
title: {
display: true,
text: 'Chart.js Bar Chart'
},
}
},
};
new Chart(document.getElementById("bar-chart-horizontal"), chartConfig);
}
It looks like there is a simple solution but I can't find it)
Your namespace is wrong, you putted a capital L in there while it needs to be fully lower case. After that you can set anchor and align to 'end' to get the value on top of the bars:
Chart.register(ChartDataLabels)
const options = {
type: 'bar',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
backgroundColor: 'pink'
}]
},
options: {
plugins: {
datalabels: {
color: 'black',
font: {
size: 40
},
anchor: 'end',
align: 'end'
}
}
}
}
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.8.0/chart.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/chartjs-plugin-datalabels/2.0.0/chartjs-plugin-datalabels.js"></script>
</body>
I've got the following function making doughnut charts in ChartJS, the function imports the data, label text, and the id of the element. For some reason the options legend labels does not work for me. The default color of '#666' is not usable for my site's layout either.
my function:
function newDoughnutChart(id, labels, data) {
var donutChartCanvas = $(id).get(0).getContext('2d')
var donutData = {
labels: labels,
datasets: [
{
data: data,
backgroundColor: backgroundColor,
}
]
}
var donutOptions = {
maintainAspectRatio: false,
responsive: true,
options: {
legend: {
labels: {
usePointStyle: true,
fontColor: "#fff",
}
}
}
}
new Chart(donutChartCanvas, {
type: 'doughnut',
data: donutData,
options: donutOptions
})
}
backgroundColor is a variable I've set globally for this js file.
The legend config has been moved to the plugins section
Example:
var options = {
type: 'line',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
borderWidth: 1
},
{
label: '# of Points',
data: [7, 11, 5, 8, 3, 7],
borderWidth: 1
}
]
},
options: {
plugins: {
legend: {
labels: {
color: 'red'
}
}
}
}
}
var 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.3.2/chart.js"></script>
</body>
var donutOptions = {
maintainAspectRatio: false,
responsive: true,
options: {
plugins: {
legend: {
display: true,
labels: {
color: 'rgb(255, 99, 132)'
}
}
}
}
}
You can change the color by grabbing the class of that div tag using CSS selector. But It's not the best idea because it will change the color in your whole app.
I am having trouble with my chartsjs labels.
my graph generates fine, I am trying to set the chart so that the data labels are for the text part of the data and not the numbers part. my code shows the data labels as 4, 6 and 2 where as i need them to show the text: me, you and them.
<script>
var ctx = document.getElementById('myChart4').getContext('2d');
var myChart4 = new Chart(ctx, {
plugins: [ChartDataLabels],
type: 'doughnut',
data: {
labels: ['me','you','them'
],
datasets: [{
label: false,
data: [4,6,2
],
}]
},
options: {
responsive: false,
plugins: {
datalabels: {
color: 'black',
anchor: 'end',
align: 'end',
offset: 15
},
legend: {
display: false
},
title: {
display: true,
text:'Reason'
}
},
responsive: false,
onClick: (evt, activeEls) => {
show();
},
}
});
You can use the formatter function for this:
Chart.register(ChartDataLabels)
const options = {
type: 'bar',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
backgroundColor: 'orange'
}]
},
options: {
plugins: {
datalabels: {
color: 'black',
anchor: 'end',
align: 'end',
offset: 15,
formatter: (val, ctx) => (ctx.chart.data.labels[ctx.dataIndex])
},
}
}
}
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.6.0/chart.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/chartjs-plugin-datalabels/2.0.0/chartjs-plugin-datalabels.js"></script>
</body>
I currently display my data like this:
Click here
but I would like to display the data like this:
Click here
The idea is that at the bottom it would show the summary of all three colors numbers combined, but once you hover it would show how much each color has.
If all is one bar, if red is 7, blue is 3, the red but be a lot more in the bar.
This is the code for version 1, done with chart js
var ctx = document.getElementById("myChart").getContext("2d");
var data = {
labels: ["Chocolate", "Vanilla", "Strawberry"],
datasets: [
{
label: "Blue",
backgroundColor: "blue",
data: [3, 7, 4]
},
{
label: "Red",
backgroundColor: "red",
data: [4, 3, 5]
},
{
label: "Green",
backgroundColor: "green",
data: [7, 2, 6]
}
]
};
var myBarChart = new Chart(ctx, {
type: 'bar',
data: data,
options: {
barValueSpacing: 20,
scales: {
yAxes: [{
ticks: {
min: 0,
}
}]
}
}
});
const myChart = new Chart(
document.getElementById('myChart'),
config
);
your problem is the next, you are using a wrong config you must something like this:
<script src="https://cdn.jsdelivr.net/npm/chart.js#3.6.0/dist/chart.min.js"></script>
<canvas id="MyChart" width="400" height="200"></canvas>
<script>
new Chart(document.getElementById("MyChart"), {
type: 'bar',
data: {
labels: [2017],
datasets: [{
label: "Chocolate",
type: "bar",
stack: "Base",
backgroundColor: "#eece01",
data: [30],
}, {
label: "Vanilla",
type: "bar",
stack: "Base",
backgroundColor: "#87d84d",
data: [-15],
}, {
label: "Strawberry",
type: "bar",
stack: "Base",
backgroundColor: "#f8981f",
data: [20],
}, {
label: "candy",
type: "bar",
stack: "Base",
backgroundColor: "#00b300",
backgroundColorHover: "#3e95cd",
data: [-10]
}]
},
options: {
plugins: {
title: {
display: true,
text: 'Chart.js Bar Chart - Stacked'
},
},
responsive: true,
interaction: {
intersect: false,
},
scales: {
x: {
stacked: true,
},
y: {
stacked: true
}
}
}
});
</script>
Now you just need to fix the styles and sizes of the graphic
If someone finds this, the solution is this:
const config = {
type: 'bar',
data: data,
options: {
plugins: {
title: {
display: true,
text: 'Chart.js Bar Chart - Stacked'
},
},
responsive: true,
scales: {
x: {
stacked: true,
},
y: {
stacked: true
}
}
}
};
I've got a Piechart with two different Datasets:
How I can make internal pie chart bigger (or external thinner)?
Is there any option how I can adjust it?
Here is my code:
var ctx = $('#open_chart');
var chart = new Chart(ctx, {
type: 'pie',
data: {
datasets: [{
data: [1, 5],
backgroundColor: ['red', 'blue'],
}],
labels: ['Minor', 'Other'],
},
options: {
responsive: true,
title: {
display: true,
text: 'Title',
position: 'bottom',
fontSize: 15,
fontColor: '#000000'
},
events: ['mousemove'], // cursor: pointer on hover
onHover: function (event, chartElement) {
event.target.style.cursor = chartElement[0] ? 'pointer' : 'default';
},
legend: {
display: false
}
},
});
var newDataset = {
data: [1, 3],
backgroundColor: ['red', 'blue'],
};
var config = {
type: 'pie',
data: {
datasets: [{
data: [1, 3],
backgroundColor: ['red', 'blue'],
}],
labels: ['Red', 'Blue']
},
options: {
responsive: true
}
};
chart.data.datasets.push(newDataset);
chart.update();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<div class="chart-container" style="position: relative; height:500px; width:300px">
<canvas id="open_chart" style="position:absolute;top:150px;" width="200" height="200"></canvas>
</div>
I've tried to combine different pie charts: link, but it doesn't work.
From the styling section of the pie chart documentation of the chart.js library available here, you will see that there is a weight property. This property is used exactly for making the circles bigger/smaller.
Basically, by playing with the weight of the two data sets you can adjust the sizes of the circles. In the code below, I set the weight of the first dataset to 1 and for the second dataset to 4.
By running the snippet you will see the desired output.
Full code sample
var ctx = $('#open_chart');
var chart = new Chart(ctx, {
type: 'pie',
data: {
datasets: [{
data: [1, 5],
backgroundColor: ['red', 'blue'],
weight: 1
}],
labels: ['Minor', 'Other']
},
options: {
responsive: true,
title: {
display: true,
text: 'Title',
position: 'bottom',
fontSize: 15,
fontColor: '#000000'
},
events: ['mousemove'], // cursor: pointer on hover
onHover: function (event, chartElement) {
event.target.style.cursor = chartElement[0] ? 'pointer' : 'default';
},
legend: {
display: false
},
},
});
var newDataset = {
data: [1, 3],
backgroundColor: ['red', 'blue'],
weight: 4
};
var config = {
type: 'pie',
data: {
datasets: [{
data: [1, 3],
backgroundColor: ['red', 'blue'],
}],
labels: ['Red', 'Blue']
},
options: {
responsive: true
}
};
chart.data.datasets.push(newDataset);
chart.update();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<div class="chart-container" style="position: relative; height:500px; width:300px">
<canvas id="open_chart" style="position:absolute;top:150px;" width="200" height="200"></canvas>
</div>
Have you tried experimenting with the cutoutPercentage in options { }?