I want to generate a stacked bar chart like this. How can I achieve this? Any solution will be highly appreciated.
Asked
Active
Viewed 211 times
-2
-
Have you tried it ? Please post some code so that we can help you – theFrontEndDev Jun 01 '20 at 13:00
-
Yes, I have tried on it but not found any work around. Okay, I will be giving some code in this regard. Thank you very much. – Salahuddin Ahmed Jun 01 '20 at 13:33
-
Can you post the code , I can help you – theFrontEndDev Jun 01 '20 at 13:42
-
1@JithinB please check my code here in JSFiddle https://jsfiddle.net/sahmed/nk56awmx/6/ – Salahuddin Ahmed Jun 01 '20 at 14:28
-
Great ! you have a stacked bar chart implemented her. Now can I know the problem you are trying to solve ? – theFrontEndDev Jun 01 '20 at 14:36
-
@JithinB I would like to display the values in opposite directions making sure no overlap in case of very low value. I mean violet (Salary Plan) portion's value will be vertically placed bottom of the violet bar same way green (Expenses Plan) portion's value will be vertically placed on top of the green bar. Hope that I made you understand. – Salahuddin Ahmed Jun 01 '20 at 14:45
1 Answers
1
After some research and study, finally I got a way out regarding my problem I have posted here.
public static drawDashboard2Chart(data: Dashboard2Data[], canvas: ElementRef) {
const planProfit = data.map(dataUnit => dataUnit.p_profit);
const planExpenses = data.map(dataUnit => dataUnit.p_expenses);
const planSalary = data.map(dataUnit => dataUnit.p_salary);
const factProfit = data.map(dataUnit => dataUnit.f_profit);
const factExpenses = data.map(dataUnit => dataUnit.f_expenses);
const factSalary = data.map(dataUnit => dataUnit.f_salary);
const ctx = canvas.nativeElement.getContext('2d');
const dataArray = [
{
label: 'REVENUES PLAN',
backgroundColor: '#d14035',
hoverBackgroundColor: '#d14035',
stack: '0',
data: planProfit,
datalabels: {
color: '#d14035',
}
},
{
label: 'SALARY PLAN',
backgroundColor: '#72598e',
hoverBackgroundColor: '#72598e',
stack: '1',
data: planSalary,
datalabels: {
color: '#72598e',
}
},
{
label: 'EXPENSES PLAN',
backgroundColor: '#a9bb30',
hoverBackgroundColor: '#a9bb30',
stack: '1',
data: planExpenses,
datalabels: {
color: '#a9bb30',
}
},
{
label: 'ACTUAL REVENUES',
backgroundColor: '#05a6a6',
hoverBackgroundColor: '#05a6a6',
stack: '2',
data: factProfit,
datalabels: {
color: '#05a6a6',
}
},
{
label: 'ACTUAL SALARY',
backgroundColor: '#c2718c',
hoverBackgroundColor: '#c2718c',
stack: '3',
data: factSalary,
datalabels: {
color: '#c2718c',
}
},
{
label: 'ACTUAL EXPENSES',
backgroundColor: '#eb8a3c',
hoverBackgroundColor: '#eb8a3c',
stack: '3',
data: factExpenses,
datalabels: {
color: '#eb8a3c',
}
}
]
const options = {
responsive: true,
maintainAspectRatio: false,
hover: {
animationDuration: 0
},
plugins: {
datalabels: {
display: true,
align: 'center',
anchor: 'center',
font: {
size: '18',
weight: '700'
},
rotation: 270,
formatter: function (value, context) {
return value !== 0 ? value : null;
}
}
},
legend: {
onClick: (e) => e.stopPropagation(),
display: true,
position: 'top',
labels: {
fontFamily: '\'Montserrat\', sans-serif',
fontSize: 14,
fontColor: '#000'
}
},
tooltips: {
callbacks: {
label: function (tooltipItem, data) {
return tooltipItem.yLabel.toFixed().replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1 ');
}
}
},
scales: {
xAxes: [{
stacked: true,
ticks: {
fontSize: 15,
fontStyle: 'normal',
padding: 100
}
},
{
type: 'category',
offset: true,
position: 'top',
ticks: {
fontColor: "#000",
fontSize: 18,
fontStyle: 'bold',
callback: function (value, index, values) {
return "";
}
}
}
],
yAxes: [{
stacked: true,
ticks: {
fontSize: 15,
fontStyle: 'normal'
},
}],
},
animation: {
duration: 1,
onComplete: function () {
var chartInstance = this.chart,
ctx = chartInstance.ctx;
var fontSize = 15;
var fontStyle = 'normal';
ctx.font = Chart.helpers.fontString(fontSize, fontStyle, Chart.defaults.global.defaultFontFamily);
ctx.textAlign = 'center';
ctx.textBaseline = 'center';
this.data.datasets.forEach(function (dataset, i) {
var meta = chartInstance.controller.getDatasetMeta(i);
meta.data.forEach(function (bar, index) {
if (dataset.data[index] > 0) {
if(dataset.stack == '0')
{
var data = dataset.data[index].toFixed().replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1 ');
ctx.save();
ctx.translate(bar._model.x, bar._model.y + bar.height());
ctx.rotate(0.5 * Math.PI);
ctx.fillText(data, 35, 0);
ctx.restore();
}
else if(dataset.stack == '1' && dataset.label == 'EXPENSES PLAN')
{
var data = dataset.data[index].toFixed().replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1 ');
ctx.save();
ctx.translate(bar._model.x, bar._model.y);
ctx.rotate(-0.5 * Math.PI);
ctx.fillText(data, 35, 0);
ctx.restore();
}
else if(dataset.stack == '1' && dataset.label == 'SALARY PLAN')
{
var data = dataset.data[index].toFixed().replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1 ');
ctx.save();
ctx.translate(bar._model.x, bar._model.y + bar.height());
ctx.rotate(0.5 * Math.PI);
ctx.fillText(data, 35, 0);
ctx.restore();
}
else if(dataset.stack == '2')
{
var data = dataset.data[index].toFixed().replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1 ');
ctx.save();
ctx.translate(bar._model.x, bar._model.y + bar.height());
ctx.rotate(0.5 * Math.PI);
ctx.fillText(data, 35, 0);
ctx.restore();
}
else if(dataset.stack == '3' && dataset.label == 'ACTUAL EXPENSES')
{
var data = dataset.data[index].toFixed().replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1 ');
ctx.save();
ctx.translate(bar._model.x, bar._model.y);
ctx.rotate(-0.5 * Math.PI);
ctx.fillText(data, 35, 0);
ctx.restore();
}
else if(dataset.stack == '3' && dataset.label == 'ACTUAL SALARY')
{
var data = dataset.data[index].toFixed().replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1 ');
ctx.save();
ctx.translate(bar._model.x, bar._model.y + bar.height());
ctx.rotate(0.5 * Math.PI);
ctx.fillText(data, 35, 0);
ctx.restore();
}
}
});
});
}
}
}
new Chart(ctx, {
type: "bar",
data: {
labels: MONTHS,
datasets: dataArray
},
options: options
});
}

Salahuddin Ahmed
- 4,854
- 4
- 14
- 35