目录
- 1 前言
- 2 分时图
- 2.1 vue引入Echarts
- 2.2 分时图介绍
- 2.3 分时折线图配置
- 2.4 组合交易量图
- 2.5 鼠标指示数据设置
- 2.6 项目完整代码
- 3 总结
1 前言
近来发现Echarts API越发的强大,对于绘制各类图形可以使用Echarts实现,前面已经介绍了柱状图、饼状图、折线图、极坐标图。对于k线图,除了前面介绍的vue+Echarts绘制K线图详解(一)----基本日K图绘制以外,k线图中包含其他多种类型的图形,休息了半载左右,今天继续来进一步深入介绍一下分时图和成交量图,为打造一个完整的版面添砖加瓦。
2 分时图
2.1 vue引入Echarts
前面已经介绍过了,还不知道怎么引入的同学请参考以前的教程:在Vue项目中引入 ECharts。
2.2 分时图介绍
分时图本质上也是一个折线图,横坐标为一天交易的每一分钟,纵坐标为股市的实时单价。除了实现这两个基本的功能以外,还需要带上每分钟交易量图,当鼠标放在图上时,要展示当前时间对应的相关数据;如下图所示:
我们本期要实现的功能为:分时折线图、分时成交量图,鼠标指示展示详细数据,对应成交量颜色划分;其余的一些细节的功能(图切换,细节颜色以及样式处理)我们以后再做介绍。
2.3 分时折线图配置
分时折线图本质上是折线图,我们通过设置图类型为折线即可,重点是对数据的处理,我们的数据源格式是json
对象数组数据,每一分钟数据如下所示:
{"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"},
首先我们需要对数据进行处理,才能应用于Echarts之中;我们分时折线图配置项代码代码如下所示:
// 横坐标数据配置
xAxis: [
{
type: "category",
data: this.xData,
boundaryGap: false,
axisLine: { onZero: false },
splitLine: { show: false },
min: "dataMin",
max: "dataMax"
},
]
// 纵坐标配置
yAxis: [
{
scale: true,
splitArea: {
show: true
}
},
]
//图形数据配置:
series: [
{
type: "line",
data: this.hourData,
symbol: "none", //无标记图案
lineStyle: {
width: 1
}
},
]
其中,this.xData
是我们vue页面中的经过处理的横坐标数据,this.hourData
是我们页面中经过处理的每小时数据。
注意:series
中symbol
属性要设置为none,这样的到的折线图上将会不出线标记图案。
数据处理代码如下:
// 横坐标数据处理
initxData() {
for (let i = 0; i < this.klineData.length; i++) {
this.xData[i] = this.klineData[i].datetime;
}
},
// 数据计算以及拆分,将json数据转为数组数据
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数据。
到此我们可以来看一下分时折线图的效果:
可以看到得到的折线图就是为我们的分时折线图。
2.4 组合交易量图
交易量图为2.2图中底部的红绿交间的柱状图,交易量图本质是一个柱状图,我们可以看到有两个特点:
- 横坐标与分时折线图公用,且柱状图在交易图下方;
- 当前为涨时,柱子为红色,当前为跌时,柱子为绿色;
对于特点1,在我们之前介绍的图中,都是公用坐标系的图,这里新知识点就是不公用坐标系,但是公用横坐标数据应该怎么处理;就是在xAxis
、yAxis
和series
中设置两个对象出来,代表两个不同的坐标西,然后将两个坐标系的横坐标进行对齐即可;
代码如下:
// 横坐标数据
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
属性;官网上对该属性的说明是:自定义『分段式视觉映射组件(visualMapPiecewise)』的每一段的范围,以及每一段的文字,以及每一段的特别的样式。
我们直接上代码以及讲解,来看这个属性怎么使用,代码如下:
visualMap: {
type: "piecewise",
show: false, //不展示map,只应用对应颜色划分逻辑
seriesIndex: 1, //指定取哪个系列的数据
dimension: 2,
// 定义每一段的颜色
pieces: [
{
value: -1,
color: this.downColor
},
{
value: 1,
color: this.upcolor
}
]
},
这段代码的解释是:当series
的data
数据里面有value==-1
的值时,使用color
为this.downColor
,value==1
时,使用color
为this.upcolor
.
此时,我们还需要对颜色数据进行处理一下,将k线图对应时间段的增长和下跌展示在数组里面,成交量数据处理代码如下:
// 初始化交易数据和交易柱状图颜色参数
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]
];
}
},
到这里我们成交量柱状图即可渲染出来了,下一步就是将折线图和柱状图位置进行调整,给两个图分配合适的区域,代码如下:
// 图像位置配置
grid: [
{
left: "10%",
right: "10%",
height: "50%"
},
{
left: "10%",
right: "10%",
top: "65%",
height: "18%"
}
],
grid
配置两个对象分别代表折线图和柱状图位置;
融合之后我们看到的效果图如下:
2.5 鼠标指示数据设置
k线图的要求是当鼠标指示在图的某个位置时,需要将这个时间段的详细数据展示出来;在此我们需要要利用到tooltip
属性,但这个属性默认之后展示当前横坐标和纵坐标的值,吐过需要对展示的数据进行配置的话,我们还需要借助tooltip.formatter
属性来返回我们想要的展示的数据,该属性可拓展范围非常广,本次不展开介绍,只介绍在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线图数据
hourData: [], //charts表格小时数据
xData: [],
culomnColor: [], //颜色
culomnValue: []
};
},
mounted() {
// 数据初始化
this.initData();
// 图标初始化
this.initEcharts();
},
methods: {
initData() {
this.klineData = SZHourData.priceinfo;
this.hourData = this.splitData(this.klineData);
this.initxData();
},
initEcharts() {
const option = {
title: {
text: "上证指数",
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, //指定取哪个系列的数据
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%"
}
],
// 横坐标数据
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, //展示的数据范围,默认为50%-100%
end: 100
},
{
show: true,
xAxisIndex: [0, 1],
type: "slider",
top: "90%",
start: 50, //展示的数据范围,默认为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);
//随着屏幕大小调节图表
window.addEventListener("resize", () => {
myChart.resize();
});
},
// 横坐标数据处理
initxData() {
for (let i = 0; i < this.klineData.length; i++) {
this.xData[i] = this.klineData[i].datetime;
}
this.initCulomnColor();
},
// 初始化交易数据和交易柱状图颜色参数
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]
];
}
},
// 数据计算以及拆分,将json数据转为数组数据
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绘制k线图(二)–分时图和交易量图到此结束,后续将继续探讨k线图其他知识的实现。若有问题请进行留言。