【问题标题】:Hide or show two datasets with one click event of legend in chart.js在chart.js中通过图例的一键事件隐藏或显示两个数据集
【发布时间】:2022-01-04 16:58:43
【问题描述】:

我想显示 2 个班次的机器停机时间可视化 - 白天(12 小时)和晚上(12 小时),共 30 天。因此,我使用带有组的堆叠条形图,看起来不错,我不想让图例显示两个班次(白天和黑夜)。

stacked bar chart with groups

<canvas id="myChart"></canvas>

<script>

    var ctx = document.getElementById("myChart").getContext('2d');

    var myChart = new Chart(ctx, {
        type: 'bar',
        data: {
            labels: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30",],
            datasets: [{
                label: 'Machine 1 - Day',
                stack: 'Stack 0',
                data: [5, 13, 5, 20, 4, 9, 28, 19, 21, 5, 13, 7, 21, 26, 10, 28, 19, 21, 30, 10, 27, 6, 12, 15, 4, 2, 13, 8, 29, 30],
                backgroundColor: '#FF4A4A',
            },
            {
                label: 'Machine 1 - Night',
                stack: 'Stack 1',
                data: [5, 13, 5, 20, 4, 9, 28, 19, 21, 5, 13, 7, 21, 26, 10, 28, 19, 21, 30, 10, 27, 6, 12, 15, 4, 2, 13, 8, 29, 30],
                backgroundColor: '#FF4A4A',
            },
            {
                label: 'Machine 2 - Day',
                stack: 'Stack 0',
                data: [5, 13, 5, 20, 4, 9, 28, 19, 21, 5, 13, 7, 21, 26, 10, 28, 19, 21, 30, 10, 27, 6, 12, 15, 4, 2, 13, 8, 29, 30],
                backgroundColor: '#FF9C2A',
            },
            {
                label: 'Machine 2 - Night',
                stack: 'Stack 1',
                data: [12, 13, 5, 20, 4, 9, 28, 19, 21, 5, 13, 7, 21, 26, 10, 28, 19, 21, 30, 10, 27, 6, 12, 15, 4, 2, 13, 8, 29, 30],
                backgroundColor: '#FF9C2A',
            },

            ]
        },
        options: {
            plugins: {
                legend: {
                    display: true
                }
            },
            scales: {
                xAxes: [{
                    stacked: true,
                }],
                yAxes: [{
                    stacked: true
                }]
            }
        }
    });

</script>

如何在图例中将机器 1 或 2 组合为昼夜班次,然后单击机器 1 或 2 将隐藏两个班次(昼夜)

stacked bar chart with groups edit Legend

我发现下面的方法可能对我有用。 https://www.chartjs.org/docs/3.1.0/configuration/legend.html#custom-on-click-actions

click handler of the first two datasets

如何处理点击处理程序的后两个数据集,依此类推。

    <canvas id="myChart"></canvas>


<script>


    var defaultLegendClickHandler = Chart.defaults.plugins.legend.onClick;
    var newLegendClickHandler = function (e, legendItem, legend) {
        var index = legendItem.datasetIndex;

        if (index > 1) {
            // Do the original logic
            defaultLegendClickHandler(e, legendItem);
        } else {
            let ci = legend.chart;
            [
                ci.getDatasetMeta(0),
                ci.getDatasetMeta(1)
            ].forEach(function (meta) {
                meta.hidden = meta.hidden === null ? !ci.data.datasets[index].hidden : null;
            });
            ci.update();
        }
    };



    var ctx = document.getElementById("myChart").getContext('2d');

    var myChart = new Chart(ctx, {
        type: 'bar',
        data: {
            labels: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30",],
            datasets: [{
                label: 'Machine 1 - Day',
                stack: 'Stack 0',
                data: [5, 13, 5, 20, 4, 9, 28, 19, 21, 5, 13, 7, 21, 26, 10, 28, 19, 21, 30, 10, 27, 6, 12, 15, 4, 2, 13, 8, 29, 30],
                backgroundColor: '#FF4A4A',
            },
            {
                label: 'Machine 1 - Night',
                stack: 'Stack 1',
                data: [5, 13, 5, 20, 4, 9, 28, 19, 21, 5, 13, 7, 21, 26, 10, 28, 19, 21, 30, 10, 27, 6, 12, 15, 4, 2, 13, 8, 29, 30],
                backgroundColor: '#FF4A4A',
            },
            {
                label: 'Machine 2 - Day',
                stack: 'Stack 0',
                data: [5, 13, 5, 20, 4, 9, 28, 19, 21, 5, 13, 7, 21, 26, 10, 28, 19, 21, 30, 10, 27, 6, 12, 15, 4, 2, 13, 8, 29, 30],
                backgroundColor: '#FF9C2A',
            },
            {
                label: 'Machine 2 - Night',
                stack: 'Stack 1',
                data: [12, 13, 5, 20, 4, 9, 28, 19, 21, 5, 13, 7, 21, 26, 10, 28, 19, 21, 30, 10, 27, 6, 12, 15, 4, 2, 13, 8, 29, 30],
                backgroundColor: '#FF9C2A',
            },

            ]
        },
        options: {
            plugins: {
                legend: {
                    onClick: newLegendClickHandler
                }
            },
            scales: {
                xAxes: [{
                    stacked: true,
                }],
                yAxes: [{
                    stacked: true
                }]
            }
        }
    });

</script>

【问题讨论】:

    标签: javascript chart.js


    【解决方案1】:

    首先,您需要定义一个 legend.labels.generateLabels 函数来过滤掉不需要的图例标签并更改其余标签的文本。

    generateLabels: chart => chart.data.datasets.map((ds, i) => ({
        text: ds.label.substring(0, ds.label.indexOf('-')),
        datasetIndex: i,
        fillStyle: chart.data.datasets[i].backgroundColor,
        strokeStyle: chart.data.datasets[i].backgroundColor,
        hidden: chart.getDatasetMeta(i).hidden
      }))
      .filter((ds, i) => i % 2),
    

    然后您必须定义一个legend.onClick 函数,该函数还负责在用户单击图例标签时显示/隐藏同级数据集。

    onClick: (event, legendItem, legend) => {
      let hidden = !legend.chart.getDatasetMeta(legendItem.datasetIndex).hidden;
      (legendItem.datasetIndex == 1 ? [0, 1] : [2, 3])
      .forEach(i => legend.chart.getDatasetMeta(i).hidden = hidden);
      legend.chart.update();
    }
    

    有关详细信息,请参阅 Chart.js 文档的 LegendAPI 章节。

    请查看您修改后的代码,看看它是如何工作的。

    new Chart('chart', {
      type: 'bar',
      data: {
        labels: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", ],
        datasets: [{
            label: 'Machine 1 - Day',
            stack: 'Stack 0',
            data: [5, 13, 5, 20, 4, 9, 28, 19, 21, 5, 13, 7, 21, 26, 10, 28, 19, 21, 30, 10, 27, 6, 12, 15, 4, 2, 13, 8, 29, 30],
            backgroundColor: '#FF4A4A',
          },
          {
            label: 'Machine 1 - Night',
            stack: 'Stack 1',
            data: [5, 13, 5, 20, 4, 9, 28, 19, 21, 5, 13, 7, 21, 26, 10, 28, 19, 21, 30, 10, 27, 6, 12, 15, 4, 2, 13, 8, 29, 30],
            backgroundColor: '#FF4A4A',
          },
          {
            label: 'Machine 2 - Day',
            stack: 'Stack 0',
            data: [5, 13, 5, 20, 4, 9, 28, 19, 21, 5, 13, 7, 21, 26, 10, 28, 19, 21, 30, 10, 27, 6, 12, 15, 4, 2, 13, 8, 29, 30],
            backgroundColor: '#FF9C2A',
          },
          {
            label: 'Machine 2 - Night',
            stack: 'Stack 1',
            data: [12, 13, 5, 20, 4, 9, 28, 19, 21, 5, 13, 7, 21, 26, 10, 28, 19, 21, 30, 10, 27, 6, 12, 15, 4, 2, 13, 8, 29, 30],
            backgroundColor: '#FF9C2A',
          }
        ]
      },
      options: {
        plugins: {
          legend: {
            labels: {
              generateLabels: chart => chart.data.datasets.map((ds, i) => ({
                  text: ds.label.substring(0, ds.label.indexOf('-')),
                  datasetIndex: i,
                  fillStyle: chart.data.datasets[i].backgroundColor,
                  strokeStyle: chart.data.datasets[i].backgroundColor,
                  hidden: chart.getDatasetMeta(i).hidden
                }))
                .filter((ds, i) => i % 2),
            },
            onClick: (event, legendItem, legend) => {
              let hidden = !legend.chart.getDatasetMeta(legendItem.datasetIndex).hidden;
              (legendItem.datasetIndex == 1 ? [0, 1] : [2, 3])
              .forEach(i => legend.chart.getDatasetMeta(i).hidden = hidden);
              legend.chart.update();
            }
          }
        },
        scales: {
          x: {
            stacked: true,
          },
          y: {
            stacked: true
          }
        }
      }
    });
    canvas {
      max-height: 190px;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.7.0/chart.js"></script>
    <canvas id="chart"></canvas>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-01-23
      • 1970-01-01
      • 2021-08-01
      • 1970-01-01
      • 2014-08-14
      • 2016-09-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多