fix:修复业绩走势折线图展示问题
This commit is contained in:
@@ -779,20 +779,29 @@ export const fetchFundHistory = async (code, range = '1m') => {
|
|||||||
|
|
||||||
if (Array.isArray(trend) && trend.length) {
|
if (Array.isArray(trend) && trend.length) {
|
||||||
const startMs = start.startOf('day').valueOf();
|
const startMs = start.startOf('day').valueOf();
|
||||||
// end 可能是当日任意时刻,这里用 end-of-day 包含最后一天
|
|
||||||
const endMs = end.endOf('day').valueOf();
|
const endMs = end.endOf('day').valueOf();
|
||||||
|
|
||||||
const out = trend
|
// 若起始日没有净值,则往前推到最近一日有净值的数据作为有效起始
|
||||||
.filter((d) => d && typeof d.x === 'number' && d.x >= startMs && d.x <= endMs)
|
const validTrend = trend
|
||||||
|
.filter((d) => d && typeof d.x === 'number' && Number.isFinite(Number(d.y)) && d.x <= endMs)
|
||||||
|
.sort((a, b) => a.x - b.x);
|
||||||
|
const startDayEndMs = startMs + 24 * 60 * 60 * 1000 - 1;
|
||||||
|
const hasPointOnStartDay = validTrend.some((d) => d.x >= startMs && d.x <= startDayEndMs);
|
||||||
|
let effectiveStartMs = startMs;
|
||||||
|
if (!hasPointOnStartDay) {
|
||||||
|
const lastBeforeStart = validTrend.filter((d) => d.x < startMs).pop();
|
||||||
|
if (lastBeforeStart) effectiveStartMs = lastBeforeStart.x;
|
||||||
|
}
|
||||||
|
|
||||||
|
const out = validTrend
|
||||||
|
.filter((d) => d.x >= effectiveStartMs && d.x <= endMs)
|
||||||
.map((d) => {
|
.map((d) => {
|
||||||
const value = Number(d.y);
|
const value = Number(d.y);
|
||||||
if (!Number.isFinite(value)) return null;
|
|
||||||
const date = dayjs(d.x).tz(TZ).format('YYYY-MM-DD');
|
const date = dayjs(d.x).tz(TZ).format('YYYY-MM-DD');
|
||||||
return { date, value };
|
return { date, value };
|
||||||
})
|
});
|
||||||
.filter(Boolean);
|
|
||||||
|
|
||||||
// 解析 Data_grandTotal 为多条对比曲线,保存在数组属性 out.grandTotalSeries 上
|
// 解析 Data_grandTotal 为多条对比曲线,使用同一有效起始日
|
||||||
if (Array.isArray(grandTotal) && grandTotal.length) {
|
if (Array.isArray(grandTotal) && grandTotal.length) {
|
||||||
const grandTotalSeries = grandTotal
|
const grandTotalSeries = grandTotal
|
||||||
.map((series) => {
|
.map((series) => {
|
||||||
@@ -801,7 +810,7 @@ export const fetchFundHistory = async (code, range = '1m') => {
|
|||||||
const points = series.data
|
const points = series.data
|
||||||
.filter((item) => Array.isArray(item) && typeof item[0] === 'number')
|
.filter((item) => Array.isArray(item) && typeof item[0] === 'number')
|
||||||
.map(([ts, val]) => {
|
.map(([ts, val]) => {
|
||||||
if (ts < startMs || ts > endMs) return null;
|
if (ts < effectiveStartMs || ts > endMs) return null;
|
||||||
const numVal = Number(val);
|
const numVal = Number(val);
|
||||||
if (!Number.isFinite(numVal)) return null;
|
if (!Number.isFinite(numVal)) return null;
|
||||||
const date = dayjs(ts).tz(TZ).format('YYYY-MM-DD');
|
const date = dayjs(ts).tz(TZ).format('YYYY-MM-DD');
|
||||||
@@ -814,7 +823,6 @@ export const fetchFundHistory = async (code, range = '1m') => {
|
|||||||
.filter(Boolean);
|
.filter(Boolean);
|
||||||
|
|
||||||
if (grandTotalSeries.length) {
|
if (grandTotalSeries.length) {
|
||||||
// 给数组挂一个属性,供前端图表组件读取
|
|
||||||
out.grandTotalSeries = grandTotalSeries;
|
out.grandTotalSeries = grandTotalSeries;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,9 +62,14 @@ export default function FundTrendChart({ code, isExpanded, onToggleExpand, trans
|
|||||||
const [error, setError] = useState(null);
|
const [error, setError] = useState(null);
|
||||||
const chartRef = useRef(null);
|
const chartRef = useRef(null);
|
||||||
const hoverTimeoutRef = useRef(null);
|
const hoverTimeoutRef = useRef(null);
|
||||||
|
const clearActiveIndexRef = useRef(null);
|
||||||
const [hiddenGrandSeries, setHiddenGrandSeries] = useState(() => new Set());
|
const [hiddenGrandSeries, setHiddenGrandSeries] = useState(() => new Set());
|
||||||
const [activeIndex, setActiveIndex] = useState(null);
|
const [activeIndex, setActiveIndex] = useState(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
clearActiveIndexRef.current = () => setActiveIndex(null);
|
||||||
|
});
|
||||||
|
|
||||||
const chartColors = useMemo(() => getChartThemeColors(theme), [theme]);
|
const chartColors = useMemo(() => getChartThemeColors(theme), [theme]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -161,8 +166,11 @@ export default function FundTrendChart({ code, isExpanded, onToggleExpand, trans
|
|||||||
grandAccent3,
|
grandAccent3,
|
||||||
chartColors.text,
|
chartColors.text,
|
||||||
];
|
];
|
||||||
const grandDatasets = grandTotalSeries.map((series, idx) => {
|
// 隐藏第一条对比线(数据与图示);第二条用原第一条颜色,第三条用原第二条,顺延
|
||||||
const color = grandColors[idx % grandColors.length];
|
const visibleGrandSeries = grandTotalSeries.filter((_, idx) => idx > 0);
|
||||||
|
const grandDatasets = visibleGrandSeries.map((series, displayIdx) => {
|
||||||
|
const color = grandColors[displayIdx % grandColors.length];
|
||||||
|
const idx = displayIdx + 1; // 原始索引,用于 hiddenGrandSeries 的 key
|
||||||
const key = `${series.name || 'series'}_${idx}`;
|
const key = `${series.name || 'series'}_${idx}`;
|
||||||
const isHidden = hiddenGrandSeries.has(key);
|
const isHidden = hiddenGrandSeries.has(key);
|
||||||
const pointsByDate = new Map(series.points.map(p => [p.date, p.value]));
|
const pointsByDate = new Map(series.points.map(p => [p.date, p.value]));
|
||||||
@@ -374,6 +382,7 @@ export default function FundTrendChart({ code, isExpanded, onToggleExpand, trans
|
|||||||
chart.tooltip.setActiveElements([], { x: 0, y: 0 });
|
chart.tooltip.setActiveElements([], { x: 0, y: 0 });
|
||||||
}
|
}
|
||||||
chart.update();
|
chart.update();
|
||||||
|
clearActiveIndexRef.current?.();
|
||||||
}, 2000);
|
}, 2000);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -606,17 +615,19 @@ export default function FundTrendChart({ code, isExpanded, onToggleExpand, trans
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
{Array.isArray(data.grandTotalSeries) &&
|
{Array.isArray(data.grandTotalSeries) &&
|
||||||
data.grandTotalSeries.map((series, idx) => {
|
data.grandTotalSeries
|
||||||
// 与折线数据使用同一套对比色,且排除红/绿
|
.filter((_, idx) => idx > 0)
|
||||||
const legendAccent3 = theme === 'light' ? '#f97316' : '#fb923c';
|
.map((series, displayIdx) => {
|
||||||
const legendColors = [
|
const idx = displayIdx + 1;
|
||||||
primaryColor,
|
const legendAccent3 = theme === 'light' ? '#f97316' : '#fb923c';
|
||||||
chartColors.muted,
|
const legendColors = [
|
||||||
legendAccent3,
|
primaryColor,
|
||||||
chartColors.text,
|
chartColors.muted,
|
||||||
];
|
legendAccent3,
|
||||||
const color = legendColors[idx % legendColors.length];
|
chartColors.text,
|
||||||
const key = `${series.name || 'series'}_${idx}`;
|
];
|
||||||
|
const color = legendColors[displayIdx % legendColors.length];
|
||||||
|
const key = `${series.name || 'series'}_${idx}`;
|
||||||
const isHidden = hiddenGrandSeries.has(key);
|
const isHidden = hiddenGrandSeries.has(key);
|
||||||
let valueText = '--';
|
let valueText = '--';
|
||||||
if (!isHidden && currentIndex != null && data[currentIndex]) {
|
if (!isHidden && currentIndex != null && data[currentIndex]) {
|
||||||
|
|||||||
Reference in New Issue
Block a user