@smartnet360/svelte-components 0.0.50 → 0.0.53

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 (71) hide show
  1. package/dist/apps/site-check/SiteCheck.svelte +7 -1
  2. package/dist/apps/site-check/SiteCheck.svelte.d.ts +1 -0
  3. package/dist/apps/site-check/transforms.js +2 -2
  4. package/dist/core/Charts/ChartCard.svelte +6 -1
  5. package/dist/core/Charts/ChartComponent.svelte +11 -4
  6. package/dist/core/Charts/ChartComponent.svelte.d.ts +1 -0
  7. package/dist/core/Charts/GlobalControls.svelte +171 -25
  8. package/dist/core/Charts/GlobalControls.svelte.d.ts +1 -0
  9. package/dist/core/Charts/adapt.js +1 -1
  10. package/dist/core/Charts/charts.model.d.ts +3 -0
  11. package/dist/core/Charts/data-utils.js +8 -1
  12. package/dist/core/FeatureRegistry/index.js +1 -1
  13. package/dist/core/index.d.ts +0 -1
  14. package/dist/core/index.js +2 -1
  15. package/dist/index.d.ts +1 -0
  16. package/dist/index.js +2 -0
  17. package/dist/map/controls/MapControl.svelte +204 -0
  18. package/dist/map/controls/MapControl.svelte.d.ts +17 -0
  19. package/dist/map/controls/SiteFilterControl.svelte +126 -0
  20. package/dist/map/controls/SiteFilterControl.svelte.d.ts +16 -0
  21. package/dist/map/demo/DemoMap.svelte +98 -0
  22. package/dist/map/demo/DemoMap.svelte.d.ts +12 -0
  23. package/dist/map/demo/demo-data.d.ts +12 -0
  24. package/dist/map/demo/demo-data.js +220 -0
  25. package/dist/map/hooks/useCellData.d.ts +14 -0
  26. package/dist/map/hooks/useCellData.js +29 -0
  27. package/dist/map/hooks/useMapbox.d.ts +14 -0
  28. package/dist/map/hooks/useMapbox.js +29 -0
  29. package/dist/map/index.d.ts +27 -0
  30. package/dist/map/index.js +47 -0
  31. package/dist/map/layers/CellsLayer.svelte +242 -0
  32. package/dist/map/layers/CellsLayer.svelte.d.ts +21 -0
  33. package/dist/map/layers/CoverageLayer.svelte +37 -0
  34. package/dist/map/layers/CoverageLayer.svelte.d.ts +9 -0
  35. package/dist/map/layers/LayerBase.d.ts +42 -0
  36. package/dist/map/layers/LayerBase.js +58 -0
  37. package/dist/map/layers/SitesLayer.svelte +282 -0
  38. package/dist/map/layers/SitesLayer.svelte.d.ts +19 -0
  39. package/dist/map/providers/CellDataProvider.svelte +43 -0
  40. package/dist/map/providers/CellDataProvider.svelte.d.ts +12 -0
  41. package/dist/map/providers/MapboxProvider.svelte +38 -0
  42. package/dist/map/providers/MapboxProvider.svelte.d.ts +9 -0
  43. package/dist/map/providers/providerHelpers.d.ts +17 -0
  44. package/dist/map/providers/providerHelpers.js +26 -0
  45. package/dist/map/stores/cellDataStore.d.ts +21 -0
  46. package/dist/map/stores/cellDataStore.js +53 -0
  47. package/dist/map/stores/interactions.d.ts +20 -0
  48. package/dist/map/stores/interactions.js +33 -0
  49. package/dist/map/stores/mapStore.d.ts +8 -0
  50. package/dist/map/stores/mapStore.js +10 -0
  51. package/dist/map/types.d.ts +115 -0
  52. package/dist/map/types.js +10 -0
  53. package/dist/map/utils/geojson.d.ts +20 -0
  54. package/dist/map/utils/geojson.js +78 -0
  55. package/dist/map/utils/mapboxHelpers.d.ts +51 -0
  56. package/dist/map/utils/mapboxHelpers.js +98 -0
  57. package/dist/map/utils/math.d.ts +40 -0
  58. package/dist/map/utils/math.js +95 -0
  59. package/dist/map/utils/siteTreeUtils.d.ts +27 -0
  60. package/dist/map/utils/siteTreeUtils.js +164 -0
  61. package/package.json +1 -1
  62. package/dist/core/Map/Map.svelte +0 -312
  63. package/dist/core/Map/Map.svelte.d.ts +0 -230
  64. package/dist/core/Map/index.d.ts +0 -9
  65. package/dist/core/Map/index.js +0 -9
  66. package/dist/core/Map/mapSettings.d.ts +0 -147
  67. package/dist/core/Map/mapSettings.js +0 -226
  68. package/dist/core/Map/mapStore.d.ts +0 -73
  69. package/dist/core/Map/mapStore.js +0 -136
  70. package/dist/core/Map/types.d.ts +0 -72
  71. package/dist/core/Map/types.js +0 -32
@@ -22,9 +22,13 @@
22
22
  showGroupingSelector?: boolean; // Show/hide the grouping dropdown (default: true)
23
23
  onSearch?: (searchTerm: string) => void; // Optional: Search callback (if provided, shows search box)
24
24
  searchPlaceholder?: string; // Optional: Search box placeholder text (default: "Search...")
25
+ plotlyLayout?: Record<string, any>; // Optional Plotly layout configuration
25
26
  }
26
27
 
27
- let { rawData, multiCellLayout, singleLteLayout, singleNrLayout, baseMetrics, mode = "scrollspy", markers = [], cellStyling = defaultCellStyling, initialGrouping = defaultTreeGrouping, showGroupingSelector = true, onSearch, searchPlaceholder = "Search..." }: Props = $props();
28
+ let { rawData, multiCellLayout, singleLteLayout,
29
+ singleNrLayout, baseMetrics, mode = "scrollspy", markers = [],
30
+ cellStyling = defaultCellStyling, initialGrouping = defaultTreeGrouping,
31
+ showGroupingSelector = true, onSearch, searchPlaceholder = "Search...", plotlyLayout }: Props = $props();
28
32
 
29
33
  // Search state
30
34
  let searchTerm = $state('');
@@ -319,6 +323,8 @@
319
323
  markers={markers}
320
324
  showGlobalControls={true}
321
325
  enableAdaptation={true}
326
+ plotlyLayout={plotlyLayout}
327
+ persistSettings={true}
322
328
  />
323
329
  {:else}
324
330
  <div class="d-flex align-items-center justify-content-center h-100">
@@ -14,6 +14,7 @@ interface Props {
14
14
  showGroupingSelector?: boolean;
15
15
  onSearch?: (searchTerm: string) => void;
16
16
  searchPlaceholder?: string;
17
+ plotlyLayout?: Record<string, any>;
17
18
  }
18
19
  declare const SiteCheck: import("svelte").Component<Props, {}, "">;
19
20
  type SiteCheck = ReturnType<typeof SiteCheck>;
@@ -229,7 +229,7 @@ export function buildTreeNodes(data, grouping = { level0: 'site', level1: 'azimu
229
229
  sector: record.sector,
230
230
  azimuth: record.azimuth
231
231
  },
232
- defaultChecked: true
232
+ defaultChecked: false // Start unselected
233
233
  };
234
234
  level1Node.children.push(cellNode);
235
235
  });
@@ -293,7 +293,7 @@ function build2LevelTree(data, grouping) {
293
293
  sector: record.sector,
294
294
  azimuth: record.azimuth
295
295
  },
296
- defaultChecked: true
296
+ defaultChecked: false // Start unselected
297
297
  };
298
298
  level0Node.children.push(cellNode);
299
299
  });
@@ -8,6 +8,7 @@
8
8
  import { adaptPlotlyLayout, addMarkersToLayout, type ContainerSize } from './adapt.js';
9
9
  import { getKPIValues, type ProcessedChartData } from './data-processor.js';
10
10
  import { log } from '../logger';
11
+ import { checkHealth, getMessage } from '../FeatureRegistry';
11
12
 
12
13
  interface Props {
13
14
  chart: ChartModel;
@@ -39,6 +40,7 @@
39
40
  let chartDiv: HTMLElement;
40
41
  let containerSize = $state<ContainerSize>({ width: 0, height: 0 });
41
42
  let chartInitialized = $state(false); // Track if chart has been created
43
+ let isHealthy = $state(checkHealth('charts'));
42
44
 
43
45
  function handleContextMenu(event: MouseEvent) {
44
46
  event.preventDefault();
@@ -268,6 +270,7 @@
268
270
  }
269
271
 
270
272
  onMount(() => {
273
+
271
274
  log('📈 ChartCard mounted', {
272
275
  chartTitle: chart.title,
273
276
  leftKPIs: chart.yLeft.length,
@@ -286,7 +289,9 @@
286
289
  height: rect.height
287
290
  });
288
291
  }
289
-
292
+ if(!isHealthy){
293
+ return;
294
+ }
290
295
  renderChart();
291
296
 
292
297
  // Set up ResizeObserver with debouncing to prevent excessive re-renders
@@ -7,6 +7,7 @@
7
7
  import GlobalControls from './GlobalControls.svelte';
8
8
  import { getPreprocessedData, type ProcessedChartData } from './data-processor.js';
9
9
  import { log } from '../logger';
10
+ import { checkHealth, getMessage } from '../FeatureRegistry';
10
11
 
11
12
  interface Props {
12
13
  layout: Layout;
@@ -16,6 +17,7 @@
16
17
  plotlyLayout?: any; // Optional custom Plotly layout
17
18
  enableAdaptation?: boolean; // Enable size-based adaptations
18
19
  showGlobalControls?: boolean; // Show/hide global controls section (default: true)
20
+ persistSettings?: boolean; // Enable localStorage persistence for global controls (default: false)
19
21
  }
20
22
 
21
23
  const GRID_DIMENSIONS: Record<ChartGrid, { rows: number; columns: number }> = {
@@ -54,8 +56,8 @@
54
56
  section: Section;
55
57
  }
56
58
 
57
- let { layout, data, mode, markers, plotlyLayout, enableAdaptation = true, showGlobalControls = true }: Props = $props();
58
-
59
+ let { layout, data, mode, markers, plotlyLayout, enableAdaptation = true, showGlobalControls = true, persistSettings = false }: Props = $props();
60
+ let isHealthy = $state(checkHealth('charts'));
59
61
  // Log component initialization
60
62
  $effect(() => {
61
63
  log('📊 ChartComponent initialized', {
@@ -88,6 +90,9 @@
88
90
  },
89
91
  hoverMode: {
90
92
  mode: layout.hoverMode ?? 'x' // Default to 'x' if not specified
93
+ },
94
+ adaptive: {
95
+ enabled: enableAdaptation // Initialize from prop, always present
91
96
  }
92
97
  });
93
98
 
@@ -272,6 +277,7 @@
272
277
  }
273
278
 
274
279
  onMount(() => {
280
+
275
281
  const handleKeydown = (event: KeyboardEvent) => {
276
282
  if (event.key === 'Escape') {
277
283
  if (zoomedChart) {
@@ -328,7 +334,7 @@
328
334
  {processedData}
329
335
  {markers}
330
336
  {plotlyLayout}
331
- {enableAdaptation}
337
+ enableAdaptation={globalControls.adaptive?.enabled ?? true}
332
338
  sectionId={section.id}
333
339
  sectionMovingAverage={section.movingAverage}
334
340
  layoutMovingAverage={layout.movingAverage}
@@ -353,6 +359,7 @@
353
359
  onUpdate={handleControlsUpdate}
354
360
  isExpanded={showControlsPanel}
355
361
  onToggle={() => showControlsPanel = !showControlsPanel}
362
+ persistSettings={persistSettings}
356
363
  />
357
364
  {/if}
358
365
 
@@ -447,7 +454,7 @@
447
454
  {processedData}
448
455
  {markers}
449
456
  {plotlyLayout}
450
- {enableAdaptation}
457
+ enableAdaptation={globalControls.adaptive?.enabled ?? true}
451
458
  sectionId={activeZoom.section.id}
452
459
  sectionMovingAverage={activeZoom.section.movingAverage}
453
460
  layoutMovingAverage={layout.movingAverage}
@@ -7,6 +7,7 @@ interface Props {
7
7
  plotlyLayout?: any;
8
8
  enableAdaptation?: boolean;
9
9
  showGlobalControls?: boolean;
10
+ persistSettings?: boolean;
10
11
  }
11
12
  declare const ChartComponent: import("svelte").Component<Props, {}, "">;
12
13
  type ChartComponent = ReturnType<typeof ChartComponent>;
@@ -1,6 +1,7 @@
1
1
  <svelte:options runes={true} />
2
2
 
3
3
  <script lang="ts">
4
+ import { onMount } from 'svelte';
4
5
  import type { GlobalChartControls, HoverMode } from './charts.model.js';
5
6
 
6
7
  interface Props {
@@ -8,55 +9,110 @@
8
9
  onUpdate: (controls: GlobalChartControls) => void;
9
10
  isExpanded?: boolean;
10
11
  onToggle?: () => void;
12
+ persistSettings?: boolean; // Optional: enable localStorage persistence
11
13
  }
12
14
 
13
- let { controls, onUpdate, isExpanded = false, onToggle }: Props = $props();
15
+ let { controls, onUpdate, isExpanded = false, onToggle, persistSettings = false }: Props = $props();
16
+
17
+ const STORAGE_KEY = 'chart-global-controls';
18
+
19
+ // Load saved settings on mount
20
+ onMount(() => {
21
+ if (persistSettings && typeof window !== 'undefined') {
22
+ try {
23
+ const saved = localStorage.getItem(STORAGE_KEY);
24
+ if (saved) {
25
+ const savedControls = JSON.parse(saved) as GlobalChartControls;
26
+ onUpdate(savedControls);
27
+ }
28
+ } catch (error) {
29
+ console.warn('Failed to load chart controls from localStorage:', error);
30
+ }
31
+ }
32
+ });
33
+
34
+ // Save settings to localStorage
35
+ function saveSettings(updatedControls: GlobalChartControls) {
36
+ if (persistSettings && typeof window !== 'undefined') {
37
+ try {
38
+ console.log('💾 Saving chart controls to localStorage:', updatedControls);
39
+ localStorage.setItem(STORAGE_KEY, JSON.stringify(updatedControls));
40
+ console.log('✅ Saved successfully');
41
+ } catch (error) {
42
+ console.warn('Failed to save chart controls to localStorage:', error);
43
+ }
44
+ } else {
45
+ console.log('⚠️ Not saving: persistSettings =', persistSettings);
46
+ }
47
+ }
14
48
 
15
49
  function updateControls(updates: Partial<GlobalChartControls>) {
16
- onUpdate({
50
+ const newControls = {
17
51
  ...controls,
18
52
  ...updates
19
- });
53
+ };
54
+ onUpdate(newControls);
55
+ saveSettings(newControls);
20
56
  }
21
57
 
22
58
  function updateMovingAverage(updates: Partial<NonNullable<GlobalChartControls['movingAverage']>>) {
23
- onUpdate({
59
+ const newControls = {
24
60
  ...controls,
25
61
  movingAverage: {
26
62
  ...controls.movingAverage!,
27
63
  ...updates
28
64
  }
29
- });
65
+ };
66
+ onUpdate(newControls);
67
+ saveSettings(newControls);
30
68
  }
31
69
 
32
70
  function updateMarkers(updates: Partial<NonNullable<GlobalChartControls['markers']>>) {
33
- onUpdate({
71
+ const newControls = {
34
72
  ...controls,
35
73
  markers: {
36
74
  ...controls.markers!,
37
75
  ...updates
38
76
  }
39
- });
77
+ };
78
+ onUpdate(newControls);
79
+ saveSettings(newControls);
40
80
  }
41
81
 
42
82
  function updateLegend(updates: Partial<NonNullable<GlobalChartControls['legend']>>) {
43
- onUpdate({
83
+ const newControls = {
44
84
  ...controls,
45
85
  legend: {
46
86
  ...controls.legend!,
47
87
  ...updates
48
88
  }
49
- });
89
+ };
90
+ onUpdate(newControls);
91
+ saveSettings(newControls);
50
92
  }
51
93
 
52
94
  function updateHoverMode(updates: Partial<NonNullable<GlobalChartControls['hoverMode']>>) {
53
- onUpdate({
95
+ const newControls = {
54
96
  ...controls,
55
97
  hoverMode: {
56
98
  ...controls.hoverMode!,
57
99
  ...updates
58
100
  }
59
- });
101
+ };
102
+ onUpdate(newControls);
103
+ saveSettings(newControls);
104
+ }
105
+
106
+ function updateAdaptive(updates: Partial<NonNullable<GlobalChartControls['adaptive']>>) {
107
+ const newControls = {
108
+ ...controls,
109
+ adaptive: {
110
+ ...controls.adaptive!,
111
+ ...updates
112
+ }
113
+ };
114
+ onUpdate(newControls);
115
+ saveSettings(newControls);
60
116
  }
61
117
  </script>
62
118
 
@@ -102,7 +158,11 @@
102
158
  checked={controls.markers.enabled}
103
159
  onchange={() => updateMarkers({ enabled: !controls.markers!.enabled })}
104
160
  />
105
- <label class="btn btn-outline-primary btn-sm" for="markersToggle">
161
+ <label
162
+ class="btn btn-outline-primary btn-sm"
163
+ for="markersToggle"
164
+ title="Show or hide data point markers on charts"
165
+ >
106
166
  Markers
107
167
  </label>
108
168
  </div>
@@ -118,17 +178,41 @@
118
178
  checked={controls.legend.enabled}
119
179
  onchange={() => updateLegend({ enabled: !controls.legend!.enabled })}
120
180
  />
121
- <label class="btn btn-outline-primary btn-sm" for="legendToggle">
181
+ <label
182
+ class="btn btn-outline-primary btn-sm"
183
+ for="legendToggle"
184
+ title="Show or hide the chart legend with series names"
185
+ >
122
186
  Legend
123
187
  </label>
124
188
  </div>
125
189
  {/if}
190
+
191
+ <!-- Adaptive Toggle (Always Present - Not Optional) -->
192
+ <div class="control-group-inline">
193
+ <input
194
+ type="checkbox"
195
+ class="btn-check"
196
+ id="adaptiveToggle"
197
+ checked={controls.adaptive?.enabled ?? true}
198
+ onchange={() => updateAdaptive({ enabled: !(controls.adaptive?.enabled ?? true) })}
199
+ />
200
+ <label
201
+ class="btn btn-outline-primary btn-sm"
202
+ for="adaptiveToggle"
203
+ title="Enable adaptive chart display based on chart size and data density"
204
+ >
205
+ Adaptive
206
+ </label>
207
+ </div>
126
208
  </div>
127
209
 
128
210
  <!-- Hover Mode Controls -->
129
211
  {#if controls.hoverMode}
130
212
  <div class="control-group">
131
- <div class="control-label">Hover Mode</div>
213
+ <div class="control-label" title="Control how hover tooltips appear when you move your mouse over the chart">
214
+ Hover Mode
215
+ </div>
132
216
  <div class="btn-group btn-group-sm" role="group" aria-label="Hover Mode">
133
217
  <input
134
218
  type="radio"
@@ -138,7 +222,13 @@
138
222
  checked={controls.hoverMode.mode === 'x'}
139
223
  onchange={() => updateHoverMode({ mode: 'x' })}
140
224
  />
141
- <label class="btn btn-outline-primary" for="hoverModeX">X-Axis</label>
225
+ <label
226
+ class="btn btn-outline-primary"
227
+ for="hoverModeX"
228
+ title="Show all data points at the same X-axis position"
229
+ >
230
+ X-Axis
231
+ </label>
142
232
 
143
233
  <!-- <input
144
234
  type="radio"
@@ -158,7 +248,13 @@
158
248
  checked={controls.hoverMode.mode === 'closest'}
159
249
  onchange={() => updateHoverMode({ mode: 'closest' })}
160
250
  />
161
- <label class="btn btn-outline-primary" for="hoverModeClosest">Closest</label>
251
+ <label
252
+ class="btn btn-outline-primary"
253
+ for="hoverModeClosest"
254
+ title="Show only the single closest data point to your cursor"
255
+ >
256
+ Closest
257
+ </label>
162
258
 
163
259
  <input
164
260
  type="radio"
@@ -168,7 +264,13 @@
168
264
  checked={controls.hoverMode.mode === 'x unified'}
169
265
  onchange={() => updateHoverMode({ mode: 'x unified' })}
170
266
  />
171
- <label class="btn btn-outline-primary" for="hoverModeXUnified">X-Unified</label>
267
+ <label
268
+ class="btn btn-outline-primary"
269
+ for="hoverModeXUnified"
270
+ title="Show all data points at the same X position with a single unified tooltip"
271
+ >
272
+ X-Unified
273
+ </label>
172
274
 
173
275
  <!-- <input
174
276
  type="radio"
@@ -188,7 +290,13 @@
188
290
  checked={controls.hoverMode.mode === false}
189
291
  onchange={() => updateHoverMode({ mode: false })}
190
292
  />
191
- <label class="btn btn-outline-primary" for="hoverModeFalse">Off</label>
293
+ <label
294
+ class="btn btn-outline-primary"
295
+ for="hoverModeFalse"
296
+ title="Disable hover tooltips completely"
297
+ >
298
+ Off
299
+ </label>
192
300
  </div>
193
301
  </div>
194
302
  {/if}
@@ -204,7 +312,11 @@
204
312
  checked={controls.movingAverage.enabled}
205
313
  onchange={() => updateMovingAverage({ enabled: !controls.movingAverage!.enabled })}
206
314
  />
207
- <label class="btn btn-outline-primary btn-sm" for="maToggle">
315
+ <label
316
+ class="btn btn-outline-primary btn-sm"
317
+ for="maToggle"
318
+ title="Apply smoothing to chart data using moving average calculations"
319
+ >
208
320
  Moving Average
209
321
  </label>
210
322
 
@@ -220,7 +332,13 @@
220
332
  checked={controls.movingAverage.windowOverride === undefined}
221
333
  onchange={() => updateMovingAverage({ windowOverride: undefined })}
222
334
  />
223
- <label class="btn btn-outline-primary" for="maWindowAuto">Auto</label>
335
+ <label
336
+ class="btn btn-outline-primary"
337
+ for="maWindowAuto"
338
+ title="Default size from settings"
339
+ >
340
+ Auto
341
+ </label>
224
342
 
225
343
  <input
226
344
  type="radio"
@@ -230,7 +348,13 @@
230
348
  checked={controls.movingAverage.windowOverride === 7}
231
349
  onchange={() => updateMovingAverage({ windowOverride: 7 })}
232
350
  />
233
- <label class="btn btn-outline-primary" for="maWindow7">7</label>
351
+ <label
352
+ class="btn btn-outline-primary"
353
+ for="maWindow7"
354
+ title="Use a 7-period moving average window"
355
+ >
356
+ 7
357
+ </label>
234
358
 
235
359
  <input
236
360
  type="radio"
@@ -240,7 +364,13 @@
240
364
  checked={controls.movingAverage.windowOverride === 14}
241
365
  onchange={() => updateMovingAverage({ windowOverride: 14 })}
242
366
  />
243
- <label class="btn btn-outline-primary" for="maWindow14">14</label>
367
+ <label
368
+ class="btn btn-outline-primary"
369
+ for="maWindow14"
370
+ title="Use a 14-period moving average window"
371
+ >
372
+ 14
373
+ </label>
244
374
 
245
375
  <input
246
376
  type="radio"
@@ -250,7 +380,13 @@
250
380
  checked={controls.movingAverage.windowOverride === 24}
251
381
  onchange={() => updateMovingAverage({ windowOverride: 24 })}
252
382
  />
253
- <label class="btn btn-outline-primary" for="maWindow24">24</label>
383
+ <label
384
+ class="btn btn-outline-primary"
385
+ for="maWindow24"
386
+ title="Use a 24-period moving average window"
387
+ >
388
+ 24
389
+ </label>
254
390
 
255
391
  <input
256
392
  type="radio"
@@ -260,7 +396,13 @@
260
396
  checked={controls.movingAverage.windowOverride === 30}
261
397
  onchange={() => updateMovingAverage({ windowOverride: 30 })}
262
398
  />
263
- <label class="btn btn-outline-primary" for="maWindow30">30</label>
399
+ <label
400
+ class="btn btn-outline-primary"
401
+ for="maWindow30"
402
+ title="Use a 30-period moving average window"
403
+ >
404
+ 30
405
+ </label>
264
406
  </div>
265
407
 
266
408
  <!-- Show Original Toggle Button -->
@@ -271,7 +413,11 @@
271
413
  checked={controls.movingAverage.showOriginal}
272
414
  onchange={() => updateMovingAverage({ showOriginal: !controls.movingAverage!.showOriginal })}
273
415
  />
274
- <label class="btn btn-outline-primary btn-sm ms-2" for="showOriginal">
416
+ <label
417
+ class="btn btn-outline-primary btn-sm ms-2"
418
+ for="showOriginal"
419
+ title="Display both the original data and the moving average together"
420
+ >
275
421
  Show Original
276
422
  </label>
277
423
  </div>
@@ -4,6 +4,7 @@ interface Props {
4
4
  onUpdate: (controls: GlobalChartControls) => void;
5
5
  isExpanded?: boolean;
6
6
  onToggle?: () => void;
7
+ persistSettings?: boolean;
7
8
  }
8
9
  declare const GlobalControls: import("svelte").Component<Props, {}, "">;
9
10
  type GlobalControls = ReturnType<typeof GlobalControls>;
@@ -9,7 +9,7 @@
9
9
  function adaptHoverBehavior(layout, containerSize, chartInfo, originalHoverMode) {
10
10
  const { width, height } = containerSize;
11
11
  const isTiny = width < 250 || height < 200;
12
- const isSmall = width < 400 || height < 300;
12
+ const isSmall = width < 250 || height < 200;
13
13
  const isMedium = width < 600 || height < 400;
14
14
  const totalSeries = chartInfo.leftSeriesCount + chartInfo.rightSeriesCount;
15
15
  // Only override hover mode in critical cases for performance/UX
@@ -69,6 +69,9 @@ export interface GlobalChartControls {
69
69
  hoverMode?: {
70
70
  mode: HoverMode;
71
71
  };
72
+ adaptive?: {
73
+ enabled: boolean;
74
+ };
72
75
  }
73
76
  export interface CellStylingConfig {
74
77
  bandColors: Record<string, string>;
@@ -302,7 +302,14 @@ export function createDefaultPlotlyLayout(title, hoverMode, coloredHover = true)
302
302
  showgrid: true,
303
303
  gridcolor: '#ecf0f1',
304
304
  linecolor: '#bdc3c7',
305
- tickfont: { size: 11 }
305
+ tickfont: { size: 11 },
306
+ // Show Y-axis marker with line when in 'closest' hover mode
307
+ // showspikes: hoverMode === 'closest',
308
+ // spikemode: 'marker', // Line to axis + triangle marker
309
+ // spikesnap: 'cursor', // Snap to cursor position
310
+ // spikethickness: 1, // Line thickness
311
+ // spikecolor: '#000000ff', // Primary blue color
312
+ // spikedash: 'dot' // Dotted line
306
313
  },
307
314
  margin: { l: 60, r: 60, t: 60, b: 50 },
308
315
  paper_bgcolor: 'rgba(0,0,0,0)',
@@ -1,4 +1,4 @@
1
- const R = new Date('2025-12-31T23:59:59Z').getTime();
1
+ const R = new Date('2026-03-31T23:59:59Z').getTime();
2
2
  export function checkHealth(feature) {
3
3
  // Skip check during SSR
4
4
  if (typeof window === 'undefined')
@@ -3,5 +3,4 @@ export * from './Charts/index.js';
3
3
  export * from './TreeView/index.js';
4
4
  export * from './Settings/index.js';
5
5
  export * from './logger/index.js';
6
- export * from './Map/index.js';
7
6
  export * from './FeatureRegistry/index.js';
@@ -11,6 +11,7 @@ export * from './Settings/index.js';
11
11
  // Logger utility for debugging and monitoring
12
12
  export * from './logger/index.js';
13
13
  // Map component - Mapbox GL + Deck.GL integration
14
- export * from './Map/index.js';
14
+ // TODO: Moved to top-level src/lib/map module
15
+ // export * from './Map/index.js';
15
16
  // FeatureRegistry - Component access management
16
17
  export * from './FeatureRegistry/index.js';
package/dist/index.d.ts CHANGED
@@ -1,2 +1,3 @@
1
1
  export * from './core/index.js';
2
+ export * from './map/index.js';
2
3
  export * from './apps/index.js';
package/dist/index.js CHANGED
@@ -2,5 +2,7 @@
2
2
  // This approach keeps the main index clean and allows for easy expansion
3
3
  // Core components (Desktop orchestration + Charts + TreeView)
4
4
  export * from './core/index.js';
5
+ // Map components (Mapbox cellular visualization)
6
+ export * from './map/index.js';
5
7
  // Complete applications
6
8
  export * from './apps/index.js';