Echarts 堆叠柱状图实现
后端返回数据形式:
{
"success": true,
"message": "成功",
"code": "0",
"data": {
"A": {
"aa": 123456,
"bb": 102568,
"cc": 100234,
"dd": 100004
},
"B": {
"aa": 123456,
"bb": 102568,
"cc": 100234
},
"C": {
"aa": 123456,
"dd": 100004
},
"D": {
"dd": 100004
},
"E": {
"aa": 123456,
"bb": 102568,
"dd": 100004
},
"F": {
"aa": 123456,
"bb": 102568
}
}
}
图样
vue 代码
<div id="itemLabel" style="width: 100%;height:300px;"></div>
itemStageLabel :后端返回数据源
barItemLabelCharts() {
let ks;
const orgData = this.itemStageLabel;
const xAxisData = [];
const orgList = [];
const orgCount = {};
for (const org in orgData) {
xAxisData.push(org);
const odata = orgData[org];
let num = 0;
for (const ks in odata) {
num++;
if (orgList.indexOf(ks) == -1) {
orgList.push(ks);
}
}
orgCount[org] = num;
}
const dataMap = {};
let count = 0;
for (const org in orgData) {
;
const odata = orgData[org];
let preOrg = undefined;
let preCount = 0;
for (ks in odata) {
if (dataMap[ks] == undefined) {
dataMap[ks] = [];
}
preCount += this.checkEmpty(orgList, preOrg, ks);
dataMap[ks].push([count, count + 1, odata[ks], ks, preCount, orgCount[org]]);
preOrg = ks;
}
count++;
}
const series = [];
for (const d in orgList) {
ks = orgList[d];
const ds = dataMap[ks];
series.push({
data: ds,
type: 'bar',
renderItem: this.renderItem,
stack: "1",
encode: {
x: [0, 10],
y: 2,
tooltip: [3, 2],
itemName: 5
}
});
}
const option = {
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
},
confine: true,
enterable: true, // 鼠标是否可进入提示框浮层中
hideDelay: 200, // 浮层隐藏的延迟
// appendToBody: true
backgroundColor: 'rgba(0,0,0,0.6)',
formatter: function (params) {
let htmlStr = '<div style="height: auto;max-height: 240px;overflow-y: auto;"><p>' + params[0].axisValue + '</p>';
for (let i = 0; i < params.length; i++) {
htmlStr += '<p style="color: #fff;">' + params[i].marker + params[i].data[3] + ':'+" " + params[i].data[2].toLocaleString()+ '</p>';
}
htmlStr += '</div>'
return htmlStr
},
extraCssText: 'box-shadow: 0 0 3px rgba(150,150,150, 0.7);',
textStyle: {
fontSize: 16,
color: '#fff'
}
},
// legend: {
// type: 'scroll',
// orient: 'horizontal',
// left: 15,
// right: 15,
// bottom: 10,
// // data: this.itemStageLabel,
// pageButtonPosition: 'end'
// },
xAxis: {
type: 'category',
data: xAxisData,
boundaryGap: true,
axisTick: {
show: false
},
axisLine: {
show: true,
lineStyle: {
color: "#eeeeee"
}
},
axisLabel: {
//坐标轴刻度标签
inside: false,
textStyle: {
color: "#999",
fontWeight: "normal",
fontSize: "12"
}
},
splitArea: {
show: false
}
},
yAxis: {
type: 'value',
axisTick: {
show: false,
},
axisLine: {
show: true,
lineStyle: {
color: "#eeeeee",
},
},
splitLine: {
show: false,
lineStyle: {
color: "#32346c ",
},
},
axisLabel: {
textStyle: {
color: "#bac0c0",
fontWeight: "normal",
fontSize: "12",
},
formatter: "{value}",
},
},
series: series
};
const dom = $('#itemLabel')[0];
const ec = this.$echarts.init(dom);
ec.setOption(option, true);
},
checkEmpty(orgList, preOrg, curOrg) {
if (preOrg == undefined) {
return orgList.indexOf(curOrg);
} else {
return orgList.indexOf(curOrg) - orgList.indexOf(preOrg) - 1;
}
},
renderItem(params, api) {
const yValue = api.value(2);
const start = api.coord([api.value(0), yValue]);
const size = api.size([api.value(1) - api.value(0), yValue]);
const style = api.style();
const barWidth = 10;
const emptyCount = api.value(4);
let d = 0;
if (emptyCount > 0) {
d = -barWidth * emptyCount;
}
const barNum = api.value(5);
const p = [-barNum * barWidth / 2, 0];
return {
type: 'rect',
position: p,
shape: {
x: start[0] + params.seriesIndex * barWidth + d,
y: start[1],
width: barWidth,
height: size[1]
},
style: style
};
}