test: add unit tests for temperature chart data and visibility policy, and document city data sources
This commit is contained in:
@@ -48,7 +48,7 @@
|
||||
| amsterdam | KNMI 数据平台 | 10 min | 荷兰 |
|
||||
| taipei | CWA 开放数据 (466920) | ~10 min | 台湾 |
|
||||
| tel aviv | IMS Lod (225) | 实时 | 以色列 |
|
||||
| paris | AEROWEB 实况 / AROME HD 15min | 实时/15min | 法国 |
|
||||
| paris | AEROWEB 实况 / AROME HD | 实时/15min | 法国 (AROME是15分钟临近预报) |
|
||||
|
||||
### Tier 4 — 仅 METAR(10 分钟缓存)
|
||||
|
||||
@@ -107,3 +107,30 @@ ankara, istanbul, helsinki, amsterdam, paris
|
||||
- **Tier 2 城市**(5 分钟级):修正效果良好,MADIS 更新稳定
|
||||
- **Tier 3 城市**(10-15 分钟级):修正可用但滞后较大
|
||||
- **Tier 4 城市**(仅 METAR):修正效果有限,不建议依赖
|
||||
|
||||
|
||||
## 关于网站终端图表的数据曲线展示逻辑
|
||||
|
||||
### 1. 实测数据(默认全开,突出核心)
|
||||
|
||||
- **跑道全量展示**:北京、上海、广州、成都、重庆、武汉、首尔等城市的跑道实测数据,默认全量开启,无需手动勾选。
|
||||
- **结算跑道高亮**:系统内置了各大机场的官方结算跑道映射。命中的跑道将被**重点强调**(加粗的青色实线 #009688,线宽 2.8),并标记为“[跑道号] 结算跑道”。具体的跑道映射如下:
|
||||
- 北京:19/01
|
||||
- 上海:17L/35R
|
||||
- 广州:02L/20R
|
||||
- 成都:02L/20R
|
||||
- 重庆:20R/02L
|
||||
- 武汉:04/22
|
||||
- 首尔:15R/33L
|
||||
- **辅助跑道弱化**:同一机场下的其他非结算跑道,也会同时展示,但采用较细的虚线(线宽 1.2)以作陪衬区分。
|
||||
- **其他实测展示**:所有城市的 METAR 报文曲线、官方气象站实测(如 Hong Kong / Lau Fau Shan 的香港天文台曲线)均默认展示。
|
||||
|
||||
### 2. 核心预测数据(默认展示)
|
||||
|
||||
- **DEB 模型融合**:作为平台核心的高精度智能融合预测曲线,默认始终展示给用户。
|
||||
|
||||
### 3. 多模型原始数据(默认隐藏,按需自选)
|
||||
|
||||
- **保持整洁**:为了防止图表线缆过于杂乱,各大原始模型(ECMWF, GFS, ICON, GEM 等)的数据曲线在初次加载时**默认隐藏**。
|
||||
- **特例**:仅针对巴黎(Paris),由于其 AROME HD 是高精度的 15 分钟级临近预报,极具参考价值,因此默认开启。
|
||||
- **自由交互**:用户可通过图表底部的图例交互按钮,随时自由勾选、叠加或隐藏任意所需的数据曲线。
|
||||
|
||||
+56
@@ -13,6 +13,10 @@ function seriesByKey(series: Array<{ key: string }>, key: string) {
|
||||
return series.find((item) => item.key === key);
|
||||
}
|
||||
|
||||
function runwayKey(rwy: string) {
|
||||
return `runway_${rwy.split("/").map((part) => part.trim().toUpperCase()).join("_")}`;
|
||||
}
|
||||
|
||||
export function runTests() {
|
||||
const guangzhou = {
|
||||
city: "guangzhou",
|
||||
@@ -95,10 +99,62 @@ export function runTests() {
|
||||
),
|
||||
"users should still be able to enable a hidden multi-model curve from the legend",
|
||||
);
|
||||
assert(
|
||||
defaultVisibleSeries.some((item) => item.key === "hourly_forecast"),
|
||||
"DEB fusion forecast should be visible by default",
|
||||
);
|
||||
assert(
|
||||
__isTemperatureSeriesVisibleByDefaultForTest("paris", "model_curve_AROME HD"),
|
||||
"Paris AROME HD should be the only default-visible model curve exception",
|
||||
);
|
||||
assert(
|
||||
__getVisibleTemperatureSeriesForTest(
|
||||
"paris",
|
||||
[{ key: "model_curve_AROME HD" }, { key: "model_curve_ECMWF" }] as any,
|
||||
{},
|
||||
).some((item) => item.key === "model_curve_AROME HD"),
|
||||
"Paris AROME HD should be active in the default visible series",
|
||||
);
|
||||
|
||||
const settlementRunwayCases = [
|
||||
["beijing", "19/01"],
|
||||
["shanghai", "17L/35R"],
|
||||
["guangzhou", "02L/20R"],
|
||||
["chengdu", "02L/20R"],
|
||||
["chongqing", "20R/02L"],
|
||||
["wuhan", "04/22"],
|
||||
["seoul", "15R/33L"],
|
||||
] as const;
|
||||
settlementRunwayCases.forEach(([city, settlementRwy]) => {
|
||||
const chart = __buildTemperatureChartDataForTest(
|
||||
{
|
||||
city,
|
||||
local_date: "2026-05-25",
|
||||
local_time: "10:00",
|
||||
tz_offset_seconds: 8 * 60 * 60,
|
||||
runway_plate_history: {
|
||||
[settlementRwy]: [
|
||||
{ time: "00:05", temp: 25.1 },
|
||||
{ time: "00:35", temp: 25.3 },
|
||||
],
|
||||
"99/00": [
|
||||
{ time: "00:05", temp: 24.1 },
|
||||
{ time: "00:35", temp: 24.3 },
|
||||
],
|
||||
},
|
||||
} as any,
|
||||
{ localTime: "10:00", times: ["00:00", "00:30"], temps: [25, 26] } as any,
|
||||
"1D",
|
||||
);
|
||||
const highlighted = seriesByKey(chart.series, runwayKey(settlementRwy)) as any;
|
||||
assert(highlighted, `${city} settlement runway should be present`);
|
||||
assert(highlighted.label.includes("结算跑道"), `${city} settlement runway should be labeled`);
|
||||
assert(highlighted.color === "#009688", `${city} settlement runway should use highlight cyan`);
|
||||
assert(highlighted.featured === true, `${city} settlement runway should be featured`);
|
||||
assert(!highlighted.dashed, `${city} settlement runway should be solid`);
|
||||
const auxiliary = seriesByKey(chart.series, "runway_99_00") as any;
|
||||
assert(auxiliary?.dashed === true, `${city} auxiliary runway should be dashed`);
|
||||
});
|
||||
|
||||
const shenzhen = __buildTemperatureChartDataForTest(
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user