feat(history): align units and history data

This commit is contained in:
2026-09-14 12:30:57 +08:00
parent 35b6819459
commit 08ddb4453d
21 changed files with 1849 additions and 3618 deletions
+124 -9
View File
@@ -1,17 +1,132 @@
export const FLOW_DISPLAY_UNIT = "m³/h";
const M3H_FACTOR = 3600;
const LPS_FLOW_PROPERTIES = new Set(["flow", "actual_demand", "actualdemand"]);
export const PRESSURE_DISPLAY_UNIT = "m";
export const VELOCITY_DISPLAY_UNIT = "m/s";
export type MeasurementMetric = "flow" | "pressure" | "velocity";
export interface NetworkResultUnits {
flow: string;
pressure: string;
velocity: string;
}
export const isLpsFlowProperty = (property: string) =>
LPS_FLOW_PROPERTIES.has(property);
export const DEFAULT_NETWORK_RESULT_UNITS: NetworkResultUnits = {
flow: "LPS",
pressure: "MTR",
velocity: "m/s",
};
const M3H_FACTOR = 3600;
const FLOW_PROPERTIES = new Set([
"flow",
"demand",
"base_demand",
"actual_demand",
"actualdemand",
]);
const PRESSURE_PROPERTIES = new Set(["pressure"]);
const VELOCITY_PROPERTIES = new Set(["velocity"]);
const IMPERIAL_FLOW_UNITS = new Set(["CFS", "GPM", "MGD", "IMGD", "AFD"]);
export const metricForResultProperty = (
property: string,
): MeasurementMetric | null => {
const normalizedProperty = property.trim().toLowerCase();
if (FLOW_PROPERTIES.has(normalizedProperty)) return "flow";
if (PRESSURE_PROPERTIES.has(normalizedProperty)) return "pressure";
if (VELOCITY_PROPERTIES.has(normalizedProperty)) return "velocity";
return null;
};
export const networkResultUnitsFromOptions = (
options: Record<string, string>,
): NetworkResultUnits => {
const flow = options.FLOW_UNITS || options.UNITS || "LPS";
const pressure = options.PRESSURE_UNITS || options.PRESSURE || "MTR";
return {
flow,
pressure,
velocity: IMPERIAL_FLOW_UNITS.has(flow.trim().toUpperCase())
? "ft/s"
: "m/s",
};
};
export const toM3h = (value: number, sourceUnit: string = "m³/s") => {
if (!Number.isFinite(value)) return Number.NaN;
const normalizedUnit = sourceUnit.trim().toLowerCase();
if (normalizedUnit === "m³/h") return value;
if (normalizedUnit === "lps" || normalizedUnit === "l/s") return value * 3.6;
if (normalizedUnit === "m³/s") return value * M3H_FACTOR;
return value * M3H_FACTOR;
const normalizedUnit = sourceUnit.trim().toUpperCase().replace("³", "3");
const factors: Record<string, number> = {
CFS: 101.9406477312,
GPM: 0.22712470704,
MGD: 157.725491,
IMGD: 189.4204167,
AFD: 51.39507656,
LPS: 3.6,
"L/S": 3.6,
LPM: 0.06,
MLD: 41.6666666667,
CMH: 1,
"M3/H": 1,
CMD: 1 / 24,
"M3/D": 1 / 24,
"M3/S": M3H_FACTOR,
};
const factor = factors[normalizedUnit];
if (factor === undefined) throw new Error(`不支持的流量单位: ${sourceUnit}`);
return value * factor;
};
export const toMeters = (value: number, sourceUnit: string = "m") => {
if (!Number.isFinite(value)) return Number.NaN;
const normalizedUnit = sourceUnit.trim().toUpperCase();
const factors: Record<string, number> = {
METERS: 1,
METRES: 1,
MTR: 1,
M: 1,
MH2O: 1,
"M H2O": 1,
KPA: 0.1019716213,
PSI: 0.7032496149,
};
const factor = factors[normalizedUnit];
if (factor === undefined) throw new Error(`不支持的压力单位: ${sourceUnit}`);
return value * factor;
};
export const toMetersPerSecond = (
value: number,
sourceUnit: string = "m/s",
) => {
if (!Number.isFinite(value)) return Number.NaN;
const normalizedUnit = sourceUnit.trim().toUpperCase();
if (["M/S", "MPS"].includes(normalizedUnit)) return value;
if (["FT/S", "FPS"].includes(normalizedUnit)) return value * 0.3048;
throw new Error(`不支持的流速单位: ${sourceUnit}`);
};
export const toDisplayValue = (
value: number | null | undefined,
metric: MeasurementMetric,
sourceUnit: string,
) => {
if (value === null || value === undefined) return null;
switch (metric) {
case "flow":
return toM3h(value, sourceUnit);
case "pressure":
return toMeters(value, sourceUnit);
case "velocity":
return toMetersPerSecond(value, sourceUnit);
}
};
export const toModelDisplayValue = (
value: number,
property: string,
units: NetworkResultUnits,
) => {
const metric = metricForResultProperty(property);
if (!metric) return value;
return toDisplayValue(value, metric, units[metric])!;
};
export const toM3s = (value: number, sourceUnit: string = "m³/h") => {