使用百度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这里有一段是没有连接上的,因为是两个图表的原因所以会断开,这个将在下一章修正。下一章我们将添加图表的一些指示器,修正一些小问题。

猜你喜欢

转载自www.cnblogs.com/jellybean961/p/11232365.html
今日推荐