需求分析:
在使用echarts堆叠柱状图的时候,常规堆叠柱状图每条柱子的堆叠种类是相同的,在开发中遇到了这样的一个需求:有多个分公司,每个公司污染物类型差距很大,有些公司有这几个污染物,有些公司又没有这几个污染物,这就导致堆叠的时候echarts的series堆叠的种类以及数据无法对应到每一个公司,用echarts现有的堆叠柱状图无法满足,所以吭哧吭哧鼓捣了一早上,最终还是实现了这个需求。以下直接上效果照片和代码,有啥不懂的欢迎邮箱交流指教(weijianpeng18421@outlook.com)
。
贴一下图片效果:
贴一下上图中的代码:代码中用了假数据jsonData,后续自己改成通过接口获取的,这是一个完整的vue脚本,直接全部复制过去就能运行,没有引其他东西,页面不会报错,放心使用。
//页面创建的时候获取code(第一次获取不到,第二次进入页面时通过重定向的方式会携带过来)
<template>
<div>
<div id="myChartOne" style="height: 600px;margin-top: 20px;"/>
</div>
</template>
<script>
export default {
data() {
return {
jsonData: [
{
"pollutantVoList": [
{
"pollutantCode": "CODE001",
"pollutantValue": "120",
"pollutantName": "除尘灰"
},
{
"pollutantCode": "CODE002",
"pollutantValue": "144.6",
"pollutantName": "垃圾"
},
{
"pollutantCode": "CODE003",
"pollutantValue": "901.3",
"pollutantName": "炉渣"
}
],
"company": "铸铁事业部(银川)"
},
{
"pollutantVoList": [
{
"pollutantCode": "CODE001",
"pollutantValue": "30",
"pollutantName": "除尘灰"
},
{
"pollutantCode": "CODE003",
"pollutantValue": "12.0",
"pollutantName": "炉渣"
},
{
"pollutantCode": "CODE004",
"pollutantValue": "72.0",
"pollutantName": "熔炼废砖"
},
{
"pollutantCode": "CODE006",
"pollutantValue": "0.0",
"pollutantName": "熔炼垃圾"
},
],
"company": "共享铸钢"
},
{
"pollutantVoList": [
{
"pollutantCode": "CODE002",
"pollutantValue": "999",
"pollutantName": "垃圾"
}
],
"company": "共享智能装备"
},
{
"pollutantVoList": [
{
"pollutantCode": "CODE008",
"pollutantValue": "15",
"pollutantName": "固体废弃物"
}
],
"company": "共享(潍坊)中心"
},
{
"pollutantVoList": null,
"company": "苏州共享"
}
],
commonTooltip: {
confine: true,//限制tooltip在图表内显示
formatter: function (params) { // 提示内容太多隔行显示内容
let newList = []//去除null的数据
newList = params.filter(item => {
if (item.data !== null && item.data !== undefined) {
return item
}
})
let astr = ''
let isBig = newList.length > 9
newList.forEach((ele, index) => {
astr += `<div style="display: block;height:20px;${index % 2 === 0 ? 'width: ' + (isBig ? '33.33' : '100') + '%;' : 'width: ' + (isBig ? '33.33' : '100') + '%;'}float:left;">
<i style="width: 10px;height: 10px;display: inline-block;background: ${ele.color};border-radius: 10px;"></i>
<span>${ele.seriesName}: ${ele.data}</span>
</div>`
})
return '<div style="width:' + (isBig ? '50' : '') + 'vw;">' + astr + '<div>'
},
}
}
},
created() {
},
mounted() {
this.onChangeOneDate()
},
methods: {
onChangeOneDate() {
let company = this.jsonData//正常应该是用过接口获取到的,这里用假数据模拟。
let xData = []
let ySeriesData = []
let baseStack = []//去重
if (company) {
company.map(com => {//找到所有公司下所有的污染物(每条污染物不重复,用来遍历初始化echarts的series)
if (com.hasOwnProperty('pollutantVoList') && com.pollutantVoList) {
com.pollutantVoList.map(pollutant => {
let has = false//查重
baseStack.find(stack => {
if (stack.pollutantCode === pollutant.pollutantCode) {
has = true
}
})
!has && baseStack.push(pollutant)
})
}
xData.push(com.company)
})
let seriesDataList = []
baseStack.map((base, bIndex) => {//设置每个公司的污染物数据dataList
let obj = {
name: base.pollutantName,
code: base.pollutantCode,
dataList: []
}
company.map((com, cIndex) => {
if (com.pollutantVoList) {
com.pollutantVoList.map((pollutant, pIndex) => {
if (pollutant.pollutantCode === base.pollutantCode) {
obj.dataList[cIndex] = pollutant.pollutantValue
}
})
}
if (!obj.dataList[cIndex]) {
obj.dataList[cIndex] = null
}
})
seriesDataList.push(obj)
})
seriesDataList.forEach(item => {//设置echarts的series数据
let objRealSeries = {
name: item.name,
type: 'bar',
stack: 'stack',
tooltip: {
valueFormatter: function (value) {
return value + ' 条';
}
},
barWidth: '18%',
data: item.dataList,
}
ySeriesData.push(objRealSeries)
})
this.chartInitOne(xData, ySeriesData)
}
},
chartInitOne(xData, ySeriesData) {
const myChart = this.$echarts.init(document.getElementById('myChartOne'))
myChart.setOption({
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
},
...this.commonTooltip,//这里会将代码148行设置为null的数据筛选掉不显示在tooltip中
},
legend: {
type: 'scroll', //数据(公司)过多时分页显示legend
containLabel: true
},
toolbox: {
show: true,
orient: 'vertical',
left: 'right',
top: 'center',
feature: {
dataZoom: {
yAxisIndex: 'none'
},
dataView: {readOnly: false},
magicType: {type: ['line', 'bar']},
restore: {},
saveAsImage: {}
}
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: [
{
type: 'category',
data: xData,
}
],
yAxis: [
{
type: 'value'
}
],
series: [
...ySeriesData,
]
}
)
window.addEventListener('resize', () => {
if (myChart) {
myChart.resize()
}
})
},
}
}
</script>
结束--->下班下班--------------------------->>>回家回家