VUE 爬坑之旅

您所在的位置:网站首页 分时图和k线图切换 VUE 爬坑之旅

VUE 爬坑之旅

2023-07-06 17:11| 来源: 网络整理| 查看: 265

现在的项目中需要做一个K线图的功能,花了几天时间查资料,读文档,总算是基本搞定了,下面把这过程中一些需要注意的点记下来,以备不时之需。需要达到的效果如下: 这里写图片描述 这里写图片描述

说到做图表,现在的成熟的解决方案就是百度的 ECharts 了,功能强大齐全,文档详细,用的人多,碰到问题也好解决。老规矩,先上文档 ECharts 文档,文档内容很多,全部看一遍得花很多时间,,,看的我头晕,,,

上周,饿了么团队开源了一个基于 Vue2.0 和 echarts 封装的图表组件 v-charts 文档地址,用了下之后发现整体上还是做的很好的,只不过如果想对图表的细节做一些自定义或者优化的话,还是必须去看 ECharts 的文档,在这方面 v-charts 的文档显得太简单了,只适合对 UI 没什么要求的人使用。 如果项目中对图表样式什么的要求比较高的,我建议还是直接用 ECharts ,ECharts 本身也可以很方便的在 vue 项目中使用,只不过需要仔细的阅读下文档,自己根据项目需要做一下简单的封装就好了。

下面进入正题,

安装,导入并使用

首先用 npm 安装

npm install echarts --save

ECharts 本身已经很好的支持了按需引入,在vue 组件中 import 需要的组件就可以使用了,使用前需要先给 ECharts 指定一个容器,

import echarts from 'echarts/lib/echarts' import 'zrender/lib/svg/svg' import 'echarts/lib/chart/line' import 'echarts/lib/chart/candlestick' import chartUtil from '../../utils/chartUtil' export default { name: 'quotation', data () { return { chart: null, } }, mounted () { //初始化 ECharts 实例,不能在created生命周期内初始化,因为那时候DOM还没有渲染,是找不到元素的 this.initChart() }, beforeDestroy () { //组件销毁前先销毁 ECharts 实例 if (!this.chart) { return } this.chart.dispose() this.chart = null }, methods: { initChart () { // 基于准备好的dom,初始化echarts实例,移动端建议使用 svg模式 this.chart = echarts.init(document.getElementById('echarts'), 'light', {renderer: 'svg'}) this.chart.setOption(chartUtil.lineOption()) //图标根据窗口大小自动缩放 // window.addEventListener("resize", this.chart.resize); }, }, }

这里有几个需要注意的地方:

图表高度,若想给图表指定高度的话就必须给承载 ECharts 的容器指定高度,否则它会使用默认高度,给它的父容器定高也是不行的。初始化时机,初始化不能在 created 生命周期里面,因为这时候还没有生成 DOM,所以为它指定的容器还不存在,也就无法初始化在 vue 组件销毁之前,应该要将 ECharts 实例销毁,以避免内存泄漏的问题 处理数据,简单封装使用

上面完成了使用前的基本工作,但是现在还没有数据,所以是没有效果出来的,下面就弄一些数据来模拟下。除了数据之外,还有很多 ECharts 本身的设置等东西,为了避免在 vue 组件中写入过多的代码而难以维护,所以我将他们单独抽出来,写成一个工具类,在 vue 组件中直接导入使用就可以了

//K线图的颜色设置 let upColor = '#D73F43' let upBorderColor = '#D73F43' let downColor = '#2AB180' let downBorderColor = '#2AB180' // 数据意义:时间,开盘(open),收盘(close),最低(lowest),最高(highest) let data = [ ['2013/3/4', 2332.08, 2273.4, 2259.25, 2333.54], ['2013/3/5', 2274.81, 2326.31, 2270.1, 2328.14], ['2013/3/6', 2333.61, 2347.18, 2321.6, 2351.44], ['2013/3/7', 2340.44, 2324.29, 2304.27, 2352.02], ['2013/3/8', 2326.42, 2318.61, 2314.59, 2333.67], ['2013/3/11', 2314.68, 2310.59, 2296.58, 2320.96], ['2013/3/12', 2309.16, 2286.6, 2264.83, 2333.29], ['2013/3/13', 2282.17, 2263.97, 2253.25, 2286.33], ['2013/3/14', 2255.77, 2270.28, 2253.31, 2276.22], ['2013/3/15', 2269.31, 2278.4, 2250, 2312.08], ['2013/3/18', 2267.29, 2240.02, 2239.21, 2276.05], ['2013/3/19', 2244.26, 2257.43, 2232.02, 2261.31], ['2013/3/20', 2257.74, 2317.37, 2257.42, 2317.86], ['2013/3/21', 2318.21, 2324.24, 2311.6, 2330.81], ['2013/3/22', 2321.4, 2328.28, 2314.97, 2332], ['2013/3/25', 2334.74, 2326.72, 2319.91, 2344.89], ['2013/3/26', 2318.58, 2297.67, 2281.12, 2319.99], ['2013/3/27', 2299.38, 2301.26, 2289, 2323.48], ['2013/3/28', 2273.55, 2236.3, 2232.91, 2273.55], ['2013/3/29', 2238.49, 2236.62, 2228.81, 2246.87], ['2013/4/1', 2229.46, 2234.4, 2227.31, 2243.95], ['2013/4/2', 2234.9, 2227.74, 2220.44, 2253.42], ['2013/4/3', 2232.69, 2225.29, 2217.25, 2241.34], ['2013/4/8', 2196.24, 2211.59, 2180.67, 2212.59], ['2013/4/9', 2215.47, 2225.77, 2215.47, 2234.73], ['2013/4/10', 2224.93, 2226.13, 2212.56, 2233.04], ['2013/4/11', 2236.98, 2219.55, 2217.26, 2242.48], ['2013/4/12', 2218.09, 2206.78, 2204.44, 2226.26], ['2013/4/15', 2199.91, 2181.94, 2177.39, 2204.99], ['2013/4/16', 2169.63, 2194.85, 2165.78, 2196.43], ['2013/4/17', 2195.03, 2193.8, 2178.47, 2197.51], ['2013/4/18', 2181.82, 2197.6, 2175.44, 2206.03], ['2013/4/19', 2201.12, 2244.64, 2200.58, 2250.11], ['2013/4/22', 2236.4, 2242.17, 2232.26, 2245.12], ['2013/4/23', 2242.62, 2184.54, 2182.81, 2242.62], ['2013/4/24', 2187.35, 2218.32, 2184.11, 2226.12], ['2013/4/25', 2213.19, 2199.31, 2191.85, 2224.63], ['2013/4/26', 2203.89, 2177.91, 2173.86, 2210.58], ['2013/5/2', 2170.78, 2174.12, 2161.14, 2179.65], ['2013/5/3', 2179.05, 2205.5, 2179.05, 2222.81], ['2013/5/6', 2212.5, 2231.17, 2212.5, 2236.07], ['2013/5/7', 2227.86, 2235.57, 2219.44, 2240.26], ['2013/5/8', 2242.39, 2246.3, 2235.42, 2255.21], ['2013/5/9', 2246.96, 2232.97, 2221.38, 2247.86], ['2013/5/10', 2228.82, 2246.83, 2225.81, 2247.67], ['2013/5/13', 2247.68, 2241.92, 2231.36, 2250.85], ['2013/5/14', 2238.9, 2217.01, 2205.87, 2239.93], ['2013/5/15', 2217.09, 2224.8, 2213.58, 2225.19], ['2013/5/16', 2221.34, 2251.81, 2210.77, 2252.87], ['2013/5/17', 2249.81, 2282.87, 2248.41, 2288.09], ] //处理数据,分别拿到分时图和K线图的数据 let lineData = sliceLineData(data) let candleData = sliceCandleData(data) function sliceCandleData (data) { let categoryData = [] let values = [] for (let i = 0; i < data.length; i++) { categoryData.push(data[i].slice(0, 1)[0]); values.push(data[i].slice(1)) } return { categoryData: categoryData, values: values, } } function sliceLineData (data) { let categoryData = [] let values = [] for (let i = 0; i < data.length; i++) { categoryData.push(data[i].slice(0, 1)[0]) values.push(data[i].slice(1, 2)[0]) } return { categoryData: categoryData, values: values, } } //计算 MA 均线的数据 function calculateMA (dayCount) { let result = [] for (let i = 0, len = candleData.values.length; i < len; i++) { if (i < dayCount) { result.push('-') continue } let sum = 0 for (let j = 0; j < dayCount; j++) { sum += candleData.values[i - j][1] } result.push(sum / dayCount) } return result } //面积图 图表设置 let lineSeries = [ { type: 'line', data: lineData.values, smooth:true, itemStyle:{ color:'#354162', opacity:0.1 }, lineStyle:{ width:1, color:'#354162' }, areaStyle: { color:'#EEEEEE' }, }, ] //K线图 图表设置 let candleSeries = [ { type: 'candlestick', data: candleData.values, // barWidth:5, itemStyle: { normal: { color: upColor, color0: downColor, borderColor: upBorderColor, borderColor0: downBorderColor, }, }, }, ] //共用的一些图表设置 let option = { grid: { top: 10, bottom: 20, left: 10, right: 10, }, xAxis: { data: undefined, scale: true, axisLabel: { color: '#A0A0A0', fontSize: 10, }, axisLine: { lineStyle: { color: '#A0A0A0', }, }, }, yAxis: { scale: true, position: 'right', axisLabel: { color: '#A0A0A0', fontSize: 10, inside: true, }, axisLine: { lineStyle: { color: '#A0A0A0', }, }, splitLine: { lineStyle: { color: '#EEEEEE', }, }, }, series: undefined, } export default class chartUtil { static lineOption = () => { option.xAxis.data = lineData.categoryData option.series = lineSeries return option } static candleOption = () => { option.xAxis.data = candleData.categoryData option.series = candleSeries return option } }

上面就是工具类的完整代码,对 ECharts 来说,最重要的就是 option ,option 里面包含了渲染图表所需要的数据,各种属性等东西。 option 里面各属性的含义我这里就不多说了,不清楚的就去看下文档,因为每个项目的要求都不一样,肯定是需要根据自己的需求对 option 进行相应的修改的。 这里只有一点需要特别说明下的就是 grid 这个属性,这个属性的作用是指定图表内容到它的容器的四个边的距离,如果不修改 grid 的话,效果是这样的 这里写图片描述 可以看到,图表内容距离四边都有一段不小的距离,要怎么减小这个距离呢,就是通过 grid 属性来设置的。

在我的项目中,因为要显示分时图和K线图二种图表,而且还要进行切换,所以我将 option.xAxis.data 和 option.series 这两个需要变动的部分抽出来以实现切换的功能,这也就是简单封装下,大家可以根据自己的项目需要来进行相应的封装。 这样,基本工作就做完了,在需要切换图表的时候,只需要给 ECharts 设置不同的 option 就可以了

if (index === 0) { this.chart.setOption(chartUtil.lineOption()) } else { this.chart.setOption(chartUtil.candleOption()) }

以上,就是这次使用 ECharts 后的总结,当然,现在这样做出来的只是静态页面,一般这种K线图的数据需要从服务器实时获取,现在主流的做法是采用 WebSocket 来让客户端和服务器之间保持一个长链接,以达到及时推送数据的目的。 WebSocket 如何使用什么的,估计得找个时间另外写一票了,,,



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3