通过chart.js中图例的一键事件隐藏或显示两个数据集

2024-01-26

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

带组的堆积条形图 https://i.stack.imgur.com/IUsPM.png

<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 将隐藏两个班次(日班和夜班)

带组的堆叠条形图编辑图例 https://i.stack.imgur.com/XqMK5.png

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

前两个数据集的点击处理程序 https://i.stack.imgur.com/0Iprs.png

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

    <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>

首先,您需要定义一个 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();
}

有关更多详细信息,请参阅Legend https://www.chartjs.org/docs/3.7.0/configuration/legend.html and API https://www.chartjs.org/docs/3.7.0/developers/api.htmlChart.js 文档的章节。

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

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>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

通过chart.js中图例的一键事件隐藏或显示两个数据集 的相关文章

随机推荐