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


這章節將完成我們的分時圖,並使用真實的數據來進行展示分時圖。

一天的交易時間段分為上午的09:30~11:30,下午的13:00~15:00兩個時間段,因為分時間段的關系,數據是不連續的,所以會先分為2個grid,上午的grid跟下午的grid,又因為分時圖是由折線圖跟柱狀圖來組成的,所以又把上下午的grid再一分為二,變成了4個grid,這也是為什么會分解成4個grid的原因。

 

先看看分時圖的數據。

現在我們再重新看一下雪球的分時圖

根路徑的last_price指的是昨日收盤價,這個數值很重要,我們需要這個數值來建立一條基准線;然后items里面就是今天的交易數據了,current表示這一分鍾應該取的價格,一般是指一分鍾內最后一筆成交的價格,也是折線圖的數據;volume則是這一分鍾的成交量,也就是下方柱狀圖的數據;timestamp表示這是哪個時間的數據,我們用來作為x軸的數據。

將x軸的type設置成“time”。為了方便我們也把坐標軸的最大最小值設置成隨數據的最大最小值,把max設置成"dataMax",min設置成"dataMin"。

type: 'time',
max:'dataMax',
min:'dataMin'

y軸也是需要進行一些配置,已達到完全對稱的效果,需要配置interval屬性以及max,min屬性。x軸的時間是已經固定了09:30~11:30,13:00~15:00,所以可以直接寫死,但是y軸的價格是會波動的,所以這三個數值是要經過運算得來的。

我們先配置上方的折線圖的y軸坐標軸線為9條,設置splitNumber屬性為9即可,定義變量priceMax、priceMin、priceInterval(priceInterval表示價格的差值),以及左邊的數據數組grid1Data,右邊的數據數組grid3Data。(注:由於x軸的type修改成了'time'類型,所以去掉x軸的data屬性)。下方的柱狀圖也是這樣,下方的柱狀圖一共是3條坐標軸線,設置splitNumber屬性為3即可,定義變量volumeMax,volumeMin,volumeInterval(volumeInterval表示價格的差值),以及左邊的數據數組grid2Data,右邊的數據數組grid4Data;柱狀圖每一條柱子的顏色設置方式為

color: function (params) {
   // params.dataIndex 柱子的下標
return "#000"; }

所以要新建兩個數組volumeColor1,volumeColor2來存放柱子的顏色。接下來,我們要遍歷我們拿到的分時圖數據data,來組成我們需要的數據。

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;
                        }
                        // 右上方折線圖
                        grid3Data.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(data.data.items[i].current >= data.data.items[i-1].current){
                             volumeColor2.push(UP_COLOR);
                         }else{
                             volumeColor2.push(DOWN_COLOR);
                         }
                    
                        // 右下方柱狀圖
                        grid4Data.push([data.data.items[i].timestamp,data.data.items[i].volume]);
                        
                    }
                }

遍歷完成后,得到了價格的最大最小值,成交量的最大值,接下來還要處理一下價格的最大最小值,以達到對稱的效果。列入,昨日收盤價是1,今日最高價是上漲了0.5塊,最高價是1+0.5 = 1.5塊,那么為了達到對稱的效果,下方的價格線應該是1-0.5=0.5塊。

// 重新計算價格的最大最小值,以達到對稱的效果
                if((lastPrice - priceMax) * -1 > (lastPrice - priceMin)){
                    priceMin = (lastPrice - ((lastPrice - priceMax)* -1));
                }else{
                    priceMax =(lastPrice + (lastPrice - priceMin));
                }
                
                priceInterval = (priceMax - lastPrice) / 4;
                volumeInterval = volumeMax / 2;

重新計算了最大最小價格,並得到了價格的差值,成交量的差值,把這些數值設置到對應的位置上。第一個跟第三個grid的y軸屬性max,min,interval分別設置成priceMax,priceMin,priceInterval;第二個跟第四個grid的y軸屬性max,min,interval分別設置成volumeMax,0,volumeInterval。然后我們會發現,y軸上的值的小數位非常大,x軸上顯示的是月日時分的格式,所以還要對這些顯示的數值進行格式化。首先對y軸的數據進行格式化,左上方的y軸設置:

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;
                                    }
                                    
                                }
                            },

右上方的y軸的設置:

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;
                                    }
                                    
                                }
                            },

下方的柱狀圖的y軸數值則隱藏不顯示,只需要把第二個第四個grid的y軸的axisLabel.show設置成false即可

axisLabel:{
    //設置顯示坐標軸的數值為不顯示
       show:false
 },

然后重新對x軸的時間進行格式化成HH:mm的格式,只需要對第二個跟第四個grid的x軸進行配置即可。

第二個grid的x軸的配置

axisLabel: {
                                    fontSize:12,
                                    show: true,
                                    color:'#888',
                                    formatter: function (value) {
                                        var a = echarts.format.formatTime('hh:mm', value);
                                        if(a == "11:30"){
                                            return "";
                                        }
                                        if(a == "09:30"){
                                            return "        09:30";
                                        }
                                        return a;
                                    }
                                },

第四個grid的x軸的配置

axisLabel: {
                                    fontSize:12,
                                    show: true,
                                    showMinLabel:false,
                                    color:'#888',
                                    formatter: function (value) {
                                        var a = echarts.format.formatTime('hh:mm', value);
                                        if(a == "13:00"){
                                            return "11:30/13:00";
                                        }
                                        if(a == "15:00"){
                                            return "15:00        ";
                                        }
                                        return a;
                                    }
                                },

接下來配置一下柱狀圖的柱子顏色。在series里找到柱狀圖的配置,對itemStyle進行配置即可。

第一個柱狀圖的配置

itemStyle:{
                                normal: {
                                    color: function (params) {
                                        return volumeColor1[params.dataIndex];
                                    }
                                }
                            }

第二個柱狀圖的配置

itemStyle:{
                                normal: {
                                    color: function (params) {
                                        return volumeColor2[params.dataIndex];
                                    }
                                }
                            }

最后我們把各個坐標軸的小尖刺,就是刻度值旁邊的短線去掉。把各個坐標軸的axisTick.show設置成false即可。

axisTick:{show:false}

做完這一步后,我們的代碼就成了這樣

// 雪球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 = [];
            // 第四個grid數據(柱狀圖)
            var grid4Data = [];
            
            // 柱狀圖的顏色
            // 柱狀圖的紅綠規則比較麻煩,所以本次采用的規則則是根據價格的漲跌來區分
            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 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;
                        }
                        // 右上方折線圖
                        grid3Data.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(data.data.items[i].current >= data.data.items[i-1].current){
                             volumeColor2.push(UP_COLOR);
                         }else{
                             volumeColor2.push(DOWN_COLOR);
                         }
                    
                        // 右下方柱狀圖
                        grid4Data.push([data.data.items[i].timestamp,data.data.items[i].volume]);
                        
                    }
                }
                
                
                // 重新計算價格的最大最小值,以達到對稱的效果
                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(){
                
                // 初始化一個echarts的對象
                var chart =  echarts.init(document.getElementById('charts'));
                
                // echarts折線圖的配置項
                var option = {
                    // grid
                    grid:[
                        // 第一個grid
                        {
                            top:10,// 圖表的外邊距
                            height:200,// 圖表的高度
                            left:'0',
                            width:'50%',//因為是左右各一個圖表,使用百分比的方式顯得更方便,
                        },
                        // 第二個grid,第二個圖表是在第一個圖表的下方,所以要把它定位到底部
                        {
                            top:240,//設置上方的外邊距是第一個圖表的高度再加10,使用top是方便我們調整下方grid的高度
                            left:'0',
                            width:'50%',// 寬度與第一個圖表一個大
                            height:100
                        },
                        // 第三個grid,第三個圖表是在第一個圖表的右方,所以要把它定位到右方
                        {
                            top:10,// 圖表的外邊距
                            left:'50%',//設置右邊圖表的左邊距是第一個圖表的大小,達到定位右邊的效果
                            width:'50%',// 寬度與第一個圖表一個大
                            height:200
                        },
                        // 第四個grid,第四個圖表是在第三個圖表的下方,所以要把它定位到底部
                        {
                            top:240,//設置上方的外邊距是第三個圖表的高度再加10,使用top是方便我們調整下方grid的高度
                            left:'50%',//設置右邊圖表的左邊距是第三個圖表的大小,達到定位右邊的效果
                            width:'50%',// 寬度與第一個圖表一個大
                            height:100
                        }
                    ],
                    // 多個圖表則會存在對個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',
                                axisLine:{
                                    lineStyle:{
                                        color:"#ECEEF2"
                                    }
                                },
                                splitLine:{
                                    lineStyle:{
                                        color:"#ECEEF2",
                                    // 設置線條喂風格為虛線
                                        type:"dashed"
                                    }
                                },
                            },
                            // 第二個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 "";
                                        }
                                        if(a == "09:30"){
                                            return "        09:30";
                                        }
                                        return a;
                                    }
                                },
                                axisLine:{
                                    lineStyle:{
                                        color:"#ECEEF2"
                                    }
                                },
                                splitLine:{
                                    lineStyle:{
                                        color:"#ECEEF2",
                                    // 設置線條喂風格為虛線
                                        type:"dashed"
                                    }
                                },
                            },
                            // 第三個grid的x軸屬性
                            {
                                // 告訴echarts,這個第一個grid的x軸
                                gridIndex:2,
                                // 坐標軸是否留白
                                boundaryGap:false,
                                // x軸的刻度
                                axisTick:{show:false},
                                // x軸的刻度值
                                axisLabel:{show:false},
                                type: 'time',
                                max:'dataMax',
                                min:'dataMin',
                                axisLine:{
                                    lineStyle:{
                                        color:"#ECEEF2"
                                    }
                                },
                                splitLine:{
                                    lineStyle:{
                                        color:"#ECEEF2",
                                    // 設置線條喂風格為虛線
                                        type:"dashed"
                                    }
                                },
                            },
                            // 第四個grid的x軸屬性
                            {
                                // 告訴echarts,這個第一個grid的x軸
                                gridIndex:3,
                                // 坐標軸是否留白
                                boundaryGap:false,
                                // x軸的刻度
                                axisTick:{show:false},
                                type: 'time',
                                max:'dataMax',
                                min:'dataMin',
                                axisLabel: {
                                    fontSize:12,
                                    show: true,
                                    showMinLabel:false,
                                    color:'#888',
                                    formatter: function (value) {
                                        var a = echarts.format.formatTime('hh:mm', value);
                                        if(a == "13:00"){
                                            return "11:30/13:00";
                                        }
                                        if(a == "15:00"){
                                            return "15:00        ";
                                        }
                                        return a;
                                    }
                                },
                                axisLine:{
                                    lineStyle:{
                                        color:"#ECEEF2"
                                    }
                                },
                                splitLine:{
                                    lineStyle:{
                                        color:"#ECEEF2",
                                    // 設置線條喂風格為虛線
                                        type:"dashed"
                                    }
                                },
                            }
                        ],
                    // y軸配置
                    yAxis: [
                        // 第一個grid的y軸屬性
                        {    
                            // 去掉刻度值旁邊的指示線
                            axisTick:{show:false},
                            splitNumber:9,
                            gridIndex:0,
                            interval:priceInterval,
                            max:priceMax,
                            min:priceMin,
                            splitLine:{
                                lineStyle:{
                                    color:"#ECEEF2",
                                    // 設置線條喂風格為虛線
                                    type:"dashed",
                                }
                            },
                            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;
                                    }
                                    
                                }
                            },
                        },
                        // 第二個grid的y軸屬性
                        {
                            // 去掉刻度值旁邊的指示線
                            axisTick:{show:false},
                            splitNumber:3,
                            gridIndex:1,
                            interval:volumeInterval,
                            max:volumeMax,
                            min:0,
                            splitLine:{
                                lineStyle:{
                                    color:"#ECEEF2",
                                    // 設置線條喂風格為虛線
                                    type:"dashed"
                                }
                            },
                            axisLine:{
                                lineStyle:{
                                    color:"#ECEEF2"
                                }
                            },
                            axisLabel:{
                                //設置顯示坐標軸的數值為不顯示
                                show:false
                            },
                        },
                        // 第三個grid的y軸屬性
                        {
                            // 去掉刻度值旁邊的指示線
                            axisTick:{show:false},
                            splitNumber:9,
                            position:'right',
                            gridIndex:2,
                            interval:priceInterval,
                            max:priceMax,
                            min:priceMin,
                            splitLine:{
                                lineStyle:{
                                    color:"#ECEEF2",
                                    // 設置線條喂風格為虛線
                                    type:"dashed"
                                }
                            },
                            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;
                                    }
                                    
                                }
                            },
                        },
                        // 第四個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:"dashed"
                                }
                            },
                            axisLine:{
                                lineStyle:{
                                    color:"#ECEEF2"
                                }
                            },
                        }
                    ],
                    // 數據可以通過xAxisIndex,yAxisIndex屬性,來指定是哪個grid的數據
                    series: [
                        // 第一個圖表的數據
                        {
                            // 平滑曲線
                            smooth:true,
                            // 是否顯示折線上的圓點
                            symbol:'none',
                            // 線條顏色
                            lineStyle:{
                                color:"#0481F8",
                                width:1
                            },
                            xAxisIndex:0,
                            yAxisIndex:0,
                            data: grid1Data,
                            type: 'line',
                        },
                         // 第二個圖表的數據
                        {
                            xAxisIndex:1,
                            yAxisIndex:1,
                            // 柱狀圖柱子寬度
                            barWidth:1,
                            data: grid2Data,
                            type: 'bar',
                            // 設置柱狀圖顏色
                            itemStyle:{
                                normal: {
                                    color: function (params) {
                                        return volumeColor1[params.dataIndex];
                                    }
                                }
                            }
                        },
                         // 第三個圖表的數據
                        {
                            // 平滑曲線
                            smooth:true,
                            // 是否顯示折線上的圓點
                            symbol:'none',
                            // 線條顏色
                            lineStyle:{
                                color:"#0481F8",
                                width:1
                            },
                            xAxisIndex:2,
                            yAxisIndex:2,
                            data: grid3Data,
                            type: 'line',
                        },
                         // 第四個圖表的數據
                        {
                            xAxisIndex:3,
                            yAxisIndex:3,
                            // 柱狀圖柱子寬度
                            barWidth:1,
                            data: grid4Data,
                            type: 'bar',
                            // 設置柱狀圖顏色
                            itemStyle:{
                                normal: {
                                    color: function (params) {
                                        return volumeColor2[params.dataIndex];
                                    }
                                }
                            }
                        }
                    ]
                };
                
                chart.setOption(option);
                
            }

效果圖如下:

我們的分時圖已經基本完成了,但是我們還是能看到11:30/13:00這里有一段是沒有連接上的,因為是兩個圖表的原因所以會斷開,這個將在下一章修正。下一章我們將添加圖表的一些指示器,修正一些小問題。


免責聲明!

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



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