diff --git a/app/components/FundIntradayChart.jsx b/app/components/FundIntradayChart.jsx index 4d11516..24748cd 100644 --- a/app/components/FundIntradayChart.jsx +++ b/app/components/FundIntradayChart.jsx @@ -1,6 +1,6 @@ 'use client'; -import { useMemo } from 'react'; +import { useMemo, useRef, useEffect } from 'react'; import { Chart as ChartJS, CategoryScale, @@ -27,6 +27,9 @@ ChartJS.register( * referenceNav: 参考净值(最新单位净值),用于计算涨跌幅;未传则用当日第一个估值作为参考。 */ export default function FundIntradayChart({ series = [], referenceNav }) { + const chartRef = useRef(null); + const hoverTimeoutRef = useRef(null); + const chartData = useMemo(() => { if (!series.length) return { labels: [], datasets: [] }; const labels = series.map((d) => d.time); @@ -91,7 +94,7 @@ export default function FundIntradayChart({ series = [], referenceNav }) { }, y: { display: true, - position: 'right', + position: 'left', grid: { color: '#1f2937', drawBorder: false }, ticks: { color: '#9ca3af', @@ -100,11 +103,45 @@ export default function FundIntradayChart({ series = [], referenceNav }) { } } }, - onHover: (event, chartElement) => { - event.native.target.style.cursor = chartElement[0] ? 'crosshair' : 'default'; + onHover: (event, chartElement, chart) => { + const target = event?.native?.target; + if (target) { + target.style.cursor = chartElement[0] ? 'crosshair' : 'default'; + } + + const currentChart = chart || chartRef.current; + if (!currentChart) return; + + if (hoverTimeoutRef.current) { + clearTimeout(hoverTimeoutRef.current); + hoverTimeoutRef.current = null; + } + + if (chartElement[0]) { + hoverTimeoutRef.current = setTimeout(() => { + const c = chartRef.current || currentChart; + if (!c) return; + c.setActiveElements([]); + if (c.tooltip) { + c.tooltip.setActiveElements([], { x: 0, y: 0 }); + } + c.update(); + if (target) { + target.style.cursor = 'default'; + } + }, 2000); + } } }), []); + useEffect(() => { + return () => { + if (hoverTimeoutRef.current) { + clearTimeout(hoverTimeoutRef.current); + } + }; + }, []); + const plugins = useMemo(() => [{ id: 'crosshair', afterDraw: (chart) => { @@ -157,9 +194,9 @@ export default function FundIntradayChart({ series = [], referenceNav }) { const valueStr = typeof val === 'number' ? `${val >= 0 ? '+' : ''}${val.toFixed(2)}%` : String(val); const vw = ctx.measureText(valueStr).width + 8; ctx.fillStyle = prim; - ctx.fillRect(rightX - vw, y - 8, vw, 16); + ctx.fillRect(leftX, y - 8, vw, 16); ctx.fillStyle = bgText; - ctx.fillText(valueStr, rightX - vw / 2, y); + ctx.fillText(valueStr, leftX + vw / 2, y); } ctx.restore(); } @@ -191,7 +228,7 @@ export default function FundIntradayChart({ series = [], referenceNav }) { {displayDate && 估值日期 {displayDate}}