| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221 |
- /**
- * 异常检测图表视觉语义(前端全场图 + 报告共用)
- *
- * 原则:
- * - 颜色优先表达诊断结论,不用彩虹色表达大量风机编号
- * - 异常同时使用红色、菱形和更高层级,避免只依赖颜色
- * - 连续变量使用感知均匀、色盲友好的 Viridis 色带
- */
- export const DIAGNOSTIC_COLORS = {
- normal: "#2E90FA",
- anomaly: "#F04438",
- warning: "#F79009",
- reference: "#98A2B3",
- mean: "#7F56D9",
- blade1: "#2E90FA",
- blade2: "#12B76A",
- blade3: "#7F56D9",
- };
- export const DIAGNOSTIC_CATEGORICAL_COLORS = [
- "#2E90FA",
- "#12B76A",
- "#F79009",
- "#7F56D9",
- "#06AED4",
- "#EE46BC",
- "#6172F3",
- "#47CD89",
- "#FDB022",
- "#84ADFF",
- ];
- /** 全场总图:正常风机冷色,异常风机红橙暖色;同组内用不同色相区分机组 */
- export const FARM_NORMAL_COOL_COLORS = Object.freeze([
- "#3B82F6",
- "#06B6D4",
- "#0EA5E9",
- "#2563EB",
- "#14B8A6",
- "#6366F1",
- "#38BDF8",
- "#0D9488",
- ]);
- export const FARM_ANOMALY_WARM_COLORS = Object.freeze([
- "#F04438",
- "#F97316",
- "#EF4444",
- "#FB7185",
- "#EA580C",
- "#E11D48",
- "#F59E0B",
- "#DC2626",
- ]);
- export const DIAGNOSTIC_CONTINUOUS_COLORS = [
- "#440154",
- "#3B528B",
- "#21918C",
- "#5EC962",
- "#FDE725",
- ];
- export const DIAGNOSTIC_FARM_STYLES = Object.freeze({
- normal: Object.freeze({
- pointOpacity: 0.5,
- lineWidth: 1,
- lineOpacity: 0.5,
- z: 1,
- }),
- anomaly: Object.freeze({
- pointOpacity: 1,
- lineWidth: 2.4,
- lineOpacity: 1,
- z: 20,
- }),
- category: Object.freeze({
- pointOpacity: 0.88,
- lineWidth: 1.8,
- lineOpacity: 1,
- z: 2,
- }),
- });
- function seriesText(rowOrLabel) {
- if (rowOrLabel && typeof rowOrLabel === "object") {
- return `${rowOrLabel.originalLabel || ""} ${rowOrLabel.label || ""}`;
- }
- return String(rowOrLabel || "");
- }
- export function classifyDiagnosticSeries(rowOrLabel) {
- const text = seriesText(rowOrLabel);
- if (/桨叶\s*1/.test(text)) return "blade1";
- if (/桨叶\s*2/.test(text)) return "blade2";
- if (/桨叶\s*3/.test(text)) return "blade3";
- if (/异常/.test(text) && !/正常/.test(text)) return "anomaly";
- if (/上限|下限|阈值|警戒|频繁/.test(text)) return "warning";
- if (/均值|平均|趋势/.test(text)) return "mean";
- if (/参考|理论|合同|基准|标准/.test(text) || rowOrLabel?.__shared) {
- return "reference";
- }
- if (/正常/.test(text)) return "normal";
- return "category";
- }
- export function diagnosticSeriesColor(rowOrLabel, index = 0) {
- const role = classifyDiagnosticSeries(rowOrLabel);
- if (DIAGNOSTIC_COLORS[role]) return DIAGNOSTIC_COLORS[role];
- const safeIndex = Math.abs(Number(index) || 0);
- return DIAGNOSTIC_CATEGORICAL_COLORS[
- safeIndex % DIAGNOSTIC_CATEGORICAL_COLORS.length
- ];
- }
- function paletteIndexOf(rowOrLabel, index = 0) {
- const turbineIndex = Number(rowOrLabel?.turbineIndex);
- if (Number.isFinite(turbineIndex)) return Math.abs(turbineIndex);
- return Math.abs(Number(index) || 0);
- }
- function turbineAnomalyFlag(rowOrLabel) {
- if (!rowOrLabel || typeof rowOrLabel !== "object") return null;
- if (typeof rowOrLabel.extra?.anomaly === "boolean") return rowOrLabel.extra.anomaly;
- if (typeof rowOrLabel.anomaly === "boolean") return rowOrLabel.anomaly;
- return null;
- }
- /**
- * 全场总图是否按「异常风机」上色。
- * 降载图正常/异常是同一台机的点,颜色仍跟风机走,点形再区分状态。
- */
- export function isFarmAnomalyTurbine(rowOrLabel, templateKey = "") {
- const flagged = turbineAnomalyFlag(rowOrLabel);
- if (typeof flagged === "boolean") return flagged;
- if (templateKey === "ctrl_deload") return false;
- return classifyDiagnosticSeries(rowOrLabel) === "anomaly";
- }
- export function farmStatusPaletteColor(
- rowOrLabel,
- index = 0,
- templateKey = "",
- ) {
- const palette = isFarmAnomalyTurbine(rowOrLabel, templateKey)
- ? FARM_ANOMALY_WARM_COLORS
- : FARM_NORMAL_COOL_COLORS;
- return palette[paletteIndexOf(rowOrLabel, index) % palette.length];
- }
- /**
- * 全场图颜色语义:
- * - 正常风机冷色、异常风机红橙暖色,组内再按机组区分;
- * - 降载图颜色跟风机,点形区分正常/异常点;
- * - 参考 / 阈值 / 均值保持语义色。
- */
- export function diagnosticFarmSeriesColor(
- rowOrLabel,
- index = 0,
- templateKey = "",
- ) {
- const role = classifyDiagnosticSeries(rowOrLabel);
- if (role === "reference" || role === "warning" || role === "mean") {
- return diagnosticSeriesColor(rowOrLabel, index);
- }
- return farmStatusPaletteColor(rowOrLabel, index, templateKey);
- }
- export function diagnosticFarmSymbolSize(
- rowOrLabel,
- pointCount = 0,
- templateKey = "",
- ) {
- const role = classifyDiagnosticSeries(rowOrLabel);
- if (role === "anomaly") return 14;
- if (role === "normal") return 7;
- if (templateKey === "pitch_coord") return pointCount > 800 ? 12 : 14;
- return pointCount > 500 ? 10 : 12;
- }
- export function diagnosticFarmStyle(rowOrLabel) {
- const role = classifyDiagnosticSeries(rowOrLabel);
- return (
- DIAGNOSTIC_FARM_STYLES[role] ||
- DIAGNOSTIC_FARM_STYLES.category
- );
- }
- export function diagnosticBladeStyle(rowOrLabel) {
- const role = classifyDiagnosticSeries(rowOrLabel);
- if (role === "blade1") {
- return { symbol: "rect", lineType: "dashed", showSymbol: true };
- }
- if (role === "blade2") {
- return { symbol: "circle", lineType: "solid", showSymbol: true };
- }
- if (role === "blade3") {
- return { symbol: "triangle", lineType: "dotted", showSymbol: true };
- }
- return null;
- }
- export function diagnosticSeriesSymbol(rowOrLabel, fallback = "circle") {
- const role = classifyDiagnosticSeries(rowOrLabel);
- if (role === "anomaly") return "diamond";
- if (role === "blade1") return "rect";
- if (role === "blade2") return "circle";
- if (role === "blade3") return "triangle";
- return fallback;
- }
- export function diagnosticLineType(rowOrLabel) {
- const role = classifyDiagnosticSeries(rowOrLabel);
- if (role === "warning" || role === "reference" || role === "mean") {
- return "dashed";
- }
- if (role === "blade1") return "dashed";
- if (role === "blade3") return "dotted";
- return "solid";
- }
|