1👍
Easiest way is to provide your data with multiple sets :
data: {
labels: ['total votes']
, datasets: [{
label: 'Blue'
, backgroundColor: ['#2C79C5']
, data: ['12']
},{
label: 'Green'
, backgroundColor: ['#7FA830']
, data: ['2']
},
...
]
}
But you can generate a custom labels using generateLabels
– http://www.chartjs.org/docs/#chart-configuration-legend-configuration
Or even customise the whole legend, including formatting, with legendCallback
– http://www.chartjs.org/docs/#chart-configuration-common-chart-configuration
2👍
In one of the most recent releases of Chart.js 2.1.x, they added back this functionality. So go get the latest release first. Then insert the code below.
It is located under the options and legend. Here is how you use it:
options: {
legend: {
position: 'right'
}
}
0👍
This solution uses Chart.js version 3. You can pre-process your data using the Plugin Core API. The API offers different hooks that may be used for executing custom code.
I use the beforeInit
hook to create individual datasets for each defined label/value pair. Note that the data
of these new datasets are defined in point format (for instance [{ x: 1, y: 12 }]
):
beforeInit: chart => {
let dataset = chart.config.data.datasets[0];
chart.config.data.datasets = chart.config.data.labels.map((l, i) => ({
label: l,
data: [{ x: i + 1, y: dataset.data[i] }],
backgroundColor: dataset.backgroundColor[i],
categoryPercentage: 1
}));
chart.config.data.labels = undefined;
}
Further you need to define a second x-axis that will contain the labels.
x1: {
offset: true,
gridLines: {
display: false
}
}
The labels
on x1
need to be collected and defined programmatically each time the hidden
state of a dataset
changes. This can be done in the beforeLayout
hook.
beforeLayout: chart => chart.options.scales.x1.labels = chart.config.data.datasets.filter((ds, i) => !chart.getDatasetMeta(i).hidden).map(ds => ds.label)
Please take a look at below runnable code and see how it works.
new Chart('chart', {
type: 'bar',
plugins: [{
beforeInit: chart => {
let dataset = chart.config.data.datasets[0];
chart.config.data.datasets = chart.config.data.labels.map((l, i) => ({
label: l,
data: [{ x: i + 1, y: dataset.data[i] }],
backgroundColor: dataset.backgroundColor[i],
categoryPercentage: 1
}));
chart.config.data.labels = undefined;
},
beforeLayout: chart => chart.options.scales.x1.labels = chart.config.data.datasets.filter((ds, i) => !chart.getDatasetMeta(i).hidden).map(ds => ds.label)
}],
data: {
labels: ['Blue', 'Green', 'Yellow', 'Red', 'Purple', 'Orange'],
datasets: [{
data: ['12', '2', '5', '0', '9', '1'],
backgroundColor: ['#2C79C5', '#7FA830', '#FFF200', '#ED4D40', '#800080', '#EC802F']
}]
},
options: {
interaction: {
intersect: true,
mode: 'nearest'
},
plugins: {
legend: {
position: 'right'
},
tooltip: {
callbacks: {
title: () => undefined
}
}
},
scales: {
y: {
beginAtZero: true
},
x: {
display: false
},
x1: {
offset: true,
gridLines: {
display: false
}
}
}
}
});
canvas {
max-width: 400px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.2.0/chart.min.js"></script>
<canvas id="chart" height="120"></canvas>