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.

  • Dataset: 1

  • Dataset: 1

HTML Legend - 图1

plugin data setup

  1. const getOrCreateLegendList = (chart, id) => {
  2. const legendContainer = document.getElementById(id);
  3. let listContainer = legendContainer.querySelector('ul');
  4. if (!listContainer) {
  5. listContainer = document.createElement('ul');
  6. listContainer.style.display = 'flex';
  7. listContainer.style.flexDirection = 'row';
  8. listContainer.style.margin = 0;
  9. listContainer.style.padding = 0;
  10. legendContainer.appendChild(listContainer);
  11. }
  12. return listContainer;
  13. };
  14. const htmlLegendPlugin = {
  15. id: 'htmlLegend',
  16. afterUpdate(chart, args, options) {
  17. const ul = getOrCreateLegendList(chart, options.containerID);
  18. // Remove old legend items
  19. while (ul.firstChild) {
  20. ul.firstChild.remove();
  21. }
  22. // Reuse the built-in legendItems generator
  23. const items = chart.options.plugins.legend.labels.generateLabels(chart);
  24. items.forEach(item => {
  25. const li = document.createElement('li');
  26. li.style.alignItems = 'center';
  27. li.style.cursor = 'pointer';
  28. li.style.display = 'flex';
  29. li.style.flexDirection = 'row';
  30. li.style.marginLeft = '10px';
  31. li.onclick = () => {
  32. const {type} = chart.config;
  33. if (type === 'pie' || type === 'doughnut') {
  34. // Pie and doughnut charts only have a single dataset and visibility is per item
  35. chart.toggleDataVisibility(item.index);
  36. } else {
  37. chart.setDatasetVisibility(item.datasetIndex, !chart.isDatasetVisible(item.datasetIndex));
  38. }
  39. chart.update();
  40. };
  41. // Color box
  42. const boxSpan = document.createElement('span');
  43. boxSpan.style.background = item.fillStyle;
  44. boxSpan.style.borderColor = item.strokeStyle;
  45. boxSpan.style.borderWidth = item.lineWidth + 'px';
  46. boxSpan.style.display = 'inline-block';
  47. boxSpan.style.height = '20px';
  48. boxSpan.style.marginRight = '10px';
  49. boxSpan.style.width = '20px';
  50. // Text
  51. const textContainer = document.createElement('p');
  52. textContainer.style.color = item.fontColor;
  53. textContainer.style.margin = 0;
  54. textContainer.style.padding = 0;
  55. textContainer.style.textDecoration = item.hidden ? 'line-through' : '';
  56. const text = document.createTextNode(item.text);
  57. textContainer.appendChild(text);
  58. li.appendChild(boxSpan);
  59. li.appendChild(textContainer);
  60. ul.appendChild(li);
  61. });
  62. }
  63. };
  1. const NUM_DATA = 7;
  2. const NUM_CFG = {count: NUM_DATA, min: 0, max: 100};
  3. const data = {
  4. labels: Utils.months({count: NUM_DATA}),
  5. datasets: [
  6. {
  7. label: 'Dataset: 1',
  8. data: Utils.numbers(NUM_CFG),
  9. borderColor: Utils.CHART_COLORS.red,
  10. backgroundColor: Utils.transparentize(Utils.CHART_COLORS.red, 0.5),
  11. fill: false,
  12. },
  13. {
  14. label: 'Dataset: 1',
  15. data: Utils.numbers(NUM_CFG),
  16. borderColor: Utils.CHART_COLORS.blue,
  17. backgroundColor: Utils.transparentize(Utils.CHART_COLORS.blue, 0.5),
  18. fill: false,
  19. },
  20. ],
  21. };
  1. const config = {
  2. type: 'line',
  3. data: data,
  4. options: {
  5. plugins: {
  6. htmlLegend: {
  7. // ID of the container to put the legend in
  8. containerID: 'legend-container',
  9. },
  10. legend: {
  11. display: false,
  12. }
  13. }
  14. },
  15. plugins: [htmlLegendPlugin],
  16. };

Docs