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)這兩個基本的功能以外,還需要帶上每分鐘交易量圖,當鼠標放在圖上時,要展示當前時間對應的相關數(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ù)轉為數(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ù)轉為數(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 總結
本次介紹的Echarts新屬性的使用較多,不知各位有沒有體會到echarts的強大,若能將各種屬性進行融匯貫通,則變強指日可待。需要注意以上代碼僅供學習參考,非項目級別代碼,里面存在各種未考慮邊界值問題,以及可能存在的兼容性問題,請各位同學知曉。
到此這篇關于Vue+Echarts實現(xiàn)分時圖和交易量圖的繪制的文章就介紹到這了,更多相關Vue Echarts繪制分時圖 交易量圖內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
vue props傳值失敗 輸出undefined的解決方法
今天小編就為大家分享一篇vue props傳值失敗 輸出undefined的解決方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-09-09
vue使用map代替Aarry數(shù)組循環(huán)遍歷的方法
這篇文章主要介紹了vue使用map代替Aarry數(shù)組循環(huán)遍歷的方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-04-04
詳解element-ui表格的合并行和列(非常細節(jié))
最近在需求中遇到了elementUI合并行,索性給大家整理下,這篇文章主要給大家介紹了關于element-ui表格的合并行和列的相關資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下2023-06-06
Vue項目中Api的組織和返回數(shù)據(jù)處理的操作
這篇文章主要介紹了Vue項目中Api的組織和返回數(shù)據(jù)處理的操作,本文給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下2019-11-11

