# 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: `
`.
```js chart-editor // 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)); } 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; 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); }); } }; // // 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, }, ], }; // // 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], }; // 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)