问题
I've created a vertical stacked bar chart with Baidu ECharts.
Is it possible to show the sum of all values on top of the stack?
Edited : i have edited my example using the (very well explained) answer from @jeffrey but i get Uncaught TypeError: Cannot read property 'forEach' of undefined error. What am i doing wrong here ?
<!DOCTYPE html>
<html style="height: 100%">
<head>
<meta charset="utf-8">
</head>
<body style="height: 100%; margin: 0">
<div id="container" style="height: 100%"></div>
<script type="text/javascript" src="echarts-en.min.js"></script>
<script type="text/javascript">
var mySeries = [
{
name: 'Department 1',
type: 'bar',
stack: 'stack1',
data: [320, 302, 301, 334, 390, 330, 320]
},
{
name: 'Department 2',
type: 'bar',
stack: 'stack1',
data: [120, 132, 101, 134, 90, 230, 210]
},
{
name: 'Department 3',
type: 'bar',
stack: 'stack1',
data: [220, 182, 191, 234, 290, 330, 310]
},
{
name: 'Department 4',
type: 'bar',
stack: 'stack1',
data: [150, 212, 201, 154, 190, 330, 410]
},
{
name: 'Department 5',
type: 'bar',
stack: 'stack1',
data: [185, 120, 55, 66, 77, 88, 40],
label: {
normal: {
show: true,
position: 'top',
formatter: (params) => {
let total = 0;
this.series.forEach(serie => {
total += serie.data[params.dataIndex];
})
return total;
}
}
}
}
];
var dom = document.getElementById("container");
var myChart = echarts.init(dom);
var option = null;
option = {
tooltip : {
trigger: 'axis',
axisPointer : {
type : 'shadow'
}
},
legend: {
data: ['Department 1', 'Department 2','Department 3','Department 4','Department 5'],
},
toolbox: {
show: true,
orient: 'vertical',
left: 'right',
top: 'center',
feature: {
dataView: {show: false, readOnly: false},
magicType: {show: true, type: ['line', 'bar', 'stack', 'tiled']},
restore: {show: true},
saveAsImage: {show: true}
}
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
yAxis: {
type: 'value'
},
xAxis: {
type: 'category',
data: ["Jen\n2018", "Feb\n2018", "Mar\n2018", "Apr\n2018", "May\n2018", "Jun\n2018", "Jul\n2018"]
}
};;
myChart.setOption(option, true);
myChart.setOption({
series: mySeries
})
</script>
</body>
</html>
回答1:
To get a custom serie label you should use the label formatter.
When you define your series data outside of your chart object, and map it to this
, you can access the data in the formatter. It is important to use the formatter, so the original label and values will not be altered (such as tooltips and legends).
First, we define your series. The formatter should be added to the last serie. This will be the serie on top of the stack, showing the label with the total value:
this.mySeries = [
{
name:'Dataset 1',
type:'bar',
stack: 'Stack 1',
data: [120, 132, 101, 134, 90, 230, 210]
},
{
name:'Dataset 2',
type:'bar',
stack: 'Stack 1',
data: [220, 182, 191, 234, 290, 330, 310]
},
{
name:'Dataset 3',
type:'bar',
stack: 'Stack 1',
data: [820, 932, 901, 934, 1290, 1330, 1320],
label: {
normal: {
show: true,
position: 'top',
formatter: (params) => {
let total = 0;
this.mySeries.forEach(serie => {
total += serie.data[params.dataIndex];
})
return total;
}
}
}
}
];
Here is the formatter again with annotations, so you can understand how this works:
label: {
// You can choose from 'normal' (always visible )
// and 'emphasis' (only visible on stack hover)
normal: {
// Enable the label
show: true,
// Position it on top of the stack
position: 'top',
// Add a label formatter
// (params) holds all the data of the current serie and datapoint
// You can use console.log(params) to check all available values
formatter: (params) => {
let total = 0;
// Now we iterate over each of the series, and get the value of
// the current xAxis datapoint by using the serie dataIndex
this.mySeries.forEach(serie => {
total += serie.data[params.dataIndex];
})
// The return value will be shown on top of your stack
return total;
}
}
}
Now, all you have to do is map the series data to your chart object:
myChart.setOption({
series: this.mySeries
})
回答2:
Please see this answer, it helped me a lot, and I did a little simplification in the code, nothing relevant. I found the explanation easier. Basically you will use the formatter attribute inside the label, with some specifications
serie example
let series = [
{
name: 'Reclamação',
data: this.relatos_tipo_y.R,
},
{
name: 'Elogio',
data: this.relatos_tipo_y.E,
},
{
name: 'Sugestão',
data: this.relatos_tipo_y.S,
},
{
name: 'Denúncia',
data: this.relatos_tipo_y.D,
},
];
function for formatter
genFormatter = (series) => {
return (param) => {
console.log(param);
let sum = 0;
series.forEach(item => {
sum += item.data[param.dataIndex];
});
return sum
}
};
inside your chart options place this
series: series.map((item, index) => Object.assign(item, {
type: 'bar',
stack: true,
label: {
show: index === series.length - 1,
formatter: genFormatter(series),
fontSize: 20,
color: 'black',
position: 'top'
},
})),
Click Here
It's very similar to the other answer, but I find it easier to understand the code.
来源:https://stackoverflow.com/questions/49114475/show-the-sum-of-data-values-on-top-of-stacked-bar-chart-using-baidu-echarts