Chart.js/docs/samples/legend/html.md

143 lines
4.0 KiB
Markdown
Raw Permalink Normal View History

2021-04-03 22:10:39 +02:00
# 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.
For an html legend to work you need to place an empty div at your web page with the ID you provide in the options to bind to like so: `<div id="legend-container"></div>`.
2021-04-03 22:10:39 +02:00
<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 = () => {
const {type} = chart.config;
if (type === 'pie' || type === 'doughnut') {
// Pie and doughnut charts only have a single dataset and visibility is per item
chart.toggleDataVisibility(item.index);
} else {
chart.setDatasetVisibility(item.datasetIndex, !chart.isDatasetVisible(item.datasetIndex));
}
2021-04-03 22:10:39 +02:00
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.flexShrink = 0;
2021-04-03 22:10:39 +02:00
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,
};
```
## Docs
* [Data structures (`labels`)](../../general/data-structures.md)
* [Line](../../charts/line.md)
* [Legend](../../configuration/legend.md)
* `display: false`
* [Plugins](../../developers/plugins.md)