[Chartjs]-AmCharts: Clustered bar chart with sub-categories

5đź‘Ť

âś…

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/

0đź‘Ť

i have resloved Clustered bar chart with sub-categories problem
i have developed Clustered bar chart with sub categories as Years – 200X and P1, P2….

https://jsfiddle.net/amantandon1/09d3f8cr/33/

/**
 * ---------------------------------------
 * This demo was created using amCharts 4.
 * 
 * For more information visit:
 * https://www.amcharts.com/
 * 
 * Documentation is available at:
 * https://www.amcharts.com/docs/v4/
 * ---------------------------------------
 */

// Themes begin
am4core.useTheme(am4themes_animated);
// Themes end

// Create chart instance
var chart = am4core.create("chartdiv", am4charts.XYChart);

// Add data
chart.data = [ {
  "year": "2003",
  "P1":0,
  "P2":0,
  "p3":0,
  "namerica-p1": 3.0,
  "namerica-p3": 6.7,
  "asia-p1": 4.2,
  "asia-p2": 3.2,
  "africa-p3": 5.1
}, {
  "year": "2004",
  "P1":0,
  "P2":0,
  "p3":0,
  "namerica-p1": 2.7,
  "namerica-p2": 4.7,
  "asia-p1": 2.2,
  "asia-p3": 5.2,
  "africa-p1": 3.1
}, {
  "year": "2005",
  "P1":0,
  "P2":0,
  "p3":0,
  "namerica-p1": 1.7,
  "namerica-p2": 2,
  "namerica-p3": 3.9,
  "asia-p1": 8.2,
  "asia-p2": 11,
  "asia-p3": 13,
  "africa-p3": 15.1
},{
  "year": "2006",
  "P1":0,
  "P2":0,
  "p3":0,
  "namerica-p1": 3.0,
  "namerica-p3": 6.7,
  "asia-p1": 4.2,
  "asia-p2": 3.2,
  "africa-p3": 5.1
}, {
  "year": "2007",
  "P1":0,
  "P2":0,
  "p3":0,
  "namerica-p1": 2.7,
  "namerica-p2": 4.7,
  "asia-p1": 2.2,
  "asia-p3": 5.2,
  "africa-p1": 3.1
}, {
  "year": "2008",
  "P1":0,
  "P2":0,
  "p3":0,
  "namerica-p1": 1.7,
  "namerica-p2": 2,
  "namerica-p3": 3.9,
  "asia-p1": 8.2,
  "asia-p2": 11,
  "asia-p3": 13,
  "africa-p3": 15.1
},{
  "year": "2009",
  "P1":0,
  "P2":0,
  "p3":0,
  "namerica-p1": 3.0,
  "namerica-p3": 6.7,
  "asia-p1": 4.2,
  "asia-p2": 3.2,
  "africa-p3": 5.1
}, {
  "year": "2010",
  "P1":0,
  "P2":0,
  "p3":0,
  "namerica-p1": 2.7,
  "namerica-p2": 4.7,
  "asia-p1": 2.2,
  "asia-p3": 5.2,
  "africa-p1": 3.1
}, {
  "year": "2011",
  "P1":0,
  "P2":0,
  "p3":0,
  "namerica-p1": 1.7,
  "namerica-p2": 2,
  "namerica-p3": 3.9,
  "asia-p1": 8.2,
  "asia-p2": 11,
  "asia-p3": 13,
  "africa-p3": 15.1
}];

// Create axes
var categoryAxis = chart.xAxes.push(new am4charts.CategoryAxis());
 
categoryAxis.dataFields.category = "year";
categoryAxis.renderer.grid.template.location = 0;
categoryAxis.renderer.minGridDistance = 20;
categoryAxis.renderer.inside = true;
categoryAxis.renderer.labels.template.valign = "top";
categoryAxis.renderer.labels.template.fontSize = 12;
categoryAxis.renderer.cellStartLocation = 0.1;
categoryAxis.renderer.cellEndLocation = 0.9;

var  valueAxis = chart.yAxes.push(new am4charts.ValueAxis());
valueAxis.min = 0;
valueAxis.max = ("{valueY.Total}" + '50');

// Create series
function createSeries(field, name, stacked, a) {

    var dValue = a != undefined ? a : "{valueY}"; 
  var series = chart.series.push(new am4charts.ColumnSeries());
  series.dataFields.valueY = field;
  series.dataFields.categoryX = "year";
  series.name = name;
  series.columns.template.tooltipText = "{name}: [bold]{valueY}[/]";
  // series.fill = "rgba(220,220,220,0.1)";
   // series.fill = 0;
//  series.fill = 'blue';
  series.stacked = stacked;
  

  series.columns.template.width = am4core.percent(95);
  
  var bullet = series.bullets.push(new am4charts.LabelBullet());
  bullet.label.text = dValue;
  //bullet.label.rotation = 90;
  bullet.label.truncate = false;

  bullet.label.hideOversized = false;
  bullet.label.vertical = "bottom";
  bullet.locationY = 0;
  bullet.locationY = 0;
  bullet.dy = 8;
  bullet.label.fontSize = 8;
  
  
}
 
  
var series1 = createSeries("P1", "Advento", false, "P1");

var series3 = createSeries("namerica-p1", "Noth America", true);
var series2 = createSeries("asia-p1", "Asia", true);
var series4 = createSeries("africa-p1", "Africa", true);

var series1 = createSeries("P2", "Xmplex", false, "P2");

var series3 = createSeries("namerica-p2", "Noth America", true);
var series2 = createSeries("asia-p2", "Asia", true);
var series4 = createSeries("africa-p2", "Africa", true);

var series1 = createSeries("p3", "ASC", false, "P3");
var series3 = createSeries("namerica-p3", "Noth America", true);
var series2 = createSeries("asia-p3", "Asia", true);
var series4 = createSeries("africa-p3", "Africa", true);
var series4 = createSeries("asia-p2", "Asia", true);

var series1 = createSeries("p3", "ASC", false, "P3");
var series3 = createSeries("namerica-p3", "Noth America", true);
var series2 = createSeries("asia-p3", "Asia", true);
var series4 = createSeries("africa-p3", "Africa", true);
var series4 = createSeries("asia-p2", "Asia", true);

var series1 = createSeries("p3", "ASC", false, "P3");
var series3 = createSeries("namerica-p3", "Noth America", true);
var series2 = createSeries("asia-p3", "Asia", true);
var series4 = createSeries("africa-p3", "Africa", true);
var series4 = createSeries("asia-p2", "Asia", true);


chart.maskBullets = false;
chart.height = 400;


// Add legend
chart.legend = new am4charts.Legend();
chart.legend.position = 'bottom';
chart.legend.fontSize = 9;
chart.legend.dy = 14;
//chart.legend.maxHeight = 200;
chart.legend.scrollable = true;
chart.legend.itemContainers.template.clickable = false;
chart.legend.itemContainers.template.focusable = false;
chart.legend.data = [
    {"name":'Asia',"fill":'red'},
  {"name":'North America',"fill":'blue'},
  {"name":'Africa',"fill":'green'}
];
body {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
}

#chartdiv {
  width: 100%;
  height: 500px;
}

#chartdiv {
    width   : 100%;
    height  : 500px;
}
                                        
<script src="https://cdn.amcharts.com/lib/4/core.js"></script>
<script src="https://cdn.amcharts.com/lib/4/charts.js"></script>
<script src="https://cdn.amcharts.com/lib/4/themes/animated.js"></script>


<script src="//www.amcharts.com/lib/3/amcharts.js"></script>
<script src="//www.amcharts.com/lib/3/serial.js"></script>
<script src="//www.amcharts.com/lib/3/themes/light.js"></script>

<script src="https://www.amcharts.com/lib/3/plugins/export/export.min.js"></script>
<link rel="stylesheet" href="https://www.amcharts.com/lib/3/plugins/export/export.css" type="text/css" media="all" />
<div id="chartdiv">
  
  
</div>                                                                                  

i have added custom legends for colors you can create custom color

Leave a comment