From c42857f46e7c6fa6f8bb0b75f399707789c4ab72 Mon Sep 17 00:00:00 2001
From: lxf <1371462558@qq.com>
Date: Sat, 21 Jun 2025 16:47:27 +0800
Subject: [PATCH] k线添加网格

---
 src/components/kline-charts/index.vue |  319 ++++++++++++++++++++++++++++++++++++-----------------
 1 files changed, 216 insertions(+), 103 deletions(-)

diff --git a/src/components/kline-charts/index.vue b/src/components/kline-charts/index.vue
index a5c96a0..9d891b4 100644
--- a/src/components/kline-charts/index.vue
+++ b/src/components/kline-charts/index.vue
@@ -1,196 +1,309 @@
 <template>
   <div class="kline-charts">
-    <ul class="flex px-32 pb-20 box-border justify-between text-grey fontStyle font-26"
-      style="border-bottom:1px solid rgba(68,75,88,0.2);">
-      <li v-for="item in timeList" :key="item.id" class="mr-10" :class="{ 'textColor': item.id === timeValue.id }"
-        @click="choiceTime(item)">{{ item.text }}</li>
+    <ul
+      class="flex px-32 pb-20 box-border justify-between text-grey fontStyle font-26"
+      style="border-bottom: 1px solid rgba(68, 75, 88, 0.2)"
+    >
+      <li
+        v-for="item in timeList"
+        :key="item.id"
+        class="mr-10"
+        :class="{ textColor: item.id === timeValue.id }"
+        @click="choiceTime(item)"
+      >
+        {{ item.text }}
+      </li>
     </ul>
     <div class="relative">
       <div id="kline" class="h-828"></div>
       <div
-        class="flex justify-center items-center text-center text-grey absolute left-0 top-0  w-full h-full z-10 mainBackground"
-        v-if="chartLoading">
+        class="flex justify-center items-center text-center text-grey absolute left-0 top-0 w-full h-full z-10 mainBackground"
+        v-if="chartLoading"
+      >
         <van-loading type="spinner"></van-loading>
       </div>
     </div>
-    <ul class="flex  px-32 py-20 box-border justify-between text-grey font-26" v-if="showBottom"
-      style="border-top:1px solid rgba(68,75,88,0.2);">
-      <li v-for="item in subTechnicalIndicatorTypes" :key="item" class="mr-20"
-        :class="{ 'textColor': typeValue === item }" @click="choiceType(item)">{{ item }}</li>
+    <ul
+      class="flex px-32 py-20 box-border justify-between text-grey font-26"
+      v-if="showBottom"
+      style="border-top: 1px solid rgba(68, 75, 88, 0.2)"
+    >
+      <li
+        v-for="item in subTechnicalIndicatorTypes"
+        :key="item"
+        class="mr-20"
+        :class="{ textColor: typeValue === item }"
+        @click="choiceType(item)"
+      >
+        {{ item }}
+      </li>
     </ul>
   </div>
 </template>
 <script>
-import { init, dispose } from 'klinecharts'
-let chart = null
-import { _getKline } from '@/API/trade.api'
-import config from './config'
-import { Loading } from 'vant';
+import { init, dispose } from "klinecharts";
+let chart = null;
+import { _getKline } from "@/API/trade.api";
+import config from "./config";
+import { Loading } from "vant";
 import { scientificNotationToString } from "@/utils/utis";
 export default {
-  name: 'KlineCharts',
+  name: "KlineCharts",
   data() {
     return {
       // symbol: 'btc',
-      dealInfo: {},//交易对信息
+      dealInfo: {}, //交易对信息
 
       timeValue: {}, // 当前k线周期
-      subTechnicalIndicatorTypes: ['MA', 'EMA', 'BOLL', 'VOL', 'MACD', 'KDJ', 'RSI'],
-      typeValue: 'VOL',//图形类型
-      klinecharts: null,//K线图实例
+      subTechnicalIndicatorTypes: [
+        "MA",
+        "EMA",
+        "BOLL",
+        "VOL",
+        "MACD",
+        "KDJ",
+        "RSI",
+      ],
+      typeValue: "VOL", //图形类型
+      klinecharts: null, //K线图实例
       chart: null,
       // resolution: '1',//分辨率
       // lang: 'en', //语言
       chartLoading: true, //加载动画
-      paneId: '',
+      paneId: "",
       chartData: [], // 图表数据
-      timer: null
-    }
+      timer: null,
+      grid: {
+        show: true,
+        horizontal: {
+          show: true,
+          size: 0.1,
+          color: "#f0f0f0",
+          style: "dashed",
+          dashedValue: [1, 2],
+        },
+        vertical: {
+          show: true,
+          size: 0.1,
+          color: "#f0f0f0",
+          style: "dashed",
+          dashedValue: [1, 2],
+        },
+      },
+    };
   },
   computed: {
     timeList() {
       return [
-        { id: '1min', time: '1min', text: this.$t('分时'), ts: 1 * 60 * 1000 },
-        { id: '1mins', time: '1min', text: '1' + this.$t('分'), ts: 1 * 60 * 1000 },
-        { id: '5min', time: '5min', text: '5' + this.$t('分'), ts: 5 * 60 * 1000 },
-        { id: '15min', time: '15min', text: '15' + this.$t('分'), ts: 15 * 60 * 1000 },
-        { id: '30min', time: '30min', text: '30' + this.$t('分'), ts: 30 * 60 * 1000 },
-        { id: '60min', time: '60min', text: '1' + this.$t('小时'), ts: 60 * 60 * 1000 },
-        { id: '4hour', time: '4hour', text: '4' + this.$t('小时'), ts: 4 * 60 * 60 * 1000 },
-        { id: '1day', time: '1day', text: '1' + this.$t('天'), ts: 24 * 60 * 60 * 1000 },
-        { id: '1week', time: '1week', text: '1' + this.$t('周'), ts: 7 * 24 * 60 * 60 * 1000 },
-        { id: '1mon', time: '1mon', text: '1' + this.$t('月'), ts: 30 * 24 * 60 * 60 * 1000 }
-      ]//时间列表
-    }
+        { id: "1min", time: "1min", text: this.$t("分时"), ts: 1 * 60 * 1000 },
+        {
+          id: "1mins",
+          time: "1min",
+          text: "1" + this.$t("分"),
+          ts: 1 * 60 * 1000,
+        },
+        {
+          id: "5min",
+          time: "5min",
+          text: "5" + this.$t("分"),
+          ts: 5 * 60 * 1000,
+        },
+        {
+          id: "15min",
+          time: "15min",
+          text: "15" + this.$t("分"),
+          ts: 15 * 60 * 1000,
+        },
+        {
+          id: "30min",
+          time: "30min",
+          text: "30" + this.$t("分"),
+          ts: 30 * 60 * 1000,
+        },
+        {
+          id: "60min",
+          time: "60min",
+          text: "1" + this.$t("小时"),
+          ts: 60 * 60 * 1000,
+        },
+        {
+          id: "4hour",
+          time: "4hour",
+          text: "4" + this.$t("小时"),
+          ts: 4 * 60 * 60 * 1000,
+        },
+        {
+          id: "1day",
+          time: "1day",
+          text: "1" + this.$t("天"),
+          ts: 24 * 60 * 60 * 1000,
+        },
+        {
+          id: "1week",
+          time: "1week",
+          text: "1" + this.$t("周"),
+          ts: 7 * 24 * 60 * 60 * 1000,
+        },
+        {
+          id: "1mon",
+          time: "1mon",
+          text: "1" + this.$t("月"),
+          ts: 30 * 24 * 60 * 60 * 1000,
+        },
+      ]; //时间列表
+    },
   },
   components: {
-    [Loading.name]: Loading
+    [Loading.name]: Loading,
   },
   props: {
     symbol: {
       type: String,
-      default: ''
+      default: "",
     },
     updateKey: {
       type: Number,
-      default: 0
+      default: 0,
     },
     updateData: {
       type: Object,
       default() {
-        return {}
-      }
+        return {};
+      },
     },
     showBottom: {
       type: Boolean,
-      default: true
+      default: true,
     },
     isChangeLine: {
       type: Boolean,
-      default: false
+      default: false,
     },
   },
   mounted() {
-    this.initData()
+    this.initData();
   },
   beforeDestroy() {
-    this.clearTimer()
-    dispose('kline')
+    this.clearTimer();
+    dispose("kline");
   },
   watch: {
     isChangeLine(val) {
-      this.clearTimer()
-      this.fetchData()
+      this.clearTimer();
+      this.fetchData();
     },
-    updateKey() { // 更新charts
-      const dataList = chart.getDataList()
-      const lastData = dataList[dataList.length - 1]
-      const nowData = this.updateData
-      const timeValue = this.timeValue
+    updateKey() {
+      // 更新charts
+      const dataList = chart.getDataList();
+      const lastData = dataList[dataList.length - 1];
+      const nowData = this.updateData;
+      const timeValue = this.timeValue;
       const newData = {
         close: nowData.close / 1,
         current_time: lastData.current_time,
-        high: lastData.high > nowData.close / 1 ? lastData.high : (nowData.close / 1),
+        high:
+          lastData.high > nowData.close / 1 ? lastData.high : nowData.close / 1,
         // high: lastData.high,
         line: timeValue.id,
-        low: lastData.low < nowData.close / 1 ? lastData.low : (nowData.close / 1),
+        low:
+          lastData.low < nowData.close / 1 ? lastData.low : nowData.close / 1,
         // low: lastData.low,
         open: lastData.open,
         symbol: lastData.symbol,
         ts: lastData.ts, //
-        timestamp: (nowData.ts - lastData.ts) < timeValue.ts ? lastData.ts : (lastData.ts + timeValue.ts),
-        volume: lastData.volume / 1
-      }
+        timestamp:
+          nowData.ts - lastData.ts < timeValue.ts
+            ? lastData.ts
+            : lastData.ts + timeValue.ts,
+        volume: lastData.volume / 1,
+      };
       this.$nextTick(() => {
-        this.setChartType()
-        chart.updateData(newData)
-      })
-    }
+        this.setChartType();
+        chart.updateData(newData);
+      });
+    },
   },
   methods: {
     initData() {
-      this.timeValue = this.timeList[0]
-      chart = init('kline', config);
-      chart.setOffsetRightSpace(25)
-      chart.setDataSpace(10)
-      chart.setPriceVolumePrecision(4, 2)
-      chart.createTechnicalIndicator('MA', false, { id: 'candle_pane' });
-      this.paneId = chart.createTechnicalIndicator('VOL');
-      this.fetchData()
+      this.timeValue = this.timeList[0];
+      chart = init("kline", config);
+      chart.setOffsetRightSpace(25);
+      chart.setDataSpace(10);
+      chart.setPriceVolumePrecision(4, 2);
+      chart.createTechnicalIndicator("MA", false, { id: "candle_pane" });
+      chart.getStyleOptions().grid = this.grid;
+      chart.setStyleOptions({
+        grid: this.grid,
+        // candle: {
+        //   upColor: "#FF0000",
+        //   downColor: "#00FF00",
+        //   borderUpColor: "#FF0000",
+        //   borderDownColor: "#00FF00",
+        //   wickUpColor: "#FF0000",
+        //   wickDownColor: "#00FF00",
+        // },
+      });
+      this.paneId = chart.createTechnicalIndicator("VOL");
+      this.fetchData();
     },
-    fetchData(time) { // 获取数据
-      this.chartLoading = true
+    fetchData(time) {
+      // 获取数据
+      this.chartLoading = true;
       this.timer = setInterval(() => {
-        _getKline(this.symbol, this.timeValue.time || time).then(data => {
-          this.chartLoading = false
-          data.map(item => {
-            item.timestamp = item.ts
-          })
+        _getKline(this.symbol, this.timeValue.time || time).then((data) => {
+          this.chartLoading = false;
+          data.map((item) => {
+            item.timestamp = item.ts;
+          });
           //科学计数法时转成字符串
-          let str = data[0] ? scientificNotationToString(data[data.length - 1].close.toString()) : ''
-          let length = 2
-          if (str.indexOf('.') != -1) {
-            length = str.split('.')[1].length
+          let str = data[0]
+            ? scientificNotationToString(data[data.length - 1].close.toString())
+            : "";
+          let length = 2;
+          if (str.indexOf(".") != -1) {
+            length = str.split(".")[1].length;
           }
           //let length = data[0] ? data[0].close.toString().split('.')[1].length : 4
-          chart.setPriceVolumePrecision(length, 2)
-          this.setChartType()
+          chart.setPriceVolumePrecision(length, 2);
+          this.setChartType();
           chart.applyNewData(data);
-          this.$emit('updataLine', false)
-        })
+          this.$emit("updataLine", false);
+        });
       }, 1000);
     },
     setChartType() {
-      let type = 'area'
-      if (this.timeValue.id === '1min') {
-        type = 'area'
+      let type = "area";
+      if (this.timeValue.id === "1min") {
+        type = "area";
       } else {
-        type = 'candle_solid'
+        type = "candle_solid";
       }
       chart.setStyleOptions({
         candle: {
-          type
-        }
-      })
+          type,
+        },
+      });
     },
-    choiceTime(value) { // 选择周期
-      this.timeValue = value
-      this.clearTimer()
-      this.fetchData()
+    choiceTime(value) {
+      // 选择周期
+      this.timeValue = value;
+      this.clearTimer();
+      this.fetchData();
     },
-    choiceType(type) { // 选择副线
-      this.typeValue = type
-      chart.createTechnicalIndicator(type, false, { id: this.paneId })
+    choiceType(type) {
+      // 选择副线
+      this.typeValue = type;
+      chart.createTechnicalIndicator(type, false, { id: this.paneId });
     },
     clearTimer() {
-      clearInterval(this.timer)
-      this.timer = null
+      clearInterval(this.timer);
+      this.timer = null;
     },
   },
   deactivated() {
-    this.clearTimer()
-  }
-}
+    this.clearTimer();
+  },
+};
 </script>
 <style lang="scss" scoped>
 .textColor {

--
Gitblit v1.9.3