From ef52095f5e9f0a9fe2da779bb1573947d77d75b6 Mon Sep 17 00:00:00 2001
From: jhzh <1628036192@qq.com>
Date: Fri, 22 May 2026 10:53:01 +0800
Subject: [PATCH] 1

---
 src/components/Transform/kline-charts/index.vue |  198 ++++++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 168 insertions(+), 30 deletions(-)

diff --git a/src/components/Transform/kline-charts/index.vue b/src/components/Transform/kline-charts/index.vue
index 8fa0716..14840e7 100644
--- a/src/components/Transform/kline-charts/index.vue
+++ b/src/components/Transform/kline-charts/index.vue
@@ -1,5 +1,5 @@
 <template>
-  <div id="cryptos">
+  <div >
     <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);">
@@ -18,12 +18,54 @@
           </template>
         </template>
       </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">
-          <van-loading type="spinner"></van-loading>
+      <div class="chart-with-tools flex">
+        <div class="relative flex-1 min-w-0">
+          <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">
+            <van-loading type="spinner"></van-loading>
+          </div>
+        </div>
+        <!-- 铅笔图标:控制绘图工具栏显示/隐藏 -->
+        <div class="draw-tools-wrap flex">
+          <div class="pencil-trigger draw-tool-item" :class="[isNight ? 'draw-toolbar-night' : 'draw-toolbar-light', { active: showDrawToolbar }]"
+            :title="showDrawToolbar ? $t('隐藏绘图工具') : $t('显示绘图工具')" @click="showDrawToolbar = !showDrawToolbar">
+            <svg viewBox="0 0 24 24" width="20" height="20"><path fill="currentColor" d="M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04c.39-.39.39-1.02 0-1.41l-2.34-2.34c-.39-.39-1.02-.39-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z"/></svg>
+          </div>
+          <!-- 绘图工具栏 -->
+          <div v-show="showDrawToolbar" class="draw-toolbar" :class="isNight ? 'draw-toolbar-night' : 'draw-toolbar-light'">
+          <div class="draw-tool-item" :class="{ active: activeDrawTool === 'fibonacciLine' }" title="斐波那契" @click="onDrawToolClick('fibonacciLine')">
+            <svg viewBox="0 0 24 24" width="20" height="20"><path fill="currentColor" d="M4 20L20 4l-2-2L2 18v4h2z"/><circle cx="6" cy="18" r="1.5"/><circle cx="18" cy="6" r="1.5"/></svg>
+          </div>
+          <div class="draw-tool-item" :class="{ active: activeDrawTool === 'segment' }" title="线段" @click="onDrawToolClick('segment')">
+            <svg viewBox="0 0 24 24" width="20" height="20"><line x1="4" y1="20" x2="20" y2="4" stroke="currentColor" stroke-width="2"/><circle cx="4" cy="20" r="2"/><circle cx="20" cy="4" r="2"/></svg>
+          </div>
+          <div class="draw-tool-item" :class="{ active: activeDrawTool === 'horizontalStraightLine' }" title="水平线" @click="onDrawToolClick('horizontalStraightLine')">
+            <svg viewBox="0 0 24 24" width="20" height="20"><line x1="2" y1="12" x2="22" y2="12" stroke="currentColor" stroke-width="2"/><circle cx="12" cy="12" r="2"/></svg>
+          </div>
+          <div class="draw-tool-item" :class="{ active: activeDrawTool === 'horizontalSegment' }" title="水平线段" @click="onDrawToolClick('horizontalSegment')">
+            <svg viewBox="0 0 24 24" width="20" height="20"><line x1="6" y1="12" x2="18" y2="12" stroke="currentColor" stroke-width="2"/><circle cx="6" cy="12" r="2"/><circle cx="18" cy="12" r="2"/></svg>
+          </div>
+          <div class="draw-tool-item" :class="{ active: activeDrawTool === 'verticalStraightLine' }" title="垂直线" @click="onDrawToolClick('verticalStraightLine')">
+            <svg viewBox="0 0 24 24" width="20" height="20"><line x1="12" y1="2" x2="12" y2="22" stroke="currentColor" stroke-width="2"/><circle cx="12" cy="12" r="2"/></svg>
+          </div>
+          <div class="draw-tool-item" :class="{ active: activeDrawTool === 'verticalSegment' }" title="垂直线段" @click="onDrawToolClick('verticalSegment')">
+            <svg viewBox="0 0 24 24" width="20" height="20"><line x1="12" y1="6" x2="12" y2="18" stroke="currentColor" stroke-width="2"/><circle cx="12" cy="6" r="2"/><circle cx="12" cy="18" r="2"/></svg>
+          </div>
+          <div class="draw-tool-item" :class="{ active: activeDrawTool === 'rect' }" title="矩形" @click="onDrawToolClick('rect')">
+            <svg viewBox="0 0 24 24" width="20" height="20"><rect x="5" y="7" width="14" height="10" fill="none" stroke="currentColor" stroke-width="2"/><circle cx="5" cy="7" r="1.5"/><circle cx="19" cy="17" r="1.5"/></svg>
+          </div>
+          <div class="draw-tool-item" :class="{ active: activeDrawTool === 'triangle' }" title="三角形" @click="onDrawToolClick('triangle')">
+            <svg viewBox="0 0 24 24" width="20" height="20"><path d="M12 5L4 19h16L12 5z" fill="none" stroke="currentColor" stroke-width="2"/><circle cx="12" cy="5" r="1.5"/><circle cx="4" cy="19" r="1.5"/><circle cx="20" cy="19" r="1.5"/></svg>
+          </div>
+          <div class="draw-tool-item" :class="{ active: activeDrawTool === 'parallelogram' }" title="平行四边形" @click="onDrawToolClick('parallelogram')">
+            <svg viewBox="0 0 24 24" width="20" height="20"><path d="M6 6h12l-4 12H2L6 6z" fill="none" stroke="currentColor" stroke-width="2"/><circle cx="6" cy="6" r="1.5"/><circle cx="18" cy="6" r="1.5"/><circle cx="14" cy="18" r="1.5"/></svg>
+          </div>
+          <div class="draw-tool-item" title="清除全部" @click="onDrawToolClick('remove')">
+            <svg viewBox="0 0 24 24" width="20" height="20"><path fill="currentColor" d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"/></svg>
+          </div>
+          </div>
         </div>
       </div>
       <ul class="flex  px-32 py-20 box-border justify-between text-grey font-26" v-if="showBottom"
@@ -53,6 +95,7 @@
 import config from './config'
 import { clearAllTimers } from '@/utils/utis.js'
 import { Loading } from 'vant';
+import { customShapeTemplates } from './drawTools'
 export default {
   name: 'KlineCharts',
   data() {
@@ -70,19 +113,21 @@
       chartLoading: true, //加载动画
       paneId: '',
       chartData: [], // 图表数据
-      timer: null
+      timer: null,
+      activeDrawTool: '', // 当前选中的绘图工具
+      showDrawToolbar: true // 绘图工具栏是否显示,由铅笔图标切换
     }
   },
   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: '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: '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 }
@@ -136,25 +181,14 @@
       this.clearTimer()
       this.fetchData()
     },
-    updateKey() { // 更新charts
+    updateKey() { // 更新charts:只更新 this.updateData 的 close,其余沿用最后一根
       const dataList = chart.getDataList()
       if (dataList.length > 0) {
         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,
-          line: timeValue.id,
-          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
+          ...lastData,
+          close: nowData.close != null && nowData.close !== '' ? (nowData.close / 1) : lastData.close
         }
         this.$nextTick(() => {
           this.setChartType()
@@ -165,13 +199,15 @@
   },
   methods: {
     initData() {
-      this.timeValue = this.timeList[0]
+      this.timeValue = this.timeList.find(t => t.id === '15min') || 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');
+      // 注册自定义绘图图形:矩形、三角形、平行四边形
+      chart.addShapeTemplate(customShapeTemplates)
       this.fetchData()
     },
     fetchData(time) { // 获取数据
@@ -210,7 +246,7 @@
           chart.applyNewData(data);
           this.$emit('updataLine', false)
         })
-      }, 30000);
+      }, 10000);
     },
     setChartType() {
       let type = 'area'
@@ -239,6 +275,16 @@
       this.timer = null
       clearAllTimers()
     },
+    onDrawToolClick(name) {
+      if (!chart) return
+      if (name === 'remove') {
+        chart.removeShape()
+        this.activeDrawTool = ''
+        return
+      }
+      this.activeDrawTool = name
+      chart.createShape(name, 'candle_pane')
+    },
   },
   deactivated() {
     this.clearTimer()
@@ -247,7 +293,99 @@
 </script>
 <style lang="scss" scoped>
 @import "@/assets/init.scss";
-// #kline {
-//   // min-height: 828px;
-//   height: 1200px;
-// }</style>
+
+.chart-with-tools {
+  position: relative;
+}
+
+.draw-tools-wrap {
+  flex-shrink: 0;
+  display: flex;
+  border-left: 1px solid rgba(68, 75, 88, 0.2);
+}
+
+.draw-tools-wrap .pencil-trigger {
+  width: 44px;
+  min-width: 44px;
+  flex-shrink: 0;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  padding: 8px 0;
+  cursor: pointer;
+  transition: background 0.2s;
+  border-radius: 0;
+}
+.pencil-trigger.draw-toolbar-light {
+  background: rgba(255, 255, 255, 0.98);
+  color: #333;
+}
+.pencil-trigger.draw-toolbar-light:hover,
+.pencil-trigger.draw-toolbar-light.active {
+  background: rgba(0, 0, 0, 0.06);
+  color: #2196f3;
+}
+.pencil-trigger.draw-toolbar-night {
+  background: rgba(17, 26, 46, 0.98);
+  color: #d9d9d9;
+}
+.pencil-trigger.draw-toolbar-night:hover,
+.pencil-trigger.draw-toolbar-night.active {
+  background: rgba(255, 255, 255, 0.08);
+  color: #42a5f5;
+}
+
+.draw-toolbar {
+  width: 44px;
+  flex-shrink: 0;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  padding: 8px 0;
+  gap: 4px;
+}
+
+.draw-toolbar-light {
+  background: rgba(255, 255, 255, 0.98);
+  color: #333;
+}
+
+.draw-toolbar-night {
+  background: rgba(17, 26, 46, 0.98);
+  color: #d9d9d9;
+  border-left-color: rgba(68, 75, 88, 0.4);
+}
+
+.draw-tool-item {
+  width: 36px;
+  height: 36px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  border-radius: 6px;
+  cursor: pointer;
+  transition: background 0.2s;
+}
+
+.draw-toolbar-light .draw-tool-item:hover {
+  background: rgba(0, 0, 0, 0.06);
+}
+
+.draw-toolbar-light .draw-tool-item.active {
+  background: rgba(33, 150, 243, 0.15);
+  color: #2196f3;
+}
+
+.draw-toolbar-night .draw-tool-item:hover {
+  background: rgba(255, 255, 255, 0.08);
+}
+
+.draw-toolbar-night .draw-tool-item.active {
+  background: rgba(33, 150, 243, 0.25);
+  color: #42a5f5;
+}
+
+.draw-tool-item svg {
+  display: block;
+}
+</style>

--
Gitblit v1.9.3