UX 审查修复:统一修正术语、图表"现在"标记、专业术语解释、异常行动建议
P0-1 术语统一: - WeatherDecisionBand 改用"上修/下修/维持"替代"偏高温/暂不追/等待确认" - 与 AI 后端提示词使用的术语体系一致 P0-9 图表"现在"标记: - chart-utils.ts 导出 currentIndex - AiCityTemperatureChart 在 currentIndex 处绘制竖线(蓝色虚线) P0-13 专业术语解释: - DataFreshnessBar 新增 labelTitle 属性(hover tooltip) - METAR → "机场气象观测报文" / "Meteorological Aerodrome Report" - HKO → "香港天文台官方实测" / "Hong Kong Observatory official readings" P0-16 异常行动建议: - primaryReason 追加行动指引(实测突破→建议关注偏高温区间等待确认 / 峰值已过→建议避免追高 / 观测过旧→建议等待新报文) P1-8 DEB 路径分段样式: - 过去部分实线(已确定),未来部分虚线(预测不确定) P1-11 HistoryChart 单位: - tooltip 使用 temp_symbol 替代硬编码 ° Tested: npx tsc --noEmit
This commit is contained in:
@@ -125,7 +125,7 @@ export function HistoryChart() {
|
||||
titleFont: { family: "Inter", size: 13, weight: 600 },
|
||||
callbacks: {
|
||||
label: (ctx) =>
|
||||
`${ctx.dataset.label}: ${ctx.parsed.y?.toFixed(1)}°`,
|
||||
`${ctx.dataset.label}: ${ctx.parsed.y?.toFixed(1)}${store.selectedDetail?.temp_symbol || "°C"}`,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -109,7 +109,6 @@ export function AiCityTemperatureChart({ detail }: { detail: CityDetail }) {
|
||||
>["datasets"] = [
|
||||
{
|
||||
borderColor: "rgba(100, 116, 139, 0.72)",
|
||||
borderDash: [6, 4],
|
||||
borderWidth: 1.6,
|
||||
data: chartData.datasets.debPast.map(
|
||||
(value, index) => value ?? chartData.datasets.debFuture[index],
|
||||
@@ -117,6 +116,10 @@ export function AiCityTemperatureChart({ detail }: { detail: CityDetail }) {
|
||||
fill: false,
|
||||
label: forecastLabel,
|
||||
pointRadius: 0,
|
||||
segment: {
|
||||
borderDash: (ctx: { p0DataIndex: number }) =>
|
||||
chartData.currentIndex != null && ctx.p0DataIndex < chartData.currentIndex ? [] : [6, 4],
|
||||
},
|
||||
spanGaps: true,
|
||||
tension: 0.28,
|
||||
},
|
||||
@@ -148,6 +151,23 @@ export function AiCityTemperatureChart({ detail }: { detail: CityDetail }) {
|
||||
showLine: false,
|
||||
});
|
||||
|
||||
const ci = chartData.currentIndex;
|
||||
if (ci != null && ci >= 0 && ci < (chartData.times?.length || 0)) {
|
||||
datasets.push({
|
||||
backgroundColor: "rgba(77, 163, 255, 0.5)",
|
||||
borderColor: "rgba(77, 163, 255, 0.5)",
|
||||
borderDash: [3, 4],
|
||||
borderWidth: 1.2,
|
||||
data: [
|
||||
{ x: ci, y: chartData.max },
|
||||
{ x: ci, y: chartData.min },
|
||||
],
|
||||
label: "Now",
|
||||
pointRadius: 0,
|
||||
showLine: true,
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
data: {
|
||||
datasets,
|
||||
@@ -165,7 +185,7 @@ export function AiCityTemperatureChart({ detail }: { detail: CityDetail }) {
|
||||
borderColor: "rgba(77, 163, 255, 0.38)",
|
||||
borderWidth: 1,
|
||||
},
|
||||
},
|
||||
} as Record<string, unknown>,
|
||||
responsive: true,
|
||||
scales: {
|
||||
x: {
|
||||
|
||||
@@ -461,6 +461,9 @@ export function AiPinnedCityCard({
|
||||
const dataFreshnessRows = [
|
||||
{
|
||||
label: isHkoObservation ? (isEn ? "HKO" : "天文台") : "METAR",
|
||||
labelTitle: isHkoObservation
|
||||
? (isEn ? "Hong Kong Observatory official readings" : "香港天文台官方实测")
|
||||
: (isEn ? "Meteorological Aerodrome Report — airport weather observation" : "机场气象观测报文"),
|
||||
value: buildObservationFreshnessValue({
|
||||
detail,
|
||||
displayTime: metarReportTimeDisplay,
|
||||
|
||||
@@ -4,6 +4,7 @@ import type { StatusTone } from "@/components/dashboard/scan-terminal/CityStatus
|
||||
|
||||
export type DataFreshnessRow = {
|
||||
label: string;
|
||||
labelTitle?: string;
|
||||
value: string;
|
||||
tone: string;
|
||||
};
|
||||
@@ -26,7 +27,7 @@ export function DataFreshnessBar({
|
||||
<strong>{isEn ? "Data freshness" : "数据新鲜度"}</strong>
|
||||
{rows.map((freshness) => (
|
||||
<span key={freshness.label} className={freshness.tone}>
|
||||
<b>{freshness.label}{freshnessSeparator}</b>
|
||||
<b title={freshness.labelTitle}>{freshness.label}{freshnessSeparator}</b>
|
||||
<em>{freshness.value}</em>
|
||||
</span>
|
||||
))}
|
||||
|
||||
@@ -555,15 +555,15 @@ export function buildWeatherDecisionView({
|
||||
: "等待模型补齐"
|
||||
: paceTone === "warm"
|
||||
? isEn
|
||||
? "Watch hotter range"
|
||||
: "关注偏高温区间"
|
||||
? "Revise upward"
|
||||
: "预计最高温上修"
|
||||
: paceTone === "cold"
|
||||
? isEn
|
||||
? "Avoid chasing high"
|
||||
: "暂不追高温"
|
||||
? "Revise downward"
|
||||
: "预计最高温下修"
|
||||
: isEn
|
||||
? "Wait for peak-window confirmation"
|
||||
: "等待峰值窗口确认";
|
||||
? "Stay with model base"
|
||||
: "维持模型基准";
|
||||
const expectedHigh =
|
||||
center != null && Number.isFinite(Number(center))
|
||||
? formatTemperatureValue(Number(center), tempSymbol, { digits: 1 })
|
||||
|
||||
@@ -142,28 +142,28 @@ export function buildCityDecisionState({
|
||||
: "watch";
|
||||
const primaryReason = observedHighBreak
|
||||
? isEn
|
||||
? "Observation has broken above the model range."
|
||||
: "实测已突破模型上沿。"
|
||||
? "Observation has broken above the model range. Consider the upside scenario; wait for the next bulletin to confirm the breakout."
|
||||
: "实测已突破模型上沿。建议关注偏高温区间,等待下一报文确认突破是否持续。"
|
||||
: peakHasPassed
|
||||
? isEn
|
||||
? "Peak window has passed; confirm whether a new high can still form."
|
||||
: "峰值窗口已过,确认是否还会出现新高。"
|
||||
? "Peak window has passed; confirm whether a new high can still form. Avoid chasing if no new high prints."
|
||||
: "峰值窗口已过,确认是否还会出现新高。若无新高,建议避免追高。"
|
||||
: observationStale
|
||||
? isEn
|
||||
? "Observation is stale and needs the next report."
|
||||
: "观测已过旧,需要下一报文确认。"
|
||||
? "Observation is stale and needs the next report. Use only as background reference until fresh data arrives."
|
||||
: "观测已过旧,需要下一报文确认。当前数据仅作背景参考,建议等待新报文后再做判断。"
|
||||
: marketStatus === "unavailable"
|
||||
? isEn
|
||||
? "Weather evidence is usable, but no tradable quote is available yet."
|
||||
: "天气证据可参考,但暂无可交易价格。"
|
||||
? "Weather evidence is usable, but no tradable quote is available yet. Weather judgment still applies."
|
||||
: "天气证据可参考,但暂无可交易价格。天气判断仍可参考,无需急于操作。"
|
||||
: modelHighlyConsistent
|
||||
? isEn
|
||||
? "Models are aligned; wait for observation confirmation."
|
||||
: "模型高度一致,等待实测确认。"
|
||||
? "Models are aligned; wait for observation confirmation. A clear direction should emerge after the next report."
|
||||
: "模型高度一致,等待实测确认。下一报文后方向会更明确。"
|
||||
: needsNextBulletin
|
||||
? isEn
|
||||
? "The next bulletin is more likely to decide direction."
|
||||
: "下一报文更可能决定方向。"
|
||||
? "The next bulletin is more likely to decide direction. Hold until the picture clears."
|
||||
: "下一报文更可能决定方向。建议等待信号明确后再做决策。"
|
||||
: isEn
|
||||
? "Compare new observations with the expected high through the peak window."
|
||||
: "在峰值窗口内继续对照实测与预计高点。";
|
||||
|
||||
@@ -877,6 +877,7 @@ export function getTemperatureChartData(
|
||||
const xMax = times.length ? chartHmToMinutes(times[times.length - 1]) ?? 24 * 60 : 24 * 60;
|
||||
|
||||
return {
|
||||
currentIndex,
|
||||
datasets: {
|
||||
airportMetarPoints,
|
||||
airportMetarSeries,
|
||||
|
||||
Reference in New Issue
Block a user