feat: implement interactive temperature chart dashboard with runway trend visualization and multi-source data collection support

This commit is contained in:
2569718930@qq.com
2026-05-27 01:16:49 +08:00
parent c4119c1aab
commit 2670e2f8ee
13 changed files with 308 additions and 52 deletions
@@ -91,12 +91,16 @@ export function runTests() {
const chartStatsPath = path.join(process.cwd(), "components", "dashboard", "scan-terminal", "TemperatureStatsBars.tsx");
const chartRunwayPath = path.join(process.cwd(), "components", "dashboard", "scan-terminal", "TemperatureRunwayDetails.tsx");
const chartTooltipPath = path.join(process.cwd(), "components", "dashboard", "scan-terminal", "TemperatureTooltipContent.tsx");
const chartSummaryPath = path.join(process.cwd(), "components", "dashboard", "scan-terminal", "ModelCurvesSummary.tsx");
assert(fs.existsSync(chartCanvasPath), "temperature chart Recharts canvas must live in TemperatureChartCanvas.tsx");
assert(fs.existsSync(chartStatsPath), "temperature chart stat bars must live in TemperatureStatsBars.tsx");
assert(fs.existsSync(chartRunwayPath), "temperature chart runway detail panel must live in TemperatureRunwayDetails.tsx");
assert(fs.existsSync(chartTooltipPath), "temperature chart tooltip must live in TemperatureTooltipContent.tsx");
assert(fs.existsSync(chartSummaryPath), "temperature chart model summary must live in ModelCurvesSummary.tsx");
const chartCanvas = fs.readFileSync(chartCanvasPath, "utf8");
const chartTooltip = fs.readFileSync(chartTooltipPath, "utf8");
const chartRunway = fs.readFileSync(chartRunwayPath, "utf8");
const chartSummary = fs.readFileSync(chartSummaryPath, "utf8");
const chartLogicPath = path.join(process.cwd(), "components", "dashboard", "scan-terminal", "temperature-chart-logic.ts");
assert(fs.existsSync(chartLogicPath), "temperature chart pure data logic must live in temperature-chart-logic.ts");
const chartLogic = fs.readFileSync(chartLogicPath, "utf8");
@@ -112,6 +116,18 @@ export function runTests() {
assert(chart.includes("TemperatureChartCanvas"), "temperature chart shell must compose the extracted chart canvas");
assert(chart.includes("TemperatureStatsBars"), "temperature chart shell must compose the extracted stat bars");
assert(chart.includes("TemperatureRunwayDetails"), "temperature chart shell must compose the extracted runway panel");
assert(chart.includes("tempSymbol={row?.temp_symbol || \"°C\"}"), "temperature chart shell must pass the city temperature unit into stat bars");
assert(chart.includes("<TemperatureRunwayDetails") && chart.includes("tempSymbol={row?.temp_symbol || \"°C\"}"), "temperature chart shell must pass the city unit into runway details");
assert(chart.includes("<ModelCurvesSummary") && chart.includes("tempSymbol={row?.temp_symbol || \"°C\"}"), "temperature chart shell must pass the city unit into model summaries");
const chartStats = fs.readFileSync(chartStatsPath, "utf8");
assert(chartStats.includes("tempSymbol"), "temperature stat bars must accept the city temperature unit");
assert(chartStats.includes("temp(displayRunwayTemp, tempSymbol)"), "temperature stat bars must render live observations with the city unit");
assert(chartRunway.includes("tempSymbol") && !chartRunway.includes("}°C`"), "runway detail rows must render values with the city unit");
assert(chartSummary.includes("tempSymbol") && chartSummary.includes("temp(stats.latest, tempSymbol)"), "model curve summaries must render values with the city unit");
assert(chartCanvas.includes("const tempSymbol = row?.temp_symbol || \"°C\""), "temperature chart canvas must derive the city unit from the row");
assert(chartCanvas.includes("tempSymbol={tempSymbol}"), "temperature chart canvas must pass the city unit into tooltips");
assert(chartCanvas.includes("tickFormatter={(v) => `${Number(v).toFixed(0)}${tempSymbol}`}"), "temperature y-axis ticks must include °C/°F instead of a bare degree mark");
assert(chartTooltip.includes("tempSymbol"), "temperature tooltip must accept the city temperature unit");
assert(!chart.includes("from \"recharts\""), "LiveTemperatureThresholdChart.tsx must not import Recharts directly");
assert(!chart.includes("function TemperatureTooltipContent"), "LiveTemperatureThresholdChart.tsx must not define tooltip content inline");
assert(chartCanvas.includes("TemperatureTooltipContent"), "temperature chart canvas must use a custom tooltip content component");