]> git.ipfire.org Git - thirdparty/Chart.js.git/commitdiff
HTML Legend sample (#8804)
authorEvert Timberg <evert.timberg+github@gmail.com>
Sat, 3 Apr 2021 20:10:39 +0000 (16:10 -0400)
committerGitHub <noreply@github.com>
Sat, 3 Apr 2021 20:10:39 +0000 (16:10 -0400)
docs/.vuepress/config.js
docs/samples/legend/html.md [new file with mode: 0644]

index 701b23a8e356ed7662758f804c8b04a161e03b90..436e3ab19a20684878ffd92dea73f24fa034023f 100644 (file)
@@ -167,6 +167,7 @@ module.exports = {
             'legend/title',
             'legend/point-style',
             'legend/events',
+            'legend/html',
           ]
         },
         {
diff --git a/docs/samples/legend/html.md b/docs/samples/legend/html.md
new file mode 100644 (file)
index 0000000..ab0add5
--- /dev/null
@@ -0,0 +1,127 @@
+# 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,
+};
+```