Search code examples
objectchart.jsvisualization

Bar Chart.js with objects using custom properties - problem to show


I have a set of data organized in 10 areas. In each area there are three categories: A, B and C and each of these categories has a set of data. My goal is to achieve with html and chart.js a bar chart with a selector (it works correctly) that allows you to change AREA and then show in the chart those three CATEGORIES and their data for that AREA.

I have already read the Chart.Js documentation but I see that I can't find information for the visualization and I don't see similar cases on the internet, only this one but I follow the steps in the same way but I don't reach the result (https://www.youtube.com/watch?v=cPsyh_KuYNA). My problem is that it shows only the data of one of the CATEGORIES and if I change the AREA it shows me the data of another CATEGORY but not the others.

I share part of my code

<div class="chartBox">
                        <canvas id="myChart" ></canvas>
                    <select id="areax" class= "sel_area" onchange="cambioarea()">                       
                        <option value="area_1">Area 1</options>                             
                        <option value="area_2">Area 2</options>
                        <option value="area_3">Area 3</options>
                        <option value="area_4">Area 4</options>
                        <option value="area_5">Area 5</options>
                        <option value="area_6">Area 6</options>
                        <option value="area_7">Area 7</options>
                        <option value="area_8">Area 8</options>
                        <option value="area_9">Area 9</options>
                        <option value="area_10">Area 10</options>
                    </select>
                    </div>
// setup 
const data = {
        //labels: ['A', 'B', 'C'],    
        datasets: [{
            label: 'Kms. por area',
            //data: [50, 12, 6, 9, 12, 3, 9],
            data: [
            {id: 'A', calzada:
                {
                    area_1: {a:613.810},
                    area_2: {a:600.586},
                    area_3: {a:1091.87}, 
                    area_4: {a:656.29},
                    area_5: {a:866.47},
                    area_6: {a:2262.059},
                    area_7: {a:1055.978},
                    area_8: {a:490.487}, 
                    area_9: {a:763.41},
                    area_10: {a:1099.84},
                }
            },
            {id: 'B', calzada:
                {
                    area_1: {b:11.981},
                    area_2: {b:209.617},
                    area_3: {b:317.616},
                    area_4: {b:106.509},
                    area_5: {b:70.190},
                    area_6: {b:84.109},
                    area_7: {b:18.875},
                    area_8: {b:39.619},
                    area_9: {b:27.899},
                    area_10: {b:50.787},
                }
            },
            {id: 'C', calzada:
                {
                    area_1: {c:534.647},
                    area_2: {c:988.239},
                    area_3: {c:519.770},
                    area_4: {c:672.867},
                    area_5: {c:725.431},
                    area_6: {c:1080.430},
                    area_7: {c:916.132},
                    area_8: {c:1224.730},
                    area_9: {c:1193.990},
                    area_10: {c:211.585},
                }
            }],
            backgroundColor: [
                '#ff0127',
                '#ffffff',
                '#db6adb'
            ],
            borderColor: [
                'black',
                'black',
                'black',
            ],
            borderWidth: 1
        }]
    };

    // config 
    const config = {
        type: 'bar',
        data,             // tambien funciona como:  data:data,
        options: {
            parsing: {
                xAxisKey: 'id',
                yAxisKey: 'calzada.area_1.a'
            },
            scales: {
                y: {
                    beginAtZero: true
                }
            }
        }
    };
          
    // render init block
    const myChart = new Chart(
        document.getElementById('myChart'),
        config
        );
function cambioarea(){
        const areax = document.getElementById('areax').value;
        console.log(areax);
        myChart.config.options.parsing.yAxisKey = `calzada.${areax}.a`;
        myChart.config.options.parsing.yAxisKey = `calzada.${areax}.b`;
        myChart.config.options.parsing.yAxisKey = `calzada.${areax}.c`;
        myChart.update();
    }

This is what happens : enter image description here

I think my problem is in my function CAMBIOAREA. Thanks for your help in advance


Solution

  • It would be a lot better to let ChartJS handle the show/hide of some data.

    For example, if you place each area in a dataset, you can use the labels at the top to toggle them.

    See this example:

    const backgroundColor = ["red", "blue", "green"];
    const data = {  
        labels: [ 'a','b','c'],
        datasets: [
          {
            label: "area 1",
            data: [65, 59, 80],
            backgroundColor
          },
          {
            label: "area 2",
            data: [50, 21, 12],
            hidden: true,
            backgroundColor
          }
        ]
    };
    
    const config = {
        type: 'bar',
        data,       
        
        options: {
            scales: {
                y: {
                    beginAtZero: true
                }
            }
        }
    };
    
    
    
    // render init block
    const myChart = new Chart(
        document.getElementById('myChart'),
        config
    );
    <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.8.1/chart.min.js"></script>
    <div class="chartBox">
        <canvas id="myChart" ></canvas>
    </div>


    Otherwise, you could hide those labels to toggle, and then hide/show the sets when the changes:

    //Hide
    chart.getDatasetMeta(1).hidden=true;
    chart.update();
    
    //Show
    chart.getDatasetMeta(1).hidden=false;
    chart.update();