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

ccgok5k5  于 2022-11-07  发布在  Chart.js
关注(0)|答案(2)|浏览(224)

我想显示30天内两个班次的机器停机时间的可视化-白天(12小时)和晚上(12小时)。因此,我使用了组堆叠条形图,它看起来很好,接受我不想用图例显示两个班次(白天和晚上)。
stacked bar chart with groups

  1. <canvas id="myChart"></canvas>
  2. <script>
  3. var ctx = document.getElementById("myChart").getContext('2d');
  4. var myChart = new Chart(ctx, {
  5. type: 'bar',
  6. data: {
  7. 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",],
  8. datasets: [{
  9. label: 'Machine 1 - Day',
  10. stack: 'Stack 0',
  11. 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],
  12. backgroundColor: '#FF4A4A',
  13. },
  14. {
  15. label: 'Machine 1 - Night',
  16. stack: 'Stack 1',
  17. 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],
  18. backgroundColor: '#FF4A4A',
  19. },
  20. {
  21. label: 'Machine 2 - Day',
  22. stack: 'Stack 0',
  23. 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],
  24. backgroundColor: '#FF9C2A',
  25. },
  26. {
  27. label: 'Machine 2 - Night',
  28. stack: 'Stack 1',
  29. 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],
  30. backgroundColor: '#FF9C2A',
  31. },
  32. ]
  33. },
  34. options: {
  35. plugins: {
  36. legend: {
  37. display: true
  38. }
  39. },
  40. scales: {
  41. xAxes: [{
  42. stacked: true,
  43. }],
  44. yAxes: [{
  45. stacked: true
  46. }]
  47. }
  48. }
  49. });
  50. </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
如何处理单击处理程序的后两个数据集,依此类推。

  1. <canvas id="myChart"></canvas>
  2. <script>
  3. var defaultLegendClickHandler = Chart.defaults.plugins.legend.onClick;
  4. var newLegendClickHandler = function (e, legendItem, legend) {
  5. var index = legendItem.datasetIndex;
  6. if (index > 1) {
  7. // Do the original logic
  8. defaultLegendClickHandler(e, legendItem);
  9. } else {
  10. let ci = legend.chart;
  11. [
  12. ci.getDatasetMeta(0),
  13. ci.getDatasetMeta(1)
  14. ].forEach(function (meta) {
  15. meta.hidden = meta.hidden === null ? !ci.data.datasets[index].hidden : null;
  16. });
  17. ci.update();
  18. }
  19. };
  20. var ctx = document.getElementById("myChart").getContext('2d');
  21. var myChart = new Chart(ctx, {
  22. type: 'bar',
  23. data: {
  24. 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",],
  25. datasets: [{
  26. label: 'Machine 1 - Day',
  27. stack: 'Stack 0',
  28. 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],
  29. backgroundColor: '#FF4A4A',
  30. },
  31. {
  32. label: 'Machine 1 - Night',
  33. stack: 'Stack 1',
  34. 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],
  35. backgroundColor: '#FF4A4A',
  36. },
  37. {
  38. label: 'Machine 2 - Day',
  39. stack: 'Stack 0',
  40. 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],
  41. backgroundColor: '#FF9C2A',
  42. },
  43. {
  44. label: 'Machine 2 - Night',
  45. stack: 'Stack 1',
  46. 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],
  47. backgroundColor: '#FF9C2A',
  48. },
  49. ]
  50. },
  51. options: {
  52. plugins: {
  53. legend: {
  54. onClick: newLegendClickHandler
  55. }
  56. },
  57. scales: {
  58. xAxes: [{
  59. stacked: true,
  60. }],
  61. yAxes: [{
  62. stacked: true
  63. }]
  64. }
  65. }
  66. });
  67. </script>
bmvo0sr5

bmvo0sr51#

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

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

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

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

有关详细信息,请参阅Chart.js文档的LegendAPI章节。
请查看修改后的代码并了解其工作原理。
第一个

展开查看全部
7hiiyaii

7hiiyaii2#

嘿,我得到了类似这样的工作,但我隐藏了所有与相同的堆栈变量,并隐藏某些数据系列,以及,这样我就可以隐藏他们没有他们的图例项目可供点击:
我有很多系列具有相同的数据集(即,失败的数字,重新测试的数字,不想显示这些标签)

  1. // Get Data From Views and Add Custom onClick Listener
  2. let tempData = { ...views[i].data };
  3. if (
  4. // Kill the onClick and add a much slower but grouping onClick, hide all with part number in stack
  5. tempData &&
  6. tempData.options &&
  7. tempData.options.plugins &&
  8. tempData.options.plugins.legend
  9. )
  10. tempData.options.plugins.legend.onClick = (e, legendItem) => {
  11. // My labels always start with the part number and a space so I grab that.
  12. const partName = legendItem.text.split(' ')[0];
  13. const chart = Chart.getChart('temp-chart');
  14. // Toggle the data set that was clicked on
  15. const datasetIndex = legendItem.datasetIndex;
  16. if (!chart.getDatasetMeta(datasetIndex).hidden) chart.hide(datasetIndex);
  17. else chart.show(datasetIndex);
  18. let j = 0;
  19. // Iterate through all datasets, cap at 200 for safety
  20. while (chart.getDatasetMeta(j).stack && j < 200) {
  21. const datasetMeta = chart.getDatasetMeta(j);
  22. const stack = datasetMeta.stack;
  23. const datasetName = datasetMeta.label;
  24. // I add a stack id to all my datasets and use that to determine what is 'grouped'
  25. // I have a plugin that does not render any datasets which do not have a label
  26. // If the stack group matches and the dataset does not have a label it will be hidden.
  27. if (
  28. stack === partName &&
  29. (datasetName == null ||
  30. datasetName === '' ||
  31. datasetName === 'undefined')
  32. ) {
  33. if (!chart.getDatasetMeta(j).hidden) chart.hide(j);
  34. else chart.show(j);
  35. }
  36. j++;
  37. }
  38. };
  39. new Chart('temp-chart', { ...tempData });

和图例插件来隐藏没有标签的图例项。

  1. Chart.defaults.plugins.legend.labels.filter = (item) => {
  2. return item.text != null;
  3. };

Heres what I got - Pictures

展开查看全部

相关问题