前言:因為公司需要做一款報表類app專供boss查詢毁腿,且敲定了用vue實現(xiàn)拧抖,圖標類就用自己比較熟悉的e charts应狱。所以就有了下面的實現(xiàn)姥份,封裝一個vue+echarts組件。
實現(xiàn)效果:
實現(xiàn)單個圖表實例中存在多組y軸數(shù)據(jù)(同一x軸稽荧,多組y軸橘茉;本文中直規(guī)范實現(xiàn)了前兩組數(shù)據(jù)格式,如果插入超過兩組的數(shù)據(jù)姨丈,實現(xiàn)的樣式為echarts默認樣式)畅卓,點擊切換天數(shù),實現(xiàn)多組數(shù)據(jù)實時更新蟋恬。如果數(shù)據(jù)較多可左右滑動翁潘;也可動態(tài)加載一起展示。
想要達到的效果是只需要傳入3個數(shù)據(jù):ydata為導入的y軸數(shù)據(jù)歼争,數(shù)組格式拜马,數(shù)組中的每個對象為一組數(shù)據(jù)。例 [{name:"銷售額(元)",type:"bar",data:[21000, 4000.9, ...]}]name為圖例名稱沐绒,type為圖例表現(xiàn)方式俩莽,同echarts,data為數(shù)據(jù)洒沦;
xdata為導入的x軸數(shù)據(jù)豹绪,數(shù)組格式价淌,例 xdata=['2018-01-01','2018-02-01',...]申眼;
total為當前選中的按鈕瞒津,數(shù)字,為天數(shù)
<echart-container :ydata="ydata" :xdata="xdata" :total="nowtab"></echart-container>
- 組件編寫括尸,初始化(標簽命名echart-container巷蚪,接收參數(shù)ydata,xdata濒翻,total)
var charts = Vue.component('echart-container', {
props: {
total:Number,
ydata:Array,
xdata:Array,
},
template: '',
mounted:function() {},
watch:{},
methods:{}
})
- 編寫模版(我當時拿到的UI圖有圖表的背景及x軸的陰影效果屁柏,所以我直接定義了圖表高度,在圖表外部直接添加效果有送。當然echarts內(nèi)部也可以編輯圖表的背景淌喻,但是我試驗之后覺得效果沒有在外面直接用css做的方便。不需要的可以直接去掉雀摘,即以下代碼的2&3行)裸删,放入template中
var temp = '<div class="echart-wrap">';
temp += '<img class="echart-back" src="https://img.~.png"/>';
temp += '<div class="wb-shadow-up"></div>';
temp += '<div class="echart-contain">';
temp += '<div id="container"></div>';
temp += '</div></div>';
- 編寫圖表初始化方法,參考echarts官網(wǎng)阵赠,下面貼上的是我寫的初始化代碼(根據(jù)公司UI編寫涯塔,可以根據(jù)想要的效果替換)我寫的規(guī)范了前2組y軸數(shù)據(jù)的樣式,如果超過2組清蚀,后面的數(shù)據(jù)會是默認樣式匕荸;如果有需要可以繼續(xù)增加。
這個配置是實現(xiàn)左右可滑動效果枷邪,若是不需要可以去掉相關配置進度條以及x軸進度條配置榛搔,就可以直接展示所有數(shù)據(jù),若要動態(tài)添加可使用setInterval&clearInterval方法齿风,具體就不貼了药薯,可參考echarts官網(wǎng)示例http://echarts.baidu.com/examples/editor.html?c=dynamic-data
initChart:function(){
var myChart=echarts.init(document.getElementById("container"))//初始化
var app = {};
var option = null;//配置
var legend=[];//圖例
var yset=[];//y軸設置
for (var i =0; i<this.ydata.length; i++) {
//圖例
legend[i]={
name: this.ydata[i].name,//圖例名稱
icon: 'roundRect',//圖例圖標
textStyle:{//圖例文字樣式
fontSize:8,
color:'#ccc'
}
}
//圖例的圖片設置
if (i==1&&this.ydata[1].type=='line') {
legend[1].icon='image://https://img.~.png'//圖例圖標
}
//y軸數(shù)據(jù)對齊方式
var yAlign='';
if (i==0) {yAlign='left';} else if(i==1) {yAlign='right';}
//y軸數(shù)據(jù)設置
yset[i]={
type: 'value',//坐標軸類型,默認
position: i==0?'left':"right",//位置
axisLine: {show:false},//y軸線設置不顯示
axisTick: {show:false},//y軸刻度設置不顯示
axisLabel: { //刻度顯示
formatter: function(value){
if (value==0) {
return ''
} else if (value<=1&&value>0) {
return value*100+'%'
} else if (value>=1000) {
return value/10000+'w'
} else {
return value;
}
},
fontSize:10,
fontFamily:'DINEngschrift',
fontWeight:'bold',
color:'#D8D8D8',
align:yAlign
},
splitLine: {show:false}//y軸分割線設置
}
this.ydata[i].yAxisIndex=i;//使用的 y 軸的 index救斑,在單個圖表實例中存在多個y軸的時候有用
if (this.ydata[i].type=='line') {
this.ydata[i].smooth = true;//折線流暢
this.ydata[i].lineStyle={
width:3, //折線粗細
shadowColor: 'rgba(250,52,101, 0.3)',//陰影顏色
shadowBlur: 4,//陰影粗細
shadowOffsetY:8//陰影垂直偏移
}
this.ydata[i].symbolSize=6
this.ydata[i].hoverAnimation= false
this.ydata[i].animation= false
}
if (this.ydata[i].type=='bar') {
this.ydata[i].barWidth = 6;//柱狀圖粗細
this.ydata[i].barGap = 0.5;//柱狀圖間隔
this.ydata[i].itemStyle={//圓角
barBorderRadius: [1,1,0,0]
}
}
if (i==0) {//第一個圖表顏色
if (this.ydata[0].itemStyle) {
this.ydata[0].itemStyle.color = "#4992F5"
} else {
this.ydata[0].itemStyle={
color: "#4992F5"
}
}
} else if (i==1) {//第二個圖表顏色童本,為bar,黃色;line玫紅
if (this.ydata[1].type=='bar') {
if (this.ydata[1].itemStyle) {
this.ydata[1].itemStyle.color = "#F7BB42"
} else {
this.ydata[1].itemStyle={
color: "#F7BB42"
}
}
} else if (this.ydata[1].type=='line'){
if (this.ydata[1].itemStyle) {
this.ydata[1].itemStyle.color = "#FA3465"
} else {
this.ydata[1].itemStyle={
color: "#FA3465"
}
}
}
}
}
var yDt=[]; //完全深度復制對象this.ydata
for (var i =0; i<this.ydata.length; i++) {
yDt[i]={};
for(key in this.ydata[i]) {
if (typeof (this.ydata[i][key]) == 'Object') {
yDt[i][key]=[];
for (var j=0; j<this.ydata[i][key].length; j++) {
yDt[i][key][j]=this.ydata[i][key][j];
}
} else {
yDt[i][key]=this.ydata[i][key];
}
}
}
//控制傳入的數(shù)據(jù)長度
for (var i =0; i<yDt.length; i++) {
yDt[i].data=yDt[i].data.slice(0,this.total)
for (var t=0 ;t<yDt[i].data.length; t++) {
yDt[i].data[t]<1?yDt[i].data[t]*100:yDt[i].data[t];
}
}
var endPercent = this.total>7?30:100;//進度條長度控制
option = {
tooltip: {//鼠標點擊的提示
trigger: 'axis',
axisPointer: {
type: 'shadow',
shadowStyle:{
color:'rgba(73,146,245, 0.1)'
}
},
position: function (point,params) {// 固定在頂部
if (params.length==1) return [point[0]-80,-40];
if (params.length==2) return [point[0]-80,-60];
},
backgroundColor:'transparent',
triggerOn:'click',//提示框觸發(fā)的條件
formatter: function(params){//提示內(nèi)容
var str='<div class="tooltip-wrap">';
for (var k=0; k< params.length; k++){
var val=params[k].data;
var valStr='';
if (val<=1&&val>0) {
valStr=val*100+'%'
} else {
valStr=val
}
str+='<p>'+params[k].seriesName+':<span>'+valStr+'</span></p>'
}
str+='</div>'
return str;
}
},
grid: { //圖表位置
top:20,
left:15,
right:15,
bottom: 82,//距離
},
legend: {//設置圖例
itemWidth: 7,
itemHeight: 7,
bottom:0,//圖例位置
data:legend
},
dataZoom: [//給x軸設置滾動條
{
show: false,
start:0,//默認為0
end: endPercent,
type: 'slider',
xAxisIndex: [0],
handleSize: 0,//滑動條的 左右2個滑動條的大小
},
//下面這個屬性是里面拖到
{
type: 'inside',
preventDefaultMouseMove:false
},
],
xAxis: [
{
type: 'category',//x軸類型,默認
axisTick: {show:false},//x軸刻度設置不顯示
axisLine: {show:false}, //x軸線設置顯示
data: this.xdata.slice(0,this.total),
axisLabel:{rotate:-60,fontSize:9,color:'#999',padding:[10,0,-10,-5]}, //x軸標簽設置
}
],
yAxis: yset,
series: yDt
};
if (option && typeof option === "object") {
myChart.setOption(option, true);
}
}
- 動態(tài)監(jiān)聽數(shù)據(jù)變化(我做的是x軸監(jiān)聽脸候,代碼里提到的changeperiod方法是我做的數(shù)據(jù)增減的動畫效果穷娱,大家可以自己寫,我這里就不放了)
xdata:function(val,old){
if (val[0]!=old[0]) {
this.initChart();
return;
}
if (val.length!=old.length) {
this.changeperiod(val.length,old.length);
return;
}
if (val[0]==old[0]&&val.length==old.length) {
this.initChart();
return;
}
},
以上运沦,就是我封裝的vue+echarts組件泵额,除了效果圖的外部css這邊沒有附上,別的基本都有了携添。只需要引入vue.js及echarts.js和echarts.css后就可以用了嫁盲。
這是我的第一篇技術(shù)筆記,還需要完善烈掠。