Vue+Echarts實現(xiàn)分時圖和交易量圖的繪制
1 前言
近來發(fā)現(xiàn)Echarts API越發(fā)的強大,對于繪制各類圖形可以使用Echarts實現(xiàn),前面已經(jīng)介紹了柱狀圖、餅狀圖、折線圖、極坐標圖。對于k線圖,除了前面介紹的vue+Echarts繪制K線圖詳解(一)----基本日K圖繪制以外,k線圖中包含其他多種類型的圖形,休息了半載左右,今天繼續(xù)來進一步深入介紹一下分時圖和成交量圖,為打造一個完整的版面添磚加瓦。
2 分時圖
2.1 vue引入Echarts
前面已經(jīng)介紹過了,還不知道怎么引入的同學請參考以前的教程:在Vue項目中引入 ECharts。
2.2 分時圖介紹
分時圖本質(zhì)上也是一個折線圖,橫坐標為一天交易的每一分鐘,縱坐標為股市的實時單價。除了實現(xiàn)這兩個基本的功能以外,還需要帶上每分鐘交易量圖,當鼠標放在圖上時,要展示當前時間對應的相關(guān)數(shù)據(jù);如下圖所示:
我們本期要實現(xiàn)的功能為:分時折線圖、分時成交量圖,鼠標指示展示詳細數(shù)據(jù),對應成交量顏色劃分;其余的一些細節(jié)的功能(圖切換,細節(jié)顏色以及樣式處理)我們以后再做介紹。
2.3 分時折線圖配置
分時折線圖本質(zhì)上是折線圖,我們通過設置圖類型為折線即可,重點是對數(shù)據(jù)的處理,我們的數(shù)據(jù)源格式是json對象數(shù)組數(shù)據(jù),每一分鐘數(shù)據(jù)如下所示:
{"time":"1678411800","price":"3255.51","ratio":"-0.63%","increase":"-20.58","volume":"2925368","avgPrice":"3261.35","amount":"29.00\u4ebf","timeKey":"0930","datetime":"03-10 09:30","oriAmount":"2900320446","show":"1"},
首先我們需要對數(shù)據(jù)進行處理,才能應用于Echarts之中;我們分時折線圖配置項代碼代碼如下所示:
// 橫坐標數(shù)據(jù)配置 xAxis: [ { type: "category", data: this.xData, boundaryGap: false, axisLine: { onZero: false }, splitLine: { show: false }, min: "dataMin", max: "dataMax" }, ] // 縱坐標配置 yAxis: [ { scale: true, splitArea: { show: true } }, ] //圖形數(shù)據(jù)配置: series: [ { type: "line", data: this.hourData, symbol: "none", //無標記圖案 lineStyle: { width: 1 } }, ]
其中,this.xData是我們vue頁面中的經(jīng)過處理的橫坐標數(shù)據(jù),this.hourData是我們頁面中經(jīng)過處理的每小時數(shù)據(jù)。
注意:series中symbol屬性要設置為none,這樣的到的折線圖上將會不出線標記圖案。
數(shù)據(jù)處理代碼如下:
// 橫坐標數(shù)據(jù)處理 initxData() { for (let i = 0; i < this.klineData.length; i++) { this.xData[i] = this.klineData[i].datetime; } }, // 數(shù)據(jù)計算以及拆分,將json數(shù)據(jù)轉(zhuǎn)為數(shù)組數(shù)據(jù) splitData(jsonData) { const hourData = []; for (let i = 0; i < jsonData.length; i++) { hourData.push([ i, jsonData[i].price, jsonData[i].increase, jsonData[i].volume, jsonData[i].ratio, jsonData[i].amount, jsonData[i].datetime ]); } return hourData; }
其中, this.klineData是我們頁面引入的json數(shù)據(jù)。
到此我們可以來看一下分時折線圖的效果:
可以看到得到的折線圖就是為我們的分時折線圖。
2.4 組合交易量圖
交易量圖為2.2圖中底部的紅綠交間的柱狀圖,交易量圖本質(zhì)是一個柱狀圖,我們可以看到有兩個特點:
1.橫坐標與分時折線圖公用,且柱狀圖在交易圖下方;
2.當前為漲時,柱子為紅色,當前為跌時,柱子為綠色;
對于特點1,在我們之前介紹的圖中,都是公用坐標系的圖,這里新知識點就是不公用坐標系,但是公用橫坐標數(shù)據(jù)應該怎么處理;就是在xAxis、yAxis和series中設置兩個對象出來,代表兩個不同的坐標西,然后將兩個坐標系的橫坐標進行對齊即可;
代碼如下:
// 橫坐標數(shù)據(jù) xAxis: [ // 折線圖 { type: "category", data: this.xData, boundaryGap: false, axisLine: { onZero: false }, splitLine: { show: false }, min: "dataMin", max: "dataMax" }, // 柱狀圖 { type: "category", gridIndex: 1, //x 軸所在的 grid 的索引,默認位于第一個 grid。 data: this.xData, boundaryGap: false, axisLine: { onZero: false }, axisTick: { show: false }, splitLine: { show: false }, axisLabel: { show: false }, min: "dataMin", max: "dataMax" } ], // 縱坐標配置 yAxis: [ { scale: true, splitArea: { show: true } }, { scale: true, gridIndex: 1, // y 軸所在的 grid 的索引,默認位于第一個 grid splitNumber: 2, axisLabel: { show: false }, axisLine: { show: false }, axisTick: { show: false }, splitLine: { show: false } } ], series: [ { type: "line", data: this.hourData, symbol: "none", //無標記圖案 lineStyle: { width: 1 } }, { name: "Volume", type: "bar", xAxisIndex: 1, yAxisIndex: 1, data: this.culomnValue } ]
對于特點2,控制每個柱狀圖顏色不同,我們需要用到visualMap.pieces屬性;官網(wǎng)上對該屬性的說明是:自定義『分段式視覺映射組件(visualMapPiecewise)』的每一段的范圍,以及每一段的文字,以及每一段的特別的樣式。
我們直接上代碼以及講解,來看這個屬性怎么使用,代碼如下:
visualMap: { type: "piecewise", show: false, //不展示map,只應用對應顏色劃分邏輯 seriesIndex: 1, //指定取哪個系列的數(shù)據(jù) dimension: 2, // 定義每一段的顏色 pieces: [ { value: -1, color: this.downColor }, { value: 1, color: this.upcolor } ] },
這段代碼的解釋是:當series的data數(shù)據(jù)里面有value==-1的值時,使用color為this.downColor,value==1時,使用color為this.upcolor.
此時,我們還需要對顏色數(shù)據(jù)進行處理一下,將k線圖對應時間段的增長和下跌展示在數(shù)組里面,成交量數(shù)據(jù)處理代碼如下:
// 初始化交易數(shù)據(jù)和交易柱狀圖顏色參數(shù) initCulomnColor() { this.culomnColor[0] = this.klineData[0].increase > 0 ? 1 : -1; this.culomnValue[0] = [0, this.klineData[0].volume, -1]; for (let i = 1; i < this.klineData.length; i++) { this.culomnColor[i] = this.klineData[i].price > this.klineData[i - 1].price ? 1 : -1; this.culomnValue[i] = [ i, this.klineData[i].volume, this.culomnColor[i] ]; } },
到這里我們成交量柱狀圖即可渲染出來了,下一步就是將折線圖和柱狀圖位置進行調(diào)整,給兩個圖分配合適的區(qū)域,代碼如下:
// 圖像位置配置 grid: [ { left: "10%", right: "10%", height: "50%" }, { left: "10%", right: "10%", top: "65%", height: "18%" } ],
grid配置兩個對象分別代表折線圖和柱狀圖位置;
融合之后我們看到的效果圖如下:
2.5 鼠標指示數(shù)據(jù)設置
k線圖的要求是當鼠標指示在圖的某個位置時,需要將這個時間段的詳細數(shù)據(jù)展示出來;在此我們需要要利用到tooltip屬性,但這個屬性默認之后展示當前橫坐標和縱坐標的值,吐過需要對展示的數(shù)據(jù)進行配置的話,我們還需要借助tooltip.formatter屬性來返回我們想要的展示的數(shù)據(jù),該屬性可拓展范圍非常廣,本次不展開介紹,只介紹在k線圖中的基本使用。代碼如下:
tooltip: { trigger: "axis", axisPointer: { type: "cross" //十字準星指示器 }, borderWidth: 1, borderColor: "#ccc", padding: 10, textStyle: { color: "#000" }, formatter: function(param) { param = param[0]; return [ "時間: " + param.data[6] + '<hr size=1 style="margin: 3px 0">', "價格: " + param.data[1] + "<br/>", "漲跌額: " + param.data[2] + "<br/>", "成交量: " + param.data[3] + "<br/>", "漲跌幅: " + param.data[4] + "<br/>" ].join(""); } },
我們將:時間、價格、漲跌額、成交量、漲跌幅五個屬性展示在頁面上,樣式從簡。得到的效果如下:
至此基本完成了分時折線圖和交易量圖的繪制;
2.6 項目完整代碼
vue項目完整代碼如下:
<template> <div class="echart" id="mychart" style="width:100%; height: 500px;"></div> </template> <script> import * as echarts from "echarts"; import SZHourData from "./data/hourData.TS"; export default { data() { return { upcolor: "#FF0000", //增長顏色 upBorderColor: "#8A0000", downColor: "#008000", // 下跌顏色 downBorderColor: "#008F28", klineData: [], //k線圖數(shù)據(jù) hourData: [], //charts表格小時數(shù)據(jù) xData: [], culomnColor: [], //顏色 culomnValue: [] }; }, mounted() { // 數(shù)據(jù)初始化 this.initData(); // 圖標初始化 this.initEcharts(); }, methods: { initData() { this.klineData = SZHourData.priceinfo; this.hourData = this.splitData(this.klineData); this.initxData(); }, initEcharts() { const option = { title: { text: "上證指數(shù)", left: 0 }, tooltip: { trigger: "axis", axisPointer: { type: "cross" //十字準星指示器 }, borderWidth: 1, borderColor: "#ccc", padding: 10, textStyle: { color: "#000" }, formatter: function(param) { param = param[0]; return [ "時間: " + param.data[6] + '<hr size=1 style="margin: 3px 0">', "價格: " + param.data[1] + "<br/>", "漲跌額: " + param.data[2] + "<br/>", "成交量: " + param.data[3] + "<br/>", "漲跌幅: " + param.data[4] + "<br/>" ].join(""); } }, visualMap: { type: "piecewise", show: false, //不展示map,只應用對應顏色劃分邏輯 seriesIndex: 1, //指定取哪個系列的數(shù)據(jù) dimension: 2, // 定義每一段的顏色 pieces: [ { value: -1, color: this.downColor }, { value: 1, color: this.upcolor } ] }, // 圖像位置配置 grid: [ { left: "10%", right: "10%", height: "50%" }, { left: "10%", right: "10%", top: "65%", height: "18%" } ], // 橫坐標數(shù)據(jù) xAxis: [ // 折線圖 { type: "category", data: this.xData, boundaryGap: false, axisLine: { onZero: false }, splitLine: { show: false }, min: "dataMin", max: "dataMax" }, // 柱狀圖 { type: "category", gridIndex: 1, //x 軸所在的 grid 的索引,默認位于第一個 grid。 data: this.xData, boundaryGap: false, axisLine: { onZero: false }, axisTick: { show: false }, splitLine: { show: false }, axisLabel: { show: false }, min: "dataMin", max: "dataMax" } ], // 縱坐標配置 yAxis: [ { scale: true, splitArea: { show: true } }, { scale: true, gridIndex: 1, // y 軸所在的 grid 的索引,默認位于第一個 grid splitNumber: 2, axisLabel: { show: false }, axisLine: { show: false }, axisTick: { show: false }, splitLine: { show: false } } ], dataZoom: [ { type: "inside", xAxisIndex: [0, 1], start: 50, //展示的數(shù)據(jù)范圍,默認為50%-100% end: 100 }, { show: true, xAxisIndex: [0, 1], type: "slider", top: "90%", start: 50, //展示的數(shù)據(jù)范圍,默認為50%-100% end: 100 } ], series: [ { type: "line", data: this.hourData, symbol: "none", //無標記圖案 lineStyle: { width: 1 } }, { name: "Volume", type: "bar", xAxisIndex: 1, yAxisIndex: 1, data: this.culomnValue } ] }; const myChart = echarts.init(document.getElementById("mychart")); myChart.setOption(option); //隨著屏幕大小調(diào)節(jié)圖表 window.addEventListener("resize", () => { myChart.resize(); }); }, // 橫坐標數(shù)據(jù)處理 initxData() { for (let i = 0; i < this.klineData.length; i++) { this.xData[i] = this.klineData[i].datetime; } this.initCulomnColor(); }, // 初始化交易數(shù)據(jù)和交易柱狀圖顏色參數(shù) initCulomnColor() { this.culomnColor[0] = this.klineData[0].increase > 0 ? 1 : -1; this.culomnValue[0] = [0, this.klineData[0].volume, -1]; for (let i = 1; i < this.klineData.length; i++) { this.culomnColor[i] = this.klineData[i].price > this.klineData[i - 1].price ? 1 : -1; this.culomnValue[i] = [ i, this.klineData[i].volume, this.culomnColor[i] ]; } }, // 數(shù)據(jù)計算以及拆分,將json數(shù)據(jù)轉(zhuǎn)為數(shù)組數(shù)據(jù) splitData(jsonData) { const hourData = []; for (let i = 0; i < jsonData.length; i++) { hourData.push([ i, jsonData[i].price, jsonData[i].increase, jsonData[i].volume, jsonData[i].ratio, jsonData[i].amount, jsonData[i].datetime ]); } return hourData; } } }; </script>
3 總結(jié)
本次介紹的Echarts新屬性的使用較多,不知各位有沒有體會到echarts的強大,若能將各種屬性進行融匯貫通,則變強指日可待。需要注意以上代碼僅供學習參考,非項目級別代碼,里面存在各種未考慮邊界值問題,以及可能存在的兼容性問題,請各位同學知曉。
到此這篇關(guān)于Vue+Echarts實現(xiàn)分時圖和交易量圖的繪制的文章就介紹到這了,更多相關(guān)Vue Echarts繪制分時圖 交易量圖內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue props傳值失敗 輸出undefined的解決方法
今天小編就為大家分享一篇vue props傳值失敗 輸出undefined的解決方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-09-09vue使用map代替Aarry數(shù)組循環(huán)遍歷的方法
這篇文章主要介紹了vue使用map代替Aarry數(shù)組循環(huán)遍歷的方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-04-04詳解element-ui表格的合并行和列(非常細節(jié))
最近在需求中遇到了elementUI合并行,索性給大家整理下,這篇文章主要給大家介紹了關(guān)于element-ui表格的合并行和列的相關(guān)資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下2023-06-06Vue項目中Api的組織和返回數(shù)據(jù)處理的操作
這篇文章主要介紹了Vue項目中Api的組織和返回數(shù)據(jù)處理的操作,本文給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下2019-11-11