chart.jsbar-chartamcharts

AmCharts: Clustered bar chart with sub-categories


I try to realize a clustered bar chart with sub-categories in amcharts (two levels in my x-axis). I couldn't find a way to do it.

Does anyone know how to do it ?


Solution

  • The tricky part is the parent category name_fr on the graph. To do that, we need to use Guide(https://docs.amcharts.com/3/javascriptcharts/Guide) within the CategoryAxis.

    But in order to use Guide, each category needs an unique identifier as each guide (in your case, it's each name) needs a starting point field (called Category) and an ending point field (called ToCategory).

    Create ID for each data point

    Here I just concat the name and date field. If your data has an ID field, you can use that too.

    let data = [
        {
            "category": "Allemagne-1/3/2005",
            "name_fr": "Allemagne",
            "date": "1/3/2005",
            "Décile 1": 11.91166848,
            "Décile 5": 6.663209907,
            "Décile 9": 3.912389412
        },
        {
            "category": "Allemagne-12/18/2017",
            "name_fr": "Allemagne",
            "date": "12/18/2017",
            "Décile 1": 12.08203299,
            "Décile 5": 6.181569343,
            "Décile 9": 3.380401158
        },
        {
            "category": "Espagne-1/3/2005",
            "name_fr": "Espagne",
            "date": "1/3/2005",
            "Décile 1": 18.16145046,
            "Décile 5": 8.049555152,
            "Décile 9": 4.02786022
        },
        {
            "category": "Espagne-12/18/2017",
            "name_fr": "Espagne",
            "date": "12/18/2017",
            "Décile 1": 22.27695636,
            "Décile 5": 8.698725621,
            "Décile 9": 4.224440949
        },
        {
            "category": "France-1/3/2005",
            "name_fr": "France",
            "date": "1/3/2005",
            "Décile 1": 11.29143493,
            "Décile 5": 6.365859777,
            "Décile 9": 3.476250813
        },
        {
            "category": "France-12/18/2017",
            "name_fr": "France",
            "date": "12/18/2017",
            "Décile 1": 11.46405229,
            "Décile 5": 6.355936042,
            "Décile 9": 3.441408741
        },
        {
            "category": "Italie-1/3/2005",
            "name_fr": "Italie",
            "date": "1/3/2005",
            "Décile 1": 16.86187094,
            "Décile 5": 7.798630041,
            "Décile 9": 4.017535647
        },
        {
            "category": "Italie-12/18/2017",
            "name_fr": "Italie",
            "date": "12/18/2017",
            "Décile 1": 21.92640815,
            "Décile 5": 9.365977512,
            "Décile 9": 4.893619709
        },
        {
            "category": "Royaume-Uni-1/3/2005",
            "name_fr": "Royaume-Uni",
            "date": "1/3/2005",
            "Décile 1": 13.55694413,
            "Décile 5": 6.402068504,
            "Décile 9": 3.057193284
        },
        {
            "category": "Royaume-Uni-12/19/2016",
            "name_fr": "Royaume-Uni",
            "date": "12/19/2016",
            "Décile 1": 13.19564289,
            "Décile 5": 6.639341135,
            "Décile 9": 3.359725023
        }
    ];
    

    Create Guide array from data

    Before you plug the data into AmChart, if you don't want to hard code the Guide array, you can generate that from the data first.

    The idea here is to group by the data by name_fr, and then grab the first item category as the Category of the guide, and the last item category as the ToCategory of the guide.

    You can write your own JavaScript function to do group by, but here I am lazy and just want to use a library called underscore.js (https://underscorejs.org) to do so.

    let byName = _.groupBy(data, "name_fr");
    let guides = _.map(byName, function(items, key) {
        return {
            "category": _.first(items).category,
            "toCategory": _.last(items).category,
            "lineAlpha": 0,
            "expand": true,
            "label": key,
            "labelRotation": 0,
            "tickLength": 80
        };
    });
    

    Make the graph

    Then you can feed the data along with the guides into AmChart to make the graph.

    enter image description here

    fiddle: http://jsfiddle.net/davidliang2008/kp16Lv4a/