Files
next-tjwater-frontend/src/features/workbench/utils/investigation-dev-complex-cases.ts
T
jiang 0ae0a41e61
Generic Container CI/CD / test-build-publish (push) Successful in 2m7s
Frontend CI/CD / build-test-publish-and-deploy (push) Successful in 2m8s
feat(charts): manage investigation charts in a scrolling workspace
2026-11-10 17:56:23 +08:00

95 lines
7.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { INVESTIGATION_DEV_NETWORK } from "./investigation-dev-network";
import type { AnswerUiBlock } from "@/features/agent";
import { createPresentationRecord, createUiRecord, serializeInvestigationDevJsonl } from "./investigation-dev-preview";
export const complexInvestigationDevCases = [
{ id: "complex_investigation", label: "复杂调查:多图多表联动", expected: "压力与管流分别聚合,另有方案柱状图、2 张表与合成覆盖面;右侧切换对象,下方控制图例。" },
{ id: "complex_tables", label: "复杂表格:宽表、长文本与边界数据", expected: "50 行 8 列宽表、空表和含零值、负数、重复值的对照表;检查搜索、数值排序和横向滚动。" },
{ id: "complex_charts", label: "复杂图表:多测点与长时序", expected: "8 个压力点与 4 个管段各含 96 个时刻、当前曲线与七日历史散点,聚合为 2 个子图表,由总图表窗口统一管理,另有方案柱状图。" }
] as const;
type ComplexCaseId = (typeof complexInvestigationDevCases)[number]["id"];
type Node = AnswerUiBlock["spec"]["elements"][string];
const ui = (id: string, node: Node) => createUiRecord({
version: "answer-ui@1", block_id: `dev-complex-${id}`, phase: "final",
fallback_text: "本地合成展示数据,不代表实际监测、调查结论或现场方案。",
spec: { root: "result", elements: { result: node } }
});
const table = (id: string, title: string, columns: string[], rows: string[][]) =>
ui(id, { type: "Table", props: { title, columns, rows }, children: [] });
const times = Array.from({ length: 96 }, (_, index) => `${String(Math.floor(index / 4)).padStart(2, "0")}:${String(index % 4 * 15).padStart(2, "0")}`);
const comparisonChart = (id: string, title: string, axis: string, baseline: number[], current: number[]) => ({
title: `${id} ${title}`, chart_type: "time_comparison" as const,
x_axis_name: "时间", y_axis_name: axis, x_data: times,
series: [{ name: `${id} 当前 2026-07-16`, type: "line" as const, data: current,
sample_times: times.map((time) => `2026-07-16T${time}:00+08:00`) },
...Array.from({ length: 7 }, (_, day) => {
const date = `2026-07-${String(9 + day).padStart(2, "0")}`;
return { name: `${id} ${date}`, type: "scatter" as const,
data: times.map((_, index) => index >= 40 && index <= 42 ? Number((baseline[index] + day * 0.1).toFixed(2)) : null),
sample_times: times.map((time, index) => index >= 40 && index <= 42 ? `${date}T${time}:00+08:00` : null) };
})]
});
const pressure = Array.from({ length: 8 }, (_, object) => {
const baseline = times.map((_, index) => Number((34 + object * 0.6 + Math.sin(index / 7 + object) * 2.4).toFixed(2)));
return comparisonChart(INVESTIGATION_DEV_NETWORK.nodeAnchors[object].id, "合成全天压力对比", "压力水头(m)", baseline,
baseline.map((value, index) => Number((value - (index >= 32 && index < 44 ? 7 - object * 0.4 : 0)).toFixed(2))));
});
const flow = Array.from({ length: 4 }, (_, object) => {
const baseline = times.map((_, index) => Number((120 + object * 28 + Math.sin(index / 9 + object) * 24).toFixed(1)));
return comparisonChart(INVESTIGATION_DEV_NETWORK.pipeIds[object], "合成分区流量趋势", "流量(m³/h)", baseline,
baseline.map((value, index) => Number((value + (index >= 32 && index < 44 ? 38 : 0)).toFixed(1))));
});
const chart = (id: string, value: ReturnType<typeof comparisonChart>) => createPresentationRecord({
action: "open_chart", chart_id: `dev-complex-${id}`, evidence_refs: ["dev:synthetic"], chart: value
});
const objectCharts = () => [
...pressure.map((value, index) => chart(`pressure-${index + 1}`, value)),
...flow.map((value, index) => chart(`flow-${index + 1}`, value))
];
const comparison = {
title: "合成候选方案影响对比", chart_type: "bar" as const,
x_data: ["合成方案 A:局部隔离", "合成方案 B:扩大核查", "合成方案 C:保持供水", "合成方案 D:分段验证", "合成方案 E:待补充资料"],
series: [{ name: "合成影响用户数(户)", data: [245, 610, 0, 128, 72] }]
};
const columns = ["序号", "管段 ID", "合成片区", "长度(m)", "压力变化(m)", "影响户数(户)", "核查状态", "核查说明"];
const rows = Array.from({ length: 50 }, (_, index) => [
String(index + 1), INVESTIGATION_DEV_NETWORK.pipeIds[index],
`合成片区 ${index % 5 + 1} · ${index % 2 ? "学校与居民区交界" : "工业园区及长距离末端支线"}`,
String(80 + index * 13.5), (index % 7 === 0 ? 0 : -(index % 13) / 2).toFixed(1),
String(index % 6 === 0 ? 0 : (index * 37) % 600),
["待现场核验", "资料待补充", "合成候选,未确认"][index % 3],
index % 5 === 0
? `仅供本地测试:样例记录 ${String(index + 1).padStart(3, "0")} 包含较长的核查说明,用于检查换行、滚动、筛选及放大后阅读。请分别核对供水边界、阀门状态与现场回执。合成引用 SYNTHETIC_REFERENCE_${"LONG_SEGMENT_".repeat(8)}${index + 1},不是真实证据。`
: `仅为合成候选资料,样例记录 ${String(index + 1).padStart(3, "0")};不代表已确认故障或已执行操作。`
]);
export function createComplexInvestigationDevCase(caseId: ComplexCaseId, [longitude, latitude]: [number, number]): string {
if (caseId === "complex_charts") return serializeInvestigationDevJsonl([
...objectCharts(),
createPresentationRecord({ action: "open_chart", chart_id: "dev-complex-plans", evidence_refs: ["dev:synthetic"], chart: comparison })
]);
if (caseId === "complex_tables") return serializeInvestigationDevJsonl([
table("wide-table", "合成候选核查宽表", columns, rows),
table("empty-table", "合成空结果表", ["对象", "核查结果", "说明"], []),
table("edge-table", "合成排序与缺口对照", ["对象", "变化量", "完成率", "说明"], [
["合成对象 A", "0", "0%", "零值不是缺失"], ["合成对象 B", "-2.5", "50%", "负数与百分比排序"],
["合成对象 C", "10", "100%", "按数值排列,不按文本排列"], ["合成对象 D", "2", "50%", "重复值保持可读"],
["合成对象 E", "2", "50%", "重复值第二行"], ["合成对象 F", "未提供", "未提供", "缺失不替换为零"]
])
]);
const point = (dx: number, dy: number): [number, number] => [Math.max(-180, Math.min(180, longitude + dx)), Math.max(-89.99, Math.min(89.99, latitude + dy))];
return serializeInvestigationDevJsonl([
createPresentationRecord({ action: "set_overlay", mode: "geometry", overlay_id: "dev-complex-coverage", title: "合成分区覆盖示意", evidence_id: "dev:synthetic",
data: { type: "FeatureCollection", features: [-0.002, 0.002].map((dx, index) => ({ type: "Feature", properties: { project_code: INVESTIGATION_DEV_NETWORK.projectCode, origin: "synthetic", label: `合成片区 ${index + 1}` },
geometry: { type: "Polygon", coordinates: [[point(dx - 0.001, -0.001), point(dx + 0.001, -0.001), point(dx + 0.001, 0.001), point(dx - 0.001, 0.001), point(dx - 0.001, -0.001)]] } })) } }),
...objectCharts(),
createPresentationRecord({ action: "open_chart", chart_id: "dev-complex-plans", evidence_refs: ["dev:synthetic"], chart: comparison }),
table("candidates", "合成候选方案核查", columns, rows.slice(0, 24)),
table("valves", "合成阀门核查清单", ["阀门", "合成片区", "位置描述", "核查要求", "当前状态"],
INVESTIGATION_DEV_NETWORK.valveIds.map((id, index) => [id, `合成片区 ${index % 3 + 1}`, "合成居民区与主干管交界处,位置尚未现场核验", "核对可操作性、实际开度及现场回执;不执行关阀", "待核查"]))
]);
}