@aquera/nile-visualization 0.3.0 → 0.5.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 (50) hide show
  1. package/dist/src/index.d.ts +8 -2
  2. package/dist/src/index.js +3 -0
  3. package/dist/src/internal/chart-adapters.js +86 -0
  4. package/dist/src/internal/highcharts-provider.js +27 -0
  5. package/dist/src/internal/types/all-chart-config.type.d.ts +2 -4
  6. package/dist/src/internal/types/chart-config.type.d.ts +3 -2
  7. package/dist/src/internal/types/chart-donut-config.type.d.ts +2 -0
  8. package/dist/src/internal/types/chart-heatmap-config.type.d.ts +19 -0
  9. package/dist/src/internal/types/chart-heatmap-config.type.js +2 -0
  10. package/dist/src/internal/types/chart-kpi-config.type.d.ts +5 -21
  11. package/dist/src/internal/types/chart-line-column-config.type.d.ts +14 -0
  12. package/dist/src/internal/types/chart-line-column-config.type.js +2 -0
  13. package/dist/src/internal/types/chart-organization-config.type.d.ts +13 -0
  14. package/dist/src/internal/types/chart-organization-config.type.js +2 -0
  15. package/dist/src/internal/types/index.d.ts +4 -1
  16. package/dist/src/internal/types/primitive-chart-config.type.d.ts +5 -1
  17. package/dist/src/nile-ai-panel/nile-ai-panel.css.js +8 -0
  18. package/dist/src/nile-ai-panel/nile-ai-panel.d.ts +2 -0
  19. package/dist/src/nile-ai-panel/nile-ai-panel.js +8 -0
  20. package/dist/src/nile-bellcurve-chart/nile-bellcurve-chart.js +3 -1
  21. package/dist/src/nile-chart/index.d.ts +2 -2
  22. package/dist/src/nile-chart/nile-chart-config.d.ts +39 -96
  23. package/dist/src/nile-chart/nile-chart.css.js +31 -6
  24. package/dist/src/nile-chart/nile-chart.d.ts +48 -7
  25. package/dist/src/nile-chart/nile-chart.js +527 -54
  26. package/dist/src/nile-donut-chart/nile-donut-chart.d.ts +2 -0
  27. package/dist/src/nile-donut-chart/nile-donut-chart.js +16 -1
  28. package/dist/src/nile-heatmap-chart/index.d.ts +2 -0
  29. package/dist/src/nile-heatmap-chart/index.js +2 -0
  30. package/dist/src/nile-heatmap-chart/nile-heatmap-chart.css.d.ts +1 -0
  31. package/dist/src/nile-heatmap-chart/nile-heatmap-chart.css.js +28 -0
  32. package/dist/src/nile-heatmap-chart/nile-heatmap-chart.d.ts +49 -0
  33. package/dist/src/nile-heatmap-chart/nile-heatmap-chart.js +259 -0
  34. package/dist/src/nile-histogram-chart/nile-histogram-chart.js +3 -1
  35. package/dist/src/nile-kpi-chart/nile-kpi-chart.css.js +4 -4
  36. package/dist/src/nile-kpi-chart/nile-kpi-chart.d.ts +2 -0
  37. package/dist/src/nile-kpi-chart/nile-kpi-chart.js +6 -0
  38. package/dist/src/nile-line-column-chart/index.d.ts +2 -0
  39. package/dist/src/nile-line-column-chart/index.js +2 -0
  40. package/dist/src/nile-line-column-chart/nile-line-column-chart.css.d.ts +1 -0
  41. package/dist/src/nile-line-column-chart/nile-line-column-chart.css.js +28 -0
  42. package/dist/src/nile-line-column-chart/nile-line-column-chart.d.ts +42 -0
  43. package/dist/src/nile-line-column-chart/nile-line-column-chart.js +205 -0
  44. package/dist/src/nile-organization-chart/index.d.ts +2 -0
  45. package/dist/src/nile-organization-chart/index.js +2 -0
  46. package/dist/src/nile-organization-chart/nile-organization-chart.css.d.ts +1 -0
  47. package/dist/src/nile-organization-chart/nile-organization-chart.css.js +28 -0
  48. package/dist/src/nile-organization-chart/nile-organization-chart.d.ts +57 -0
  49. package/dist/src/nile-organization-chart/nile-organization-chart.js +206 -0
  50. package/package.json +4 -1
@@ -19,8 +19,39 @@ import '../nile-spline-chart/index.js';
19
19
  import '../nile-radar-chart/index.js';
20
20
  import '../nile-gauge-chart/index.js';
21
21
  import '../nile-waterfall-chart/index.js';
22
+ import '../nile-cluster-chart/index.js';
23
+ import '../nile-stacked-chart/index.js';
24
+ import '../nile-histogram-chart/index.js';
25
+ import '../nile-bellcurve-chart/index.js';
26
+ import '../nile-boxplot-chart/index.js';
27
+ import '../nile-timeline-chart/index.js';
28
+ import '../nile-dumbbell-chart/index.js';
29
+ import '../nile-dumbbell-lower-chart/index.js';
30
+ import '../nile-dumbbell-upper-chart/index.js';
31
+ import '../nile-fan-chart/index.js';
32
+ import '../nile-funnel-chart/index.js';
33
+ import '../nile-organization-chart/index.js';
34
+ import '../nile-line-column-chart/index.js';
35
+ import '../nile-heatmap-chart/index.js';
36
+ import '../nile-flame-chart/index.js';
37
+ import '../nile-spiderweb-chart/index.js';
38
+ import '../nile-column-pyramid-chart/index.js';
39
+ import '../nile-lollipop-chart/index.js';
40
+ import '../nile-inverted-area-chart/index.js';
41
+ import '../nile-area-spline-chart/index.js';
42
+ import '../nile-area-negative-chart/index.js';
43
+ import '../nile-area-range-chart/index.js';
44
+ import '../nile-column-range-chart/index.js';
45
+ import '../nile-column-drilldown-chart/index.js';
46
+ import '../nile-radial-bar-chart/index.js';
47
+ import '../nile-variable-pie-chart/index.js';
48
+ import '../nile-euler-chart/index.js';
49
+ import '../nile-polygon-chart/index.js';
50
+ import '../nile-vector-chart/index.js';
51
+ import '../nile-xrange-chart/index.js';
52
+ import '../nile-kpi-chart/index.js';
22
53
  import '../nile-ai-panel/index.js';
23
- const TYPE_LABELS = {
54
+ const CORE_CHART_LABELS = {
24
55
  bar: 'Bar',
25
56
  pie: 'Pie',
26
57
  trendline: 'Trendline',
@@ -35,27 +66,60 @@ const TYPE_LABELS = {
35
66
  radar: 'Radar',
36
67
  gauge: 'Gauge',
37
68
  waterfall: 'Waterfall',
69
+ stacked: 'Stacked column',
70
+ cluster: 'Cluster',
71
+ histogram: 'Histogram',
72
+ bellcurve: 'Bell curve',
73
+ boxplot: 'Box plot',
74
+ timeline: 'Timeline',
75
+ dumbbell: 'Dumbbell',
76
+ fan: 'Fan',
77
+ funnel: 'Funnel',
78
+ organization: 'Organization',
79
+ heatmap: 'Heatmap',
80
+ flame: 'Flame',
81
+ spiderweb: 'Spiderweb',
82
+ euler: 'Euler / Venn',
83
+ polygon: 'Polygon',
84
+ vector: 'Vector',
85
+ xrange: 'X-range',
86
+ lollipop: 'Lollipop',
87
+ 'line-column': 'Line + column',
88
+ kpi: 'KPI',
38
89
  };
90
+ function chartTypeLabel(type) {
91
+ const hit = CORE_CHART_LABELS[type];
92
+ if (hit)
93
+ return hit;
94
+ return String(type)
95
+ .replace(/([a-z])([A-Z])/g, '$1 $2')
96
+ .replace(/-/g, ' ')
97
+ .replace(/\b\w/g, ch => ch.toUpperCase());
98
+ }
39
99
  let NileChart = class NileChart extends NileElement {
40
100
  constructor() {
41
101
  super(...arguments);
42
102
  /** Full chart configuration. Accepts flat NileChartConfig or separated { chart, aq } input. */
43
103
  this.config = null;
44
- /** The summary/insight text displayed in the overlay (fallback when config is not set). */
104
+ /**
105
+ * When set, fills `chart.type` if the config omits it (same values as `chart.type`, e.g. `stacked`, `pie`).
106
+ * Usage: `<nile-chart chart-type="pie" />` plus `config.chart` with series data only.
107
+ */
108
+ this.chartTypeAttr = '';
109
+ /** Summary/insight text — shown as the AI panel's opening message when the chat is opened. */
45
110
  this.summary = '';
46
- /** Label for the toggle button (fallback when config is not set). */
47
- this.toggleLabel = 'Summary';
48
- /** Whether the insight overlay is visible. */
49
- this.open = false;
50
111
  this.activeType = null;
51
112
  this.activeConfig = null;
52
113
  this.menuOpen = false;
53
114
  this.chatOpen = false;
115
+ /** True when elements are projected into the `header` slot (default title/subtitle hidden). */
116
+ this.hasHeaderSlotContent = false;
117
+ /** True when elements are projected into `header-actions` (used to show the header row). */
118
+ this.hasHeaderActionsSlot = false;
54
119
  this.handleOutsideClick = (e) => {
55
120
  if (!this.contains(e.target)) {
56
- this.open = false;
57
121
  this.menuOpen = false;
58
- this.emit('nile-chart-toggle', { open: this.open });
122
+ this.chatOpen = false;
59
123
  }
60
124
  };
61
125
  this.resolvedConfig = null;
@@ -63,11 +127,9 @@ let NileChart = class NileChart extends NileElement {
63
127
  get effectiveSummary() {
64
128
  return this.resolvedConfig?.summary ?? this.summary;
65
129
  }
66
- get effectiveToggleLabel() {
67
- return this.resolvedConfig?.toggleLabel ?? this.toggleLabel;
68
- }
130
+ /** AI panel shows when ai.enabled is true OR when a summary is provided. */
69
131
  get aiEnabled() {
70
- return this.resolvedConfig?.ai?.enabled === true;
132
+ return this.resolvedConfig?.ai?.enabled === true || !!this.effectiveSummary;
71
133
  }
72
134
  connectedCallback() {
73
135
  super.connectedCallback();
@@ -83,27 +145,29 @@ let NileChart = class NileChart extends NileElement {
83
145
  super.disconnectedCallback();
84
146
  document.removeEventListener('click', this.handleOutsideClick);
85
147
  }
148
+ mergeChartTypeFromAttr(chart) {
149
+ const t = this.chartTypeAttr?.trim();
150
+ if (t && chart.type == null) {
151
+ return { ...chart, type: t };
152
+ }
153
+ return chart;
154
+ }
86
155
  /** Resolve { chart, aq } input to flat NileChartConfig. */
87
156
  resolveConfig(input) {
88
157
  if ('chart' in input && input.chart) {
89
- return nileChartConfig(input);
158
+ const raw = input;
159
+ const chart = this.mergeChartTypeFromAttr({ ...raw.chart });
160
+ return nileChartConfig({ ...raw, chart });
90
161
  }
91
- return input;
162
+ return this.mergeChartTypeFromAttr({ ...input });
92
163
  }
93
164
  updated(changedProperties) {
94
- if (changedProperties.has('config') && this.config) {
165
+ if ((changedProperties.has('config') || changedProperties.has('chartTypeAttr')) && this.config) {
95
166
  this.resolvedConfig = this.resolveConfig(this.config);
96
167
  this.activeType = this.resolvedConfig.type;
97
168
  this.activeConfig = this.resolvedConfig;
98
169
  }
99
170
  }
100
- toggle(e) {
101
- e.stopPropagation();
102
- this.open = !this.open;
103
- if (this.open)
104
- this.chatOpen = false;
105
- this.emit('nile-chart-toggle', { open: this.open });
106
- }
107
171
  toggleMenu(e) {
108
172
  e.stopPropagation();
109
173
  this.menuOpen = !this.menuOpen;
@@ -111,8 +175,6 @@ let NileChart = class NileChart extends NileElement {
111
175
  toggleChat(e) {
112
176
  e.stopPropagation();
113
177
  this.chatOpen = !this.chatOpen;
114
- if (this.chatOpen)
115
- this.open = false;
116
178
  this.emit('nile-chart-ai-toggle', { open: this.chatOpen });
117
179
  }
118
180
  /** Push an AI response into the chat panel. Call this from your AI handler. */
@@ -148,6 +210,52 @@ let NileChart = class NileChart extends NileElement {
148
210
  get headerSubtitle() {
149
211
  return this.activeConfig?.chartSubtitle ?? this.resolvedConfig?.chartSubtitle ?? '';
150
212
  }
213
+ onHeaderSlotChange(e) {
214
+ const slot = e.target;
215
+ this.hasHeaderSlotContent = slot.assignedElements({ flatten: true }).length > 0;
216
+ this.requestUpdate();
217
+ }
218
+ onHeaderActionsSlotChange(e) {
219
+ const slot = e.target;
220
+ this.hasHeaderActionsSlot = slot.assignedElements({ flatten: true }).length > 0;
221
+ this.requestUpdate();
222
+ }
223
+ syncHeaderSlots() {
224
+ const root = this.shadowRoot;
225
+ if (!root)
226
+ return;
227
+ const headerSlot = root.querySelector('slot[name="header"]');
228
+ const actionsSlot = root.querySelector('slot[name="header-actions"]');
229
+ let changed = false;
230
+ if (headerSlot) {
231
+ const next = headerSlot.assignedElements({ flatten: true }).length > 0;
232
+ if (next !== this.hasHeaderSlotContent) {
233
+ this.hasHeaderSlotContent = next;
234
+ changed = true;
235
+ }
236
+ }
237
+ if (actionsSlot) {
238
+ const next = actionsSlot.assignedElements({ flatten: true }).length > 0;
239
+ if (next !== this.hasHeaderActionsSlot) {
240
+ this.hasHeaderActionsSlot = next;
241
+ changed = true;
242
+ }
243
+ }
244
+ if (changed)
245
+ this.requestUpdate();
246
+ }
247
+ firstUpdated(changedProperties) {
248
+ super.firstUpdated(changedProperties);
249
+ this.syncHeaderSlots();
250
+ }
251
+ shouldShowHeader() {
252
+ const hasTitles = !!(this.headerTitle || this.headerSubtitle);
253
+ const hasBuiltinActions = this.aiEnabled || (this.resolvedConfig?.switchableTypes?.length ?? 0) > 0;
254
+ return (hasTitles ||
255
+ this.hasHeaderSlotContent ||
256
+ this.hasHeaderActionsSlot ||
257
+ hasBuiltinActions);
258
+ }
151
259
  renderTypeSwitcher() {
152
260
  const types = this.resolvedConfig?.switchableTypes;
153
261
  if (!types || types.length === 0)
@@ -172,7 +280,7 @@ let NileChart = class NileChart extends NileElement {
172
280
  role="menuitem"
173
281
  @click=${() => this.switchType(type)}
174
282
  >
175
- ${TYPE_LABELS[type] ?? type} Chart
283
+ ${chartTypeLabel(type)} chart
176
284
  </button>
177
285
  `)}
178
286
  </div>
@@ -196,19 +304,24 @@ let NileChart = class NileChart extends NileElement {
196
304
  `;
197
305
  }
198
306
  renderHeader() {
307
+ if (!this.shouldShowHeader())
308
+ return nothing;
199
309
  const title = this.headerTitle;
200
310
  const subtitle = this.headerSubtitle;
201
- const hasTypeSwitcher = (this.resolvedConfig?.switchableTypes?.length ?? 0) > 0;
202
- const hasActions = hasTypeSwitcher || this.aiEnabled;
203
- if (!title && !subtitle && !hasActions)
204
- return nothing;
311
+ const showDefaultTitles = !this.hasHeaderSlotContent && !!(title || subtitle);
205
312
  return html `
206
313
  <div class="chart-header">
207
314
  <div class="chart-header-titles">
208
- ${title ? html `<h3 class="chart-header-title">${title}</h3>` : nothing}
209
- ${subtitle ? html `<p class="chart-header-subtitle">${subtitle}</p>` : nothing}
315
+ <slot name="header" @slotchange=${this.onHeaderSlotChange}></slot>
316
+ ${showDefaultTitles
317
+ ? html `
318
+ ${title ? html `<h3 class="chart-header-title">${title}</h3>` : nothing}
319
+ ${subtitle ? html `<p class="chart-header-subtitle">${subtitle}</p>` : nothing}
320
+ `
321
+ : nothing}
210
322
  </div>
211
323
  <div class="chart-header-actions">
324
+ <slot name="header-actions" @slotchange=${this.onHeaderActionsSlotChange}></slot>
212
325
  ${this.renderAiTrigger()}
213
326
  ${this.renderTypeSwitcher()}
214
327
  </div>
@@ -218,12 +331,19 @@ let NileChart = class NileChart extends NileElement {
218
331
  renderAiPanel() {
219
332
  if (!this.aiEnabled)
220
333
  return nothing;
221
- const aiConfig = this.resolvedConfig.ai;
334
+ const aiConfig = this.resolvedConfig?.ai;
335
+ const summary = this.effectiveSummary;
336
+ // Summary always takes priority. When summary is present it is the only
337
+ // opening message (shown in blue). welcomeMessage is only used when there
338
+ // is no summary at all.
339
+ const summaryMessage = summary;
340
+ const welcomeMessage = summary ? '' : (aiConfig?.welcomeMessage ?? '');
222
341
  return html `
223
342
  <div class="ai-panel-overlay" ?data-open=${this.chatOpen}>
224
343
  <nile-ai-panel
225
- .placeholder=${aiConfig.placeholder ?? 'Ask about this chart...'}
226
- .welcomeMessage=${aiConfig.welcomeMessage ?? ''}
344
+ .placeholder=${aiConfig?.placeholder ?? 'Ask about this chart...'}
345
+ .welcomeMessage=${welcomeMessage}
346
+ .summaryMessage=${summaryMessage}
227
347
  @nile-ai-send=${this.handleAiSend}
228
348
  ></nile-ai-panel>
229
349
  </div>
@@ -308,6 +428,7 @@ let NileChart = class NileChart extends NileElement {
308
428
  .seriesName=${config.seriesName ?? ''}
309
429
  .height=${config.height ?? '400px'}
310
430
  .innerSize=${config.innerSize ?? '50%'}
431
+ .semiCircle=${config.semiCircle ?? false}
311
432
  .showDataLabels=${config.showDataLabels ?? true}
312
433
  .showLegend=${config.showLegend ?? true}
313
434
  .options=${mergedOptions}
@@ -368,6 +489,368 @@ let NileChart = class NileChart extends NileElement {
368
489
  .options=${mergedOptions}
369
490
  .loading=${config.loading ?? false}
370
491
  ></nile-waterfall-chart>`;
492
+ case 'stacked':
493
+ return html `<nile-stacked-chart
494
+ .data=${config.data}
495
+ .categories=${config.categories ?? []}
496
+ .height=${config.height ?? '400px'}
497
+ .yAxisTitle=${config.yAxisTitle ?? ''}
498
+ .stackMode=${config.stackMode ?? 'normal'}
499
+ .showLegend=${config.showLegend ?? true}
500
+ .pointPadding=${config.pointPadding ?? 0.05}
501
+ .options=${mergedOptions}
502
+ .loading=${config.loading ?? false}
503
+ ></nile-stacked-chart>`;
504
+ case 'cluster':
505
+ return html `<nile-cluster-chart
506
+ .data=${config.data}
507
+ .categories=${config.categories ?? []}
508
+ .height=${config.height ?? '400px'}
509
+ .yAxisTitle=${config.yAxisTitle ?? ''}
510
+ .showLegend=${config.showLegend ?? true}
511
+ .groupPadding=${config.groupPadding ?? 0.15}
512
+ .pointPadding=${config.pointPadding ?? 0.05}
513
+ .options=${mergedOptions}
514
+ .loading=${config.loading ?? false}
515
+ ></nile-cluster-chart>`;
516
+ case 'histogram':
517
+ return html `<nile-histogram-chart
518
+ .data=${config.data}
519
+ .height=${config.height ?? '400px'}
520
+ .xAxisTitle=${config.xAxisTitle ?? ''}
521
+ .yAxisTitle=${config.yAxisTitle ?? ''}
522
+ .histogramSeriesName=${config.histogramSeriesName ?? ''}
523
+ .sourceSeriesName=${config.sourceSeriesName ?? ''}
524
+ .histogramColor=${config.histogramColor ?? '#3b82f6'}
525
+ .binsNumber=${String(config.binsNumber ?? 'square-root')}
526
+ .binWidth=${config.binWidth ?? 0}
527
+ .showLegend=${config.showLegend ?? true}
528
+ .options=${mergedOptions}
529
+ .loading=${config.loading ?? false}
530
+ ></nile-histogram-chart>`;
531
+ case 'bellcurve':
532
+ return html `<nile-bellcurve-chart
533
+ .data=${config.data}
534
+ .height=${config.height ?? '400px'}
535
+ .xAxisTitle=${config.xAxisTitle ?? ''}
536
+ .yAxisTitle=${config.yAxisTitle ?? ''}
537
+ .bellcurveSeriesName=${config.bellcurveSeriesName ?? ''}
538
+ .sourceSeriesName=${config.sourceSeriesName ?? ''}
539
+ .bellcurveColor=${config.bellcurveColor ?? '#6366f1'}
540
+ .bellcurveFill=${config.bellcurveFill ?? 'rgba(99, 102, 241, 0.2)'}
541
+ .intervals=${config.intervals ?? 3}
542
+ .pointsInInterval=${config.pointsInInterval ?? 40}
543
+ .showLegend=${config.showLegend ?? true}
544
+ .options=${mergedOptions}
545
+ .loading=${config.loading ?? false}
546
+ ></nile-bellcurve-chart>`;
547
+ case 'boxplot':
548
+ return html `<nile-boxplot-chart
549
+ .data=${config.data}
550
+ .categories=${config.categories ?? []}
551
+ .height=${config.height ?? '400px'}
552
+ .xAxisTitle=${config.xAxisTitle ?? ''}
553
+ .yAxisTitle=${config.yAxisTitle ?? ''}
554
+ .horizontal=${config.horizontal ?? false}
555
+ .showLegend=${config.showLegend ?? true}
556
+ .options=${mergedOptions}
557
+ .loading=${config.loading ?? false}
558
+ ></nile-boxplot-chart>`;
559
+ case 'timeline':
560
+ return html `<nile-timeline-chart
561
+ .data=${config.data}
562
+ .height=${config.height ?? '400px'}
563
+ .seriesName=${config.seriesName ?? ''}
564
+ .datetimeAxis=${config.datetimeAxis ?? false}
565
+ .inverted=${config.inverted ?? false}
566
+ .alternateLabels=${config.alternateLabels ?? false}
567
+ .showLegend=${config.showLegend ?? true}
568
+ .options=${mergedOptions}
569
+ .loading=${config.loading ?? false}
570
+ ></nile-timeline-chart>`;
571
+ case 'dumbbell':
572
+ return html `<nile-dumbbell-chart
573
+ .data=${config.data}
574
+ .height=${config.height ?? '400px'}
575
+ .yAxisTitle=${config.yAxisTitle ?? ''}
576
+ .seriesName=${config.seriesName ?? ''}
577
+ .lowMarkerColor=${config.lowMarkerColor ?? ''}
578
+ .connectorColor=${config.connectorColor ?? ''}
579
+ .horizontal=${config.horizontal ?? false}
580
+ .showLegend=${config.showLegend ?? true}
581
+ .options=${mergedOptions}
582
+ .loading=${config.loading ?? false}
583
+ ></nile-dumbbell-chart>`;
584
+ case 'dumbbellLower':
585
+ return html `<nile-dumbbell-lower-chart
586
+ .data=${config.data}
587
+ .height=${config.height ?? '400px'}
588
+ .yAxisTitle=${config.yAxisTitle ?? ''}
589
+ .seriesName=${config.seriesName ?? ''}
590
+ .lowMarkerColor=${config.lowMarkerColor ?? ''}
591
+ .connectorColor=${config.connectorColor ?? ''}
592
+ .horizontal=${config.horizontal ?? false}
593
+ .showLegend=${config.showLegend ?? true}
594
+ .options=${mergedOptions}
595
+ .loading=${config.loading ?? false}
596
+ ></nile-dumbbell-lower-chart>`;
597
+ case 'dumbbellUpper':
598
+ return html `<nile-dumbbell-upper-chart
599
+ .data=${config.data}
600
+ .height=${config.height ?? '400px'}
601
+ .yAxisTitle=${config.yAxisTitle ?? ''}
602
+ .seriesName=${config.seriesName ?? ''}
603
+ .lowMarkerColor=${config.lowMarkerColor ?? ''}
604
+ .connectorColor=${config.connectorColor ?? ''}
605
+ .horizontal=${config.horizontal ?? false}
606
+ .showLegend=${config.showLegend ?? true}
607
+ .options=${mergedOptions}
608
+ .loading=${config.loading ?? false}
609
+ ></nile-dumbbell-upper-chart>`;
610
+ case 'fan':
611
+ return html `<nile-fan-chart
612
+ .lineData=${config.lineData}
613
+ .bands=${config.bands}
614
+ .height=${config.height ?? '400px'}
615
+ .yAxisTitle=${config.yAxisTitle ?? ''}
616
+ .lineSeriesName=${config.lineSeriesName ?? ''}
617
+ .lineColor=${config.lineColor ?? '#1d4ed8'}
618
+ .forecastStartIndex=${config.forecastStartIndex ?? -1}
619
+ .forecastBandLabel=${config.forecastBandLabel ?? ''}
620
+ .showLegend=${config.showLegend ?? false}
621
+ .options=${mergedOptions}
622
+ .loading=${config.loading ?? false}
623
+ ></nile-fan-chart>`;
624
+ case 'funnel':
625
+ return html `<nile-funnel-chart
626
+ .data=${config.data}
627
+ .height=${config.height ?? '400px'}
628
+ .seriesName=${config.seriesName ?? ''}
629
+ .showDataLabels=${config.showDataLabels ?? true}
630
+ .options=${mergedOptions}
631
+ .loading=${config.loading ?? false}
632
+ ></nile-funnel-chart>`;
633
+ case 'organization':
634
+ return html `<nile-organization-chart
635
+ .nodes=${config.nodes}
636
+ .links=${config.links}
637
+ .height=${config.height ?? '480px'}
638
+ .seriesName=${config.seriesName ?? ''}
639
+ .inverted=${config.inverted ?? true}
640
+ .options=${mergedOptions}
641
+ .loading=${config.loading ?? false}
642
+ ></nile-organization-chart>`;
643
+ case 'line-column':
644
+ return html `<nile-line-column-chart
645
+ .categories=${config.categories}
646
+ .columnSeries=${config.columnSeries}
647
+ .lineSeries=${config.lineSeries}
648
+ .height=${config.height ?? '400px'}
649
+ .columnAxisTitle=${config.columnAxisTitle ?? ''}
650
+ .lineAxisTitle=${config.lineAxisTitle ?? ''}
651
+ .options=${mergedOptions}
652
+ .loading=${config.loading ?? false}
653
+ ></nile-line-column-chart>`;
654
+ case 'heatmap':
655
+ return html `<nile-heatmap-chart
656
+ .xCategories=${config.xCategories}
657
+ .yCategories=${config.yCategories}
658
+ .data=${config.data}
659
+ .height=${config.height ?? '400px'}
660
+ .seriesName=${config.seriesName ?? ''}
661
+ .colorMin=${config.colorMin ?? null}
662
+ .colorMax=${config.colorMax ?? null}
663
+ .minColor=${config.minColor ?? '#ffffff'}
664
+ .maxColor=${config.maxColor ?? '#1e40af'}
665
+ .colorAxisTitle=${config.colorAxisTitle ?? ''}
666
+ .showDataLabels=${config.showDataLabels ?? true}
667
+ .options=${mergedOptions}
668
+ .loading=${config.loading ?? false}
669
+ ></nile-heatmap-chart>`;
670
+ case 'flame':
671
+ return html `<nile-flame-chart
672
+ .layout=${config.layout ?? 'flame'}
673
+ .data=${config.data ?? []}
674
+ .sunburstData=${config.sunburstData ?? []}
675
+ .height=${config.height ?? '480px'}
676
+ .options=${mergedOptions}
677
+ .loading=${config.loading ?? false}
678
+ ></nile-flame-chart>`;
679
+ case 'spiderweb':
680
+ return html `<nile-spiderweb-chart
681
+ .data=${config.data}
682
+ .categories=${config.categories ?? []}
683
+ .height=${config.height ?? '400px'}
684
+ .showArea=${config.showArea ?? false}
685
+ .options=${mergedOptions}
686
+ .loading=${config.loading ?? false}
687
+ ></nile-spiderweb-chart>`;
688
+ case 'invertedArea':
689
+ return html `<nile-inverted-area-chart
690
+ .data=${config.data}
691
+ .categories=${config.categories ?? []}
692
+ .height=${config.height ?? '400px'}
693
+ .yAxisTitle=${config.yAxisTitle ?? ''}
694
+ .stacked=${config.stacked ?? false}
695
+ .options=${mergedOptions}
696
+ .loading=${config.loading ?? false}
697
+ ></nile-inverted-area-chart>`;
698
+ case 'columnPyramid':
699
+ return html `<nile-column-pyramid-chart
700
+ .data=${config.data}
701
+ .categories=${config.categories ?? []}
702
+ .height=${config.height ?? '400px'}
703
+ .options=${mergedOptions}
704
+ .loading=${config.loading ?? false}
705
+ ></nile-column-pyramid-chart>`;
706
+ case 'lollipop':
707
+ return html `<nile-lollipop-chart
708
+ .data=${config.data}
709
+ .categories=${config.categories ?? []}
710
+ .height=${config.height ?? '400px'}
711
+ .options=${mergedOptions}
712
+ .loading=${config.loading ?? false}
713
+ ></nile-lollipop-chart>`;
714
+ case 'areaSpline':
715
+ return html `<nile-area-spline-chart
716
+ .data=${config.data}
717
+ .categories=${config.categories ?? []}
718
+ .height=${config.height ?? '400px'}
719
+ .yAxisTitle=${config.yAxisTitle ?? ''}
720
+ .stacked=${config.stacked ?? false}
721
+ .options=${mergedOptions}
722
+ .loading=${config.loading ?? false}
723
+ ></nile-area-spline-chart>`;
724
+ case 'areaNegative':
725
+ return html `<nile-area-negative-chart
726
+ .data=${config.data}
727
+ .categories=${config.categories ?? []}
728
+ .height=${config.height ?? '400px'}
729
+ .yAxisTitle=${config.yAxisTitle ?? ''}
730
+ .threshold=${config.threshold ?? 0}
731
+ .options=${mergedOptions}
732
+ .loading=${config.loading ?? false}
733
+ ></nile-area-negative-chart>`;
734
+ case 'areaRange':
735
+ return html `<nile-area-range-chart
736
+ .data=${config.data}
737
+ .categories=${config.categories ?? []}
738
+ .height=${config.height ?? '400px'}
739
+ .yAxisTitle=${config.yAxisTitle ?? ''}
740
+ .options=${mergedOptions}
741
+ .loading=${config.loading ?? false}
742
+ ></nile-area-range-chart>`;
743
+ case 'columnRange':
744
+ return html `<nile-column-range-chart
745
+ .data=${config.data}
746
+ .categories=${config.categories ?? []}
747
+ .height=${config.height ?? '400px'}
748
+ .yAxisTitle=${config.yAxisTitle ?? ''}
749
+ .options=${mergedOptions}
750
+ .loading=${config.loading ?? false}
751
+ ></nile-column-range-chart>`;
752
+ case 'columnDrilldown':
753
+ return html `<nile-column-drilldown-chart
754
+ .data=${config.data}
755
+ .drilldownSeries=${config.drilldownSeries}
756
+ .height=${config.height ?? '400px'}
757
+ .seriesName=${config.seriesName ?? ''}
758
+ .yAxisTitle=${config.yAxisTitle ?? ''}
759
+ .options=${mergedOptions}
760
+ .loading=${config.loading ?? false}
761
+ ></nile-column-drilldown-chart>`;
762
+ case 'radialBar':
763
+ return html `<nile-radial-bar-chart
764
+ .data=${config.data}
765
+ .categories=${config.categories}
766
+ .height=${config.height ?? '400px'}
767
+ .yAxisTitle=${config.yAxisTitle ?? ''}
768
+ .innerSize=${config.innerSize ?? '28%'}
769
+ .paneSize=${config.paneSize ?? '82%'}
770
+ .options=${mergedOptions}
771
+ .loading=${config.loading ?? false}
772
+ ></nile-radial-bar-chart>`;
773
+ case 'variablePie':
774
+ return html `<nile-variable-pie-chart
775
+ .data=${config.data}
776
+ .height=${config.height ?? '400px'}
777
+ .seriesName=${config.seriesName ?? ''}
778
+ .showDataLabels=${config.showDataLabels ?? true}
779
+ .showLegend=${config.showLegend ?? true}
780
+ .options=${mergedOptions}
781
+ .loading=${config.loading ?? false}
782
+ ></nile-variable-pie-chart>`;
783
+ case 'euler':
784
+ return html `<nile-euler-chart
785
+ .data=${config.data}
786
+ .height=${config.height ?? '400px'}
787
+ .options=${mergedOptions}
788
+ .loading=${config.loading ?? false}
789
+ ></nile-euler-chart>`;
790
+ case 'polygon':
791
+ return html `<nile-polygon-chart
792
+ .series=${config.series}
793
+ .height=${config.height ?? '400px'}
794
+ .xAxisTitle=${config.xAxisTitle ?? ''}
795
+ .yAxisTitle=${config.yAxisTitle ?? ''}
796
+ .options=${mergedOptions}
797
+ .loading=${config.loading ?? false}
798
+ ></nile-polygon-chart>`;
799
+ case 'vector':
800
+ return html `<nile-vector-chart
801
+ .data=${config.data}
802
+ .height=${config.height ?? '400px'}
803
+ .seriesName=${config.seriesName ?? ''}
804
+ .xAxisTitle=${config.xAxisTitle ?? ''}
805
+ .yAxisTitle=${config.yAxisTitle ?? ''}
806
+ .options=${mergedOptions}
807
+ .loading=${config.loading ?? false}
808
+ ></nile-vector-chart>`;
809
+ case 'xrange':
810
+ return html `<nile-xrange-chart
811
+ .data=${config.data}
812
+ .categories=${config.categories}
813
+ .height=${config.height ?? '400px'}
814
+ .seriesName=${config.seriesName ?? ''}
815
+ .datetimeAxis=${config.datetimeAxis ?? false}
816
+ .options=${mergedOptions}
817
+ .loading=${config.loading ?? false}
818
+ ></nile-xrange-chart>`;
819
+ case 'kpi': {
820
+ const k = config;
821
+ return html `<nile-kpi-chart
822
+ .config=${{
823
+ chart: {
824
+ type: 'kpi',
825
+ variant: k.variant,
826
+ label: k.label,
827
+ value: k.value,
828
+ prefix: k.prefix,
829
+ suffix: k.suffix,
830
+ trendValue: k.trendValue,
831
+ trendDirection: k.trendDirection,
832
+ trendLabel: k.trendLabel,
833
+ description: k.description,
834
+ sparkline: k.sparkline,
835
+ sparklineColor: k.sparklineColor,
836
+ gaugeValue: k.gaugeValue,
837
+ gaugeMin: k.gaugeMin,
838
+ gaugeMax: k.gaugeMax,
839
+ gaugeColor: k.gaugeColor,
840
+ loading: k.loading,
841
+ options: k.options,
842
+ height: k.height,
843
+ },
844
+ aq: {
845
+ chartSubtitle: k.chartSubtitle,
846
+ },
847
+ }}
848
+ ></nile-kpi-chart>`;
849
+ }
850
+ default: {
851
+ const _exhaustive = config;
852
+ return _exhaustive;
853
+ }
371
854
  }
372
855
  }
373
856
  render() {
@@ -377,23 +860,10 @@ let NileChart = class NileChart extends NileElement {
377
860
  <div class="chart-wrapper">
378
861
  <div class="chart-inner">
379
862
  ${this.activeConfig ? this.renderChartContent() : html `<slot></slot>`}
380
- <button
381
- class="chart-toggle"
382
- aria-expanded="${this.open}"
383
- @click="${this.toggle}"
384
- >
385
- ${this.effectiveToggleLabel}
386
- </button>
387
- <div class="chart-overlay" ?data-open="${this.open}">
388
- <div class="chart-content">
389
- ${this.resolvedConfig
390
- ? this.effectiveSummary
391
- : html `<slot name="insight">${this.summary}</slot>`}
392
- </div>
393
- </div>
394
863
  ${this.renderAiPanel()}
395
864
  </div>
396
865
  </div>
866
+ <slot name="footer"></slot>
397
867
  </div>
398
868
  `;
399
869
  }
@@ -402,15 +872,12 @@ NileChart.styles = styles;
402
872
  __decorate([
403
873
  property({ type: Object })
404
874
  ], NileChart.prototype, "config", void 0);
875
+ __decorate([
876
+ property({ type: String, attribute: 'chart-type' })
877
+ ], NileChart.prototype, "chartTypeAttr", void 0);
405
878
  __decorate([
406
879
  property({ type: String })
407
880
  ], NileChart.prototype, "summary", void 0);
408
- __decorate([
409
- property({ type: String, attribute: 'toggle-label' })
410
- ], NileChart.prototype, "toggleLabel", void 0);
411
- __decorate([
412
- state()
413
- ], NileChart.prototype, "open", void 0);
414
881
  __decorate([
415
882
  state()
416
883
  ], NileChart.prototype, "activeType", void 0);
@@ -423,6 +890,12 @@ __decorate([
423
890
  __decorate([
424
891
  state()
425
892
  ], NileChart.prototype, "chatOpen", void 0);
893
+ __decorate([
894
+ state()
895
+ ], NileChart.prototype, "hasHeaderSlotContent", void 0);
896
+ __decorate([
897
+ state()
898
+ ], NileChart.prototype, "hasHeaderActionsSlot", void 0);
426
899
  __decorate([
427
900
  query('nile-ai-panel')
428
901
  ], NileChart.prototype, "aiPanel", void 0);