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