Reputation: 5059
Input data
Engine,Car,Brand,Efficiency
ABC212,Toyota Corolla,Toyota,1.95
ABC212,Toyota Yaris,Toyota,1.94
ABC212,Totyota Etios,Toyota,1.93
ABC212,Honda City,Honda,1.93
ABC212A,Honda Brio,Honda,1.91
DEF311,Toyota Camry,Toyota,1.90
DEF310,Toyota Prius,Toyota,1.82
DEF310,Ford Explorer,Ford,1.85
DEF310,Ford Endeavour,Ford,1.83
DEF305,Ford Fugo,Ford,1.79
With data like above, I need to create a chart in ChartJs
with multi-level x-axes. An expected output created using MS excel pivot chart is as below. Here the efficiency of each model is plotted as a bar. Bars in each group is sorted in the descending order of the efficiency value. How should I create the data for this kind of chart ?
Upvotes: 6
Views: 3678
Reputation: 10828
Without being confident that this is the simplest solution, I provide some example where I use a second axis, containing labels for the groups, but in a scaled-up array, for correct alignment.
The only problem is that if you enable rotation for the group maxRotation>0
, the text will always be rotated, since (due to scaling) it is bound to a very small area.
https://jsfiddle.net/h6z4apvo/
var myData = [
["ABC212","Toyota Corolla","Toyota",1.95],
["ABC212","Toyota Yaris","Toyota",1.94],
["ABC212","Totyota Etios","Toyota",1.93],
["ABC212","Honda City","Honda",1.93],
["ABC212A","Honda Brio","Honda",1.91],
["DEF311","Toyota Camry","Toyota",1.90],
["DEF310","Toyota Prius","Toyota",1.82],
["DEF310","Ford Explorer","Ford",1.85],
["DEF310","Ford Endeavour","Ford",1.83],
["DEF305","Ford Fugo","Ford",1.79]
];
/*Calculates group labels to a scaled array so that they can align better*/
function calculateGroupLabels(data){
const scaleFactor=100;
var labels = _(data)
.groupBy((elem)=>elem[0])
.map((entriesOnSameGroup, key)=>{
var newSize = entriesOnSameGroup.length*scaleFactor;
var newArray = new Array(newSize);
newArray[0]="";
newArray[newArray.length-1]="";
newArray[parseInt((newArray.length-1)/2)]=key;
return newArray;
}).flatten().value()
return labels;
}
var labels = calculateGroupLabels(myData);
var ctx = $("#c");
var myChart = new Chart(ctx, {
type: 'bar',
data: {
datasets: [{
label: '# of Votes',
xAxisID:'modelAxis',
data: myData.map((entry)=>entry[3])
}]
},
options:{
scales:{
xAxes:[
{
id:'modelAxis',
type:"category",
ticks:{
//maxRotation:0,
autoSkip: false,
callback:function(label, x2, x3, x4){
console.log("modelAxis", label, x2, x3, x4)
return label;
}
},
labels:myData.map((entry=>entry[1]))
},
{
id:'groupAxis',
type:"category",
gridLines: {
drawOnChartArea: false,
},
ticks:{
padding:0,
maxRotation:0,
autoSkip: false,
callback:function(label){
return label;
}
},
labels:labels
}],
yAxes:[{
ticks:{
beginAtZero:true
}
}]
}
}
});
Upvotes: 0
Reputation: 1165
I have made such graph in my POC , where I used :
data: {
labels: ["ABC212", "ABC212A",...],
datasets: [
{
label: "ABC212",
data: [val1, val2,....]
}, {
label: "ABC212A",
data: [val3, val4,...]
}
]
}
Upvotes: 1