blob: 7a4e8dc1bf99e97d263aa8ab9c70c7dcffc73df0 [file]
/*
title: Stacked Bar Normalization and Variation
titleCN: 堆叠柱状图的归一化和变化
category: bar
difficulty: 3
*/
// There should not be negative values in rawData
const rawData = [
[100, 302, 301, 334, 390, 330, 320],
[320, 132, 101, 134, 90, 230, 210],
[220, 182, 191, 234, 290, 330, 310],
[150, 212, 201, 154, 190, 330, 410],
[820, 832, 901, 934, 1290, 1330, 1320]
];
const totalData: number[] = [];
for (let i = 0; i < rawData[0].length; ++i) {
let sum = 0;
for (let j = 0; j < rawData.length; ++j) {
sum += rawData[j][i];
}
totalData.push(sum);
}
const grid = {
left: 100,
right: 100,
top: 50,
bottom: 50
};
const gridWidth = myChart.getWidth() - grid.left - grid.right;
const gridHeight = myChart.getHeight() - grid.top - grid.bottom;
const categoryWidth = gridWidth / rawData[0].length;
const barWidth = categoryWidth * 0.6;
const barPadding = (categoryWidth - barWidth) / 2;
const series: echarts.BarSeriesOption[] = [
'Direct',
'Mail Ad',
'Affiliate Ad',
'Video Ad',
'Search Engine'
].map((name, sid) => {
return {
name,
type: 'bar',
stack: 'total',
barWidth: '60%',
label: {
show: true,
formatter: (params: any) => Math.round(params.value * 1000) / 10 + '%'
},
data: rawData[sid].map((d, did) =>
totalData[did] <= 0 ? 0 : d / totalData[did]
)
};
});
const color = [
'#5070dd',
'#b6d634',
'#505372',
'#ff994d',
'#0ca8df'
];
const elements = [];
for (let j = 1, jlen = rawData[0].length; j < jlen; ++j) {
const leftX = grid.left + categoryWidth * j - barPadding;
const rightX = leftX + barPadding * 2;
let leftY = grid.top + gridHeight;
let rightY = leftY;
for (let i = 0, len = series.length; i < len; ++i) {
const points = [];
const leftBarHeight = (rawData[i][j - 1] / totalData[j - 1]) * gridHeight;
points.push([leftX, leftY]);
points.push([leftX, leftY - leftBarHeight]);
const rightBarHeight = (rawData[i][j] / totalData[j]) * gridHeight;
points.push([rightX, rightY - rightBarHeight]);
points.push([rightX, rightY]);
points.push([leftX, leftY]);
leftY -= leftBarHeight;
rightY -= rightBarHeight;
elements.push({
type: 'polygon',
shape: {
points
},
style: {
fill: color[i],
opacity: 0.25
}
});
}
}
option = {
legend: {
selectedMode: false
},
grid,
yAxis: {
type: 'value'
},
xAxis: {
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
},
series,
graphic: {
elements
}
};
export {};