如何使用 chartjs 条形图 hide/show 条形图通过颜色和点击标签来区分?

How to hide/show bars differentiate by a colors and by click on labels, using chartjs bar charts?

我正在使用chartjs 显示一个月的考勤数据,我想实现的是用不同颜色显示每一天的数据,如出席、缺席和离开。我想要标签在顶部,通过点击该标签,用户应该能够 hide/show 该特定标签数据,下面是我的代码。

<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.7.1/chart.min.js" integrity="sha512-QSkVNOCYLtj73J4hbmVoOV6KVZuMluZlioC+trLpewV8qMjsWqlIQvkn1KGX2StWvPMdWGBqim1xlC8krl1EKQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

<!-- HTML -->
<canvas id="chartJsDiv"></canvas>

<script>

    function attendanceSummaryChart3(attendence)
    {
        var datasets = [];
        var labels_data = [];
        var num_of_hour = [];
        var bar_colours = [];
        var border_colr = [];
        var real_data_count = attendence.length;
        for (var i = 0; i < real_data_count; i++) {

            var mydate = new Date(attendence[i].date);
            var month = ["Jan", "Feb", "Mar", "Apr", "May", "June", "July", "Aug", "Sep", "Oct", "Nov", "Dec"][mydate.getMonth()];
            var str = mydate.getDate() + ' ' +month;

            labels_data.push(str);
            
            if(parseFloat(attendence[i].hours.replace(':','.')) < 6.00)
            {
                if(attendence[i].is_leave != null)
                {
                    var applied_leave_type = attendence[i].is_leave_applied.leave_type.slug;
                    if(applied_leave_type == "work-from-home")
                    {
                        // Full hours in case work from home
                        num_of_hour.push('9');
                        bar_colours.push('RGB(25, 135, 84)');
                        border_colr.push('rgba(3, 126, 25, 0.85)');

                        // creating datasets
                        datasets.push({label: 'Work From Home', data: '9', backgroundColor: 'RGB(25, 135, 84)' });
                    }
                    else
                    {
                        // Leave applied
                        if(parseFloat(attendence[i].hours.replace(':','.')) == 0)
                        {
                            num_of_hour.push('-9');
                            bar_colours.push('RGB(25, 135, 84)');
                            border_colr.push('rgba(14, 8, 191, 0.8)');

                            // creating datasets
                            datasets.push({label: 'On Leave', data: '-9', backgroundColor: 'RGB(25, 135, 84)'});
                        }
                        else
                        {
                            num_of_hour.push(parseFloat(attendence[i].hours.replace(':','.')));
                            bar_colours.push('RGB(25, 135, 84)');
                            border_colr.push('rgba(14, 8, 191, 0.8)');

                            // creating datasets
                            datasets.push({label: 'Half Leave', data: parseFloat(attendence[i].hours.replace(':','.')), backgroundColor: 'RGB(25, 135, 84)'});
                        }
                    }
                    
                }
                else
                {
                    if(parseFloat(attendence[i].hours.replace(':','.')) == 0)
                    {
                        // If absent and no leave is applied
                        num_of_hour.push('-9');
                        bar_colours.push('RGB(255, 0, 0)');
                        border_colr.push('rgba(6, 108, 166, 0.8)');

                        // creating datasets
                        datasets.push({label: 'Absent (No Leave Applied)', data: '-9', backgroundColor: 'RGB(255, 0, 0)' });
                    }
                    else
                    {
                        // If present and didn't complete 06 hours in office
                        num_of_hour.push(parseFloat(attendence[i].hours.replace(':','.')));
                        bar_colours.push('RGB(255, 0, 0)');
                        border_colr.push('rgba(255, 99, 132, 1)');

                        // creating datasets
                        datasets.push({label: 'Present (Half Time)', data: parseFloat(attendence[i].hours.replace(':','.')), backgroundColor: 'RGB(255, 0, 0)' });
                    }
                }     
            }
            else
            { 
                // Full hours
                num_of_hour.push(parseFloat(attendence[i].hours.replace(':','.')));
                bar_colours.push('RGB(0, 255, 0)');
                border_colr.push('rgba(75, 192, 192, 1)'); 

                // creating datasets
                datasets.push({label: 'Present', data: parseFloat(attendence[i].hours.replace(':','.')), backgroundColor: 'RGB(25, 135, 84)' });
            }
        }

        console.log(datasets);

        const ctx = document.getElementById('chartJsDiv').getContext('2d');
        const myChart = new Chart(ctx, {
            type: 'bar',
            data: {
                labels: labels_data,
                datasets: [
                    {
                        label: ['Attendence'],
                        data: num_of_hour,
                        backgroundColor: bar_colours,
                        borderColor: border_colr,
                    }
                ]
            },
            options: {
                scales: {
                    y: {
                        beginAtZero: true
                    }
                }
            },
        });
    }
</script>

我在下面附上一张截图,目前我只有一个标签,但我想要基于多个颜色栏的多个标签

应该是这部分

 label: ['Attendence', 'newLabel', 'xxx'],

低于

 const ctx = document.getElementById('chartJsDiv').getContext('2d');

您需要使用第二个数据集来实现:

然后你可以在你不使用那个数据集的值的两个数据集中填充空值,所以在正数据集中值为负的地方填空值,在另一个数据集中反之亦然。

然后你可以使用 属性 skipNull 来使条不占用 space:

const options = {
  type: 'bar',
  data: {
    labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
    datasets: [{
        label: '# of Votes',
        data: [12, null, 3, 5, null, 3],
        backgroundColor: 'green'
      },
      {
        label: '# of Points',
        data: [null, -11, null, null, -3, null],
        backgroundColor: 'red'
      }
    ]
  },
  options: {
    skipNull: true
  }
}

const ctx = document.getElementById('chartJSContainer').getContext('2d');
new Chart(ctx, options);
<body>
  <canvas id="chartJSContainer" width="600" height="400"></canvas>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.7.1/chart.js"></script>
</body>