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

Time:03-15

I am using chartjs to show one month attendance data, what I want to acheive is to show each day data with different colors like Present, absent and leave. I want labels on top and by click on that label user should be able to hide/show that particular label data, below is my code.

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

I am attaching a screenshot below currently I only have one label but I want multiple labels based on multiple colors bar

enter image description here

CodePudding user response:

should be this part

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

under

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

CodePudding user response:

You need to use a second dataset to achieve this:

Then you can fill null values in both datasets where you dont use the values of that dataset, so null values on the places where value is negative in positive dataset and vice versa in other one.

Then you can use the property skipNull to make it so the bars dont take up 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>

  • Related