From 98ee1cc99681debc6e52b995675b25de4e5e88f9 Mon Sep 17 00:00:00 2001 From: yuxuanhui Date: Wed, 2 Sep 2026 18:36:02 +0800 Subject: [PATCH 1/2] fix(selection): update chart labels and improve layout for clarity in selection components --- .../components/pattern-case-image.tsx | 4 ++-- .../components/selection-chart-option.test.ts | 14 ++++++++++-- .../components/selection-chart-option.ts | 22 +++++++++---------- .../components/selection-chart.test.tsx | 2 +- .../selection/components/selection-chart.tsx | 2 +- 5 files changed, 27 insertions(+), 17 deletions(-) diff --git a/zhixing-web/src/features/selection/components/pattern-case-image.tsx b/zhixing-web/src/features/selection/components/pattern-case-image.tsx index e6d0370..1f6a158 100644 --- a/zhixing-web/src/features/selection/components/pattern-case-image.tsx +++ b/zhixing-web/src/features/selection/components/pattern-case-image.tsx @@ -16,7 +16,7 @@ export function PatternCaseImage({ score }: PatternCaseImageProps) { patternCaseImageById[matchedCase.id as keyof typeof patternCaseImageById] return ( -
+

最接近案例:{matchedCase.name} @@ -32,7 +32,7 @@ export function PatternCaseImage({ score }: PatternCaseImageProps) { ) : ( {`${matchedCase.name} setFailedSource(source)} src={source} diff --git a/zhixing-web/src/features/selection/components/selection-chart-option.test.ts b/zhixing-web/src/features/selection/components/selection-chart-option.test.ts index 9e06ec5..225cb9c 100644 --- a/zhixing-web/src/features/selection/components/selection-chart-option.test.ts +++ b/zhixing-web/src/features/selection/components/selection-chart-option.test.ts @@ -44,6 +44,7 @@ describe("selection chart option", () => { }) expect(dataZoom[1].xAxisIndex).toEqual([0, 1, 2]) expect(legends[0]?.data).toEqual(["知行白线", "知行黄线"]) + expect(legends[1]?.data).toEqual(["J"]) expect(series.find((item) => item.name === "日线")).toMatchObject({ xAxisIndex: 0, yAxisIndex: 0, @@ -62,7 +63,16 @@ describe("selection chart option", () => { xAxisIndex: 1, yAxisIndex: 1, }) - expect(series.filter((item) => item.xAxisIndex === 2)).toHaveLength(3) + expect(series.filter((item) => item.xAxisIndex === 2)).toEqual([ + expect.objectContaining({ + data: points.map((item) => item.j), + name: "J", + xAxisIndex: 2, + yAxisIndex: 2, + }), + ]) + expect(series.find((item) => item.name === "K")).toBeUndefined() + expect(series.find((item) => item.name === "D")).toBeUndefined() expect(series[0].data[0]).toEqual([10, 10.5, 9, 11]) }) @@ -91,7 +101,7 @@ describe("selection chart option", () => { expect(candle).toHaveLength(4) expect(candle.every(Number.isNaN)).toBe(true) expect(volume?.data[0]).toMatchObject({ value: null }) - expect(lines).toHaveLength(5) + expect(lines).toHaveLength(3) for (const indicator of lines) { expect(indicator.data).toEqual([null]) } diff --git a/zhixing-web/src/features/selection/components/selection-chart-option.ts b/zhixing-web/src/features/selection/components/selection-chart-option.ts index bd8f363..b168184 100644 --- a/zhixing-web/src/features/selection/components/selection-chart-option.ts +++ b/zhixing-web/src/features/selection/components/selection-chart-option.ts @@ -35,7 +35,7 @@ export type SelectionChartOption = ComposeOption< /** * Build the three-grid financial chart configuration from aligned API points. * - * @param points Ascending qfq OHLCV, KDJ, and Zhixing-line points from the API. + * @param points Ascending qfq OHLCV, J, and Zhixing-line points from the API. * @returns One ECharts option with synchronized axes and an exact 120-point window. */ export function buildSelectionChartOption( @@ -75,7 +75,7 @@ export function buildSelectionChartOption( top: 8, }, { - data: ["K", "D", "J"], + data: ["J"], right: 20, top: "73%", }, @@ -126,25 +126,25 @@ export function buildSelectionChartOption( xAxisIndex: 1, yAxisIndex: 1, }, - ...(["k", "d", "j"] as const).map((key, index): LineSeriesOption => ({ + { connectNulls: false, - data: points.map((point) => point[key]), - name: key.toUpperCase(), + data: points.map((point) => point.j), + lineStyle: { + color: "#9333ea", + width: 1.5, + }, + name: "J", showSymbol: false, smooth: false, type: "line", xAxisIndex: 2, yAxisIndex: 2, - lineStyle: { - color: ["#2563eb", "#d97706", "#9333ea"][index], - width: 1.5, - }, - })), + }, ], title: [ { left: 12, text: "日线", textStyle: { fontSize: 12 }, top: 8 }, { left: 72, text: "成交量", textStyle: { fontSize: 12 }, top: "54%" }, - { left: 72, text: "KDJ", textStyle: { fontSize: 12 }, top: "72%" }, + { left: 72, text: "J", textStyle: { fontSize: 12 }, top: "72%" }, ], tooltip: { axisPointer: { type: "cross" }, diff --git a/zhixing-web/src/features/selection/components/selection-chart.test.tsx b/zhixing-web/src/features/selection/components/selection-chart.test.tsx index 24f4902..54c695c 100644 --- a/zhixing-web/src/features/selection/components/selection-chart.test.tsx +++ b/zhixing-web/src/features/selection/components/selection-chart.test.tsx @@ -90,7 +90,7 @@ describe("SelectionChart", () => { expect( screen.getByRole("img", { - name: "药明康德 日线、知行黄白线、成交量和 KDJ 图表", + name: "药明康德 日线、知行黄白线、成交量和 J 线图表", }), ).toBeInTheDocument() expect(chartMocks.init).toHaveBeenCalledTimes(1) diff --git a/zhixing-web/src/features/selection/components/selection-chart.tsx b/zhixing-web/src/features/selection/components/selection-chart.tsx index 3c8b4fd..1cb4e53 100644 --- a/zhixing-web/src/features/selection/components/selection-chart.tsx +++ b/zhixing-web/src/features/selection/components/selection-chart.tsx @@ -64,7 +64,7 @@ export function SelectionChart({ chart, className }: SelectionChartProps) { return (
Date: Wed, 2 Sep 2026 18:38:57 +0800 Subject: [PATCH 2/2] feat(selection): enhance PatternScore component with detailed breakdown labels and update tests for accuracy --- .../selection/components/pattern-score.tsx | 24 ++++++++++++++++--- .../pages/selection-results-page.test.tsx | 7 ++++-- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/zhixing-web/src/features/selection/components/pattern-score.tsx b/zhixing-web/src/features/selection/components/pattern-score.tsx index 0f370ab..9f3821a 100644 --- a/zhixing-web/src/features/selection/components/pattern-score.tsx +++ b/zhixing-web/src/features/selection/components/pattern-score.tsx @@ -6,6 +6,13 @@ interface PatternScoreProps { score: SelectionPatternScore | null } +const breakdownLabels = { + trend_structure: "趋势", + kdj_state: "KDJ", + volume_pattern: "量能", + price_shape: "价格形态", +} as const + export function PatternScoreSummary({ score }: PatternScoreProps) { if (!score) return 未评分 if (score.status === "failed") { @@ -44,9 +51,20 @@ export function PatternScoreDetails({ score }: PatternScoreProps) {

{formatScore(score.value)} 分

- - {score.status === "matched" ? "已匹配" : "低于匹配阈值"} - + {score.breakdown ? ( +
+ {Object.entries(breakdownLabels).map(([key, label]) => ( +
+
{label}
+
+ {formatScore( + score.breakdown?.[key as keyof typeof breakdownLabels], + )} +
+
+ ))} +
+ ) : null}
) } diff --git a/zhixing-web/src/features/selection/pages/selection-results-page.test.tsx b/zhixing-web/src/features/selection/pages/selection-results-page.test.tsx index 4e71d33..8a4e311 100644 --- a/zhixing-web/src/features/selection/pages/selection-results-page.test.tsx +++ b/zhixing-web/src/features/selection/pages/selection-results-page.test.tsx @@ -212,7 +212,10 @@ describe("SelectionResultsPage", () => { expect( within(detailPanel).getByText("最接近案例:华纳药厂"), ).toBeInTheDocument() - expect(within(detailPanel).queryByText("价格形态")).not.toBeInTheDocument() + expect(within(detailPanel).getByText("价格形态")).toBeInTheDocument() + expect(within(detailPanel).getByText("趋势")).toBeInTheDocument() + expect(within(detailPanel).getByText("量能")).toBeInTheDocument() + expect(within(detailPanel).queryByText("已匹配")).not.toBeInTheDocument() expect(within(detailPanel).getByText("J 值")).toBeInTheDocument() expect(within(detailPanel).getByText("RSI")).toBeInTheDocument() expect(within(detailPanel).getByText("日涨跌幅")).toBeInTheDocument() @@ -239,7 +242,7 @@ describe("SelectionResultsPage", () => { score: null, }, { - expected: "低于匹配阈值", + expected: "低于阈值", score: { breakdown: { kdj_state: 42,