--- /dev/null
+# 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,
+};
+```