这里写目录标题
- 需求背景
- 图表展示
- X轴鼠标滑动或者缩放设置
- 多列柱状图中某一列数据为0时不占位
- 图表代码展示
需求背景
- 用柱状图展示12个月的项目对应的供应商数据;
- 每个月有多个项目不确定,1-50之间,也就是说,12个月,每个月的X轴上有不确定的柱状;例如:1月有20根柱子,2月有5根柱子,3月有15根…
- 每月的每根柱子代表是一个项目,鼠标移入每月的每一个项目的柱子上要悬浮展示该月该项目具体供应商的情况;
当时听了这个需求,我就很不解,这数据都是不确定的,咋展示,如果只展示一个月的数据还可以,然后通过按钮去选择月份渲染,展示一年的数据,就有点小复杂啦;
图表展示
X轴数据那么多,还不确定,只能看卡能不能实现滑动,结果还真能,那就好办啦,
当然肯定还是实现啦,先把实现图表展示一下,如下图:
图表上的数据也是自己随意mock的,由于柱子数量布丁,颜色也是随机的,这些都不要在意不要,重点是图表的实现;
以上是图表主要涉及到知识点有:
1.X轴鼠标滑动或者缩放、
2.多列柱状图中其中某一列数据为0时不占位
X轴鼠标滑动或者缩放设置
dataZoom : [{
type: 'slider',//给x轴设置滚动条
show: true, //flase直接隐藏图形
xAxisIndex: [0,1,2,3,4,5,6,7,8,9,10,11],
bottom:5,
height:15,
showDetail: true,
startValue: 0,//滚动条的起始位置
endValue: 4 //滚动条的截止位置(按比例分割你的柱状图x轴长度)
},
{
type: 'inside',//设置鼠标滚轮缩放
disabled: true,
xAxisIndex: [0,1,2,3,4,5,6,7,8,9,10,11],
startValue: 0,
endValue: 4
}],
多列柱状图中某一列数据为0时不占位
正常多列柱状图,某一列数据为0时,是不显示的,但是还是会占位的,如下图:
很明显这样是很难看的,我们如要遍历然后过滤掉value值为0的柱子,把有值的柱形数据塞到 series 中,但是要配合xAxis 数据,所以我们重新格式化了一下xAxis 和 series ,方法如下图:
let xAxis=[]
let xAxisitem={
type: 'category',
data: '',
position: 'bottom',
axisTick: {
show: true
},
}
var emphasisStyle = {
itemStyle: {
shadowBlur: 10,
shadowColor: 'rgba(0,0,0,0.3)'
}
};
let xAxisitemdata=[]
for (let i = 0; i < valueData.length ; i++) {
xAxisitemdata=[]
for (let i = 0; i < valueData.length ; i++) {
xAxisitemdata.push('')
}
xAxisitemdata[i]=valueData[i].name
xAxisitem.data=JSON.parse(JSON.stringify(xAxisitemdata))
xAxis.push(JSON.parse(JSON.stringify(xAxisitem)))
}
// console.log("xAxis",xAxis)
let series=[]
for (let j = 0; j < valueData.length; j++) {
for (let i = 0; i < valueData[j].data.length; i++) {
let newArrList = [];
for (let a = 0; a < j; a++) {
newArrList.push({});
}
newArrList[j] = valueData[j].data[i];
for (let k = 0; k < legenddata.length; k++) {
let seriesitem={
type: 'bar',
name:legenddata[i],
barWidth: '10',
xAxisIndex: j,
emphasis: emphasisStyle,
itemStyle:{
barBorderRadius: [5, 5, 0, 0],//(顺时针左上,右上,右下,左下)
},
data: newArrList,
}
let a = j % legenddata.length;
if((valueData[j].data[i]).value !==0 && k===a){
series.push(JSON.parse(JSON.stringify(seriesitem)))
}
}
}
}
//console.log("series",series)
打印的xAxis 如下图:
注意看红框标记的,每月的data,只有当月显示,其他月为空;
打印的series如下图:
12个月,按10个项目,正常数据应该有120个,这里只有81个,就是所有有值的柱子的集合,把值为0的已经过滤掉,不显示,这样就不会炸图表中占位;
图表代码展示
下面我们就把上面图表的实现代码展示出来,开袋即食!
<template>
<div id="myChartFour" style="height: 260px;"></div>
</template>
<script>
import Vue from 'vue'
export default {
data(){
return{
echartData:[]
}
},
mounted(){
this.getEchartData()
},
methods:{
getEchartData(){
Vue.axios.get('/getReportDataFour', {}).then(res => {
if(res.status == 200){
this.echartData = res.data.datalist
this.initEchart(this.echartData)
}
})
},
initEchart(valueData) {
var chartDom = document.getElementById('myChartFour');
var myChart = this.$echarts.init(chartDom);
let legenddata = []
var singleData
var dateLength = 0
valueData.forEach(item => {
if(item.data.length > dateLength){
singleData = item.data
dateLength = item.data.length
}
})
singleData.forEach(item => {
legenddata.push(item.name)
})
let xAxis=[]
let xAxisitem={
type: 'category',
data: '',
position: 'bottom',
axisTick: {
show: true
},
}
var emphasisStyle = {
itemStyle: {
shadowBlur: 10,
shadowColor: 'rgba(0,0,0,0.3)'
}
};
let xAxisitemdata=[]
for (let i = 0; i < valueData.length ; i++) {
xAxisitemdata=[]
for (let i = 0; i < valueData.length ; i++) {
xAxisitemdata.push('')
}
xAxisitemdata[i]=valueData[i].name
xAxisitem.data=JSON.parse(JSON.stringify(xAxisitemdata))
xAxis.push(JSON.parse(JSON.stringify(xAxisitem)))
}
// console.log("xAxis",xAxis)
let series=[]
for (let j = 0; j < valueData.length; j++) {
for (let i = 0; i < valueData[j].data.length; i++) {
let newArrList = [];
for (let a = 0; a < j; a++) {
newArrList.push({});
}
newArrList[j] = valueData[j].data[i];
for (let k = 0; k < legenddata.length; k++) {
let seriesitem={
type: 'bar',
name:legenddata[i],
barWidth: '10',
xAxisIndex: j,
emphasis: emphasisStyle,
itemStyle:{
barBorderRadius: [5, 5, 0, 0],//(顺时针左上,右上,右下,左下)
},
data: newArrList,
}
let a = j % legenddata.length;
if((valueData[j].data[i]).value !==0 && k===a){
series.push(JSON.parse(JSON.stringify(seriesitem)))
}
}
}
}
//console.log("series",series)
let series1= JSON.parse(JSON.stringify(series))
function getColor(num){
var colorArr = []
var colorValue="0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f";
//以","为分隔符,将colorValue字符串分割为字符数组["0","1",...,"f"]
var colorArray = colorValue.split(",");
for( var j = 0; j<num;j++){
var color="#";
for(var i=0;i<6;i++){
color+=colorArray[Math.floor(Math.random()*16)];
}
colorArr.push(color)
}
return colorArr
}
const option = {
tooltip: {
extraCssText: 'box-shadow: 0 0 3px rgba(0, 0, 0, 0.5);',
backgroundColor:'rgba(255,255,255,.8)',
confine: true ,
textStyle:{
color: '#3d3d3d' ,
fontSize: 14 ,
},
formatter: function(params) {
const result = params.data
var apercent = result.a !== 0 ? ((result.a / result.value) * 100) .toFixed(1) + '%' : '0%'
var bpercent = result.b !== 0 ? ((result.b / result.value) * 100) .toFixed(1) + '%' : '0%'
var cpercent = result.c !== 0 ? ((result.c / result.value) * 100) .toFixed(1) + '%' : '0%'
var dpercent = result.d !== 0 ? ((result.d / result.value) * 100) .toFixed(1) + '%' : '0%'
return `
<div style="padding:10px 20px 10px 10px">
<div>
<span style="font-size:14px;font-weight:700">${params.seriesName}</span><span style="margin-left:15px;font-weight:700">${result.value}个</span>
</div>
<ul>
<li style="padding:3px 0;">${params.marker}A级:<span style="padding:0 15px;">${result.a}个</span><span>${apercent}</span></li>
<li style="padding:3px 0;">${params.marker}B级:<span style="padding:0 15px;">${result.b}个</span><span>${bpercent}</span></li>
<li style="padding:3px 0;">${params.marker}C级:<span style="padding:0 15px;">${result.c}个</span><span>${cpercent}</span></li>
<li style="padding:3px 0;">${params.marker}D级:<span style="padding:0 15px;">${result.d}个</span><span>${dpercent}</span></li>
</ul>
</div>
`
}
},
color:getColor(25),
legend:{
show:false,
data:legenddata,
},
dataZoom : [{
type: 'slider',//给x轴设置滚动条
show: true, //flase直接隐藏图形
xAxisIndex: [0,1,2,3,4,5,6,7,8,9,10,11],
bottom:5,
height:15,
showDetail: true,
startValue: 0,//滚动条的起始位置
endValue: 4 //滚动条的截止位置(按比例分割你的柱状图x轴长度)
},
{
type: 'inside',//设置鼠标滚轮缩放
disabled: false,
xAxisIndex: [0,1,2,3,4,5,6,7,8,9,10,11],
startValue: 0,
endValue: 4
}],
grid: {
left: 40,
right: 10,
top: 25,
bottom: 25,
},
xAxis: xAxis,
yAxis: [
{
type: 'value',
name:'供应商数量(个)',
nameGap: 10,
// max:12,
nameTextStyle:{
},
splitLine:{
show :true,
lineStyle:{
type:'dashed'
}
},
}
],
series:series1
};
myChart.setOption(option)
window.addEventListener("resize", () => {
myChart.resize();
});
},
}
}
</script>
mock的数据结构如下图:
{
"datalist":[
{
"name":"1月",
"data":[
{"value":10,"a":2,"b":3,"c":4,"d":1,"name":"项目一"},
{"value":8,"a":2,"b":3,"c":4,"d":1,"name":"项目二"},
{"value":6,"a":2,"b":3,"c":4,"d":1,"name":"项目三"},
{"value":4,"a":2,"b":3,"c":4,"d":1,"name":"项目四"},
{"value":0,"a":0,"b":0,"c":0,"d":0,"name":"项目五"},
{"value":10,"a":2,"b":3,"c":4,"d":1,"name":"项目六"},
{"value":7,"a":2,"b":3,"c":4,"d":1,"name":"项目七"},
{"value":9,"a":2,"b":3,"c":4,"d":1,"name":"项目八"},
{"value":11,"a":2,"b":3,"c":4,"d":1,"name":"项目九"},
{"value":10,"a":2,"b":3,"c":4,"d":1,"name":"项目十"}
]
},
{
"name":"2月",
"data":[
{"value":0,"a":0,"b":0,"c":0,"d":0,"name":"项目一"},
{"value":8,"a":2,"b":3,"c":4,"d":1,"name":"项目二"},
{"value":4,"a":2,"b":3,"c":4,"d":1,"name":"项目三"},
{"value":4,"a":2,"b":3,"c":4,"d":1,"name":"项目四"},
{"value":0,"a":0,"b":0,"c":0,"d":0,"name":"项目五"},
{"value":0,"a":0,"b":0,"c":0,"d":0,"name":"项目六"},
{"value":7,"a":2,"b":3,"c":4,"d":1,"name":"项目七"},
{"value":0,"a":2,"b":3,"c":4,"d":1,"name":"项目八"},
{"value":5,"a":2,"b":3,"c":4,"d":1,"name":"项目九"},
{"value":0,"a":0,"b":0,"c":0,"d":0,"name":"项目十"}
]
},
{
"name":"3月",
"data":[
{"value":0,"a":0,"b":0,"c":0,"d":0,"name":"项目一"},
{"value":0,"a":0,"b":0,"c":0,"d":0,"name":"项目二"},
{"value":0,"a":0,"b":0,"c":0,"d":0,"name":"项目三"},
{"value":4,"a":2,"b":3,"c":4,"d":1,"name":"项目四"},
{"value":0,"a":0,"b":0,"c":0,"d":0,"name":"项目五"},
{"value":0,"a":0,"b":0,"c":0,"d":0,"name":"项目六"},
{"value":7,"a":2,"b":3,"c":4,"d":1,"name":"项目七"},
{"value":9,"a":2,"b":3,"c":4,"d":1,"name":"项目八"},
{"value":14,"a":2,"b":3,"c":4,"d":1,"name":"项目九"},
{"value":10,"a":2,"b":3,"c":4,"d":1,"name":"项目十"}
]
},
{
"name":"4月",
"data":[
{"value":6,"a":2,"b":3,"c":4,"d":1,"name":"项目一"},
{"value":8,"a":2,"b":3,"c":4,"d":1,"name":"项目二"},
{"value":6,"a":2,"b":3,"c":4,"d":1,"name":"项目三"},
{"value":4,"a":2,"b":3,"c":4,"d":1,"name":"项目四"},
{"value":0,"a":0,"b":0,"c":0,"d":0,"name":"项目五"},
{"value":0,"a":0,"b":0,"c":0,"d":0,"name":"项目六"},
{"value":7,"a":2,"b":3,"c":4,"d":1,"name":"项目七"},
{"value":9,"a":2,"b":3,"c":4,"d":1,"name":"项目八"},
{"value":0,"a":0,"b":0,"c":0,"d":0,"name":"项目九"},
{"value":6,"a":2,"b":3,"c":4,"d":1,"name":"项目十"}
]
},
{
"name":"5月",
"data":[
{"value":10,"a":2,"b":3,"c":4,"d":1,"name":"项目一"},
{"value":8,"a":2,"b":3,"c":4,"d":1,"name":"项目二"},
{"value":6,"a":2,"b":3,"c":4,"d":1,"name":"项目三"},
{"value":4,"a":2,"b":3,"c":4,"d":1,"name":"项目四"},
{"value":0,"a":0,"b":0,"c":0,"d":0,"name":"项目五"},
{"value":0,"a":0,"b":0,"c":0,"d":0,"name":"项目六"},
{"value":7,"a":2,"b":3,"c":4,"d":1,"name":"项目七"},
{"value":9,"a":2,"b":3,"c":4,"d":1,"name":"项目八"},
{"value":11,"a":2,"b":3,"c":4,"d":1,"name":"项目九"},
{"value":0,"a":0,"b":0,"c":0,"d":0,"name":"项目十"}
]
},
{
"name":"6月",
"data":[
{"value":0,"a":0,"b":0,"c":0,"d":0,"name":"项目一"},
{"value":8,"a":2,"b":3,"c":4,"d":1,"name":"项目二"},
{"value":6,"a":2,"b":3,"c":4,"d":1,"name":"项目三"},
{"value":4,"a":2,"b":3,"c":4,"d":1,"name":"项目四"},
{"value":0,"a":0,"b":0,"c":0,"d":0,"name":"项目五"},
{"value":0,"a":0,"b":0,"c":0,"d":0,"name":"项目六"},
{"value":7,"a":2,"b":3,"c":4,"d":1,"name":"项目七"},
{"value":9,"a":2,"b":3,"c":4,"d":1,"name":"项目八"},
{"value":0,"a":0,"b":0,"c":0,"d":0,"name":"项目九"},
{"value":10,"a":2,"b":3,"c":4,"d":1,"name":"项目十"}
]
},
{
"name":"7月",
"data":[
{"value":11,"a":2,"b":3,"c":4,"d":1,"name":"项目一"},
{"value":8,"a":2,"b":3,"c":4,"d":1,"name":"项目二"},
{"value":6,"a":2,"b":3,"c":4,"d":1,"name":"项目三"},
{"value":4,"a":2,"b":3,"c":4,"d":1,"name":"项目四"},
{"value":0,"a":0,"b":0,"c":0,"d":0,"name":"项目五"},
{"value":3,"a":2,"b":3,"c":4,"d":1,"name":"项目六"},
{"value":7,"a":2,"b":3,"c":4,"d":1,"name":"项目七"},
{"value":9,"a":2,"b":3,"c":4,"d":1,"name":"项目八"},
{"value":0,"a":0,"b":0,"c":0,"d":0,"name":"项目九"},
{"value":0,"a":0,"b":0,"c":0,"d":0,"name":"项目十"}
]
},
{
"name":"8月",
"data":[
{"value":0,"a":0,"b":0,"c":0,"d":0,"name":"项目一"},
{"value":8,"a":2,"b":3,"c":4,"d":1,"name":"项目二"},
{"value":6,"a":2,"b":3,"c":4,"d":1,"name":"项目三"},
{"value":4,"a":2,"b":3,"c":4,"d":1,"name":"项目四"},
{"value":0,"a":0,"b":0,"c":0,"d":0,"name":"项目五"},
{"value":4,"a":2,"b":3,"c":4,"d":1,"name":"项目六"},
{"value":7,"a":2,"b":3,"c":4,"d":1,"name":"项目七"},
{"value":9,"a":2,"b":3,"c":4,"d":1,"name":"项目八"},
{"value":9,"a":2,"b":3,"c":4,"d":1,"name":"项目九"},
{"value":0,"a":0,"b":0,"c":0,"d":0,"name":"项目十"}
]
},
{
"name":"9月",
"data":[
{"value":10,"a":2,"b":3,"c":4,"d":1,"name":"项目一"},
{"value":8,"a":2,"b":3,"c":4,"d":1,"name":"项目二"},
{"value":0,"a":0,"b":0,"c":0,"d":0,"name":"项目三"},
{"value":4,"a":2,"b":3,"c":4,"d":1,"name":"项目四"},
{"value":0,"a":0,"b":0,"c":0,"d":0,"name":"项目五"},
{"value":6,"a":2,"b":3,"c":4,"d":1,"name":"项目六"},
{"value":7,"a":2,"b":3,"c":4,"d":1,"name":"项目七"},
{"value":9,"a":2,"b":3,"c":4,"d":1,"name":"项目八"},
{"value":0,"a":0,"b":0,"c":0,"d":0,"name":"项目九"},
{"value":10,"a":2,"b":3,"c":4,"d":1,"name":"项目十"}
]
},
{
"name":"10月",
"data":[
{"value":0,"a":0,"b":0,"c":0,"d":0,"name":"项目一"},
{"value":8,"a":2,"b":3,"c":4,"d":1,"name":"项目二"},
{"value":6,"a":2,"b":3,"c":4,"d":1,"name":"项目三"},
{"value":4,"a":2,"b":3,"c":4,"d":1,"name":"项目四"},
{"value":0,"a":0,"b":0,"c":0,"d":0,"name":"项目五"},
{"value":10,"a":2,"b":3,"c":4,"d":1,"name":"项目六"},
{"value":7,"a":2,"b":3,"c":4,"d":1,"name":"项目七"},
{"value":9,"a":2,"b":3,"c":4,"d":1,"name":"项目八"},
{"value":0,"a":0,"b":0,"c":0,"d":0,"name":"项目九"},
{"value":10,"a":2,"b":3,"c":4,"d":1,"name":"项目十"}
]
},
{
"name":"11月",
"data":[
{"value":9,"a":2,"b":3,"c":4,"d":1,"name":"项目一"},
{"value":0,"a":0,"b":0,"c":0,"d":0,"name":"项目二"},
{"value":6,"a":2,"b":3,"c":4,"d":1,"name":"项目三"},
{"value":4,"a":2,"b":3,"c":4,"d":1,"name":"项目四"},
{"value":0,"a":0,"b":0,"c":0,"d":0,"name":"项目五"},
{"value":10,"a":2,"b":3,"c":4,"d":1,"name":"项目六"},
{"value":7,"a":2,"b":3,"c":4,"d":1,"name":"项目七"},
{"value":0,"a":0,"b":0,"c":0,"d":0,"name":"项目八"},
{"value":9,"a":2,"b":3,"c":4,"d":1,"name":"项目九"},
{"value":4,"a":2,"b":3,"c":4,"d":1,"name":"项目十"}
]
},
{
"name":"12月",
"data":[
{"value":10,"a":2,"b":3,"c":4,"d":1,"name":"项目一"},
{"value":8,"a":2,"b":3,"c":4,"d":1,"name":"项目二"},
{"value":6,"a":2,"b":3,"c":4,"d":1,"name":"项目三"},
{"value":4,"a":2,"b":3,"c":4,"d":1,"name":"项目四"},
{"value":0,"a":0,"b":0,"c":0,"d":0,"name":"项目五"},
{"value":0,"a":2,"b":3,"c":4,"d":1,"name":"项目六"},
{"value":7,"a":2,"b":3,"c":4,"d":1,"name":"项目七"},
{"value":9,"a":2,"b":3,"c":4,"d":1,"name":"项目八"},
{"value":0,"a":0,"b":0,"c":0,"d":0,"name":"项目九"},
{"value":11,"a":2,"b":3,"c":4,"d":1,"name":"项目十"}
]
}
]
}