mirror of
https://github.com/chartjs/Chart.js.git
synced 2024-10-08 13:19:07 +02:00
128 lines
3.3 KiB
Markdown
128 lines
3.3 KiB
Markdown
|
# HTML Legend
|
||
|
|
||
|
This example shows how to create a custom HTML legend using a plugin and connect it to the chart in lieu of the default on-canvas legend.
|
||
|
|
||
|
<div id="legend-container"></div>
|
||
|
|
||
|
```js chart-editor
|
||
|
// <block:plugin:0>
|
||
|
const getOrCreateLegendList = (chart, id) => {
|
||
|
const legendContainer = document.getElementById(id);
|
||
|
let listContainer = legendContainer.querySelector('ul');
|
||
|
|
||
|
if (!listContainer) {
|
||
|
listContainer = document.createElement('ul');
|
||
|
listContainer.style.display = 'flex';
|
||
|
listContainer.style.flexDirection = 'row';
|
||
|
listContainer.style.margin = 0;
|
||
|
listContainer.style.padding = 0;
|
||
|
|
||
|
legendContainer.appendChild(listContainer);
|
||
|
}
|
||
|
|
||
|
return listContainer;
|
||
|
};
|
||
|
|
||
|
const htmlLegendPlugin = {
|
||
|
id: 'htmlLegend',
|
||
|
afterUpdate(chart, args, options) {
|
||
|
const ul = getOrCreateLegendList(chart, options.containerID);
|
||
|
|
||
|
// Remove old legend items
|
||
|
while (ul.firstChild) {
|
||
|
ul.firstChild.remove();
|
||
|
}
|
||
|
|
||
|
// Reuse the built-in legendItems generator
|
||
|
const items = chart.options.plugins.legend.labels.generateLabels(chart);
|
||
|
|
||
|
items.forEach(item => {
|
||
|
const li = document.createElement('li');
|
||
|
li.style.alignItems = 'center';
|
||
|
li.style.cursor = 'pointer';
|
||
|
li.style.display = 'flex';
|
||
|
li.style.flexDirection = 'row';
|
||
|
li.style.marginLeft = '10px';
|
||
|
|
||
|
li.onclick = () => {
|
||
|
chart.setDatasetVisibility(item.datasetIndex, !chart.isDatasetVisible(item.datasetIndex));
|
||
|
chart.update();
|
||
|
};
|
||
|
|
||
|
// Color box
|
||
|
const boxSpan = document.createElement('span');
|
||
|
boxSpan.style.background = item.fillStyle;
|
||
|
boxSpan.style.borderColor = item.strokeStyle;
|
||
|
boxSpan.style.borderWidth = item.lineWidth + 'px';
|
||
|
boxSpan.style.display = 'inline-block';
|
||
|
boxSpan.style.height = '20px';
|
||
|
boxSpan.style.marginRight = '10px';
|
||
|
boxSpan.style.width = '20px';
|
||
|
|
||
|
// Text
|
||
|
const textContainer = document.createElement('p');
|
||
|
textContainer.style.color = item.fontColor;
|
||
|
textContainer.style.margin = 0;
|
||
|
textContainer.style.padding = 0;
|
||
|
textContainer.style.textDecoration = item.hidden ? 'line-through' : '';
|
||
|
|
||
|
const text = document.createTextNode(item.text);
|
||
|
textContainer.appendChild(text);
|
||
|
|
||
|
li.appendChild(boxSpan);
|
||
|
li.appendChild(textContainer);
|
||
|
ul.appendChild(li);
|
||
|
});
|
||
|
}
|
||
|
};
|
||
|
// </block:plugin>
|
||
|
|
||
|
// <block:data:1>
|
||
|
const NUM_DATA = 7;
|
||
|
const NUM_CFG = {count: NUM_DATA, min: 0, max: 100};
|
||
|
const data = {
|
||
|
labels: Utils.months({count: NUM_DATA}),
|
||
|
datasets: [
|
||
|
{
|
||
|
label: 'Dataset: 1',
|
||
|
data: Utils.numbers(NUM_CFG),
|
||
|
borderColor: Utils.CHART_COLORS.red,
|
||
|
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.red, 0.5),
|
||
|
fill: false,
|
||
|
},
|
||
|
{
|
||
|
label: 'Dataset: 1',
|
||
|
data: Utils.numbers(NUM_CFG),
|
||
|
borderColor: Utils.CHART_COLORS.blue,
|
||
|
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.blue, 0.5),
|
||
|
fill: false,
|
||
|
},
|
||
|
],
|
||
|
};
|
||
|
// </block:data>
|
||
|
|
||
|
// <block:setup:2>
|
||
|
const config = {
|
||
|
type: 'line',
|
||
|
data: data,
|
||
|
options: {
|
||
|
plugins: {
|
||
|
htmlLegend: {
|
||
|
// ID of the container to put the legend in
|
||
|
containerID: 'legend-container',
|
||
|
},
|
||
|
legend: {
|
||
|
display: false,
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
plugins: [htmlLegendPlugin],
|
||
|
};
|
||
|
// </block:setup>
|
||
|
|
||
|
module.exports = {
|
||
|
actions: [],
|
||
|
config: config,
|
||
|
};
|
||
|
```
|