@zendir/ui 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/dist/index.js +67 -62
  3. package/dist/index.js.map +1 -1
  4. package/dist/react/3d/ZenSpace3D.js +3 -2
  5. package/dist/react/3d/ZenSpace3DShaders.js +478 -0
  6. package/dist/react/3d/ZenSpace3DShaders.js.map +1 -0
  7. package/dist/react/3d/capturePngAnalysis.js +42 -0
  8. package/dist/react/3d/capturePngAnalysis.js.map +1 -0
  9. package/dist/react/3d/index.js +57 -0
  10. package/dist/react/3d/index.js.map +1 -0
  11. package/dist/react/3d/threeLoader.js +4 -0
  12. package/dist/react/3d/threeLoader.js.map +1 -1
  13. package/dist/react/astro/ClassificationBanner.js +1 -1
  14. package/dist/react/astro/GlobalStatusBar.js +1 -1
  15. package/dist/react/astro/MissionClock.js +8 -5
  16. package/dist/react/astro/MissionClock.js.map +1 -1
  17. package/dist/react/astro/MonitoringIcon.js +1 -1
  18. package/dist/react/astro/Notification.js +1 -1
  19. package/dist/react/astro/Progress.js +1 -1
  20. package/dist/react/astro/SimulationControls.js +1 -1
  21. package/dist/react/astro/StatusIndicator.js +1 -1
  22. package/dist/react/astro/UnifiedTimeline.js +1 -1
  23. package/dist/react/astro/index.js +34 -0
  24. package/dist/react/astro/index.js.map +1 -0
  25. package/dist/react/cards/AccessCard.js +410 -0
  26. package/dist/react/cards/AccessCard.js.map +1 -0
  27. package/dist/react/cards/OrbitCard.js +372 -0
  28. package/dist/react/cards/OrbitCard.js.map +1 -0
  29. package/dist/react/cards/SpacecraftCard.js +941 -0
  30. package/dist/react/cards/SpacecraftCard.js.map +1 -0
  31. package/dist/react/cards/TelemetryCard.js +742 -0
  32. package/dist/react/cards/TelemetryCard.js.map +1 -0
  33. package/dist/react/cards/TelemetryStreamCard.js +309 -0
  34. package/dist/react/cards/TelemetryStreamCard.js.map +1 -0
  35. package/dist/react/cards/index.js +13 -0
  36. package/dist/react/cards/index.js.map +1 -0
  37. package/dist/react/charts/GroundTrackMap.js +1 -1
  38. package/dist/react/charts/GroundTrackMapLeaflet.js +1 -1
  39. package/dist/react/charts/index.js +104 -0
  40. package/dist/react/charts/index.js.map +1 -0
  41. package/dist/react/charts/unified/AstroChart.js +1 -1
  42. package/dist/react/charts/unified/PowerOverviewChart.js +488 -0
  43. package/dist/react/charts/unified/PowerOverviewChart.js.map +1 -0
  44. package/dist/react/charts/unified/domain.js +3168 -0
  45. package/dist/react/charts/unified/domain.js.map +1 -0
  46. package/dist/react/charts/unified/generators.js +518 -0
  47. package/dist/react/charts/unified/generators.js.map +1 -0
  48. package/dist/react/charts/unified/presets.js +1000 -0
  49. package/dist/react/charts/unified/presets.js.map +1 -0
  50. package/dist/react/charts/unified/sync.js +219 -0
  51. package/dist/react/charts/unified/sync.js.map +1 -0
  52. package/dist/react/charts/unified/theme.js +331 -4
  53. package/dist/react/charts/unified/theme.js.map +1 -1
  54. package/dist/react/charts/unified/useChartStream.js +226 -0
  55. package/dist/react/charts/unified/useChartStream.js.map +1 -0
  56. package/dist/react/chatgpt/index.js +163 -0
  57. package/dist/react/chatgpt/index.js.map +1 -0
  58. package/dist/react/core/data/DataTable.js +1 -1
  59. package/dist/react/core/data/DataValue.js +1 -1
  60. package/dist/react/core/display/AstroIcon.js +1 -1
  61. package/dist/react/core/display/Badge.js +1 -1
  62. package/dist/react/core/display/CardHeader.js +1 -1
  63. package/dist/react/core/display/Container.js +1 -1
  64. package/dist/react/core/display/GlassCard.js +1 -1
  65. package/dist/react/core/display/HeaderIconWithStatus.js +1 -1
  66. package/dist/react/core/feedback/Dialog.js +24 -21
  67. package/dist/react/core/feedback/Dialog.js.map +1 -1
  68. package/dist/react/core/feedback/Toast.js +1 -1
  69. package/dist/react/core/index.d.ts +4 -0
  70. package/dist/react/core/index.js +166 -0
  71. package/dist/react/core/index.js.map +1 -0
  72. package/dist/react/core/inputs/Button.js +1 -1
  73. package/dist/react/core/inputs/Checkbox.js +1 -1
  74. package/dist/react/core/inputs/Input.js +1 -1
  75. package/dist/react/core/inputs/NumberInput.js +1 -1
  76. package/dist/react/core/inputs/PinInput.js +1 -1
  77. package/dist/react/core/inputs/Select.js +1 -1
  78. package/dist/react/core/inputs/Toggle.js +1 -1
  79. package/dist/react/core/layout/Box.js +1 -1
  80. package/dist/react/core/layout/Flex.js +1 -1
  81. package/dist/react/core/layout/Grid.js +1 -1
  82. package/dist/react/core/layout/Stack.js +1 -1
  83. package/dist/react/core/navigation/AppBar.js +1 -1
  84. package/dist/react/core/navigation/Pagination.js +1 -1
  85. package/dist/react/core/navigation/SideNav.js +1 -1
  86. package/dist/react/core/navigation/SideNav.js.map +1 -1
  87. package/dist/react/core/navigation/Tabs.js +1 -1
  88. package/dist/react/core/overlays/SidePanel.js +1 -1
  89. package/dist/react/core/overlays/Tooltip.js +1 -1
  90. package/dist/react/core/widgets/Capture.js +1 -1
  91. package/dist/react/core/widgets/ChatPanel.js +1 -1
  92. package/dist/react/core/widgets/ColorPickerPanel.js +1 -1
  93. package/dist/react/core/widgets/ConnectionForm.js +1 -1
  94. package/dist/react/core/widgets/FileExplorer.js +1 -1
  95. package/dist/react/core/widgets/ImageFrame.d.ts +51 -0
  96. package/dist/react/core/widgets/ImageFrame.js +201 -0
  97. package/dist/react/core/widgets/ImageFrame.js.map +1 -0
  98. package/dist/react/core/widgets/ImageGallery.js +1 -1
  99. package/dist/react/core/widgets/ImagePanel.d.ts +43 -0
  100. package/dist/react/core/widgets/ImagePanel.js +105 -0
  101. package/dist/react/core/widgets/ImagePanel.js.map +1 -0
  102. package/dist/react/core/widgets/MessageStream.js +1 -1
  103. package/dist/react/core/widgets/MissionCalendar.js +1 -1
  104. package/dist/react/hooks/useCompactMode.js +1 -1
  105. package/dist/react/index.d.ts +2 -2
  106. package/dist/react/panels/index.js +8 -0
  107. package/dist/react/panels/index.js.map +1 -0
  108. package/dist/react/theme/config.js +30 -0
  109. package/dist/react/theme/config.js.map +1 -0
  110. package/dist/react/theme/index.js +19 -0
  111. package/dist/react/theme/index.js.map +1 -0
  112. package/dist/react/utils/index.js +8 -0
  113. package/dist/react/utils/index.js.map +1 -1
  114. package/dist/react.js +67 -62
  115. package/dist/react.js.map +1 -1
  116. package/package.json +46 -38
@@ -0,0 +1,104 @@
1
+ import { GroundTrackMap } from "./GroundTrackMap.js";
2
+ import { CARTO_ATTRIBUTION, ESRI_WORLD_IMAGERY_ATTRIBUTION, OSM_ATTRIBUTION, TILE_PRESETS, getBasemapAttribution } from "./groundTrackMapLeafletTiles.js";
3
+ import { ASTRO_DATA_VIZ_COLORS, OFFICIAL_ASTRO_DATA_VIZ_COLORS, STATUS_COLORS, ZENDIR_BRAND_COLORS, calculateAxisBounds, createAreaGradient, createAstroEChartsTheme, formatTimeLabel, formatValueWithUnit, getPaletteForDataType, getSeriesColor, getStatusColor } from "./unified/theme.js";
4
+ import { AntennaPattern3DChart, AttitudeChart, AttitudeHistory3DChart, Bar3DChart, ConjunctionAssessment3DChart, ConjunctionChart, ConstellationCoverageChart, ContactWindowChart, DopplerTrackChart, EclipseTimelineChart, HeliocentricOrbitPlot, LaunchCorridor3DChart, Lines3DChart, LinkBudgetChart, LinkMarginChart, ManeuverBudgetChart, OrbitChart, PowerChart, RoseDiagram, Scatter3DChart, SpectrumChart, SphericalRadar3DChart, SubsystemGauge, Surface3DChart, ThermalHeatmapChart, TransferOrbit3DChart, WaterfallChart } from "./unified/domain.js";
5
+ import { AreaChart, BarChart, BoxPlotChart, BubbleChart, CandlestickChart, DonutChart, DualAxisChart, GaugeChart, GraphChart, HeatmapChart, HistogramChart, LineChart, ParallelChart, PieChart, RadarChart, SankeyChart, ScatterChart, StackedAreaChart, StackedBarChart, SunburstChart, TimeSeriesChart, TreemapChart } from "./unified/presets.js";
6
+ import { AstroChart } from "./unified/AstroChart.js";
7
+ import { PowerOverviewChart, generateSamplePowerData } from "./unified/PowerOverviewChart.js";
8
+ import { dispatchToGroup, exportGroupAsCSV, exportGroupAsImages, getGroupCharts, hideGroupTooltip, resetGroupZoom, showGroupTooltip, syncZoomRange, useChartSync } from "./unified/sync.js";
9
+ import { generateAttitudeData, generateConjunctionEvents, generateConstellationCoverage, generateContactWindows, generateDopplerData, generateEclipseTimeline, generateHeliocentricOrbits, generatePowerData, generateSpectrum, generateWaterfallData } from "./unified/generators.js";
10
+ import { useChartStream, useWebSocketStream } from "./unified/useChartStream.js";
11
+ export {
12
+ ASTRO_DATA_VIZ_COLORS,
13
+ AntennaPattern3DChart,
14
+ AreaChart,
15
+ AstroChart,
16
+ AttitudeChart,
17
+ AttitudeHistory3DChart,
18
+ Bar3DChart,
19
+ BarChart,
20
+ BoxPlotChart,
21
+ BubbleChart,
22
+ CARTO_ATTRIBUTION,
23
+ CandlestickChart,
24
+ ConjunctionAssessment3DChart,
25
+ ConjunctionChart,
26
+ ConstellationCoverageChart,
27
+ ContactWindowChart,
28
+ DonutChart,
29
+ DopplerTrackChart,
30
+ DualAxisChart,
31
+ ESRI_WORLD_IMAGERY_ATTRIBUTION,
32
+ EclipseTimelineChart,
33
+ GaugeChart,
34
+ GraphChart,
35
+ GroundTrackMap,
36
+ HeatmapChart,
37
+ HeliocentricOrbitPlot,
38
+ HistogramChart,
39
+ LaunchCorridor3DChart,
40
+ LineChart,
41
+ Lines3DChart,
42
+ LinkBudgetChart,
43
+ LinkMarginChart,
44
+ ManeuverBudgetChart,
45
+ OFFICIAL_ASTRO_DATA_VIZ_COLORS,
46
+ OSM_ATTRIBUTION,
47
+ OrbitChart,
48
+ ParallelChart,
49
+ PieChart,
50
+ PowerChart,
51
+ PowerOverviewChart,
52
+ RadarChart,
53
+ RoseDiagram,
54
+ STATUS_COLORS,
55
+ SankeyChart,
56
+ Scatter3DChart,
57
+ ScatterChart,
58
+ SpectrumChart,
59
+ SphericalRadar3DChart,
60
+ StackedAreaChart,
61
+ StackedBarChart,
62
+ SubsystemGauge,
63
+ SunburstChart,
64
+ Surface3DChart,
65
+ TILE_PRESETS,
66
+ ThermalHeatmapChart,
67
+ TimeSeriesChart,
68
+ TransferOrbit3DChart,
69
+ TreemapChart,
70
+ WaterfallChart,
71
+ ZENDIR_BRAND_COLORS,
72
+ calculateAxisBounds,
73
+ createAreaGradient,
74
+ createAstroEChartsTheme,
75
+ dispatchToGroup,
76
+ exportGroupAsCSV,
77
+ exportGroupAsImages,
78
+ formatTimeLabel,
79
+ formatValueWithUnit,
80
+ generateAttitudeData,
81
+ generateConjunctionEvents,
82
+ generateConstellationCoverage,
83
+ generateContactWindows,
84
+ generateDopplerData,
85
+ generateEclipseTimeline,
86
+ generateHeliocentricOrbits,
87
+ generatePowerData,
88
+ generateSamplePowerData,
89
+ generateSpectrum,
90
+ generateWaterfallData,
91
+ getBasemapAttribution,
92
+ getGroupCharts,
93
+ getPaletteForDataType,
94
+ getSeriesColor,
95
+ getStatusColor,
96
+ hideGroupTooltip,
97
+ resetGroupZoom,
98
+ showGroupTooltip,
99
+ syncZoomRange,
100
+ useChartStream,
101
+ useChartSync,
102
+ useWebSocketStream
103
+ };
104
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;"}
@@ -5,11 +5,11 @@ import * as echarts from "echarts/core";
5
5
  import { LineChart, BarChart, PieChart, ScatterChart, RadarChart, GaugeChart, HeatmapChart, CandlestickChart, BoxplotChart, TreemapChart, SunburstChart, FunnelChart, SankeyChart, CustomChart, GraphChart, ParallelChart } from "echarts/charts";
6
6
  import { GridComponent, TooltipComponent, TitleComponent, LegendComponent, DataZoomComponent, ToolboxComponent, MarkLineComponent, MarkAreaComponent, MarkPointComponent, VisualMapComponent, BrushComponent, PolarComponent, RadarComponent, GeoComponent, ParallelComponent } from "echarts/components";
7
7
  import { CanvasRenderer, SVGRenderer } from "echarts/renderers";
8
+ import { useTheme } from "../../theme/ThemeProvider.js";
8
9
  import { AstroIcon } from "../../core/display/AstroIcon.js";
9
10
  import { HeaderIconWithStatus } from "../../core/display/HeaderIconWithStatus.js";
10
11
  import { useCardBorderStyle } from "../../context/DisplaySettingsContext.js";
11
12
  import { createAstroEChartsTheme, getSeriesColor, createAreaGradient } from "./theme.js";
12
- import { useTheme } from "../../theme/ThemeProvider.js";
13
13
  const STATUS_SHAPES = {
14
14
  off: (size, color) => /* @__PURE__ */ jsx("svg", { viewBox: "0 0 12 12", width: size, height: size, children: /* @__PURE__ */ jsx("circle", { cx: "6", cy: "6", r: "5", fill: color }) }),
15
15
  standby: (size, color) => /* @__PURE__ */ jsx("svg", { viewBox: "0 0 12 12", width: size, height: size, children: /* @__PURE__ */ jsx("circle", { cx: "6", cy: "6", r: "5", fill: color }) }),
@@ -0,0 +1,488 @@
1
+ import { jsxs, jsx } from "react/jsx-runtime";
2
+ import { useMemo } from "react";
3
+ import { AstroChart } from "./AstroChart.js";
4
+ import { useTheme } from "../../theme/ThemeProvider.js";
5
+ const STATUS_BORDER_COLORS = {
6
+ off: "#3c3e42",
7
+ standby: "#285766",
8
+ normal: "#005a00",
9
+ caution: "#645600",
10
+ serious: "#664618",
11
+ critical: "#661102"
12
+ };
13
+ const StatusShape = ({ status, size, color, borderColor, glow = true }) => {
14
+ const hasBorder = !!borderColor;
15
+ const strokeWidth = hasBorder ? 1 : 0;
16
+ const glowFilter = glow && !hasBorder ? `drop-shadow(0 0 4px ${color})` : void 0;
17
+ const renderShape = () => {
18
+ switch (status) {
19
+ case "off":
20
+ return /* @__PURE__ */ jsx("circle", { cx: "6", cy: "6", r: hasBorder ? 2.5 : 3, fill: color, stroke: borderColor, strokeWidth });
21
+ case "standby":
22
+ return /* @__PURE__ */ jsx("circle", { cx: "6", cy: "6", r: "3.5", fill: "none", stroke: color, strokeWidth: "2" });
23
+ case "normal":
24
+ return /* @__PURE__ */ jsx(
25
+ "circle",
26
+ {
27
+ cx: "6",
28
+ cy: "6",
29
+ r: hasBorder ? 4.5 : 5,
30
+ fill: color,
31
+ stroke: borderColor,
32
+ strokeWidth
33
+ }
34
+ );
35
+ case "caution":
36
+ return /* @__PURE__ */ jsx(
37
+ "rect",
38
+ {
39
+ x: hasBorder ? 1.5 : 1,
40
+ y: hasBorder ? 1.5 : 1,
41
+ width: hasBorder ? 9 : 10,
42
+ height: hasBorder ? 9 : 10,
43
+ fill: color,
44
+ stroke: borderColor,
45
+ strokeWidth
46
+ }
47
+ );
48
+ case "serious":
49
+ return /* @__PURE__ */ jsx(
50
+ "polygon",
51
+ {
52
+ points: "6,1 11,6 6,11 1,6",
53
+ fill: color,
54
+ stroke: borderColor,
55
+ strokeWidth
56
+ }
57
+ );
58
+ case "critical":
59
+ return /* @__PURE__ */ jsx(
60
+ "polygon",
61
+ {
62
+ points: "6,11 1,2 11,2",
63
+ fill: color,
64
+ stroke: borderColor,
65
+ strokeWidth
66
+ }
67
+ );
68
+ default:
69
+ return null;
70
+ }
71
+ };
72
+ return /* @__PURE__ */ jsx(
73
+ "svg",
74
+ {
75
+ viewBox: "0 0 12 12",
76
+ width: size,
77
+ height: size,
78
+ style: { filter: glowFilter },
79
+ children: renderShape()
80
+ }
81
+ );
82
+ };
83
+ const STATE_COLORS = {
84
+ running: "#0d4d4d",
85
+ // Deep teal
86
+ safe: "#8b7355",
87
+ // Brown/gold
88
+ shutdown: "#1a1a1a"
89
+ // Near black
90
+ };
91
+ const MODE_COLORS = {
92
+ none: "#1a2332",
93
+ inertial: "#1e3a5f",
94
+ sun: "#8b7355",
95
+ nadir: "#2d5a4d",
96
+ velocity: "#2e4a7c",
97
+ ground: "#4a3d6e"
98
+ };
99
+ const EVENT_COLORS = {
100
+ scenario: "#ffffff",
101
+ operator: "#ff6b9d",
102
+ spacecraft: "#a78bfa",
103
+ ground: "#4ade80"
104
+ };
105
+ const ECLIPSE_COLOR = "rgba(10, 10, 15, 0.6)";
106
+ function PowerOverviewChart(props) {
107
+ const {
108
+ data,
109
+ events = [],
110
+ title = "Power - Power Generated",
111
+ height = 300,
112
+ showBattery = false,
113
+ showLegend = false,
114
+ enableExport = true,
115
+ className,
116
+ compact = false,
117
+ showEventDots = true,
118
+ showStatus = true,
119
+ enableZoom = true
120
+ } = props;
121
+ const { tokens, mode } = useTheme();
122
+ const currentStatus = useMemo(() => {
123
+ if (!data || data.length === 0) return "off";
124
+ const latest = data[data.length - 1];
125
+ if (latest.state === "shutdown") return "critical";
126
+ if (latest.state === "safe") return "caution";
127
+ if (latest.eclipse) return "serious";
128
+ return "normal";
129
+ }, [data]);
130
+ const chartConfig = useMemo(() => {
131
+ if (!data || data.length === 0) {
132
+ return {
133
+ type: "line",
134
+ series: [],
135
+ height
136
+ };
137
+ }
138
+ const times = data.map((d) => typeof d.time === "number" ? d.time : d.time.getTime());
139
+ const minTime = Math.min(...times);
140
+ const maxTime = Math.max(...times);
141
+ const stateRegions = [];
142
+ let currentState = data[0].state;
143
+ let regionStart = minTime;
144
+ data.forEach((point, idx) => {
145
+ const pointTime = typeof point.time === "number" ? point.time : point.time.getTime();
146
+ if (point.state !== currentState || idx === data.length - 1) {
147
+ const regionEnd = idx === data.length - 1 ? maxTime : pointTime;
148
+ stateRegions.push([
149
+ {
150
+ xAxis: regionStart,
151
+ itemStyle: { color: STATE_COLORS[currentState] }
152
+ },
153
+ { xAxis: regionEnd }
154
+ ]);
155
+ regionStart = pointTime;
156
+ currentState = point.state;
157
+ }
158
+ });
159
+ const eclipseRegions = [];
160
+ let inEclipse = false;
161
+ let eclipseStart = minTime;
162
+ data.forEach((point, _idx) => {
163
+ const pointTime = typeof point.time === "number" ? point.time : point.time.getTime();
164
+ if (point.eclipse && !inEclipse) {
165
+ eclipseStart = pointTime;
166
+ inEclipse = true;
167
+ } else if (!point.eclipse && inEclipse) {
168
+ eclipseRegions.push([
169
+ {
170
+ xAxis: eclipseStart,
171
+ itemStyle: { color: ECLIPSE_COLOR }
172
+ },
173
+ { xAxis: pointTime }
174
+ ]);
175
+ inEclipse = false;
176
+ }
177
+ });
178
+ if (inEclipse) {
179
+ eclipseRegions.push([
180
+ {
181
+ xAxis: eclipseStart,
182
+ itemStyle: { color: ECLIPSE_COLOR }
183
+ },
184
+ { xAxis: maxTime }
185
+ ]);
186
+ }
187
+ const series = [
188
+ {
189
+ id: "power",
190
+ name: "Power (W)",
191
+ data: data.map((d) => ({
192
+ time: typeof d.time === "number" ? d.time : d.time.getTime(),
193
+ value: d.power
194
+ })),
195
+ color: "#ffffff",
196
+ lineStyle: { width: 2 },
197
+ areaStyle: { opacity: 0.3, color: "rgba(255, 255, 255, 0.2)" },
198
+ smooth: true,
199
+ yAxisIndex: 0
200
+ }
201
+ ];
202
+ if (showBattery) {
203
+ series.push({
204
+ id: "battery",
205
+ name: "Battery %",
206
+ data: data.map((d) => ({
207
+ time: typeof d.time === "number" ? d.time : d.time.getTime(),
208
+ value: d.battery ?? 0
209
+ })),
210
+ color: "#4ade80",
211
+ lineStyle: { width: 2, type: "dashed" },
212
+ smooth: true,
213
+ yAxisIndex: 1
214
+ });
215
+ }
216
+ const maxPower = Math.max(...data.map((d) => d.power), 100);
217
+ const eventDots = showEventDots ? events.map((event) => ({
218
+ coord: [
219
+ typeof event.time === "number" ? event.time : event.time.getTime(),
220
+ maxPower * 0.95
221
+ ],
222
+ name: event.label,
223
+ symbol: event.type === "scenario" ? "diamond" : "circle",
224
+ symbolSize: event.type === "scenario" ? 10 : 8,
225
+ itemStyle: {
226
+ color: EVENT_COLORS[event.type],
227
+ borderColor: tokens.colors.background.base,
228
+ borderWidth: 2,
229
+ shadowBlur: 4,
230
+ shadowColor: EVENT_COLORS[event.type]
231
+ },
232
+ label: {
233
+ show: false
234
+ },
235
+ emphasis: {
236
+ scale: true,
237
+ itemStyle: {
238
+ borderWidth: 3,
239
+ shadowBlur: 8
240
+ },
241
+ label: {
242
+ show: true,
243
+ fontSize: 12,
244
+ color: tokens.colors.text.primary,
245
+ backgroundColor: tokens.colors.background.surface,
246
+ borderColor: EVENT_COLORS[event.type],
247
+ borderWidth: 1,
248
+ padding: [6, 10],
249
+ borderRadius: 6,
250
+ formatter: `{b}`
251
+ }
252
+ }
253
+ })) : [];
254
+ const yAxisConfig = showBattery ? [
255
+ {
256
+ type: "value",
257
+ name: "Power (W)",
258
+ position: "left",
259
+ min: 0,
260
+ splitLine: { show: true }
261
+ },
262
+ {
263
+ type: "value",
264
+ name: "Battery %",
265
+ position: "right",
266
+ min: 0,
267
+ max: 100,
268
+ splitLine: { show: false }
269
+ }
270
+ ] : {
271
+ type: "value",
272
+ name: "Power (W)",
273
+ min: 0,
274
+ splitLine: { show: true }
275
+ };
276
+ return {
277
+ type: "area",
278
+ title,
279
+ subtitle: compact ? void 0 : `System states, operational modes, eclipse periods, and events`,
280
+ height,
281
+ series,
282
+ xAxis: {
283
+ type: "time",
284
+ showGrid: true,
285
+ splitLine: { show: true }
286
+ },
287
+ yAxis: yAxisConfig,
288
+ tooltip: {
289
+ enabled: true,
290
+ trigger: "axis",
291
+ crosshair: "both",
292
+ formatter: (params) => {
293
+ const param = Array.isArray(params) ? params[0] : params;
294
+ if (!param) return "";
295
+ const time = new Date(param.data[0]);
296
+ const dataPoint = data.find((d) => {
297
+ const t = typeof d.time === "number" ? d.time : d.time.getTime();
298
+ return t === param.data[0];
299
+ });
300
+ let html = `<div style="font-size: 13px; min-width: 220px; font-family: ${tokens.typography.fontFamily.primary};">`;
301
+ html += `<div style="font-weight: 600; margin-bottom: 10px; color: ${tokens.colors.text.primary}; font-size: 14px;">${time.toLocaleTimeString()}</div>`;
302
+ if (Array.isArray(params)) {
303
+ params.forEach((p) => {
304
+ const value = p.data[1];
305
+ const seriesName = p.seriesName;
306
+ const color = p.color;
307
+ html += `<div style="display: flex; align-items: center; gap: 8px; margin-bottom: 6px;">`;
308
+ html += `<span style="width: 12px; height: 12px; background: ${color}; border-radius: 3px; box-shadow: 0 0 4px ${color};"></span>`;
309
+ html += `<span style="color: ${tokens.colors.text.secondary};">${seriesName}: <strong style="color: ${tokens.colors.text.primary};">${value.toFixed(1)}</strong></span>`;
310
+ html += `</div>`;
311
+ });
312
+ } else {
313
+ const value = param.data[1];
314
+ html += `<div style="margin-bottom: 6px; color: ${tokens.colors.text.secondary};">Power: <strong style="color: ${tokens.colors.text.primary};">${value.toFixed(1)} W</strong></div>`;
315
+ }
316
+ if (dataPoint) {
317
+ html += `<div style="margin-top: 10px; padding-top: 10px; border-top: 1px solid ${tokens.colors.border.muted};">`;
318
+ html += `<div style="display: grid; grid-template-columns: auto 1fr; gap: 8px 12px; font-size: 12px;">`;
319
+ html += `<span style="color: ${tokens.colors.text.muted};">STATE</span>`;
320
+ html += `<span style="color: ${STATE_COLORS[dataPoint.state]}; font-weight: 600;">${dataPoint.state.toUpperCase()}</span>`;
321
+ html += `<span style="color: ${tokens.colors.text.muted};">MODE</span>`;
322
+ html += `<span style="color: ${MODE_COLORS[dataPoint.mode]}; font-weight: 600;">${dataPoint.mode.toUpperCase()}</span>`;
323
+ if (dataPoint.battery !== void 0) {
324
+ html += `<span style="color: ${tokens.colors.text.muted};">BATTERY</span>`;
325
+ html += `<span style="color: ${tokens.colors.text.primary}; font-weight: 600;">${dataPoint.battery.toFixed(1)}%</span>`;
326
+ }
327
+ html += `</div>`;
328
+ if (dataPoint.eclipse) {
329
+ html += `<div style="color: ${tokens.colors.status.caution}; font-weight: 600; margin-top: 8px; font-size: 12px; display: flex; align-items: center; gap: 6px;">`;
330
+ html += `<span style="font-weight: 600;">ECLIPSE</span>`;
331
+ html += `</div>`;
332
+ }
333
+ html += `</div>`;
334
+ }
335
+ html += `</div>`;
336
+ return html;
337
+ }
338
+ },
339
+ legend: showLegend ? {
340
+ show: true,
341
+ position: "top",
342
+ orient: "horizontal"
343
+ } : { show: false },
344
+ zoom: enableZoom ? {
345
+ enabled: true,
346
+ type: "both",
347
+ axis: "x",
348
+ start: 0,
349
+ end: 100
350
+ } : void 0,
351
+ annotations: {
352
+ markAreas: {
353
+ data: [...stateRegions, ...eclipseRegions],
354
+ itemStyle: {
355
+ opacity: 1
356
+ }
357
+ },
358
+ markPoints: eventDots
359
+ },
360
+ export: enableExport ? {
361
+ enabled: true,
362
+ formats: ["png", "svg", "csv"],
363
+ getExportFileName: () => `zendir-power-overview-${Date.now()}`
364
+ } : void 0,
365
+ infoTooltip: compact ? void 0 : {
366
+ content: /* @__PURE__ */ jsxs("div", { style: { fontSize: "13px", lineHeight: "1.6" }, children: [
367
+ /* @__PURE__ */ jsx("div", { style: { marginBottom: "8px", fontWeight: 500 }, children: "Interactive Power Timeline" }),
368
+ /* @__PURE__ */ jsx("div", { style: { marginBottom: "4px" }, children: "• Background colors show system states" }),
369
+ /* @__PURE__ */ jsx("div", { style: { marginBottom: "4px" }, children: "• Dark overlays indicate eclipse periods" }),
370
+ /* @__PURE__ */ jsx("div", { style: { marginBottom: "4px" }, children: "• Diamond markers show key events" }),
371
+ /* @__PURE__ */ jsx("div", { children: "• Scroll to zoom, drag to pan" })
372
+ ] })
373
+ },
374
+ className
375
+ };
376
+ }, [data, events, title, height, showBattery, showLegend, enableExport, className, compact, showEventDots, enableZoom, tokens]);
377
+ return /* @__PURE__ */ jsxs("div", { style: { position: "relative", width: "100%" }, children: [
378
+ showStatus && /* @__PURE__ */ jsxs("div", { style: {
379
+ position: "absolute",
380
+ top: 10,
381
+ right: 60,
382
+ zIndex: 10,
383
+ display: "flex",
384
+ alignItems: "center",
385
+ gap: 8,
386
+ padding: "6px 12px",
387
+ background: tokens.colors.background.surface,
388
+ border: `1px solid ${tokens.colors.border.default}`,
389
+ borderRadius: tokens.borderRadius.md,
390
+ fontSize: tokens.typography.fontSize.xs,
391
+ fontFamily: tokens.typography.fontFamily.primary
392
+ }, children: [
393
+ /* @__PURE__ */ jsx(
394
+ StatusShape,
395
+ {
396
+ status: currentStatus,
397
+ size: 10,
398
+ color: tokens.colors.status[currentStatus] || tokens.colors.status.off,
399
+ borderColor: mode === "light" ? STATUS_BORDER_COLORS[currentStatus] : void 0,
400
+ glow: mode !== "light"
401
+ }
402
+ ),
403
+ /* @__PURE__ */ jsx("span", { style: {
404
+ color: tokens.colors.text.primary,
405
+ fontWeight: 500,
406
+ textTransform: "uppercase",
407
+ letterSpacing: "0.5px"
408
+ }, children: currentStatus })
409
+ ] }),
410
+ /* @__PURE__ */ jsx(AstroChart, { ...chartConfig })
411
+ ] });
412
+ }
413
+ function generateSamplePowerData(durationSeconds = 3600) {
414
+ const dataPoints = [];
415
+ const eventList = [];
416
+ const startTime = Date.now();
417
+ const interval = 10;
418
+ let currentState = "running";
419
+ let currentMode = "inertial";
420
+ let inEclipse = false;
421
+ for (let i = 0; i <= durationSeconds; i += interval) {
422
+ const time = startTime + i * 1e3;
423
+ if (i === 300) currentState = "safe";
424
+ if (i === 600) currentState = "running";
425
+ if (i === 1800) currentState = "shutdown";
426
+ if (i === 2100) currentState = "running";
427
+ if (i === 2400) currentState = "safe";
428
+ if (i === 2700) currentState = "running";
429
+ if (i === 200) currentMode = "sun";
430
+ if (i === 500) currentMode = "inertial";
431
+ if (i === 800) currentMode = "nadir";
432
+ if (i === 1100) currentMode = "velocity";
433
+ if (i === 1400) currentMode = "ground";
434
+ if (i === 1700) currentMode = "sun";
435
+ if (i === 2e3) currentMode = "inertial";
436
+ if (i === 2300) currentMode = "nadir";
437
+ if (i === 2600) currentMode = "velocity";
438
+ if (i === 2900) currentMode = "ground";
439
+ if (i === 3200) currentMode = "sun";
440
+ if (i >= 1700 && i <= 2100) inEclipse = true;
441
+ else if (i >= 2400 && i <= 2700) inEclipse = true;
442
+ else inEclipse = false;
443
+ let battery = 95;
444
+ if (inEclipse) {
445
+ battery = 95 - (i - 1700) % 400 * 0.1;
446
+ } else if (currentMode === "sun") {
447
+ battery = 70 + Math.sin(i * 0.01) * 15;
448
+ } else {
449
+ battery = 90 + Math.sin(i * 5e-3) * 5;
450
+ }
451
+ battery = Math.max(10, Math.min(100, battery));
452
+ let power = 0;
453
+ if (inEclipse) {
454
+ power = 0;
455
+ } else if (currentMode === "sun") {
456
+ power = 300 + Math.sin(i * 0.02) * 50;
457
+ } else if (currentMode === "ground" || currentMode === "nadir") {
458
+ power = 150 + Math.sin(i * 0.03) * 30;
459
+ } else {
460
+ power = 50 + Math.sin(i * 0.01) * 20;
461
+ }
462
+ if (currentState === "safe") power *= 0.3;
463
+ if (currentState === "shutdown") power = 0;
464
+ dataPoints.push({
465
+ time,
466
+ power,
467
+ battery,
468
+ state: currentState,
469
+ mode: currentMode,
470
+ eclipse: inEclipse
471
+ });
472
+ }
473
+ const eventTimes = [250, 420, 550, 900, 1300, 1650, 1850, 2200, 2500, 2800, 3100, 3400];
474
+ const eventTypes = ["scenario", "operator", "spacecraft", "ground"];
475
+ eventTimes.forEach((timeOffset, idx) => {
476
+ eventList.push({
477
+ time: startTime + timeOffset * 1e3,
478
+ type: eventTypes[idx % eventTypes.length],
479
+ label: `Event ${idx + 1}`
480
+ });
481
+ });
482
+ return { data: dataPoints, events: eventList };
483
+ }
484
+ export {
485
+ PowerOverviewChart,
486
+ generateSamplePowerData
487
+ };
488
+ //# sourceMappingURL=PowerOverviewChart.js.map