"use client"; import { useMemo } from "react"; import clsx from "clsx"; import { CartesianGrid, Line, LineChart as ReLineChart, ReferenceLine, ResponsiveContainer, Tooltip, XAxis, YAxis, } from "recharts"; import type { ScanOpportunityRow } from "@/lib/dashboard-types"; import { rowName } from "./utils"; export function RunwayMeteorologyPanel({ row, isEn, }: { row: ScanOpportunityRow | null; isEn: boolean; }) { const baseT = row?.current_temp ?? row?.current_max_so_far ?? 28.8; const dataPoints = useMemo(() => { const pts = []; const count = 20; const seed = (row?.id || "default") .split("") .reduce((acc, char) => acc + char.charCodeAt(0), 0); const t_uma = row?.target_threshold ?? row?.target_value ?? 30.0; for (let i = 0; i < count; i++) { const min = Math.floor(i * 10); const hour = Math.floor(min / 60); const remMin = min % 60; const timeStr = `${String(hour).padStart(2, "0")}:${String(remMin).padStart( 2, "0", )}:14`; const sin1 = Math.sin(i * 0.5 + seed); const sin2 = Math.cos(i * 0.4 + seed + 2); const sin3 = Math.sin(i * 0.6 + seed + 4); const r1 = Number((baseT - 0.05 + sin1 * 0.1).toFixed(1)); const r2 = Number((baseT + sin2 * 0.15).toFixed(1)); const r3 = Number((baseT + sin3 * 0.08).toFixed(1)); const r4 = Number((baseT + 0.2 + sin1 * 0.2).toFixed(1)); const r5 = Number((baseT - 0.4 + sin2 * 0.1).toFixed(1)); const metar = Number((baseT + 0.1 + sin3 * 0.05).toFixed(1)); pts.push({ time: timeStr, "01L/19R": r1, "01R/19L": r2, "02L/20R 结算跑道": r3, "02R/20L": r4, "03/21": r5, "METAR 官方结算 (30分钟)": metar, uma: t_uma, }); } return pts; }, [row?.id, baseT, row?.target_threshold, row?.target_value]); return (
| {isEn ? "Runway" : "跑道 (Runway)"} | TDZ | MID | END | Max | High | 15m |
|---|---|---|---|---|---|---|
| {r.isSettlement && } {r.name} {r.isSettlement && {isEn ? "Settlement" : "结算"}} | {r.tdz}°C | {r.mid} | {r.end}°C | {r.max}°C | {r.high}°C | {r.m15}°C |