需求背景
- 用柱狀圖展示12個月的項目對應(yīng)的供應(yīng)商數(shù)據(jù);
- 每個月有多個項目不確定,1-50之間,也就是說,12個月,每個月的X軸上有不確定的柱狀;例如:1月有20根柱子,2月有5根柱子,3月有15根…
- 每月的每根柱子代表是一個項目,鼠標(biāo)移入每月的每一個項目的柱子上要懸浮展示該月該項目具體供應(yīng)商的情況;
當(dāng)時聽了這個需求,我就很不解,這數(shù)據(jù)都是不確定的,咋展示,如果只展示一個月的數(shù)據(jù)還可以,然后通過按鈕去選擇月份渲染,如果展示一年的數(shù)據(jù)的話,就有點小復(fù)雜啦,那么多數(shù)組,還不確定,能擠得下嗎?哈哈
效果圖展示
主要是X軸數(shù)據(jù)那么多,還不確定,只能看X軸能不能自適應(yīng)撐開并且能不能實現(xiàn)滑動,然后就查到了可以實現(xiàn)滑動對X軸放大或者縮放,那就好辦啦!
先把實現(xiàn)效果圖表展示一下,如下圖:
圖表上的數(shù)據(jù)也是自己隨意mock的,由于柱子數(shù)量不確定,顏色也是隨機的,這些都不要太在意了,重點是圖表的實現(xiàn);
還有,以上柱狀圖主要涉及到知識點有兩個,也順便分享一下:
1.X軸鼠標(biāo)滑動或者縮放;
2.多列柱狀圖中其中某一列數(shù)據(jù)為0時不占位;
X軸鼠標(biāo)滑動或者縮放設(shè)置
dataZoom : [{
type: 'slider',//給x軸設(shè)置滾動條
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',//設(shè)置鼠標(biāo)滾輪縮放
disabled: true,
xAxisIndex: [0,1,2,3,4,5,6,7,8,9,10,11],
startValue: 0,
endValue: 4
}],
多列柱狀圖中某一列數(shù)據(jù)為0時不占位
正常多列柱狀圖,某一列數(shù)據(jù)為0時,是不顯示的,但是還是會占位的,如下圖:
很明顯這樣是很難看的,我們要遍歷然后過濾掉value值為0的柱子,把有值的柱形數(shù)據(jù)塞到 series 中,但是要配合xAxis 數(shù)據(jù),所以我們重新格式化了一下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 如下圖:
注意看紅框標(biāo)記的,每月的data,只有當(dāng)月顯示,其他月為空;
打印的series如下圖:
12個月,按10個項目,正常數(shù)據(jù)應(yīng)該有120個,這里只有81個,就是所有有值的柱子的集合,把值為0的已經(jīng)過濾掉,不顯示,這樣就不會在圖表中占位;
全部代碼展示
下面我們就把上面圖表的實現(xiàn)的全部代碼展示出來,開袋即食!文章來源:http://www.zghlxwxcb.cn/news/detail-489346.html
<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);
//這個是獲取legenddata,把每一個項目名稱塞進去,后面也是為了和color配合自定義顏色
let legenddata = []
var singleData = valueData[0].data
singleData .forEach( item => {
legenddata.push(item.name)
})
//這里我們要重新格式化一下xAxis的屬性,如果數(shù)據(jù)不多的話,直接寫死也可以
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)
//重新格式化series,把柱狀圖每一列為空的過濾掉
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))
//此函數(shù)是隨機生成顏色的
function getColor(num){
var colorArr = []
var colorValue="0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f";
//以","為分隔符,將colorValue字符串分割為字符數(shù)組["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(legenddata.length),
legend:{
show:false,
data:legenddata,
},
dataZoom : [{
type: 'slider',//給x軸設(shè)置滾動條
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',//設(shè)置鼠標(biāo)滾輪縮放
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:'供應(yīng)商數(shù)量(個)',
nameGap: 10,
// max:12,
nameTextStyle:{
},
splitLine:{
show :true,
lineStyle:{
type:'dashed'
}
},
}
],
series:series1
};
myChart.setOption(option)
window.addEventListener("resize", () => {
myChart.resize();
});
},
}
}
</script>
mock的數(shù)據(jù)結(jié)構(gòu)如下圖:文章來源地址http://www.zghlxwxcb.cn/news/detail-489346.html
{
"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":"項目三"},
...
]
},
{
"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":"項目三"},
...
]
},
{
"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":"項目三"},
...
]
},
...
]
}
到了這里,關(guān)于Echarts—X軸鼠標(biāo)滑動或者縮放/多列柱狀圖中某一列數(shù)據(jù)為0時不占位的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!