使用百度echarts仿雪球分時圖(四)


  這章節來收拾一下一些小BUG,順便把各個小提示信息也補上,分時圖也就完成了。

  上章節末尾提到的一個bug,就是第一個grid跟第三個grid之間是斷開的,折線並沒有連在一起,所以先來收拾這個問題。沒有連着一起的原因主要是第一個grid的最后一條數據的值,跟第三個grid的第一條數據不一樣,而且grid之間是不會幫你把這兩個點連接起來的,所以會出現一上一下的斷崖。知道了是什么原因,那就知道該怎么辦了。在遍歷數據的時候,我們先往grid3Data數據里加一條數據,這條數據的值是grid1Data的最后一條數據,也就是11:30的那條數據,這樣第一個grid的最后一條數據跟第三個grid的第一條數據就一樣了,這樣就可以連起來了。但是還會有個問題,因為第三個grid跟第四個grid的x軸類型是 ‘time’類型,但是第一條數據是11:30,第二條數據是13:00,如果繼續使用'time'類型的話,第三個grid會有很長一條直線,就是11:30到13:00之間這一段會很平的,所以第三第四個grid不能使用'time'類型了,改用'category'類目類型。改用'category'類型后,要新建兩個數組來存放x軸的時間,分別是grid3DateData,grid4DateData,然后grid3Data和grid4Data存放的不再是數組,而是數值。

  遍歷數據的代碼稍微修改一下。下午數據的部分修改為

if(data.data.items[i].current > priceMax){
                            priceMax = data.data.items[i].current;
                        }
                        if(data.data.items[i].current < priceMin || priceMin == 0){
                            priceMin = data.data.items[i].current;
                        }
                        // 第三grid的數據先添加一條數據
                        if(grid3Data.length == 0){        
                            grid3Data.push(data.data.items[i-1].current);
                            grid3DateData.push(data.data.items[i-1].timestamp);
                        }
                        // 右上方折線圖
                        grid3Data.push(data.data.items[i].current);
                        grid3DateData.push(data.data.items[i].timestamp);
                        
                        
                        if(data.data.items[i].volume > volumeMax){
                            volumeMax = data.data.items[i].volume;
                        }
                        if(data.data.items[i].volume < volumeMin){
                            volumeMin = data.data.items[i].volume;
                        }
                        
                        if(data.data.items[i].current >= data.data.items[i-1].current){
                             volumeColor2.push(UP_COLOR);
                         }else{
                             volumeColor2.push(DOWN_COLOR);
                         }
                    
                        // 第四grid的數據先添加一條數據
                        if(grid4Data.length == 0){
                            grid4Data.push(data.data.items[i-1].volume);
                            grid4DateData.push(data.data.items[i-1].timestamp);
                        }
                        // 右下方柱狀圖
                        grid4Data.push(data.data.items[i].volume);
                        grid4DateData.push(data.data.items[i].timestamp);

然后第三第四個grid的x 軸配置中,data分別設置成grid3DateData和grid4DateData。然后又出現新的問題,x軸的坐標軸線分布不均勻,因為我們用的是 category 的類型,而且我們x軸的數據很多,echarts為了保證能夠顯示足夠的x軸的文字,所以會出現跳躍性的線條,顯得分布不均勻。還好,echarts中是有屬性可以自定義去顯示哪條x軸坐標軸線。就是xAxis.splitLine.interval這個屬性,可以設置數字,也可以是回調方法,interval這個屬性很熟悉了,就是線條的間隔,所以接下來使用回調方法的方式來顯示需要顯示的線條。第三第四個grid的xAxis.splitLine.interval屬性都是這樣寫的

interval:function(index,value){
                                        // 第一條第二條線是不需要顯示的,第一條是11:30的,第一個grid已經有這條數據了,所以不需要顯示
                                        // 第二條顯示的話,在中間部分會出現2條線,所以也不要顯示
                                        if(index == 0 || index == 1){
                                            return false;
                                        }
                                        // 這里的意思是第一條數據后,每30分鍾顯示一條線
                                        if((index - 1) % 30 == 0){
                                            return true;
                                        }
                                        return false;
                                    }

這么一改,不連接的問題就解決了。

 

  接下來把各個提示信息調整出來。首先要把指示器axisPointer這個屬性配置一下,axisPointer有分為公共配置和各個坐標軸的單獨配置。公共配置是配置一些公共的屬性,各個坐標軸的配置則是配置不同坐標軸的樣式,以及文字的格式化。這里我們兩者都需要進行配置。

  公共配置部分

  axisPointer.show默認是false的,我們設置成true,指示器就出來了,但是會發現,線條也是斷開的,只會顯示其中的一個grid的線條,這里需要配置一下axisPointer.link屬性來聯動。link屬性的介紹:不同軸的 axisPointer 可以進行聯動,在這里設置。聯動表示軸能同步一起活動。軸依據他們的 axisPointer 當前對應的值來聯動,link 是一個數組,其中每一項表示一個 link group,一個 group 中的坐標軸互相聯動。這里我們屬性link的xAxisIndex和yAxisIndex屬性,這兩個屬性是數組類型,里面值是數值,也就是grid的下標。重新看一下分時圖,我們放鼠標在左上方的的區域,我們希望的是x軸是第一個第二個grid聯動,y軸則是第一個第三個聯動;放在右上方邊的區域的話,x軸是第三個第四個grid聯動,y軸還是第一個第三個聯動。以此類推出左下方右下方的聯動,得到的代碼是這樣的

axisPointer:{
    show:true,
    // 配置線條風格為虛線風格
    lineStyle:{
        type:'dashed'
    },
    link:[
        {
            xAxisIndex:[0,1],
        },{
            xAxisIndex:[2,3],
        },{
            yAxisIndex:[0,2]
        },{
            yAxisIndex:[1,3]
        }
    ]
},

再看一下雪球的分時圖,發現分時圖有指示器的地方分別是第一個第二個第三個grid的y軸,第二個第四個grid的x軸,那么接下來要單獨配置一下各個坐標軸的指示器。

所有指示器的show屬性都設置成true,顯示與否則通過label.show屬性來控制。第一個第二個第三個grid的y軸的指示器的 label.show屬性我們都設置成true,第四個則設置成false。第二個第四個grid的x軸的指示器的label.show屬性設置成true,第一個第三個grid的x軸的指示器設置成false。設置完成后,成功的只顯示了需要顯示的指示器,但是默認的樣式卻不是我們想看到的樣式。接下來美化一下

  1.字體太大了,把label.fontSize調成10。

  2.內邊距太大了,把label.padding調成2即可。

  3.陰影效果也不需要了,把label.shadowBlur調成0。

  4.字體顏色也改成深色的,設置label.color即可。

經過調整后,樣式已經達到我們的要求,但是指示器上的文字還沒達到要求,那么就使用label.formatter的回調函數進行格式化,不同的坐標軸的格式化方式不一樣,這里不花太大篇幅去講解。

第一個第三個grid的x軸指示器配置

axisPointer:{
    show:true,
    label:{
        show:false
    }
}

第一個grid的y軸指示器配置

axisPointer:{
    show:true,
    type:"line",
    label:{
        show:true,
        fontSize:10,
        margin:-44,
        padding:2,
        shadowBlur:0,
        color:"#33353C",
        formatter:function(data){
            
            return data.value.toFixed(2);
        }
    },
}

第三個grid的y軸指示器配置

axisPointer:{
    show:true,
    type:"line",
    label:{
        show:true,
        fontSize:10,
        margin:-34,
        padding:2,
        shadowBlur:0,
        color:"#33353C",
        formatter:function(data){
            var persent = (data.value - lastPrice) / lastPrice;
            persent = (persent < 0) ? persent * -1 : persent;
            persent = persent * 100;

            return persent.toFixed(2) + '%';
        }
    },
 }

第二個grid的x軸指示器配置

axisPointer:{
    show:true,
    type:"line",
    label:{
        show:true,
        fontSize:10,
        margin:0,
        padding:2,
        shadowBlur:0,
        color:"#33353C",
        formatter:function(data){
            return echarts.format.formatTime('hh:mm', parseFloat(data.value))
        }
    },
}

第二個grid的y軸指示器配置

axisPointer:{
    show:true,
    type:"line",
    label:{
        show:true,
        fontSize:10,
        padding:2,
        shadowBlur:0,
        color:"#33353C",
        formatter:function(data){
            if(data.value > 1000000){
                return parseFloat(data.value / 1000000).toFixed(2)+"萬手";
            }
            return data.value;
        }
    },
}

第四個grid的x軸指示器配置

axisPointer:{
    show:true,
    type:"line",
    label:{
        show:true,
        fontSize:10,
        margin:0,
        padding:2,
        shadowBlur:0,
        color:"#33353C",
        formatter:function(data){
            return echarts.format.formatTime('hh:mm', parseFloat(data.value));
        }
    },
}

第四個grid的y軸指示器配置

axisPointer:{
    show:true,
    label:{
        show:false
    }
}

到這里,所有坐標軸的指示器都設置完成了,效果也如預期那樣。最后還有一個懸浮的提示框需要配置,配置完后我們的分時圖就完成了。

配置懸浮的提示框主要是配置根屬性的tooltip屬性。tooltip有個一個trigger的觸發類型屬性,item:數據項圖形觸發,主要在散點圖,餅圖等無類目軸的圖表中使用;axis:坐標軸觸發,主要在柱狀圖,折線圖等會使用類目軸的圖表中使用;none:什么都不觸發因為默認是item這里把觸發類型改成 axis ,提示框就會出來了。但是提示框的位置還有樣式,都不是我們想要的,又要再給它美化一下。首先我們先對它的位置進行固定,使用position屬性進行配置,position可以是字符串,數組,回調函數,要高度自定義的話,顯然回調函數比較合適,回調函數返回一個對象,這個對象與CSS的position屬性類型,對象里面是使用top,right,bottom,left屬性來控制位置的,我們可以根據回調函數里的5個回調參數來進行相應的配置,這5個回調參數分別是:

point: 鼠標位置,如 [20, 40]。
params: 同 formatter 的參數相同。
dom: tooltip 的 dom 對象。
rect: 只有鼠標在圖形上時有效,是一個用xywidthheight四個屬性表達的圖形包圍盒。
size: 包括 dom 的尺寸和 echarts 容器的當前尺寸,例如:{contentSize: [width, height], viewSize: [width, height]}

point屬性是鼠標當前的x值和y值;params跟formatter的參數相同,但是我們不需要格式化的相關配置,所以這個可以不用;dom對象,這個先保留;rect這個屬性是鼠標放在提示框上才會有效,否則就是undefined,要想鼠標能放到提示框上,要配置enterable屬性為true,但是我們不需要放鼠標上去,所以不需要;size屬性,里面的contentSize屬性指的是提示框的寬高,viewSize則是整個圖表的大小,我們需要size的viewSize結合point鼠標位置屬性來對提示框進行一個位置的定位。

我們要做的效果是鼠標在左邊圖表的時候,提示框在右邊,鼠標在右側圖表的的時候,提示框在左邊,那么就要對返回對象的left值或者right值進行配置了。判斷鼠標是在左邊還是在右邊很簡單,只需要判斷鼠標的x值是否大於第一個第二個grid的寬度即可,因為左右兩邊的寬度是相等的,所以第一個第二個grid的寬度就是viewSize[width] / 2,只要鼠標位置的x值大於這個值,那就是鼠標在右邊,小於這個值那就是在左邊;同時我們要固定在頭部,所以要把top值也設置一下。

position:function(point, params, dom, rect, size){
    var obj ={
        top:10
    }
    
    if(point[0] > size.viewSize[0] / 2){
        obj["left"] = 70;
    }else{
        obj["right"] = 70;
    }

    return obj;
}

位置調整好后,開始整理樣式。

  1.文字的顏色通過textStyle.color屬性設置成黑色

  2.設置邊框,borderWidth:1,borderColor:'#ECEEF2'

  3.設置背景色為白色半透明,backgroundColor:'rgba(255,255,255,0.9)'

  4.動畫效果也不要了,直接設置動畫時長為0,transitionDuration:0

樣式調整好后,提示框的文字也需要進行一次格式化,在formatter的回調函數中進行配置。因為提示框的渲染方式renderMode,默認是html,所以回調函數里面我們可以配合CSS來編寫我們自己的html。formatter的回調參數有3個,分別是:

  1.params,這是提示框里面展示的數據的數據集。

  2.ticket,這是異步回調的標識,數據格式跟params是一樣的,一般配合第三個參數callback使用

  3.callback,異步回調,與第二個參數ticket配合進行異步的數據展示。例如提示框中需要進行數據獲取的請求時,可以用到這個組合。

這里我們不需要異步請求數據,所以直接使用params的數據進行展示。首先我們要遍歷params數據集,拿到里面的數據,再通過數據集的數據名稱seriesName進行判斷是什么數據,對數據進行格式化,最后拼接成一段html用於渲染。(注:seriesName可以在series中,對數據進行命名) 

  命名數據

// 第一個圖表的數據
{
    name:"最新1",
    // 平滑曲線
    smooth:true,
    // 是否顯示折線上的圓點
    symbol:'none',
    // 線條顏色
    lineStyle:{
        color:"#0481F8",
        width:1
    },
    xAxisIndex:0,
    yAxisIndex:0,
    data: grid1Data,
    type: 'line',
    z:3,
    areaStyle:{
        color:"#F8FAFF"
    }
},

formatter回調函數

formatter:function(params,ticket,callback){
    var html = '';
    var x,j,c;

    for(var d in params){
        if(params[d].seriesName == '成交量1' || params[d].seriesName == '成交量2' ){
            c = params[d];
        }
        if(params[d].seriesName == '最新1' || params[d].seriesName == '最新2' ){
            x = params[d];
        }

    }
     
    if(!c.axisValue){
        return;
    }
    

    html += '<div class="tooltips-item"><span class="name">時間</span><span class="value">'+ echarts.format.formatTime('MM-dd hh:mm',parseFloat(c.axisValue)) +'</span></div>';
    html += '<div class="tooltips-item"><span class="name">最新</span><span class="value '+ colorCls((typeof x.data == 'number' ? x.data : x.data[1])) +'">'+ (typeof x.data == 'number' ? x.data : x.data[1]) +'</span></div>';
    html += '<div class="tooltips-item"><span class="name">漲跌幅</span><span class="value '+ colorCls((typeof x.data == 'number' ? x.data : x.data[1])) +'">'+ ((((typeof x.data == 'number' ? x.data : x.data[1]) - lastPrice)/ lastPrice * 100).toFixed(2)) +'%</span></div>';
    html += '<div class="tooltips-item"><span class="name">漲跌額</span><span class="value '+ colorCls((typeof x.data == 'number' ? x.data : x.data[1])) +'">'+ ((typeof x.data == 'number' ? x.data : x.data[1])- lastPrice).toFixed(2) +'</span></div>';
    html += '<div class="tooltips-item"><span class="name">成交量</span><span class="value">'+ (typeof c.data == 'number' ? (c.data / 1000000).toFixed(2) : (c.data[1] / 1000000).toFixed(2)) +'萬手</span></div>';

    return html;
}

部分CSS

#charts{
    /*折線圖的寬度*/
    width:640px;
    /*折線圖的高度*/
    height:390px;
}
.tooltips-item{
    display:flex;
    display:-webkit-flex;
    justify-content: space-between;
    color:#33333c;
    font-size:10px;
    width:120px;
}
.green{
    color:#009933
}
.red{
    color:#E24528
}

到這里,提示框的配置也完成了。仿分時圖系列就結束了。

最終效果圖如下

  

 完整的代碼

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>分時圖</title>
        <script type="text/javascript" src="js/jQuery.js" ></script>
        <script type="text/javascript" src="js/echarts.min.js" ></script>
        <style>
            #charts{
                /*折線圖的寬度*/
                width:640px;
                /*折線圖的高度*/
                height:390px;
            }
            .tooltips-item{
                display:flex;
                display:-webkit-flex;
                justify-content: space-between;
                color:#33333c;
                font-size:10px;
                width:120px;
            }
            .green{
                color:#009933
            }
            .red{
                color:#E24528
            }
        </style>
    </head>
    <body>
        <div id="charts">
            
        </div>
        <script type="text/javascript">
            // 雪球json數據 到雪球網站獲取 https://stock.xueqiu.com/v5/stock/chart/minute.json?symbol=SH000001&period=1d
            var jsonData = '';            
            var data = JSON.parse(jsonData);
            
            // 第一個grid的數據(折線圖)
            var grid1Data = [];
            // 第二個grid的數據(柱狀圖)
            var grid2Data = [];
            // 第三個grid數據(折線圖)
            var grid3Data = [];
            var grid3DateData = [];
            // 第四個grid數據(柱狀圖)
            var grid4Data = [];
            var grid4DateData = [];
            
            // 柱狀圖的顏色
            // 柱狀圖的紅綠規則比較麻煩,所以本次采用的規則則是根據價格的漲跌來區分
            var volumeColor1 = [];
            var volumeColor2 = [];
            
            var UP_COLOR = "#E24528";
            var DOWN_COLOR = "#009933";
            var NORMAL_COLOR = "#33353C";
            
            var priceMax = 0,priceMin = 0,priceInterval = 0,volumeMax = 0,volumeMin = 0,volumeInterval = 0;
            var lastPrice = data.data.last_close;
            
            initData();
            
            function colorCls(num){
                if(num > lastPrice){
                    return "red";
                }else if(num == lastPrice){
                    return "";
                }
                return "green";
            }
            
            function initData(){
            
                for(var i in data.data.items){
                    // 上午的數據
                    if(i < 121){
                        if(data.data.items[i].current > priceMax){
                            priceMax = data.data.items[i].current;
                        }
                        if(data.data.items[i].current < priceMin || priceMin == 0){
                            priceMin = data.data.items[i].current;
                        }
                        // 左上方折線圖
                        grid1Data.push([data.data.items[i].timestamp,data.data.items[i].current]);
                        
                        if(data.data.items[i].volume > volumeMax){
                            volumeMax = data.data.items[i].volume;
                        }
                        if(data.data.items[i].volume < volumeMin ){
                            volumeMin = data.data.items[i].volume;
                        }
                         
                         if(i == 0){
                             
                             if(data.data.items[i].current >= lastPrice){
                                 volumeColor1.push(UP_COLOR);
                             }else{
                                 volumeColor1.push(DOWN_COLOR);
                             }
                             
                         }else{
                             if(data.data.items[i].current >= data.data.items[i-1].current){
                                 volumeColor1.push(UP_COLOR);
                             }else{
                                 volumeColor1.push(DOWN_COLOR);
                             }
                             
                         }
                         
                        // 左下方柱狀圖
                        grid2Data.push([data.data.items[i].timestamp,data.data.items[i].volume]);
                        
                    }else{// 下午的數據
                        
                        
                        if(data.data.items[i].current > priceMax){
                            priceMax = data.data.items[i].current;
                        }
                        if(data.data.items[i].current < priceMin || priceMin == 0){
                            priceMin = data.data.items[i].current;
                        }
                        // 第三grid的數據先添加一條數據
                        if(grid3Data.length == 0){        
                            grid3Data.push(data.data.items[i-1].current);
                            grid3DateData.push(data.data.items[i-1].timestamp);
                        }
                        // 右上方折線圖
                        grid3Data.push(data.data.items[i].current);
                        grid3DateData.push(data.data.items[i].timestamp);
                        
                        
                        if(data.data.items[i].volume > volumeMax){
                            volumeMax = data.data.items[i].volume;
                        }
                        if(data.data.items[i].volume < volumeMin){
                            volumeMin = data.data.items[i].volume;
                        }
                        
                        if(data.data.items[i].current >= data.data.items[i-1].current){
                             volumeColor2.push(UP_COLOR);
                         }else{
                             volumeColor2.push(DOWN_COLOR);
                         }
                    
                        // 第四grid的數據先添加一條數據
                        if(grid4Data.length == 0){
                            grid4Data.push(data.data.items[i-1].volume);
                            grid4DateData.push(data.data.items[i-1].timestamp);
                        }
                        // 右下方柱狀圖
                        grid4Data.push(data.data.items[i].volume);
                        grid4DateData.push(data.data.items[i].timestamp);
                        
                        
                    }
                }
                
                // 重新計算價格的最大最小值,以達到對稱的效果
                if((lastPrice - priceMax) * -1 > (lastPrice - priceMin)){
                    priceMin = (lastPrice - ((lastPrice - priceMax)* -1));
                }else{
                    priceMax =(lastPrice + (lastPrice - priceMin));
                }
                
                priceInterval = (priceMax - lastPrice) / 4;
                volumeInterval = volumeMax / 2;
                
                setOptions();
            }
            
            function setOptions(){
                
                var nowDate;
                
                // 初始化一個echarts的對象
                var chart =  echarts.init(document.getElementById('charts'));
                
                // echarts折線圖的配置項
                var option = {
                    animation:false,
                    //坐標軸指示器
                    axisPointer:{
                        show:true,
                        // 配置線條風格為虛線風格
                        lineStyle:{
                            type:'dashed'
                        },
                        link:[
                            {
                                xAxisIndex:[0,1],
                            },{
                                xAxisIndex:[2,3],
                            },{
                                yAxisIndex:[0,2]
                            },{
                                yAxisIndex:[1,3]
                            }
                        ]
                    },
                    // 懸浮框
                    tooltip:{
                        trigger:'axis',
                        position:function(point, params, dom, rect, size){
                            var obj ={
                                top:10
                            }
                            
                            console.log(size);
                            
                            if(point[0] > size.viewSize[0] / 2){
                                obj["left"] = 70;
                            }else{
                                obj["right"] = 70;
                            }

                            return obj;
                        },
                        formatter:function(params,ticket,callback){
                            var html = '';
                            var x,j,c;
            
                            for(var d in params){
                                if(params[d].seriesName == '成交量1' || params[d].seriesName == '成交量2' ){
                                    c = params[d];
                                }
                                if(params[d].seriesName == '最新1' || params[d].seriesName == '最新2' ){
                                    x = params[d];
                                }

                            }
                             
                            if(!c.axisValue){
                                return;
                            }
                            
            
                            html += '<div class="tooltips-item"><span class="name">時間</span><span class="value">'+ echarts.format.formatTime('MM-dd hh:mm',parseFloat(c.axisValue)) +'</span></div>';
                            html += '<div class="tooltips-item"><span class="name">最新</span><span class="value '+ colorCls((typeof x.data == 'number' ? x.data : x.data[1])) +'">'+ (typeof x.data == 'number' ? x.data : x.data[1]) +'</span></div>';
                            html += '<div class="tooltips-item"><span class="name">漲跌幅</span><span class="value '+ colorCls((typeof x.data == 'number' ? x.data : x.data[1])) +'">'+ ((((typeof x.data == 'number' ? x.data : x.data[1]) - lastPrice)/ lastPrice * 100).toFixed(2)) +'%</span></div>';
                            html += '<div class="tooltips-item"><span class="name">漲跌額</span><span class="value '+ colorCls((typeof x.data == 'number' ? x.data : x.data[1])) +'">'+ ((typeof x.data == 'number' ? x.data : x.data[1])- lastPrice).toFixed(2) +'</span></div>';
                            html += '<div class="tooltips-item"><span class="name">成交量</span><span class="value">'+ (typeof c.data == 'number' ? (c.data / 1000000).toFixed(2) : (c.data[1] / 1000000).toFixed(2)) +'萬手</span></div>';

                            return html;
                        },
                        textStyle:{
                            color:"#000"
                        },
                        borderWidth:1,
                        borderColor:"#ECEEF2",
                        backgroundColor:"rgba(255,255,255,0.9)",
                        transitionDuration:0,
                        axisPointer:{
                            animation:false,
                            type:"cross"
                        }
                    },
                    // grid
                    grid:[
                        // 第一個grid
                        {
                            top:10,// 圖表的外邊距
                            height:240,// 圖表的高度
                            left:'5%',
                            width:'45%',//因為是左右各一個圖表,使用百分比的方式顯得更方便,
                        },
                        // 第二個grid,第二個圖表是在第一個圖表的下方,所以要把它定位到底部
                        {
                            top:280,//設置上方的外邊距是第一個圖表的高度再加10,使用top是方便我們調整下方grid的高度
                            left:'5%',
                            width:'45%',// 寬度與第一個圖表一個大
                            height:80,
                        },
                        // 第三個grid,第三個圖表是在第一個圖表的右方,所以要把它定位到右方
                        {
                            top:10,// 圖表的外邊距
                            left:'50%',//設置右邊圖表的左邊距是第一個圖表的大小,達到定位右邊的效果
                            width:'45%',// 寬度與第一個圖表一個大
                            height:240,
                        },
                        // 第四個grid,第四個圖表是在第三個圖表的下方,所以要把它定位到底部
                        {
                            top:280,//設置上方的外邊距是第三個圖表的高度再加10,使用top是方便我們調整下方grid的高度
                            left:'50%',//設置右邊圖表的左邊距是第三個圖表的大小,達到定位右邊的效果
                            width:'45%',// 寬度與第一個圖表一個大
                            height:80,
                        }
                    ],
                    // 多個圖表則會存在對個x軸y軸,所以這里的配置我們也換成數組的方式
                    // x軸配置,
                    xAxis:[
                            // 第一個grid的x軸屬性
                            {
                                
                                // 告訴echarts,這個第一個grid的x軸
                                gridIndex:0,
                                // 坐標軸是否留白
                                boundaryGap:false,
                                // x軸的刻度
                                axisTick:{show:false},
                                // x軸的刻度值
                                axisLabel:{show:false},
                                max:'dataMax',
                                min:'dataMin',
                                type: 'time',
                                axisPointer:{
                                    show:true,
                                    label:{
                                        show:false
                                    }
                                },
                                axisLine:{
                                    lineStyle:{
                                        color:"#ECEEF2"
                                    }
                                },
                                splitLine:{
                                    lineStyle:{
                                        color:"#ECEEF2",
                                        type:"solid"
                                    }
                                },
                            },
                            // 第二個grid的x軸屬性
                            {
                                // 告訴echarts,這個第一個grid的x軸
                                gridIndex:1,
                                // 坐標軸是否留白
                                boundaryGap:false,
                                // x軸的刻度
                                axisTick:{show:false},
                                max:'dataMax',
                                min:"dataMin",
                                type: 'time',
                                axisLabel: {
                                    fontSize:12,
                                    show: true,
                                    color:'#888',
                                    formatter: function (value) {
                                        var a = echarts.format.formatTime('hh:mm', value);
                                        if(a == "11:30"){
                                            return "11:30/13:00";
                                        }
                                        if(a == "09:30"){
                                            return "        09:30";
                                        }
                                        return a;
                                    }
                                },
                                axisLine:{
                                    lineStyle:{
                                        color:"#ECEEF2"
                                    }
                                },
                                splitLine:{
                                    lineStyle:{ 
                                        color:"#ECEEF2",
                                        type:"solid"
                                    }
                                },
                                axisPointer:{
                                    show:true,
                                    type:"line",
                                    label:{
                                        show:true,
                                        fontSize:10,
                                        margin:0,
                                        padding:2,
                                        shadowBlur:0,
                                        color:"#33353C",
                                        formatter:function(data){
                                            return echarts.format.formatTime('hh:mm', parseFloat(data.value))
                                        }
                                    },
                                },
                            },
                            // 第三個grid的x軸屬性
                            {
                                // 告訴echarts,這個第一個grid的x軸
                                gridIndex:2,
                                // 坐標軸是否留白
                                boundaryGap:false,
                                // x軸的刻度
                                axisTick:{show:false},
                                // x軸的刻度值
                                axisLabel:{show:false},
                                type: 'category',
                                data:grid3DateData,
                                axisLine:{
                                    lineStyle:{
                                        color:"#ECEEF2"
                                    }
                                },
                                max:"dataMax",
                                min:"dataMin",
                                axisPointer:{
                                    show:true,
                                    label:{
                                        show:false
                                    }
                                },
                                splitLine:{
                                    show:true,
                                    lineStyle:{
                                        color:"#ECEEF2",
                                        type:"solid"
                                    },
                                    interval:function(index,value){
                                        if(index == 0 || index == 1){
                                            return false;
                                        }
                                        
                                        if((index - 1) % 30 == 0){
                                            return true;
                                        }
                                        return false;
                                    },
                                },
                            },
                            // 第四個grid的x軸屬性
                            {
                                // 告訴echarts,這個第一個grid的x軸
                                gridIndex:3,
                                // 坐標軸是否留白
                                boundaryGap:false,
                                // x軸的刻度
                                axisTick:{
                                    show:false
                                },
                                type: 'category',
                                max:"dataMax",
                                min:"dataMin",
                                data:grid4DateData,
                                axisLabel: {
                                    fontSize:12,
                                    show: true,
                                    showMinLabel:false,
                                    color:'#888',
                                    interval:function(index,value){
                                        
                                        if((index - 1)  % 30 == 0){
                                            return true;
                                        }
                                        return false;
                                    },
                                    formatter: function (value) {
                                        var a = echarts.format.formatTime('hh:mm', parseFloat(value));
                                        if(a == "15:00"){
                                            return "15:00        ";
                                        }
                                        return a;
                                    }
                                },
                                axisLine:{
                                    lineStyle:{
                                        color:"#ECEEF2"
                                    }
                                },
                                splitLine:{
                                    show:true,
                                    lineStyle:{
                                        color:"#ECEEF2",
                                        type:"solid"
                                    },
                                    interval:function(index,value){
                                        // 第一條第二條線是不需要顯示的,第一條是11:30的,第一個grid已經有這條數據了,所以不需要顯示
                                        // 第二條顯示的話,在中間部分會出現2條線,所以也不要顯示
                                        if(index == 0 || index == 1){
                                            return false;
                                        }
                                        // 這里的意思是第一條數據后,每30分鍾顯示一條線
                                        if((index - 1) % 30 == 0){
                                            return true;
                                        }
                                        return false;
                                    },
                                },
                                axisPointer:{
                                    show:true,
                                    type:"line",
                                    label:{
                                        show:true,
                                        fontSize:10,
                                        margin:0,
                                        padding:2,
                                        shadowBlur:0,
                                        color:"#33353C",
                                        formatter:function(data){
                                            return echarts.format.formatTime('hh:mm', parseFloat(data.value));
                                        }
                                    },
                                },
                            }
                        ],
                    // y軸配置
                    yAxis: [
                        // 第一個grid的y軸屬性
                        {    
                            // 去掉刻度值旁邊的指示線
                            axisTick:{show:false},
                            splitNumber:9,
                            gridIndex:0,
                            interval:priceInterval,
                            max:priceMax,
                            min:priceMin,
                            splitLine:{
                                lineStyle:{
                                    color:"#ECEEF2",
                                    type:"solid",
                                }
                            },
                            axisLine:{
                                lineStyle:{
                                    color:"#ECEEF2"
                                }
                            },
                            axisLabel:{
                                fontSize:10,
                                margin:0,
                                // y軸的數值向內顯示
                                align:"left",
                                formatter: function (value, index) {
                                    return value.toFixed(2);
                                },
                                color: function (value, index) {
                                    
                                    // 中間基准線的數值為黑色
                                    if(parseFloat(value).toFixed(2) == lastPrice){
                                        return NORMAL_COLOR;
                                    }
                                    
                                    // 上漲區域的數字為紅色
                                    if(value > lastPrice){
                                        return UP_COLOR;
                                    }
                                    
                                    // 下方下跌的數值為綠色
                                    if(value < lastPrice){
                                        return DOWN_COLOR;
                                    }
                                    
                                }
                            },
                            z:3,
                            axisPointer:{
                                show:true,
                                type:"line",
                                label:{
                                    show:true,
                                    fontSize:10,
                                    margin:-44,
                                    padding:2,
                                    shadowBlur:0,
                                    color:"#33353C",
                                    formatter:function(data){
                                        
                                        return data.value.toFixed(2);
                                    }
                                },
                            },
                        },
                        // 第二個grid的y軸屬性
                        {
                            // 去掉刻度值旁邊的指示線
                            axisTick:{show:false},
                            splitNumber:3,
                            gridIndex:1,
                            interval:volumeInterval,
                            max:volumeMax,
                            min:0,
                            splitLine:{
                                lineStyle:{
                                    color:"#ECEEF2",
                                    type:"solid"
                                }
                            },
                            axisLine:{
                                lineStyle:{
                                    color:"#ECEEF2"
                                }
                            },
                            axisPointer:{
                                show:true,
                                type:"line",
                                label:{
                                    show:true,
                                    fontSize:10,
                                    padding:2,
                                    shadowBlur:0,
                                    color:"#33353C",
                                    formatter:function(data){
                                        if(data.value > 1000000){
                                               return parseFloat(data.value / 1000000).toFixed(2)+"萬手";
                                           }
                                        return data.value;
                                    }
                                },
                            },
                            axisLabel:{
                                align:"left",
                                verticalAlign:"top",
                                //設置顯示坐標軸的數值為不顯示
                                show:true,
                                fontSize:10,
                                margin:0,
                                showMaxLabel:true,
                                showMinLabel:false,
                                color:"#33353C",
                                formatter: function (value, index) {
                                    // 格式化成月/日,只在第一個刻度顯示年份 
                                   if(value == volumeMax){
                                           // 方便演示
                                           if(value > 1000000){
                                               value = parseFloat(value / 1000000).toFixed(2)+"萬手"
                                           }
                                           
                                           return value;
                                   }
                                   return "";
                                }
                            },
                        },
                        // 第三個grid的y軸屬性
                        {
                            // 去掉刻度值旁邊的指示線
                            axisTick:{show:false},
                            splitNumber:9,
                            position:'right',
                            gridIndex:2,
                            interval:priceInterval,
                            max:priceMax,
                            min:priceMin,
                            splitLine:{
                                lineStyle:{
                                    color:"#ECEEF2",
                                    type:"solid"
                                }
                            },
                            axisLine:{
                                lineStyle:{
                                    color:"#ECEEF2"
                                }
                            },
                            axisLabel:{
                                fontSize:10,
                                margin:0,
                                // y軸的數值向內顯示
                                align:"right",
                                formatter: function (value, index) {
                                    var persent = (value - lastPrice) / lastPrice;
                                    persent = (persent < 0) ? persent * -1 : persent;
                                    persent = persent * 100;
            
                                    return persent.toFixed(2) + '%';
                                },
                                color: function (value, index) {
                                    
                                    // 中間基准線的數值為黑色
                                    if(parseFloat(value).toFixed(2) == lastPrice){
                                        return NORMAL_COLOR;
                                    }
                                    
                                    // 上漲區域的數字為紅色
                                    if(value > lastPrice){
                                        return UP_COLOR;
                                    }
                                    
                                    // 下方下跌的數值為綠色
                                    if(value < lastPrice){
                                        return DOWN_COLOR;
                                    }
                                    
                                }
                            },
                            z:3,
                            axisPointer:{
                                show:true,
                                type:"line",
                                label:{
                                    show:true,
                                    fontSize:10,
                                    margin:-34,
                                    padding:2,
                                    shadowBlur:0,
                                    color:"#33353C",
                                    formatter:function(data){
                                        var persent = (data.value - lastPrice) / lastPrice;
                                        persent = (persent < 0) ? persent * -1 : persent;
                                        persent = persent * 100;
                
                                        return persent.toFixed(2) + '%';
                                    }
                                },
                            },
                        },
                        // 第四個grid的y軸屬性
                        {
                            // 去掉刻度值旁邊的指示線
                            axisTick:{show:false},
                            splitNumber:3,
                            position:'right',
                            gridIndex:3,
                            interval:volumeInterval,
                            max:volumeMax,
                            min:0,
                            axisLabel:{
                                //設置顯示坐標軸的數值為不顯示
                                show:false
                            },
                            splitLine:{
                                lineStyle:{
                                    color:"#ECEEF2",
                                    type:"solid"
                                }
                            },
                            axisPointer:{
                                show:true,
                                label:{
                                    show:false
                                }
                            },
                            axisLine:{
                                lineStyle:{
                                    color:"#ECEEF2"
                                }
                            },
                        }
                    ],
                    // 數據可以通過xAxisIndex,yAxisIndex屬性,來指定是哪個grid的數據
                    series: [
                        // 第一個圖表的數據
                        {
                            name:"最新1",
                            // 平滑曲線
                            smooth:true,
                            // 是否顯示折線上的圓點
                            symbol:'none',
                            // 線條顏色
                            lineStyle:{
                                color:"#0481F8",
                                width:1
                            },
                            xAxisIndex:0,
                            yAxisIndex:0,
                            data: grid1Data,
                            type: 'line',
                            z:3,
                            areaStyle:{
                                color:"#F8FAFF"
                            }
                        },
                         // 第二個圖表的數據
                        {
                            name:"成交量1",
                            xAxisIndex:1,
                            yAxisIndex:1,
                            // 柱狀圖柱子寬度
                            barWidth:1,
                            data: grid2Data,
                            type: 'bar',
                            // 設置柱狀圖顏色
                            itemStyle:{
                                normal: {
                                    color: function (params) {
                                        return volumeColor1[params.dataIndex];
                                    }
                                }
                            }
                        },
                         // 第三個圖表的數據
                        {
                            name:"最新2",
                            // 平滑曲線
                            smooth:true,
                            // 是否顯示折線上的圓點
                            symbol:'none',
                            // 線條顏色
                            lineStyle:{
                                color:"#0481F8",
                                width:1
                            },
                            z:3,
                            xAxisIndex:2,
                            yAxisIndex:2,
                            data: grid3Data,
                            type: 'line',
                            areaStyle:{
                                color:"#F8FAFF"
                            }
                        },
                         // 第四個圖表的數據
                        {
                            name:"成交量2",
                            xAxisIndex:3,
                            yAxisIndex:3,
                            // 柱狀圖柱子寬度
                            barWidth:1,
                            data: grid4Data,
                            type: 'bar',
                            // 設置柱狀圖顏色
                            itemStyle:{
                                normal: {
                                    color: function (params) {
                                        return volumeColor2[params.dataIndex];
                                    }
                                }
                            }
                        }
                    ]
                };
                
                chart.setOption(option);
                
            }

        </script>
    </body>
</html>

 

  總結:一開始做分時圖的時候我也不懂從哪開始做,慢慢觀察后才發現其實可以由折線圖跟柱狀圖來拼接而成。知道拼接可以達到效果后,就開始寫代碼,期間也是遇到了很多問題,最開始是用兩個echarts來組合,發現效果很丑,去查了一下文檔,發現可以用grid來解決,接着就拆成了上下兩個grid;然后上下午時間段這個問題,由於不是連續的,所以一個折線圖解決不了,再次拆圖表,把上下方的圖表再一拆為二,拆成了兩個后折線圖出現了斷崖式的效果,經過很多嘗試后,把x軸的type修改成category屬性,再對下午數據進行一些修改才解決了這個問題。做復雜的圖表時,可以先分析一下這個圖表可以由哪些圖表來組成,然后再根據需求來對各個圖表進行修改。echarts這個框架還是很好用的,圖表類型豐富,文檔全,能夠高度自定義,重要還是免費的...

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM