From a569a63a85447d6217e860094098ff9bbfabe436 Mon Sep 17 00:00:00 2001 From: zdl <3489966805@qq.com> Date: Thu, 4 Dec 2025 14:11:37 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=97=A5k=20=E5=92=8C=20=E5=88=86?= =?UTF-8?q?=E6=97=B6h5UI=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/StockChart/KLineChartModal.tsx | 82 +++++++++++-------- .../StockChart/TimelineChartModal.tsx | 60 ++++++++------ 2 files changed, 86 insertions(+), 56 deletions(-) diff --git a/src/components/StockChart/KLineChartModal.tsx b/src/components/StockChart/KLineChartModal.tsx index 75492d53..68bfa502 100644 --- a/src/components/StockChart/KLineChartModal.tsx +++ b/src/components/StockChart/KLineChartModal.tsx @@ -1,9 +1,11 @@ // src/components/StockChart/KLineChartModal.tsx - K线图弹窗组件 import React, { useEffect, useRef, useState, useCallback } from 'react'; import { createPortal } from 'react-dom'; +import { useSelector } from 'react-redux'; import * as echarts from 'echarts'; import dayjs from 'dayjs'; import { stockService } from '@services/eventService'; +import { selectIsMobile } from '@store/slices/deviceSlice'; /** * 股票信息 @@ -83,6 +85,9 @@ const KLineChartModal: React.FC = ({ const [earliestDate, setEarliestDate] = useState(null); const [totalDaysLoaded, setTotalDaysLoaded] = useState(0); + // H5 响应式适配 + const isMobile = useSelector(selectIsMobile); + // 调试日志 console.log('[KLineChartModal] 渲染状态:', { isOpen, @@ -296,16 +301,16 @@ const KLineChartModal: React.FC = ({ } } - // 图表配置 + // 图表配置(H5 响应式) const option: echarts.EChartsOption = { backgroundColor: '#1a1a1a', title: { text: `${stock?.stock_name || stock?.stock_code} - 日K线`, left: 'center', - top: 10, + top: isMobile ? 5 : 10, textStyle: { color: '#e0e0e0', - fontSize: 18, + fontSize: isMobile ? 14 : 18, fontWeight: 'bold', }, }, @@ -370,16 +375,16 @@ const KLineChartModal: React.FC = ({ }, grid: [ { - left: '5%', - right: '5%', - top: '12%', - height: '60%', + left: isMobile ? '12%' : '5%', + right: isMobile ? '5%' : '5%', + top: isMobile ? '12%' : '12%', + height: isMobile ? '55%' : '60%', }, { - left: '5%', - right: '5%', - top: '77%', - height: '18%', + left: isMobile ? '12%' : '5%', + right: isMobile ? '5%' : '5%', + top: isMobile ? '72%' : '77%', + height: isMobile ? '20%' : '18%', }, ], xAxis: [ @@ -394,7 +399,8 @@ const KLineChartModal: React.FC = ({ }, axisLabel: { color: '#999', - interval: Math.floor(dates.length / 8), + fontSize: isMobile ? 10 : 12, + interval: Math.floor(dates.length / (isMobile ? 4 : 8)), }, splitLine: { show: false, @@ -411,7 +417,8 @@ const KLineChartModal: React.FC = ({ }, axisLabel: { color: '#999', - interval: Math.floor(dates.length / 8), + fontSize: isMobile ? 10 : 12, + interval: Math.floor(dates.length / (isMobile ? 4 : 8)), }, }, ], @@ -419,6 +426,7 @@ const KLineChartModal: React.FC = ({ { scale: true, gridIndex: 0, + splitNumber: isMobile ? 4 : 5, splitLine: { show: true, lineStyle: { @@ -432,12 +440,14 @@ const KLineChartModal: React.FC = ({ }, axisLabel: { color: '#999', + fontSize: isMobile ? 10 : 12, formatter: (value: number) => value.toFixed(2), }, }, { scale: true, gridIndex: 1, + splitNumber: isMobile ? 2 : 3, splitLine: { show: false, }, @@ -448,6 +458,7 @@ const KLineChartModal: React.FC = ({ }, axisLabel: { color: '#999', + fontSize: isMobile ? 10 : 12, formatter: (value: number) => { if (value >= 100000000) { return (value / 100000000).toFixed(1) + '亿'; @@ -545,7 +556,7 @@ const KLineChartModal: React.FC = ({ return () => clearTimeout(retryTimer); } - }, [data, stock]); + }, [data, stock, isMobile]); // 加载数据 useEffect(() => { @@ -600,13 +611,13 @@ const KLineChartModal: React.FC = ({ top: '50%', left: '50%', transform: 'translate(-50%, -50%)', - width: '90vw', - maxWidth: '1400px', - maxHeight: '85vh', + width: isMobile ? '96vw' : '90vw', + maxWidth: isMobile ? 'none' : '1400px', + maxHeight: isMobile ? '85vh' : '85vh', backgroundColor: '#1a1a1a', border: '2px solid #ffd700', boxShadow: '0 0 30px rgba(255, 215, 0, 0.5)', - borderRadius: '8px', + borderRadius: isMobile ? '12px' : '8px', zIndex: 10002, display: 'flex', flexDirection: 'column', @@ -616,7 +627,7 @@ const KLineChartModal: React.FC = ({ {/* Header */}
= ({ }} >
-
- +
+ {stock.stock_name || stock.stock_code} ({stock.stock_code}) {data.length > 0 && ( - + 共{data.length}个交易日 {hasMore ? '(向左滑动加载更多)' : '(已加载全部)'} )} {loadingMore && ( - + = ({ )}
-
- 日K线图 - - 💡 鼠标滚轮缩放 | 拖动查看不同时间段 +
+ 日K线图 + + 💡 {isMobile ? '滚轮缩放 | 拖动查看' : '鼠标滚轮缩放 | 拖动查看不同时间段'}
@@ -675,26 +686,33 @@ const KLineChartModal: React.FC = ({
{/* Body */} -
+
{error && (
- {error} + {error}
)} -
+
{loading && (
= ({ const [error, setError] = useState(null); const [data, setData] = useState([]); + // H5 响应式适配 + const isMobile = useSelector(selectIsMobile); + // 加载分时图数据(优先使用缓存) const loadData = async () => { if (!stock?.stock_code) return; @@ -187,16 +192,16 @@ const TimelineChartModal: React.FC = ({ } } - // 图表配置 + // 图表配置(H5 响应式) const option: echarts.EChartsOption = { backgroundColor: '#1a1a1a', title: { text: `${stock?.stock_name || stock?.stock_code} - 分时图`, left: 'center', - top: 10, + top: isMobile ? 5 : 10, textStyle: { color: '#e0e0e0', - fontSize: 18, + fontSize: isMobile ? 14 : 18, fontWeight: 'bold', }, }, @@ -247,16 +252,16 @@ const TimelineChartModal: React.FC = ({ }, grid: [ { - left: '5%', - right: '5%', - top: '15%', - height: '55%', + left: isMobile ? '12%' : '5%', + right: isMobile ? '5%' : '5%', + top: isMobile ? '12%' : '15%', + height: isMobile ? '58%' : '55%', }, { - left: '5%', - right: '5%', - top: '75%', - height: '15%', + left: isMobile ? '12%' : '5%', + right: isMobile ? '5%' : '5%', + top: isMobile ? '75%' : '75%', + height: isMobile ? '18%' : '15%', }, ], xAxis: [ @@ -271,7 +276,8 @@ const TimelineChartModal: React.FC = ({ }, axisLabel: { color: '#999', - interval: Math.floor(times.length / 6), + fontSize: isMobile ? 10 : 12, + interval: Math.floor(times.length / (isMobile ? 4 : 6)), }, splitLine: { show: true, @@ -291,7 +297,8 @@ const TimelineChartModal: React.FC = ({ }, axisLabel: { color: '#999', - interval: Math.floor(times.length / 6), + fontSize: isMobile ? 10 : 12, + interval: Math.floor(times.length / (isMobile ? 4 : 6)), }, }, ], @@ -299,6 +306,7 @@ const TimelineChartModal: React.FC = ({ { scale: true, gridIndex: 0, + splitNumber: isMobile ? 4 : 5, splitLine: { show: true, lineStyle: { @@ -312,12 +320,14 @@ const TimelineChartModal: React.FC = ({ }, axisLabel: { color: '#999', + fontSize: isMobile ? 10 : 12, formatter: (value: number) => value.toFixed(2), }, }, { scale: true, gridIndex: 1, + splitNumber: isMobile ? 2 : 3, splitLine: { show: false, }, @@ -328,6 +338,7 @@ const TimelineChartModal: React.FC = ({ }, axisLabel: { color: '#999', + fontSize: isMobile ? 10 : 12, formatter: (value: number) => { if (value >= 10000) { return (value / 10000).toFixed(1) + '万'; @@ -443,7 +454,7 @@ const TimelineChartModal: React.FC = ({ return () => clearTimeout(retryTimer); } - }, [data, stock]); + }, [data, stock, isMobile]); // 加载数据 useEffect(() => { @@ -455,29 +466,30 @@ const TimelineChartModal: React.FC = ({ if (!stock) return null; return ( - + - - + + - + {stock.stock_name || stock.stock_code} ({stock.stock_code}) - + 分时走势图 - + {error && ( @@ -485,7 +497,7 @@ const TimelineChartModal: React.FC = ({ )} - + {loading && (