編寫折線圖/柱狀圖組件vue+echarts

前言:因為公司需要做一款報表類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ù)筆記,還需要完善烈掠。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末羞秤,一起剝皮案震驚了整個濱河市缸托,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌瘾蛋,老刑警劉巖俐镐,帶你破解...
    沈念sama閱讀 211,948評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異哺哼,居然都是意外死亡佩抹,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,371評論 3 385
  • 文/潘曉璐 我一進店門取董,熙熙樓的掌柜王于貴愁眉苦臉地迎上來棍苹,“玉大人,你說我怎么就攤上這事茵汰±炔” “怎么了?”我有些...
    開封第一講書人閱讀 157,490評論 0 348
  • 文/不壞的土叔 我叫張陵经窖,是天一觀的道長坡垫。 經(jīng)常有香客問我,道長画侣,這世上最難降的妖魔是什么冰悠? 我笑而不...
    開封第一講書人閱讀 56,521評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮配乱,結(jié)果婚禮上溉卓,老公的妹妹穿的比我還像新娘。我一直安慰自己搬泥,他們只是感情好桑寨,可當我...
    茶點故事閱讀 65,627評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著忿檩,像睡著了一般尉尾。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上燥透,一...
    開封第一講書人閱讀 49,842評論 1 290
  • 那天沙咏,我揣著相機與錄音,去河邊找鬼班套。 笑死肢藐,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的吱韭。 我是一名探鬼主播吆豹,決...
    沈念sama閱讀 38,997評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了痘煤?” 一聲冷哼從身側(cè)響起鸳吸,我...
    開封第一講書人閱讀 37,741評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎速勇,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體坎拐,經(jīng)...
    沈念sama閱讀 44,203評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡烦磁,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,534評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了哼勇。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片都伪。...
    茶點故事閱讀 38,673評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖积担,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤荆虱,帶...
    沈念sama閱讀 34,339評論 4 330
  • 正文 年R本政府宣布拌阴,位于F島的核電站,受9級特大地震影響的烁,放射性物質(zhì)發(fā)生泄漏褐耳。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,955評論 3 313
  • 文/蒙蒙 一渴庆、第九天 我趴在偏房一處隱蔽的房頂上張望铃芦。 院中可真熱鬧,春花似錦襟雷、人聲如沸刃滓。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,770評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽咧虎。三九已至,卻和暖如春计呈,著一層夾襖步出監(jiān)牢的瞬間老客,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,000評論 1 266
  • 我被黑心中介騙來泰國打工震叮, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留胧砰,地道東北人。 一個月前我還...
    沈念sama閱讀 46,394評論 2 360
  • 正文 我出身青樓苇瓣,卻偏偏與公主長得像尉间,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,562評論 2 349

推薦閱讀更多精彩內(nèi)容