Vue使用echarts图表实现k线图(分K,日K,周K,月K)

2 篇文章 0 订阅

前言:
因为K线图需要庞大的数据,这里我用的是mock.js随机产生的数据,效果相对后台反给的数据来说波动比较大。

mock.js产生的效果图:
在这里插入图片描述
在这里插入图片描述
其实真正用到项目中就比较缓和

效果图:
在这里插入图片描述
在这里插入图片描述
开始步入正题

一,安装安装 ECharts
npm install echarts --save / cnpm install echarts --save

二,vue中使用

import echarts from 'echarts'

Vue.prototype.$echarts = echarts

三,开始封装k线

先在自己的页面选择好自己的容器,定义好大小
在这里插入图片描述
数据加载完之后获取容器
在这里插入图片描述
封装getMinute()方法进行数据请求封装,里面的getMinute_k(),是我自己用mock.js模拟的数据进行的封装
在这里插入图片描述
如果有后台的话,直接请求接口,替换掉getMinute_k()方法,如图:
在这里插入图片描述

调用的setEchartOption()方法

setEchartOption() {
      let that = this;
      var option = null;
      that.myChart.setOption(
        (option = {
          animation: false,
          tooltip: {
            trigger: "axis",
            position: function(pt) {
              return [pt[0], "10%"];
            },
            formatter: function(params) {
              that.time = params[0].value[0];
              that.price = params[0].value[1];
              that.zd =
                Math.round(
                  (Number(params[0].value[1] - that.yPrice) /
                    Number(params[0].value[1])) *
                    10000
                ) / 100;
              that.cj = params[0].value[3];
            }
          },
          grid: [
            {
              left: "3",
              right: "0",
              top: "6%",
              height: "70%"
            },
            {
              left: "3",
              right: "0",
              top: "84%",
              height: "18%"
            }
          ],
          xAxis: [
            {
              type: "category",
              boundaryGap: false,
              splitLine: {
                show: true,
                lineStyle: {
                  color: "#eee"
                }
              },
              axisLine: {
                lineStyle: {
                  color: "#D6D6D6"
                }
              }
            },
            {
              type: "category",
              gridIndex: 1,
              scale: true,
              boundaryGap: false,
              axisLine: { lineStyle: { color: "#777" } },
              splitNumber: 20,
              axisPointer: {
                type: "shadow",
                label: { show: false },
                triggerTooltip: true,
                handle: {
                  show: true,
                  margin: 30,
                  color: "#D6D6D6"
                }
              }
            }
          ],
          yAxis: [
            {
              min: function(value) {
                return Math.round(value.min * 100) / 100;
              },
              max: function(value) {
                return Math.round(value.max * 1.02 * 100) / 100;
              },
              type: "value",
              position: "left",
              zlevel: 1,
              axisLabel: {
                fontSize: 12,
                fontFamily: "Arial",
                margin: 10,
                inside: true,
                formatter: function(params) {
                  return params;
                }
              },
              axisLine: {
                show: true,
                lineStyle: {
                  width: 1,
                  color: function(v) {
                    if (v == that.yPrice) {
                      return "#A5A5A8";
                    } else if (v < that.yPrice) {
                      return "#12E313";
                    } else {
                      return "#FF3B52";
                    }
                  }
                }
              },
              axisTick: {
                show: false
              },
              margin: 1,
              splitLine: {
                lineStyle: {
                  color: "#eee"
                },
                show: true
              },
              axisPointer: {
                show: true,
                type: "line",
                snap: true,
                label: {
                  precision: 2
                }
              }
            },
            {
              scale: true,
              gridIndex: 1,
              splitNumber: 2,
              axisLabel: { show: false },
              axisLine: { show: false },
              axisTick: { show: false },
              splitLine: { show: false }
            }
          ],
          dataZoom: [
            {
              type: "inside",
              start: 0,
              end: 100,
              zoomOnMouseWheel: false,
              moveOnMouseMove: false
            }
          ],
          series: [
            {
              name: "Volume", //柱状
              type: "bar",
              // barWidth:1,
              xAxisIndex: 1,
              yAxisIndex: 1,
              itemStyle: {
                color: function(v) {
                  // console.log(v)
                  if (v.value[1] == v.value[2]) {
                    return "#A5A5A8";
                  } else if (v.value[1] < v.value[2]) {
                    return "#63F763";
                  } else {
                    return "#FF576A";
                  }
                }
              },
              emphasis: {
                itemStyle: {
                  color: "#140"
                }
              },
              data: this.dataArr
            },
            {
              name: "",
              type: "line",
              smooth: true,
              symbol: "none",
              sampling: "average",
              itemStyle: {
                normal: {
                  color: "#FDE7E1",
                  lineStyle: {
                    color: "#FAA296",
                    width: 1
                  }
                }
              },
              areaStyle: {},
              data: this.dataArr
            }
          ]
        }),
        true
      );
    }

mock.js实现过程:(如果有后台,下面步骤即可省略)

安装mockjs
npm install mockjs --save-dev

main.js引入

require('./mock.js')

先自定义100条数据,随机变化(mock.js位置看你心情,我是和main.js同级)

//添加一个mock规则
const Mock = require('mockjs')


//获取mock.random对象
const Random = Mock.Random

// kline模拟数据
const getMinute_k = function () {
  let data = [];
  for (let i = 0; i < 100; i++) {
    let newArticleObject = {
      id: i,
      close: Random.natural(2800, 2888),
      high: Random.natural(2800, 2888),
      low: Random.natural(2800, 2888),
      ma5: Random.natural(2800, 2888),
      ma10: Random.natural(2800, 2888),
      ma20: Random.natural(2800, 2888),
      ma30: Random.natural(2800, 2888),
      open: Random.natural(2800, 2888),
      price: Random.natural(2800, 2888),
      price_equal: Random.natural(1000, 2000),
      time: Random.date(),
      volume: Random.natural(10000, 20000),
      yesterday_close: Random.natural(2800, 2888),
    }
    data.push(newArticleObject)
  }
  return {
    data: data
  }
}

Mock.mock('/index/minute_k', 'post', getMinute_k); // kline模拟数据

然后在src里面新建了一个api文件夹里面index.js封装get请求或者post请求用于对接数据,有后台的情况下,这些东西可以直接省略

import instance from "../until/axios"

//请求mock的数据
export function getMinute_k() {
    return new Promise((resolve,reject)=>{
        instance({
            url: "/index/minute_k",
            method: "post"
        }).then(response=>{
            resolve(response.data)
        }).catch(err=>{
            reject(err)
        })
    })
}



全部代码:

<template>
  <div>
    <div class="flex kData">
      <p>
        时间:
        <span>{{time}}</span>
      </p>
      <p>
        价格:
        <span :class="{'oColor':price>yPrice,'gColor':price<yPrice}">{{price}}</span>
      </p>
      <p>
        涨跌:
        <span :class="{'oColor':zd>0,'gColor':zd<0}">{{zd}}%</span>
      </p>
      <p>
        成交:
        <span>{{cj}}</span>
      </p>
    </div>
    <div id="Zline" :style="{width: '100vw', height: '7rem'}"></div>
  </div>
</template>

<script>
import { getMinute_k } from "../api/index";
export default {
  data() {
    return {
      myChart: null, //折线容器
      time: "",
      price: "--",
      zd: "--",
      cj: "",
      yPrice: this.$store.state.yPrice,
      timer: null,
      dataArr: []
    };
  },
  watch: {
    code() {
      this.getMinute();
    }
  },
  computed: {},
  mounted() {
    this.myChart = this.$echarts.init(document.getElementById("Zline"));
  },
  created() {
    //10秒
    this.getMinute();
    this.timer = setInterval(() => {
      this.getMinute();
    }, 10000);
  },
  destroyed() {
    clearInterval(this.timer);
  },
  methods: {
    getMinute() {
      getMinute_k().then(res => {
        this.dataArr = [];
        res.data.map(i => {
          i.time = i.time.slice(0, 2) + ":" + i.time.slice(2);
          var arr = [];
          arr[0] = i.time;
          arr[1] = i.price;
          arr[2] = i.price_equal;
          arr[3] = i.volume;
          this.dataArr.push(arr);
        });
        this.time = (this.dataArr[0][0]);
        this.price = this.dataArr[0][1];
        this.zd =
          Math.round(
            ((Number(this.price) - this.yPrice) / Number(this.price)) * 10000
          ) / 100;
        this.cj = this.dataArr[0][3];
        this.setEchartOption();
      });
    },
    setEchartOption() {
      let that = this;
      var option = null;
      that.myChart.setOption(
        (option = {
          animation: false,
          tooltip: {
            trigger: "axis",
            position: function(pt) {
              return [pt[0], "10%"];
            },
            formatter: function(params) {
              that.time = params[0].value[0];
              that.price = params[0].value[1];
              that.zd =
                Math.round(
                  (Number(params[0].value[1] - that.yPrice) /
                    Number(params[0].value[1])) *
                    10000
                ) / 100;
              that.cj = params[0].value[3];
            }
          },
          grid: [
            {
              left: "3",
              right: "0",
              top: "6%",
              height: "70%"
            },
            {
              left: "3",
              right: "0",
              top: "84%",
              height: "18%"
            }
          ],
          xAxis: [
            {
              type: "category",
              boundaryGap: false,
              splitLine: {
                show: true,
                lineStyle: {
                  color: "#eee"
                }
              },
              axisLine: {
                lineStyle: {
                  color: "#D6D6D6"
                }
              }
            },
            {
              type: "category",
              gridIndex: 1,
              scale: true,
              boundaryGap: false,
              axisLine: { lineStyle: { color: "#777" } },
              splitNumber: 20,
              axisPointer: {
                type: "shadow",
                label: { show: false },
                triggerTooltip: true,
                handle: {
                  show: true,
                  margin: 30,
                  color: "#D6D6D6"
                }
              }
            }
          ],
          yAxis: [
            {
              min: function(value) {
                return Math.round(value.min * 100) / 100;
              },
              max: function(value) {
                return Math.round(value.max * 1.02 * 100) / 100;
              },
              type: "value",
              position: "left",
              zlevel: 1,
              axisLabel: {
                fontSize: 12,
                fontFamily: "Arial",
                margin: 10,
                inside: true,
                formatter: function(params) {
                  return params;
                }
              },
              axisLine: {
                show: true,
                lineStyle: {
                  width: 1,
                  color: function(v) {
                    if (v == that.yPrice) {
                      return "#A5A5A8";
                    } else if (v < that.yPrice) {
                      return "#12E313";
                    } else {
                      return "#FF3B52";
                    }
                  }
                }
              },
              axisTick: {
                show: false
              },
              margin: 1,
              splitLine: {
                lineStyle: {
                  color: "#eee"
                },
                show: true
              },
              axisPointer: {
                show: true,
                type: "line",
                snap: true,
                label: {
                  precision: 2
                }
              }
            },
            {
              scale: true,
              gridIndex: 1,
              splitNumber: 2,
              axisLabel: { show: false },
              axisLine: { show: false },
              axisTick: { show: false },
              splitLine: { show: false }
            }
          ],
          dataZoom: [
            {
              type: "inside",
              start: 0,
              end: 100,
              zoomOnMouseWheel: false,
              moveOnMouseMove: false
            }
          ],
          series: [
            {
              name: "Volume", //柱状
              type: "bar",
              // barWidth:1,
              xAxisIndex: 1,
              yAxisIndex: 1,
              itemStyle: {
                color: function(v) {
                  // console.log(v)
                  if (v.value[1] == v.value[2]) {
                    return "#A5A5A8";
                  } else if (v.value[1] < v.value[2]) {
                    return "#63F763";
                  } else {
                    return "#FF576A";
                  }
                }
              },
              emphasis: {
                itemStyle: {
                  color: "#140"
                }
              },
              data: this.dataArr
            },
            {
              name: "",
              type: "line",
              smooth: true,
              symbol: "none",
              sampling: "average",
              itemStyle: {
                normal: {
                  color: "#FDE7E1",
                  lineStyle: {
                    color: "#FAA296",
                    width: 1
                  }
                }
              },
              areaStyle: {},
              data: this.dataArr
            }
          ]
        }),
        true
      );
    }
  }
};
</script>

<style scoped lang="scss">
.flex {
  display: flex;
  align-items: center;
}

.kData {
  padding: 0 0.4rem;

  p {
    margin-right: 0.266666rem;
  }

  color: rgb(142, 142, 147);

  .oColor {
    color: rgb(255, 69, 0);
  }

  .gColor {
    color: rgb(5, 170, 59);
  }

  .pColor {
    color: rgb(255, 62, 139);
  }

  .yColor {
    color: rgb(255, 172, 0);
  }

  .bColor {
    color: rgb(39, 224, 239);
  }
}
</style>

这里展示仅为分K的代码,如果只展示一个K线这个即可,如果需要更多,可去GitHub下载代码
地址: https://github.com/pxhing/kline.

  • 8
    点赞
  • 49
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Vue中编写EchartsK线图,首先需要下载Echarts库,可以通过npm install echarts --save命令进行下载。然后,在Vue组件中引入Echarts库,并创建Echarts的挂载实例。在mounted生命期钩子函数中初始化Echarts实例,并进行相关的K线图绘制。 以下是一个示例代码,展示了如何在Vue中编写EchartsK线图: ```javascript <template> <div ref="kLineChart" style="width: 100%; height: 400px;"></div> </template> <script> import echarts from 'echarts' export default { mounted() { // 初始化Echarts实例 const kLineChart = echarts.init(this.$refs.kLineChart) // K线图的数据 const kLineData = \[ // 数据格式示例 \[2320.26, 2320.26, 2287.3, 2362.94\], \[2300, 2291.3, 2288.26, 2308.38\], // ... \] // 设置K线图的配置项 const option = { // 配置项省略,根据实际需求进行设置 // ... series: \[{ type: 'candlestick', data: kLineData, // ... }\] } // 绘制K线图 kLineChart.setOption(option) // 监听窗口大小变化,自适应图表大小 window.addEventListener('resize', () => { kLineChart.resize() }) } } </script> ``` 在上述示例代码中,我们首先在模板中创建一个div元素,并通过ref属性给它一个引用名。然后,在mounted生命期钩子函数中,通过this.$refs.kLineChart获取到这个div元素,并将其作为Echarts实例的挂载点。接着,我们可以根据实际需求设置K线图的数据和配置项,最后调用setOption方法绘制K线图。同时,我们还监听了窗口大小变化事件,以便在窗口大小改变时自适应调整图表大小。 请注意,上述代码仅为示例,实际使用时需要根据具体需求进行适当的修改和调整。 #### 引用[.reference_title] - *1* [vue使用Echarts绘制K线图](https://blog.csdn.net/weixin_42614080/article/details/103749943)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [Vue+ECharts实现可视化地图](https://blog.csdn.net/u011924274/article/details/124941788)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值