首页 > 其他分享 >8.在 Vue 3 中使用 ECharts 实现 K 线图:完整教程与代码解析

8.在 Vue 3 中使用 ECharts 实现 K 线图:完整教程与代码解析

时间:2025-01-10 11:31:03浏览次数:3  
标签:教程 Vue const true type candlestickData data ECharts

引言

K 线图是金融领域中常用的图表类型,用于展示股票、外汇等资产的价格波动。ECharts 是一个功能强大的 JavaScript 图表库,能够帮助我们轻松实现复杂的 K 线图。本文将详细介绍如何在 Vue 3 中使用 ECharts 实现一个动态 K 线图,并逐步解析代码的实现细节。

资源

代码中的'candlestickData '已经上传至数据资源,请自行下载!!!

效果


1. 环境准备

在开始之前,确保你已经安装了以下依赖:

  • Vue 3

  • ECharts

可以通过以下命令安装 ECharts:

npm install echarts

2. 项目结构

我们将创建一个 Vue 组件来实现 K 线图。以下是项目的文件结构:

src/
├── components/
│   └── BackButton.vue
├── utils/
│   └── candlestickData.ts
├── views/
│   └── KLineChart.vue

3. 实现步骤

3.1 创建 Vue 组件

在 KLineChart.vue 中,我们定义了一个 Vue 组件,用于渲染 K 线图。

<template>
  <div class="w-full justify-start flex h-[180px] items-center pl-10">
    <BackButton @click="goBack"/>
  </div>
  <div class="font-bold text-[24px]">在Vue3中使用Echarts实现K线图</div>
  <div class="chart-container mt-4">
    <div ref="chartRef" class="stock-chart"></div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue'
import * as echarts from 'echarts'
import {candlestickData} from '@/utils/candlestickData'
import BackButton from "@/views/components/BackButton.vue";
const chartRef = ref<HTMLElement | null>(null)
let chart: echarts.ECharts | null = null
import router from "@/router";
const goBack = () => {
  setTimeout(() => {
    router.push('/Echarts')
  }, 1000)
}
// Raw data array


function splitData(candlestickData: any[]) {
  const categoryData = []
  const values = []
  const macds = []
  const difs = []
  const deas = []

  for (let i = 0; i < candlestickData.length; i++) {
    categoryData.push(candlestickData[i].splice(0, 1)[0])
    values.push(candlestickData[i])
    macds.push(candlestickData[i][6])
    difs.push(candlestickData[i][7])
    deas.push(candlestickData[i][8])
  }

  return {
    categoryData,
    values,
    macds,
    difs,
    deas
  }
}

const data0 = splitData(candlestickData)

function calculateMA(dayCount: number) {
  const result = []
  for (let i = 0, len = data0.values.length; i < len; i++) {
    if (i < dayCount) {
      result.push('-')
      continue
    }
    let sum = 0
    for (let j = 0; j < dayCount; j++) {
      sum += data0.values[i - j][1]
    }
    result.push(sum / dayCount)
  }
  return result
}

const initChart = () => {
  if (!chartRef.value) return

  chart = echarts.init(chartRef.value)

  const option = {
    tooltip: {
      trigger: 'axis',
      axisPointer: {
        type: 'cross'
      }
    },
    grid: [{
      left: '3%',
      top: '0',
      height: '75%'
    }, {
      left: '3%',
      right: '10%',
      top: '80%',
      height: '10%'
    }],
    xAxis: [{
      type: 'category',
      data: data0.categoryData,
      scale: true,
      boundaryGap: false,
      axisLine: {
        onZero: false,
        lineStyle: {
          color: 'red'
        }
      },
      splitLine: {
        show: false
      },
      splitNumber: 20
    }, {
      type: 'category',
      gridIndex: 1,
      data: data0.categoryData,
      axisLabel: { show: false }
    }],
    yAxis: [{
      scale: true,
      splitArea: {
        show: true
      },
      axisLine: {
        lineStyle: {
          color: 'red'
        }
      },
      position: 'right'
    }, {
      gridIndex: 1,
      splitNumber: 3,
      axisLine: { onZero: false },
      axisTick: { show: false },
      splitLine: { show: false },
      axisLabel: { show: true },
      axisLine: {
        lineStyle: {
          color: 'red'
        }
      },
      position: 'right'
    }],
    dataZoom: [{
      type: 'inside',
      start: 100,
      end: 80
    }, {
      show: true,
      type: 'slider',
      y: '90%',
      start: 50,
      end: 100
    }, {
      show: false,
      xAxisIndex: [0, 1],
      type: 'slider',
      start: 20,
      end: 100
    }],
    series: [{
      name: '555',
      type: 'candlestick',
      data: data0.values,
      markPoint: {
        data: [{
          name: 'XX标点'
        }]
      },
      markLine: {
        silent: true,
        data: [{
          yAxis: 2222
        }]
      }
    }, {
      name: 'MA5',
      type: 'line',
      data: calculateMA(5),
      smooth: true,
      lineStyle: {
        normal: {
          opacity: 0.5
        }
      }
    }, {
      name: 'MA10',
      type: 'line',
      data: calculateMA(10),
      smooth: true,
      lineStyle: {
        normal: {
          opacity: 0.5
        }
      }
    }, {
      name: 'MA20',
      type: 'line',
      data: calculateMA(20),
      smooth: true,
      lineStyle: {
        normal: {
          opacity: 0.5
        }
      }
    }, {
      name: 'MA30',
      type: 'line',
      data: calculateMA(30),
      smooth: true,
      lineStyle: {
        normal: {
          opacity: 0.5
        }
      }
    }, {
      name: 'MACD',
      type: 'bar',
      xAxisIndex: 1,
      yAxisIndex: 1,
      data: data0.macds,
      itemStyle: {
        normal: {
          color: function(params: any) {
            return params.data >= 0 ? '#ef232a' : '#14b143'
          }
        }
      }
    }, {
      name: 'DIF',
      type: 'line',
      xAxisIndex: 1,
      yAxisIndex: 1,
      data: data0.difs
    }, {
      name: 'DEA',
      type: 'line',
      xAxisIndex: 1,
      yAxisIndex: 1,
      data: data0.deas
    }]
  }

  chart.setOption(option)
}

const handleResize = () => {
  chart?.resize()
}

onMounted(() => {
  initChart()
  window.addEventListener('resize', handleResize)
})

onUnmounted(() => {
  chart?.dispose()
  window.removeEventListener('resize', handleResize)
})
</script>

<style scoped>
.chart-container {
  width: 80%;
  height: 70%;
  min-height: 600px;
  margin-left: 10%;
}

.stock-chart {
  width: 100%;
  height: 100%;
}

@media screen and (max-width: 768px) {
  .chart-container {
    min-height: 400px;
  }
}

@media screen and (max-width: 480px) {
  .chart-container {
    min-height: 300px;
  }
}
</style>

3.2 代码解析
  1. 模板部分:

    • 使用 ref 绑定了一个 div 元素作为 ECharts 的容器。

    • 页面顶部有一个返回按钮,点击后会延迟 1 秒跳转到 /Echarts 路由。

  2. 脚本部分:

    • 引入了 Vue 3 的 refonMounted 和 onUnmounted 生命周期钩子。

    • 使用 echarts 初始化图表,并在组件挂载时调用 initChart 函数。

    • 定义了一个 splitData 函数,用于将原始数据拆分为不同的数组。

    • calculateMA 函数用于计算移动平均线。

    • initChart 函数将数据转换为 ECharts 所需的格式,并设置图表的配置项。

    • 监听窗口的 resize 事件,以便在窗口大小变化时调整图表大小。

    • 在组件卸载时销毁图表实例并移除事件监听器。

  3. 样式部分:

    • 定义了图表容器的样式,包括宽度、高度和背景颜色。

    • 使用媒体查询对移动端进行了适配。


4. 优化建议

  1. 数据动态化:

    • 通过 API 或父组件传递数据,使图表更具通用性。

  2. 图表配置优化:

    • 将图表的配置项提取为一个单独的函数或文件,便于复用和维护。

  3. 响应式处理:

    • 进一步优化图表内容(如字体大小、符号大小等)以适应不同屏幕尺寸。

  4. 代码复用:

    • 将图表初始化逻辑封装为一个自定义 Hook 或组件。


5. 总结

通过本文的介绍,你已经学会了如何在 Vue 3 中使用 ECharts 实现一个动态 K 线图。希望这篇文章对你有所帮助!如果你有任何问题或建议,欢迎在评论区留言。


参考链接


版权声明:本文代码版权归吉檀迦俐所有,可供学习和借鉴或商用。转载请注明出处。


希望这篇文章能帮助你在 CSDN 上获得更多的阅读和点赞!如果有其他需求,欢迎随时联系我!

标签:教程,Vue,const,true,type,candlestickData,data,ECharts
From: https://blog.csdn.net/Miller777_/article/details/145053690

相关文章

  • 2025版最新渗透测试零基础入门教程,带你入门到精通(超详细),收藏这篇就够了
    一、渗透测试是什么?释义:我们理解的渗透测试是通过各种⼿段对⽬标进⾏⼀次渗透(攻击),通过渗透来测试⽬标的安全防护能⼒和安全防护意识。打个⽐⽅:⽐如电视剧《我是特种兵》⾥⾯的演习,特种部队(进攻⽅)渗透到蓝军(防守⽅)的指挥部进⾏斩⾸,如果斩⾸成功,那么就可以知道蓝⽅的防守能......
  • Vue3 hook 函数模块化 类似vue2 mixin
    1、优点代码功能模块化,复用代码2、建立新建hooks文件夹,在src下src/hooks/use功能.js3、案例a、模块化src/hooks/usepoint.jsimport{reactive,onMounted,onBeforeUnmount}from'vue';exportdefaultfunction(){letponint=reactive({x:0,......
  • Web安全攻防入门教程——hvv行动详解
    Web安全攻防入门教程Web安全攻防是指在Web应用程序的开发、部署和运行过程中,保护Web应用免受攻击和恶意行为的技术与策略。这个领域不仅涉及防御措施的实现,还包括通过渗透测试、漏洞挖掘和模拟攻击来识别潜在的安全问题。本教程将带......
  • Web安全攻防入门教程——hvv行动详解
    Web安全攻防入门教程Web安全攻防是指在Web应用程序的开发、部署和运行过程中,保护Web应用免受攻击和恶意行为的技术与策略。这个领域不仅涉及防御措施的实现,还包括通过渗透测试、漏洞挖掘和模拟攻击来识别潜在的安全问题。本教程将带你......
  • 奇迹mu1.03单机版安装教程+无需虚拟机+GM工具
    今天为大家带来一款怀旧网单《奇迹mu1.03》的游戏架设,适用于单机娱乐,仅供怀旧,本人已经安装游戏成功,特此带来详细安装教程。适用环境单机视频演示https://githubs.xyz/show/330.mp4 亲测截图  架设步骤关闭默认杀毒软件和其它自己下的杀毒软件,一定要检查关闭!!!! ......
  • Stable Diffusion超详细教程!从0-1入门到进阶
    一、本地部署StableDiffusion(全套教程文末领取哈)前言目前市面上比较权威,并能用于工作中的AI绘画软件其实就两款。一个叫Midjourney(简称MJ),另一个叫Stable-Diffusion(简称SD)。MJ需要付费使用,而SD开源免费,但是上手难度和学习成本略大,并且非常吃电脑配置(显卡、内存)。E和Mid......
  • 网络安全入门教程(非常详细)从零基础入门到精通_网路安全 教程
     前言1.入行网络安全这是一条坚持的道路,三分钟的热情可以放弃往下看了。2.多练多想,不要离开了教程什么都不会了,最好看完教程自己独立完成技术方面的开发。3.有时多百度,我们往往都遇不到好心的大神,谁会无聊天天给你做解答。4.遇到实在......
  • 网络安全入门教程(非常详细)从零基础入门到精通_网路安全 教程
      前言1.入行网络安全这是一条坚持的道路,三分钟的热情可以放弃往下看了。2.多练多想,不要离开了教程什么都不会了,最好看完教程自己独立完成技术方面的开发。3.有时多百度,我们往往都遇不到好心的大神,谁会无聊天天给你做解答。4.遇到实在搞不懂的,可以先放放,以后再来解决。→......
  • 在Vue 3中创建和使用FormData对象
    在Vue3中创建和使用FormData对象的具体步骤如下‌:‌创建FormData对象‌:在Vue组件中,首先需要创建一个新的FormData对象。FormData是一个内置的JavaScript对象,用于构建可以通过XMLHttpRequest或fetch提交的表单数据。可以通过以下方式创建:letformData=newFormData(); ......
  • JAVA开源免费项目 基于Vue和SpringBoot的常规应急物资管理系统(附源码)
    本文项目编号T159,文末自助获取源码\color{red}{T159,文末自助获取源码}......