@aquera/nile-visualization 1.7.0 → 1.9.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 (111) hide show
  1. package/dist/src/index.d.ts +1 -1
  2. package/dist/src/internal/dashboard-adapters.d.ts +1 -0
  3. package/dist/src/internal/dashboard-adapters.js +11 -1
  4. package/dist/src/internal/highcharts-provider.d.ts +6 -0
  5. package/dist/src/internal/highcharts-provider.js +32 -0
  6. package/dist/src/internal/types/aq-config.type.d.ts +5 -0
  7. package/dist/src/nile-anomaly-chart/nile-anomaly-chart.css.js +2 -0
  8. package/dist/src/nile-anomaly-chart/nile-anomaly-chart.js +1 -1
  9. package/dist/src/nile-area-chart/nile-area-chart.css.js +2 -0
  10. package/dist/src/nile-area-chart/nile-area-chart.js +1 -1
  11. package/dist/src/nile-area-negative-chart/nile-area-negative-chart.css.js +2 -0
  12. package/dist/src/nile-area-negative-chart/nile-area-negative-chart.js +1 -1
  13. package/dist/src/nile-area-range-chart/nile-area-range-chart.css.js +2 -0
  14. package/dist/src/nile-area-range-chart/nile-area-range-chart.js +1 -1
  15. package/dist/src/nile-area-spline-chart/nile-area-spline-chart.css.js +2 -0
  16. package/dist/src/nile-area-spline-chart/nile-area-spline-chart.js +1 -1
  17. package/dist/src/nile-bar-chart/nile-bar-chart.css.js +2 -0
  18. package/dist/src/nile-bar-chart/nile-bar-chart.js +1 -1
  19. package/dist/src/nile-bellcurve-chart/nile-bellcurve-chart.css.js +2 -0
  20. package/dist/src/nile-bellcurve-chart/nile-bellcurve-chart.js +1 -1
  21. package/dist/src/nile-boxplot-chart/nile-boxplot-chart.css.js +2 -0
  22. package/dist/src/nile-boxplot-chart/nile-boxplot-chart.js +1 -1
  23. package/dist/src/nile-bubble-chart/nile-bubble-chart.css.js +2 -0
  24. package/dist/src/nile-bubble-chart/nile-bubble-chart.js +1 -1
  25. package/dist/src/nile-chart/index.d.ts +1 -1
  26. package/dist/src/nile-chart/nile-chart-config.d.ts +69 -1
  27. package/dist/src/nile-chart/nile-chart.css.d.ts +1 -0
  28. package/dist/src/nile-chart/nile-chart.css.js +194 -82
  29. package/dist/src/nile-chart/nile-chart.d.ts +25 -6
  30. package/dist/src/nile-chart/nile-chart.js +241 -100
  31. package/dist/src/nile-cluster-chart/nile-cluster-chart.css.js +2 -0
  32. package/dist/src/nile-cluster-chart/nile-cluster-chart.js +1 -1
  33. package/dist/src/nile-column-chart/nile-column-chart.css.js +2 -0
  34. package/dist/src/nile-column-chart/nile-column-chart.js +1 -1
  35. package/dist/src/nile-column-drilldown-chart/nile-column-drilldown-chart.css.js +2 -0
  36. package/dist/src/nile-column-drilldown-chart/nile-column-drilldown-chart.js +1 -1
  37. package/dist/src/nile-column-pyramid-chart/nile-column-pyramid-chart.css.js +2 -0
  38. package/dist/src/nile-column-pyramid-chart/nile-column-pyramid-chart.js +1 -1
  39. package/dist/src/nile-column-range-chart/nile-column-range-chart.css.js +2 -0
  40. package/dist/src/nile-column-range-chart/nile-column-range-chart.js +1 -1
  41. package/dist/src/nile-dashboard-viewer/nile-dashboard-viewer.css.js +10 -0
  42. package/dist/src/nile-dashboard-viewer/nile-dashboard-viewer.d.ts +15 -6
  43. package/dist/src/nile-dashboard-viewer/nile-dashboard-viewer.js +47 -6
  44. package/dist/src/nile-donut-chart/nile-donut-chart.css.js +2 -0
  45. package/dist/src/nile-donut-chart/nile-donut-chart.js +1 -1
  46. package/dist/src/nile-dumbbell-chart/nile-dumbbell-chart.css.js +2 -0
  47. package/dist/src/nile-dumbbell-chart/nile-dumbbell-chart.js +1 -1
  48. package/dist/src/nile-dumbbell-lower-chart/nile-dumbbell-lower-chart.css.js +2 -0
  49. package/dist/src/nile-dumbbell-lower-chart/nile-dumbbell-lower-chart.js +1 -1
  50. package/dist/src/nile-dumbbell-upper-chart/nile-dumbbell-upper-chart.css.js +2 -0
  51. package/dist/src/nile-dumbbell-upper-chart/nile-dumbbell-upper-chart.js +1 -1
  52. package/dist/src/nile-euler-chart/nile-euler-chart.css.js +2 -0
  53. package/dist/src/nile-euler-chart/nile-euler-chart.js +1 -1
  54. package/dist/src/nile-fan-chart/nile-fan-chart.css.js +2 -0
  55. package/dist/src/nile-fan-chart/nile-fan-chart.js +1 -1
  56. package/dist/src/nile-flame-chart/nile-flame-chart.css.js +2 -0
  57. package/dist/src/nile-flame-chart/nile-flame-chart.js +1 -1
  58. package/dist/src/nile-funnel-chart/nile-funnel-chart.css.js +2 -0
  59. package/dist/src/nile-funnel-chart/nile-funnel-chart.js +1 -1
  60. package/dist/src/nile-gauge-chart/nile-gauge-chart.css.js +2 -0
  61. package/dist/src/nile-gauge-chart/nile-gauge-chart.js +1 -1
  62. package/dist/src/nile-heatmap-chart/nile-heatmap-chart.css.js +2 -0
  63. package/dist/src/nile-heatmap-chart/nile-heatmap-chart.js +1 -1
  64. package/dist/src/nile-histogram-chart/nile-histogram-chart.css.js +2 -0
  65. package/dist/src/nile-histogram-chart/nile-histogram-chart.js +1 -1
  66. package/dist/src/nile-inverted-area-chart/nile-inverted-area-chart.css.js +2 -0
  67. package/dist/src/nile-inverted-area-chart/nile-inverted-area-chart.js +1 -1
  68. package/dist/src/nile-kpi-chart/nile-kpi-chart.css.js +54 -3
  69. package/dist/src/nile-kpi-chart/nile-kpi-chart.d.ts +29 -1
  70. package/dist/src/nile-kpi-chart/nile-kpi-chart.js +164 -9
  71. package/dist/src/nile-line-chart/nile-line-chart.css.js +2 -0
  72. package/dist/src/nile-line-chart/nile-line-chart.js +1 -1
  73. package/dist/src/nile-line-column-chart/nile-line-column-chart.css.js +2 -0
  74. package/dist/src/nile-line-column-chart/nile-line-column-chart.js +1 -1
  75. package/dist/src/nile-lollipop-chart/nile-lollipop-chart.css.js +2 -0
  76. package/dist/src/nile-lollipop-chart/nile-lollipop-chart.js +1 -1
  77. package/dist/src/nile-map-chart/nile-map-chart.css.js +2 -0
  78. package/dist/src/nile-map-chart/nile-map-chart.js +1 -1
  79. package/dist/src/nile-organization-chart/nile-organization-chart.css.js +2 -0
  80. package/dist/src/nile-organization-chart/nile-organization-chart.js +1 -1
  81. package/dist/src/nile-pie-chart/nile-pie-chart.css.js +2 -0
  82. package/dist/src/nile-pie-chart/nile-pie-chart.js +1 -1
  83. package/dist/src/nile-polygon-chart/nile-polygon-chart.css.js +2 -0
  84. package/dist/src/nile-polygon-chart/nile-polygon-chart.js +1 -1
  85. package/dist/src/nile-radar-chart/nile-radar-chart.css.js +2 -0
  86. package/dist/src/nile-radar-chart/nile-radar-chart.js +1 -1
  87. package/dist/src/nile-radial-bar-chart/nile-radial-bar-chart.css.js +2 -0
  88. package/dist/src/nile-radial-bar-chart/nile-radial-bar-chart.js +1 -1
  89. package/dist/src/nile-scatter-chart/nile-scatter-chart.css.js +2 -0
  90. package/dist/src/nile-scatter-chart/nile-scatter-chart.js +1 -1
  91. package/dist/src/nile-spiderweb-chart/nile-spiderweb-chart.css.js +2 -0
  92. package/dist/src/nile-spiderweb-chart/nile-spiderweb-chart.js +1 -1
  93. package/dist/src/nile-spline-chart/nile-spline-chart.css.js +2 -0
  94. package/dist/src/nile-spline-chart/nile-spline-chart.js +1 -1
  95. package/dist/src/nile-stacked-chart/nile-stacked-chart.css.js +2 -0
  96. package/dist/src/nile-stacked-chart/nile-stacked-chart.js +1 -1
  97. package/dist/src/nile-timeline-chart/nile-timeline-chart.css.js +2 -0
  98. package/dist/src/nile-timeline-chart/nile-timeline-chart.js +1 -1
  99. package/dist/src/nile-trendline-chart/nile-trendline-chart.css.js +2 -0
  100. package/dist/src/nile-trendline-chart/nile-trendline-chart.js +1 -1
  101. package/dist/src/nile-variable-pie-chart/nile-variable-pie-chart.css.js +2 -0
  102. package/dist/src/nile-variable-pie-chart/nile-variable-pie-chart.js +1 -1
  103. package/dist/src/nile-vector-chart/nile-vector-chart.css.js +2 -0
  104. package/dist/src/nile-vector-chart/nile-vector-chart.js +1 -1
  105. package/dist/src/nile-waterfall-chart/nile-waterfall-chart.css.js +2 -0
  106. package/dist/src/nile-waterfall-chart/nile-waterfall-chart.js +1 -1
  107. package/dist/src/nile-widget-viewer/nile-widget-viewer.d.ts +4 -0
  108. package/dist/src/nile-widget-viewer/nile-widget-viewer.js +18 -2
  109. package/dist/src/nile-xrange-chart/nile-xrange-chart.css.js +2 -0
  110. package/dist/src/nile-xrange-chart/nile-xrange-chart.js +1 -1
  111. package/package.json +1 -1
@@ -2,9 +2,17 @@ import { __decorate } from "tslib";
2
2
  import { customElement, property, query, state } from 'lit/decorators.js';
3
3
  import { html, nothing } from 'lit';
4
4
  import NileElement from '../internal/nile-element.js';
5
- import { styles } from './nile-chart.css.js';
5
+ import { styles, tooltipCss } from './nile-chart.css.js';
6
6
  import { nileChartConfig } from './nile-chart-config-builder.js';
7
7
  import { convertConfig } from '../internal/chart-adapters.js';
8
+ import { deepMerge } from '../internal/utils.js';
9
+ import { initNileChartExporting, getHighcharts } from '../internal/highcharts-provider.js';
10
+ // Start loading exporting/offline-exporting/export-data at module import time.
11
+ // `chart.fullscreen` is attached via a `beforeRender` hook installed by the exporting module's
12
+ // compose step, so if a chart is constructed before the module applies, that instance will have
13
+ // no `fullscreen`. Kicking the load off here gives it a head start; handlers still await it
14
+ // before invoking methods, and viewFullscreen falls back to the DOM Fullscreen API.
15
+ initNileChartExporting();
8
16
  import '../nile-bar-chart/index.js';
9
17
  import '../nile-pie-chart/index.js';
10
18
  import '../nile-trendline-chart/index.js';
@@ -100,9 +108,20 @@ function chartTypeLabel(type) {
100
108
  .replace(/-/g, ' ')
101
109
  .replace(/\b\w/g, ch => ch.toUpperCase());
102
110
  }
111
+ let _headerTooltipStylesInjected = false;
112
+ function ensureHeaderTooltipStyles() {
113
+ if (_headerTooltipStylesInjected || typeof document === 'undefined')
114
+ return;
115
+ const style = document.createElement('style');
116
+ style.dataset['nilechart'] = '';
117
+ style.textContent = tooltipCss;
118
+ document.head.appendChild(style);
119
+ _headerTooltipStylesInjected = true;
120
+ }
103
121
  let NileChart = class NileChart extends NileElement {
104
122
  constructor() {
105
123
  super(...arguments);
124
+ this._headerTipEl = null;
106
125
  /** Full chart configuration. Accepts flat NileChartConfig or separated { chart, aq } input. */
107
126
  this.config = null;
108
127
  /**
@@ -122,16 +141,22 @@ let NileChart = class NileChart extends NileElement {
122
141
  */
123
142
  this.chartTypeAttr = '';
124
143
  /** Summary/insight text — shown as the AI panel's opening message when the chat is opened. */
144
+ this.summary = '';
125
145
  /**
126
- * When set, fills `chart.type` if the config omits it (same values as `chart.type`, e.g. `stacked`, `pie`).
127
- * Usage: `<nile-chart chart-type="pie" />` plus `config.chart` with series data only.
146
+ * Controls which items appear in the actions menu. All items are opt-in
147
+ * only items explicitly set to `true` are shown. Merged with (and takes
148
+ * priority over) `config.menu`.
149
+ *
150
+ * @example
151
+ * // PNG + CSV only
152
+ * chart.menu = { enabled: true, downloadPng: true, downloadCsv: true }
128
153
  */
129
- /** Summary/insight text — shown as the AI panel's opening message when the chat is opened. */
130
- this.summary = '';
154
+ this.menu = null;
131
155
  this.activeType = null;
132
156
  this.activeConfig = null;
133
157
  this.menuOpen = false;
134
158
  this.chatOpen = false;
159
+ this._hcChart = null;
135
160
  /** True when elements are projected into the `header` slot (default title/subtitle hidden). */
136
161
  this.hasHeaderSlotContent = false;
137
162
  /** True when elements are projected into `header-actions` (used to show the header row). */
@@ -142,7 +167,24 @@ let NileChart = class NileChart extends NileElement {
142
167
  this.chatOpen = false;
143
168
  }
144
169
  };
170
+ this.handleChartReady = (e) => {
171
+ this._hcChart = e.detail?.chart ?? null;
172
+ };
145
173
  this.resolvedConfig = null;
174
+ this._onTitleEnter = (e) => {
175
+ const el = e.currentTarget;
176
+ if (el.scrollWidth <= el.clientWidth)
177
+ return;
178
+ const rect = el.getBoundingClientRect();
179
+ this._showHeaderTip(el.textContent ?? '', rect.left + rect.width / 2, rect.top);
180
+ };
181
+ this._onSubtitleEnter = (e) => {
182
+ const el = e.currentTarget;
183
+ if (el.scrollWidth <= el.clientWidth)
184
+ return;
185
+ const rect = el.getBoundingClientRect();
186
+ this._showHeaderTip(el.textContent ?? '', rect.left + rect.width / 2, rect.top);
187
+ };
146
188
  }
147
189
  get effectiveSummary() {
148
190
  return this.resolvedConfig?.summary ?? this.summary;
@@ -153,7 +195,14 @@ let NileChart = class NileChart extends NileElement {
153
195
  }
154
196
  connectedCallback() {
155
197
  super.connectedCallback();
198
+ ensureHeaderTooltipStyles();
199
+ const tip = document.createElement('div');
200
+ tip.className = 'nile-chart-header-tooltip';
201
+ document.body.appendChild(tip);
202
+ this._headerTipEl = tip;
156
203
  document.addEventListener('click', this.handleOutsideClick);
204
+ this.addEventListener('nile-chart-ready', this.handleChartReady);
205
+ initNileChartExporting();
157
206
  // Pick up config set before element upgrade (e.g. Angular ngAfterViewInit)
158
207
  if (this.config && !this.resolvedConfig) {
159
208
  this.resolvedConfig = this.resolveConfig(this.config);
@@ -164,6 +213,9 @@ let NileChart = class NileChart extends NileElement {
164
213
  disconnectedCallback() {
165
214
  super.disconnectedCallback();
166
215
  document.removeEventListener('click', this.handleOutsideClick);
216
+ this.removeEventListener('nile-chart-ready', this.handleChartReady);
217
+ this._headerTipEl?.remove();
218
+ this._headerTipEl = null;
167
219
  }
168
220
  mergeChartTypeFromAttr(chart) {
169
221
  const t = this.chartTypeAttr?.trim();
@@ -278,7 +330,8 @@ let NileChart = class NileChart extends NileElement {
278
330
  }
279
331
  shouldShowHeader() {
280
332
  const hasTitles = !!(this.headerTitle || this.headerSubtitle);
281
- const hasBuiltinActions = this.aiEnabled || (this.resolvedConfig?.switchableTypes?.length ?? 0) > 0;
333
+ const menuEnabled = this.resolvedConfig?.menu?.enabled === true || this.menu?.enabled === true;
334
+ const hasBuiltinActions = this.aiEnabled || (this.resolvedConfig?.switchableTypes?.length ?? 0) > 0 || menuEnabled;
282
335
  return (hasTitles ||
283
336
  this.hasHeaderSlotContent ||
284
337
  this.hasHeaderActionsSlot ||
@@ -286,36 +339,102 @@ let NileChart = class NileChart extends NileElement {
286
339
  this.lightDomHasSlot('header-actions') ||
287
340
  hasBuiltinActions);
288
341
  }
289
- renderTypeSwitcher() {
290
- const types = this.resolvedConfig?.switchableTypes;
291
- if (!types || types.length === 0)
342
+ buildExportingOptions() {
343
+ return { exporting: { enabled: true, buttons: { contextButton: { enabled: false } } } };
344
+ }
345
+ /** Ensures exporting modules are loaded and the chart's exporting/fullscreen instances exist. */
346
+ async ensureExporting() {
347
+ await initNileChartExporting();
348
+ const chart = this._hcChart;
349
+ if (chart && !chart.exporting) {
350
+ const HC = await getHighcharts();
351
+ HC.fireEvent(chart, 'afterInit');
352
+ }
353
+ }
354
+ async viewFullscreen() {
355
+ this.menuOpen = false;
356
+ await this.ensureExporting();
357
+ if (this._hcChart?.fullscreen?.open) {
358
+ this._hcChart.fullscreen.open();
359
+ return;
360
+ }
361
+ const target = this.shadowRoot?.querySelector('.nile-chart-card') ?? this;
362
+ target.requestFullscreen?.();
363
+ }
364
+ async printChart() {
365
+ this.menuOpen = false;
366
+ await this.ensureExporting();
367
+ this._hcChart?.print?.();
368
+ }
369
+ async exportChart(type) {
370
+ this.menuOpen = false;
371
+ await this.ensureExporting();
372
+ const filename = (this.headerTitle || 'chart').replace(/[^a-z0-9_-]+/gi, '_');
373
+ this._hcChart?.exportChartLocal?.({ type, filename, local: true });
374
+ }
375
+ async downloadCsv() {
376
+ this.menuOpen = false;
377
+ await this.ensureExporting();
378
+ this._hcChart?.downloadCSV?.();
379
+ }
380
+ renderActionsMenu() {
381
+ if (!this.resolvedConfig)
292
382
  return nothing;
383
+ const menuCfg = { ...(this.resolvedConfig.menu ?? {}), ...(this.menu ?? {}) };
384
+ if (menuCfg.enabled !== true)
385
+ return nothing;
386
+ const types = this.resolvedConfig.switchableTypes;
387
+ const allItems = [
388
+ ...(this.resolvedConfig.menuItems ?? []),
389
+ ...(menuCfg.items ?? []),
390
+ ];
391
+ const hasChart = !!this._hcChart;
392
+ const hasAnyItems = !!(types?.length || allItems.length);
293
393
  return html `
294
- <div class="chart-menu-anchor">
394
+ <div class="nile-chart-menu-anchor">
295
395
  <button
296
- class="chart-menu-trigger"
396
+ type="button"
397
+ class="nile-chart-menu-trigger"
297
398
  aria-haspopup="true"
298
399
  aria-expanded=${this.menuOpen ? 'true' : 'false'}
299
- aria-label="Change chart type"
300
- @click=${this.toggleMenu}
400
+ aria-label="Chart actions"
401
+ @click=${(e) => this.toggleMenu(e)}
301
402
  >
302
403
  <nile-glyph name="options" size="16"></nile-glyph>
303
404
  </button>
304
- ${this.menuOpen
305
- ? html `
306
- <div class="chart-menu-dropdown" role="menu" aria-label="Chart type">
307
- ${types.map(type => html `
308
- <button
309
- class="chart-menu-item ${type === this.activeType ? 'active' : ''}"
310
- role="menuitem"
311
- @click=${() => this.switchType(type)}
312
- >
313
- ${chartTypeLabel(type)} chart
314
- </button>
315
- `)}
316
- </div>
317
- `
318
- : nothing}
405
+ ${this.menuOpen && hasAnyItems ? html `
406
+ <div class="nile-chart-menu-dropdown" role="menu">
407
+ ${types?.length ? html `
408
+ ${types.map(type => html `
409
+ <button type="button" class="nile-chart-menu-item ${type === this.activeType ? 'active' : ''}" role="menuitem" @click=${() => this.switchType(type)}>
410
+ ${chartTypeLabel(type)}
411
+ </button>
412
+ `)}
413
+ ${allItems.length ? html `<div class="nile-chart-menu-separator"></div>` : nothing}
414
+ ` : nothing}
415
+ ${allItems.map(item => {
416
+ if (item.type === 'custom') {
417
+ return html `
418
+ ${item.divider ? html `<div class="nile-chart-menu-separator"></div>` : nothing}
419
+ <button type="button" class="nile-chart-menu-item" role="menuitem"
420
+ @click=${() => { this.menuOpen = false; this.emit('nile-menu-change', { id: item.id }); }}>
421
+ ${item.label}
422
+ </button>
423
+ `;
424
+ }
425
+ if (!hasChart)
426
+ return nothing;
427
+ return html `
428
+ ${item.divider ? html `<div class="nile-chart-menu-separator"></div>` : nothing}
429
+ ${item.fullscreen ? html `<button type="button" class="nile-chart-menu-item" role="menuitem" @click=${() => this.viewFullscreen()}>${item.label ?? 'Fullscreen'}</button>` : nothing}
430
+ ${item.print ? html `<button type="button" class="nile-chart-menu-item" role="menuitem" @click=${() => this.printChart()}>${item.label ?? 'Print'}</button>` : nothing}
431
+ ${item.downloadPng ? html `<button type="button" class="nile-chart-menu-item" role="menuitem" @click=${() => this.exportChart('image/png')}>${item.label ?? 'Download PNG'}</button>` : nothing}
432
+ ${item.downloadSvg ? html `<button type="button" class="nile-chart-menu-item" role="menuitem" @click=${() => this.exportChart('image/svg+xml')}>${item.label ?? 'Download SVG'}</button>` : nothing}
433
+ ${item.downloadCsv ? html `<button type="button" class="nile-chart-menu-item" role="menuitem" @click=${() => this.downloadCsv()}>${item.label ?? 'Download CSV'}</button>` : nothing}
434
+ `;
435
+ })}
436
+ </div>
437
+ ` : nothing}
319
438
  </div>
320
439
  `;
321
440
  }
@@ -324,16 +443,28 @@ let NileChart = class NileChart extends NileElement {
324
443
  return nothing;
325
444
  return html `
326
445
  <button
327
- class="ai-trigger ${this.chatOpen ? 'active' : ''}"
446
+ class="nile-ai-trigger ${this.chatOpen ? 'active' : ''}"
328
447
  aria-label="Ask AI about this chart"
329
448
  aria-expanded=${this.chatOpen ? 'true' : 'false'}
330
449
  @click=${this.toggleChat}
331
450
  >
332
451
  <nile-glyph name="smart-code" size="16"></nile-glyph>
333
452
  </button>
334
- <slot name="ai-trigger-after"></slot>
453
+ <slot name="nile-ai-trigger-after"></slot>
335
454
  `;
336
455
  }
456
+ _showHeaderTip(text, x, y) {
457
+ if (!this._headerTipEl)
458
+ return;
459
+ this._headerTipEl.textContent = text;
460
+ this._headerTipEl.style.left = `${x}px`;
461
+ this._headerTipEl.style.top = `${y}px`;
462
+ this._headerTipEl.style.display = 'block';
463
+ }
464
+ _hideHeaderTip() {
465
+ if (this._headerTipEl)
466
+ this._headerTipEl.style.display = 'none';
467
+ }
337
468
  renderHeader() {
338
469
  if (!this.shouldShowHeader())
339
470
  return nothing;
@@ -342,20 +473,20 @@ let NileChart = class NileChart extends NileElement {
342
473
  const showDefaultTitles = !this.hasHeaderSlotContent && !!(title || subtitle);
343
474
  const headerCompact = !subtitle?.trim();
344
475
  return html `
345
- <div class="chart-header ${headerCompact ? 'chart-header--compact' : ''}">
346
- <div class="chart-header-titles">
476
+ <div class="nile-chart-header ${headerCompact ? 'nile-chart-header--compact' : ''}">
477
+ <div class="nile-chart-header-titles">
347
478
  <slot name="header" @slotchange=${this.onHeaderSlotChange}></slot>
348
479
  ${showDefaultTitles
349
480
  ? html `
350
- ${title ? html `<p class="chart-header-title">${title}</p>` : nothing}
351
- ${subtitle ? html `<p class="chart-header-subtitle">${subtitle}</p>` : nothing}
481
+ ${title ? html `<p class="nile-chart-header-title" @mouseenter=${this._onTitleEnter} @mouseleave=${() => this._hideHeaderTip()}>${title}</p>` : nothing}
482
+ ${subtitle ? html `<p class="nile-chart-header-subtitle" @mouseenter=${this._onSubtitleEnter} @mouseleave=${() => this._hideHeaderTip()}>${subtitle}</p>` : nothing}
352
483
  `
353
484
  : nothing}
354
485
  </div>
355
- <div class="chart-header-actions">
486
+ <div class="nile-chart-header-actions">
356
487
  <slot name="header-actions" @slotchange=${this.onHeaderActionsSlotChange}></slot>
357
488
  ${this.renderAiTrigger()}
358
- ${this.renderTypeSwitcher()}
489
+ ${this.renderActionsMenu()}
359
490
  </div>
360
491
  </div>
361
492
  `;
@@ -371,7 +502,7 @@ let NileChart = class NileChart extends NileElement {
371
502
  const summaryMessage = summary;
372
503
  const welcomeMessage = summary ? '' : (aiConfig?.welcomeMessage ?? '');
373
504
  return html `
374
- <div class="ai-panel-overlay" ?data-open=${this.chatOpen}>
505
+ <div class="nile-ai-panel-overlay" ?data-open=${this.chatOpen}>
375
506
  <nile-ai-panel
376
507
  .placeholder=${aiConfig?.placeholder ?? 'Ask about this chart...'}
377
508
  .welcomeMessage=${welcomeMessage}
@@ -385,13 +516,13 @@ let NileChart = class NileChart extends NileElement {
385
516
  const config = this.activeConfig;
386
517
  // Suppress inner Highcharts title/subtitle — the card header shows them
387
518
  const noTitle = { title: { text: undefined }, subtitle: { text: undefined } };
388
- const mergedOptions = { ...(config.options ?? {}), ...noTitle };
519
+ const mergedOptions = deepMerge(deepMerge(config.options ?? {}, noTitle), this.buildExportingOptions());
389
520
  switch (config.type) {
390
521
  case 'bar':
391
522
  return html `<nile-bar-chart
392
523
  .data=${config.data}
393
524
  .categories=${config.categories ?? []}
394
- .height=${config.height ?? '100%'}
525
+ .height=${this.hasAttribute('fit') ? null : (config.height ?? '100%')}
395
526
  .yAxisTitle=${config.yAxisTitle ?? ''}
396
527
  .showLegend=${config.showLegend ?? true}
397
528
  .options=${mergedOptions}
@@ -412,7 +543,7 @@ let NileChart = class NileChart extends NileElement {
412
543
  return html `<nile-pie-chart
413
544
  .data=${config.data}
414
545
  .seriesName=${config.seriesName ?? ''}
415
- .height=${config.height ?? '100%'}
546
+ .height=${this.hasAttribute('fit') ? null : (config.height ?? '100%')}
416
547
  .showDataLabels=${config.showDataLabels ?? true}
417
548
  .showLegend=${config.showLegend ?? true}
418
549
  .options=${mergedOptions}
@@ -433,7 +564,7 @@ let NileChart = class NileChart extends NileElement {
433
564
  return html `<nile-trendline-chart
434
565
  .data=${config.data}
435
566
  .categories=${config.categories ?? []}
436
- .height=${config.height ?? '100%'}
567
+ .height=${this.hasAttribute('fit') ? null : (config.height ?? '100%')}
437
568
  .yAxisTitle=${config.yAxisTitle ?? ''}
438
569
  .forecast=${config.forecast ?? null}
439
570
  .options=${mergedOptions}
@@ -454,7 +585,7 @@ let NileChart = class NileChart extends NileElement {
454
585
  return html `<nile-anomaly-chart
455
586
  .data=${config.data}
456
587
  .categories=${config.categories ?? []}
457
- .height=${config.height ?? '100%'}
588
+ .height=${this.hasAttribute('fit') ? null : (config.height ?? '100%')}
458
589
  .yAxisTitle=${config.yAxisTitle ?? ''}
459
590
  .anomaly=${config.anomaly ?? {}}
460
591
  .options=${mergedOptions}
@@ -475,7 +606,7 @@ let NileChart = class NileChart extends NileElement {
475
606
  return html `<nile-line-chart
476
607
  .data=${config.data}
477
608
  .categories=${config.categories ?? []}
478
- .height=${config.height ?? '100%'}
609
+ .height=${this.hasAttribute('fit') ? null : (config.height ?? '100%')}
479
610
  .yAxisTitle=${config.yAxisTitle ?? ''}
480
611
  .showLegend=${config.showLegend ?? true}
481
612
  .options=${mergedOptions}
@@ -496,7 +627,7 @@ let NileChart = class NileChart extends NileElement {
496
627
  return html `<nile-area-chart
497
628
  .data=${config.data}
498
629
  .categories=${config.categories ?? []}
499
- .height=${config.height ?? '100%'}
630
+ .height=${this.hasAttribute('fit') ? null : (config.height ?? '100%')}
500
631
  .yAxisTitle=${config.yAxisTitle ?? ''}
501
632
  .stacked=${config.stacked ?? false}
502
633
  .showLegend=${config.showLegend ?? true}
@@ -518,7 +649,7 @@ let NileChart = class NileChart extends NileElement {
518
649
  return html `<nile-column-chart
519
650
  .data=${config.data}
520
651
  .categories=${config.categories ?? []}
521
- .height=${config.height ?? '100%'}
652
+ .height=${this.hasAttribute('fit') ? null : (config.height ?? '100%')}
522
653
  .yAxisTitle=${config.yAxisTitle ?? ''}
523
654
  .showLegend=${config.showLegend ?? true}
524
655
  .options=${mergedOptions}
@@ -539,10 +670,9 @@ let NileChart = class NileChart extends NileElement {
539
670
  return html `<nile-donut-chart
540
671
  .data=${config.data}
541
672
  .seriesName=${config.seriesName ?? ''}
542
- .height=${config.height ?? '100%'}
673
+ .height=${this.hasAttribute('fit') ? null : (config.height ?? '100%')}
543
674
  .innerSize=${config.innerSize ?? '50%'}
544
675
  .semiCircle=${config.semiCircle ?? false}
545
- .semiCircle=${config.semiCircle ?? false}
546
676
  .showDataLabels=${config.showDataLabels ?? true}
547
677
  .showLegend=${config.showLegend ?? true}
548
678
  .options=${mergedOptions}
@@ -562,7 +692,7 @@ let NileChart = class NileChart extends NileElement {
562
692
  case 'scatter':
563
693
  return html `<nile-scatter-chart
564
694
  .data=${config.data}
565
- .height=${config.height ?? '100%'}
695
+ .height=${this.hasAttribute('fit') ? null : (config.height ?? '100%')}
566
696
  .xAxisTitle=${config.xAxisTitle ?? ''}
567
697
  .yAxisTitle=${config.yAxisTitle ?? ''}
568
698
  .showLegend=${config.showLegend ?? true}
@@ -583,7 +713,7 @@ let NileChart = class NileChart extends NileElement {
583
713
  case 'bubble':
584
714
  return html `<nile-bubble-chart
585
715
  .data=${config.data}
586
- .height=${config.height ?? '100%'}
716
+ .height=${this.hasAttribute('fit') ? null : (config.height ?? '100%')}
587
717
  .xAxisTitle=${config.xAxisTitle ?? ''}
588
718
  .yAxisTitle=${config.yAxisTitle ?? ''}
589
719
  .showLegend=${config.showLegend ?? true}
@@ -605,7 +735,7 @@ let NileChart = class NileChart extends NileElement {
605
735
  return html `<nile-spline-chart
606
736
  .data=${config.data}
607
737
  .categories=${config.categories ?? []}
608
- .height=${config.height ?? '100%'}
738
+ .height=${this.hasAttribute('fit') ? null : (config.height ?? '100%')}
609
739
  .yAxisTitle=${config.yAxisTitle ?? ''}
610
740
  .showLegend=${config.showLegend ?? true}
611
741
  .options=${mergedOptions}
@@ -626,7 +756,7 @@ let NileChart = class NileChart extends NileElement {
626
756
  return html `<nile-radar-chart
627
757
  .data=${config.data}
628
758
  .categories=${config.categories ?? []}
629
- .height=${config.height ?? '100%'}
759
+ .height=${this.hasAttribute('fit') ? null : (config.height ?? '100%')}
630
760
  .showArea=${config.showArea ?? false}
631
761
  .showLegend=${config.showLegend ?? true}
632
762
  .options=${mergedOptions}
@@ -650,7 +780,7 @@ let NileChart = class NileChart extends NileElement {
650
780
  .max=${config.max ?? 100}
651
781
  .suffix=${config.suffix ?? ''}
652
782
  .bands=${config.bands ?? []}
653
- .height=${config.height ?? '100%'}
783
+ .height=${this.hasAttribute('fit') ? null : (config.height ?? '100%')}
654
784
  .options=${mergedOptions}
655
785
  .loading=${config.loading ?? false}
656
786
  .chartBg=${config.chartBg ?? ''}
@@ -668,7 +798,7 @@ let NileChart = class NileChart extends NileElement {
668
798
  case 'waterfall':
669
799
  return html `<nile-waterfall-chart
670
800
  .data=${config.data}
671
- .height=${config.height ?? '100%'}
801
+ .height=${this.hasAttribute('fit') ? null : (config.height ?? '100%')}
672
802
  .yAxisTitle=${config.yAxisTitle ?? ''}
673
803
  .showLegend=${config.showLegend ?? true}
674
804
  .options=${mergedOptions}
@@ -692,7 +822,7 @@ let NileChart = class NileChart extends NileElement {
692
822
  .joinBy=${config.joinBy ?? ['hc-key', 'hc-key']}
693
823
  .seriesType=${config.seriesType ?? 'map'}
694
824
  .zoom=${config.zoom ?? true}
695
- .height=${config.height ?? '100%'}
825
+ .height=${this.hasAttribute('fit') ? null : (config.height ?? '100%')}
696
826
  .options=${mergedOptions}
697
827
  .loading=${config.loading ?? false}
698
828
  .chartBg=${config.chartBg ?? ''}
@@ -711,7 +841,7 @@ let NileChart = class NileChart extends NileElement {
711
841
  return html `<nile-stacked-chart
712
842
  .data=${config.data}
713
843
  .categories=${config.categories ?? []}
714
- .height=${config.height ?? '100%'}
844
+ .height=${this.hasAttribute('fit') ? null : (config.height ?? '100%')}
715
845
  .yAxisTitle=${config.yAxisTitle ?? ''}
716
846
  .stackMode=${config.stackMode ?? 'normal'}
717
847
  .showLegend=${config.showLegend ?? true}
@@ -734,7 +864,7 @@ let NileChart = class NileChart extends NileElement {
734
864
  return html `<nile-cluster-chart
735
865
  .data=${config.data}
736
866
  .categories=${config.categories ?? []}
737
- .height=${config.height ?? '100%'}
867
+ .height=${this.hasAttribute('fit') ? null : (config.height ?? '100%')}
738
868
  .yAxisTitle=${config.yAxisTitle ?? ''}
739
869
  .showLegend=${config.showLegend ?? true}
740
870
  .groupPadding=${config.groupPadding ?? 0.15}
@@ -756,7 +886,7 @@ let NileChart = class NileChart extends NileElement {
756
886
  case 'histogram':
757
887
  return html `<nile-histogram-chart
758
888
  .data=${config.data}
759
- .height=${config.height ?? '100%'}
889
+ .height=${this.hasAttribute('fit') ? null : (config.height ?? '100%')}
760
890
  .xAxisTitle=${config.xAxisTitle ?? ''}
761
891
  .yAxisTitle=${config.yAxisTitle ?? ''}
762
892
  .histogramSeriesName=${config.histogramSeriesName ?? ''}
@@ -782,7 +912,7 @@ let NileChart = class NileChart extends NileElement {
782
912
  case 'bellcurve':
783
913
  return html `<nile-bellcurve-chart
784
914
  .data=${config.data}
785
- .height=${config.height ?? '100%'}
915
+ .height=${this.hasAttribute('fit') ? null : (config.height ?? '100%')}
786
916
  .xAxisTitle=${config.xAxisTitle ?? ''}
787
917
  .yAxisTitle=${config.yAxisTitle ?? ''}
788
918
  .bellcurveSeriesName=${config.bellcurveSeriesName ?? ''}
@@ -810,7 +940,7 @@ let NileChart = class NileChart extends NileElement {
810
940
  return html `<nile-boxplot-chart
811
941
  .data=${config.data}
812
942
  .categories=${config.categories ?? []}
813
- .height=${config.height ?? '100%'}
943
+ .height=${this.hasAttribute('fit') ? null : (config.height ?? '100%')}
814
944
  .xAxisTitle=${config.xAxisTitle ?? ''}
815
945
  .yAxisTitle=${config.yAxisTitle ?? ''}
816
946
  .horizontal=${config.horizontal ?? false}
@@ -832,7 +962,7 @@ let NileChart = class NileChart extends NileElement {
832
962
  case 'timeline':
833
963
  return html `<nile-timeline-chart
834
964
  .data=${config.data}
835
- .height=${config.height ?? '100%'}
965
+ .height=${this.hasAttribute('fit') ? null : (config.height ?? '100%')}
836
966
  .seriesName=${config.seriesName ?? ''}
837
967
  .datetimeAxis=${config.datetimeAxis ?? false}
838
968
  .inverted=${config.inverted ?? false}
@@ -855,7 +985,7 @@ let NileChart = class NileChart extends NileElement {
855
985
  case 'dumbbell':
856
986
  return html `<nile-dumbbell-chart
857
987
  .data=${config.data}
858
- .height=${config.height ?? '100%'}
988
+ .height=${this.hasAttribute('fit') ? null : (config.height ?? '100%')}
859
989
  .yAxisTitle=${config.yAxisTitle ?? ''}
860
990
  .seriesName=${config.seriesName ?? ''}
861
991
  .lowMarkerColor=${config.lowMarkerColor ?? ''}
@@ -879,7 +1009,7 @@ let NileChart = class NileChart extends NileElement {
879
1009
  case 'dumbbellLower':
880
1010
  return html `<nile-dumbbell-lower-chart
881
1011
  .data=${config.data}
882
- .height=${config.height ?? '100%'}
1012
+ .height=${this.hasAttribute('fit') ? null : (config.height ?? '100%')}
883
1013
  .yAxisTitle=${config.yAxisTitle ?? ''}
884
1014
  .seriesName=${config.seriesName ?? ''}
885
1015
  .lowMarkerColor=${config.lowMarkerColor ?? ''}
@@ -903,7 +1033,7 @@ let NileChart = class NileChart extends NileElement {
903
1033
  case 'dumbbellUpper':
904
1034
  return html `<nile-dumbbell-upper-chart
905
1035
  .data=${config.data}
906
- .height=${config.height ?? '100%'}
1036
+ .height=${this.hasAttribute('fit') ? null : (config.height ?? '100%')}
907
1037
  .yAxisTitle=${config.yAxisTitle ?? ''}
908
1038
  .seriesName=${config.seriesName ?? ''}
909
1039
  .lowMarkerColor=${config.lowMarkerColor ?? ''}
@@ -928,7 +1058,7 @@ let NileChart = class NileChart extends NileElement {
928
1058
  return html `<nile-fan-chart
929
1059
  .lineData=${config.lineData}
930
1060
  .bands=${config.bands}
931
- .height=${config.height ?? '100%'}
1061
+ .height=${this.hasAttribute('fit') ? null : (config.height ?? '100%')}
932
1062
  .yAxisTitle=${config.yAxisTitle ?? ''}
933
1063
  .lineSeriesName=${config.lineSeriesName ?? ''}
934
1064
  .lineColor=${config.lineColor ?? '#1d4ed8'}
@@ -952,7 +1082,7 @@ let NileChart = class NileChart extends NileElement {
952
1082
  case 'funnel':
953
1083
  return html `<nile-funnel-chart
954
1084
  .data=${config.data}
955
- .height=${config.height ?? '100%'}
1085
+ .height=${this.hasAttribute('fit') ? null : (config.height ?? '100%')}
956
1086
  .seriesName=${config.seriesName ?? ''}
957
1087
  .showDataLabels=${config.showDataLabels ?? true}
958
1088
  .options=${mergedOptions}
@@ -973,7 +1103,7 @@ let NileChart = class NileChart extends NileElement {
973
1103
  return html `<nile-organization-chart
974
1104
  .nodes=${config.nodes}
975
1105
  .links=${config.links}
976
- .height=${config.height ?? '100%'}
1106
+ .height=${this.hasAttribute('fit') ? null : (config.height ?? '100%')}
977
1107
  .seriesName=${config.seriesName ?? ''}
978
1108
  .inverted=${config.inverted ?? true}
979
1109
  .options=${mergedOptions}
@@ -995,7 +1125,7 @@ let NileChart = class NileChart extends NileElement {
995
1125
  .categories=${config.categories}
996
1126
  .columnSeries=${config.columnSeries}
997
1127
  .lineSeries=${config.lineSeries}
998
- .height=${config.height ?? '100%'}
1128
+ .height=${this.hasAttribute('fit') ? null : (config.height ?? '100%')}
999
1129
  .columnAxisTitle=${config.columnAxisTitle ?? ''}
1000
1130
  .lineAxisTitle=${config.lineAxisTitle ?? ''}
1001
1131
  .options=${mergedOptions}
@@ -1017,7 +1147,7 @@ let NileChart = class NileChart extends NileElement {
1017
1147
  .xCategories=${config.xCategories}
1018
1148
  .yCategories=${config.yCategories}
1019
1149
  .data=${config.data}
1020
- .height=${config.height ?? '100%'}
1150
+ .height=${this.hasAttribute('fit') ? null : (config.height ?? '100%')}
1021
1151
  .seriesName=${config.seriesName ?? ''}
1022
1152
  .colorMin=${config.colorMin ?? null}
1023
1153
  .colorMax=${config.colorMax ?? null}
@@ -1045,7 +1175,7 @@ let NileChart = class NileChart extends NileElement {
1045
1175
  .layout=${config.layout ?? 'flame'}
1046
1176
  .data=${config.data ?? []}
1047
1177
  .sunburstData=${config.sunburstData ?? []}
1048
- .height=${config.height ?? '100%'}
1178
+ .height=${this.hasAttribute('fit') ? null : (config.height ?? '100%')}
1049
1179
  .options=${mergedOptions}
1050
1180
  .loading=${config.loading ?? false}
1051
1181
  .chartBg=${config.chartBg ?? ''}
@@ -1064,7 +1194,7 @@ let NileChart = class NileChart extends NileElement {
1064
1194
  return html `<nile-spiderweb-chart
1065
1195
  .data=${config.data}
1066
1196
  .categories=${config.categories ?? []}
1067
- .height=${config.height ?? '100%'}
1197
+ .height=${this.hasAttribute('fit') ? null : (config.height ?? '100%')}
1068
1198
  .showArea=${config.showArea ?? false}
1069
1199
  .showLegend=${config.showLegend ?? true}
1070
1200
  .options=${mergedOptions}
@@ -1085,7 +1215,7 @@ let NileChart = class NileChart extends NileElement {
1085
1215
  return html `<nile-inverted-area-chart
1086
1216
  .data=${config.data}
1087
1217
  .categories=${config.categories ?? []}
1088
- .height=${config.height ?? '100%'}
1218
+ .height=${this.hasAttribute('fit') ? null : (config.height ?? '100%')}
1089
1219
  .yAxisTitle=${config.yAxisTitle ?? ''}
1090
1220
  .stacked=${config.stacked ?? false}
1091
1221
  .options=${mergedOptions}
@@ -1106,7 +1236,7 @@ let NileChart = class NileChart extends NileElement {
1106
1236
  return html `<nile-column-pyramid-chart
1107
1237
  .data=${config.data}
1108
1238
  .categories=${config.categories ?? []}
1109
- .height=${config.height ?? '100%'}
1239
+ .height=${this.hasAttribute('fit') ? null : (config.height ?? '100%')}
1110
1240
  .options=${mergedOptions}
1111
1241
  .loading=${config.loading ?? false}
1112
1242
  .chartBg=${config.chartBg ?? ''}
@@ -1125,7 +1255,7 @@ let NileChart = class NileChart extends NileElement {
1125
1255
  return html `<nile-lollipop-chart
1126
1256
  .data=${config.data}
1127
1257
  .categories=${config.categories ?? []}
1128
- .height=${config.height ?? '100%'}
1258
+ .height=${this.hasAttribute('fit') ? null : (config.height ?? '100%')}
1129
1259
  .options=${mergedOptions}
1130
1260
  .loading=${config.loading ?? false}
1131
1261
  .chartBg=${config.chartBg ?? ''}
@@ -1144,7 +1274,7 @@ let NileChart = class NileChart extends NileElement {
1144
1274
  return html `<nile-area-spline-chart
1145
1275
  .data=${config.data}
1146
1276
  .categories=${config.categories ?? []}
1147
- .height=${config.height ?? '100%'}
1277
+ .height=${this.hasAttribute('fit') ? null : (config.height ?? '100%')}
1148
1278
  .yAxisTitle=${config.yAxisTitle ?? ''}
1149
1279
  .stacked=${config.stacked ?? false}
1150
1280
  .options=${mergedOptions}
@@ -1165,7 +1295,7 @@ let NileChart = class NileChart extends NileElement {
1165
1295
  return html `<nile-area-negative-chart
1166
1296
  .data=${config.data}
1167
1297
  .categories=${config.categories ?? []}
1168
- .height=${config.height ?? '100%'}
1298
+ .height=${this.hasAttribute('fit') ? null : (config.height ?? '100%')}
1169
1299
  .yAxisTitle=${config.yAxisTitle ?? ''}
1170
1300
  .threshold=${config.threshold ?? 0}
1171
1301
  .options=${mergedOptions}
@@ -1186,7 +1316,7 @@ let NileChart = class NileChart extends NileElement {
1186
1316
  return html `<nile-area-range-chart
1187
1317
  .data=${config.data}
1188
1318
  .categories=${config.categories ?? []}
1189
- .height=${config.height ?? '100%'}
1319
+ .height=${this.hasAttribute('fit') ? null : (config.height ?? '100%')}
1190
1320
  .yAxisTitle=${config.yAxisTitle ?? ''}
1191
1321
  .options=${mergedOptions}
1192
1322
  .loading=${config.loading ?? false}
@@ -1206,7 +1336,7 @@ let NileChart = class NileChart extends NileElement {
1206
1336
  return html `<nile-column-range-chart
1207
1337
  .data=${config.data}
1208
1338
  .categories=${config.categories ?? []}
1209
- .height=${config.height ?? '100%'}
1339
+ .height=${this.hasAttribute('fit') ? null : (config.height ?? '100%')}
1210
1340
  .yAxisTitle=${config.yAxisTitle ?? ''}
1211
1341
  .options=${mergedOptions}
1212
1342
  .loading=${config.loading ?? false}
@@ -1226,7 +1356,7 @@ let NileChart = class NileChart extends NileElement {
1226
1356
  return html `<nile-column-drilldown-chart
1227
1357
  .data=${config.data}
1228
1358
  .drilldownSeries=${config.drilldownSeries}
1229
- .height=${config.height ?? '100%'}
1359
+ .height=${this.hasAttribute('fit') ? null : (config.height ?? '100%')}
1230
1360
  .seriesName=${config.seriesName ?? ''}
1231
1361
  .yAxisTitle=${config.yAxisTitle ?? ''}
1232
1362
  .options=${mergedOptions}
@@ -1247,7 +1377,7 @@ let NileChart = class NileChart extends NileElement {
1247
1377
  return html `<nile-radial-bar-chart
1248
1378
  .data=${config.data}
1249
1379
  .categories=${config.categories}
1250
- .height=${config.height ?? '100%'}
1380
+ .height=${this.hasAttribute('fit') ? null : (config.height ?? '100%')}
1251
1381
  .yAxisTitle=${config.yAxisTitle ?? ''}
1252
1382
  .innerSize=${config.innerSize ?? '28%'}
1253
1383
  .paneSize=${config.paneSize ?? '82%'}
@@ -1269,7 +1399,7 @@ let NileChart = class NileChart extends NileElement {
1269
1399
  case 'variablePie':
1270
1400
  return html `<nile-variable-pie-chart
1271
1401
  .data=${config.data}
1272
- .height=${config.height ?? '100%'}
1402
+ .height=${this.hasAttribute('fit') ? null : (config.height ?? '100%')}
1273
1403
  .seriesName=${config.seriesName ?? ''}
1274
1404
  .showDataLabels=${config.showDataLabels ?? true}
1275
1405
  .showLegend=${config.showLegend ?? true}
@@ -1290,7 +1420,7 @@ let NileChart = class NileChart extends NileElement {
1290
1420
  case 'euler':
1291
1421
  return html `<nile-euler-chart
1292
1422
  .data=${config.data}
1293
- .height=${config.height ?? '100%'}
1423
+ .height=${this.hasAttribute('fit') ? null : (config.height ?? '100%')}
1294
1424
  .options=${mergedOptions}
1295
1425
  .loading=${config.loading ?? false}
1296
1426
  .chartBg=${config.chartBg ?? ''}
@@ -1308,7 +1438,7 @@ let NileChart = class NileChart extends NileElement {
1308
1438
  case 'polygon':
1309
1439
  return html `<nile-polygon-chart
1310
1440
  .series=${config.series}
1311
- .height=${config.height ?? '100%'}
1441
+ .height=${this.hasAttribute('fit') ? null : (config.height ?? '100%')}
1312
1442
  .xAxisTitle=${config.xAxisTitle ?? ''}
1313
1443
  .yAxisTitle=${config.yAxisTitle ?? ''}
1314
1444
  .options=${mergedOptions}
@@ -1328,7 +1458,7 @@ let NileChart = class NileChart extends NileElement {
1328
1458
  case 'vector':
1329
1459
  return html `<nile-vector-chart
1330
1460
  .data=${config.data}
1331
- .height=${config.height ?? '100%'}
1461
+ .height=${this.hasAttribute('fit') ? null : (config.height ?? '100%')}
1332
1462
  .seriesName=${config.seriesName ?? ''}
1333
1463
  .xAxisTitle=${config.xAxisTitle ?? ''}
1334
1464
  .yAxisTitle=${config.yAxisTitle ?? ''}
@@ -1350,7 +1480,7 @@ let NileChart = class NileChart extends NileElement {
1350
1480
  return html `<nile-xrange-chart
1351
1481
  .data=${config.data}
1352
1482
  .categories=${config.categories}
1353
- .height=${config.height ?? '100%'}
1483
+ .height=${this.hasAttribute('fit') ? null : (config.height ?? '100%')}
1354
1484
  .seriesName=${config.seriesName ?? ''}
1355
1485
  .datetimeAxis=${config.datetimeAxis ?? false}
1356
1486
  .showLegend=${config.showLegend ?? true}
@@ -1370,6 +1500,7 @@ let NileChart = class NileChart extends NileElement {
1370
1500
  ></nile-xrange-chart>`;
1371
1501
  case 'kpi': {
1372
1502
  const k = config;
1503
+ const kpiOptions = deepMerge(k.options ?? {}, this.buildExportingOptions());
1373
1504
  return html `<nile-kpi-chart
1374
1505
  embed-in-nile-chart
1375
1506
  .config=${{
@@ -1429,8 +1560,11 @@ let NileChart = class NileChart extends NileElement {
1429
1560
  contentGap: k.contentGap,
1430
1561
  tooltipEnabled: k.tooltipEnabled,
1431
1562
  loading: k.loading,
1432
- options: k.options,
1563
+ options: kpiOptions,
1433
1564
  height: k.height,
1565
+ valueFormat: k.valueFormat,
1566
+ precision: k.precision,
1567
+ unit: k.unit,
1434
1568
  },
1435
1569
  aq: {
1436
1570
  chartSubtitle: k.chartSubtitle,
@@ -1442,9 +1576,6 @@ let NileChart = class NileChart extends NileElement {
1442
1576
  const gridChrome = '--nile-data-grid-radius:0;' +
1443
1577
  '--nile-data-grid-border-color:transparent;' +
1444
1578
  '--nile-data-grid-shadow:none;';
1445
- const gridStyle = config.height
1446
- ? `${gridChrome}height:${config.height};`
1447
- : gridChrome;
1448
1579
  return html `<nile-data-grid
1449
1580
  class="nile-chart-grid"
1450
1581
  .data=${config.data}
@@ -1454,9 +1585,9 @@ let NileChart = class NileChart extends NileElement {
1454
1585
  .hoverable=${config.hoverable ?? false}
1455
1586
  .stickyHeader=${config.stickyHeader ?? false}
1456
1587
  .emptyMessage=${config.emptyMessage ?? 'No data'}
1457
- .loadingMessage=${config.loadingMessage ?? 'Loading\u2026'}
1588
+ .loadingMessage=${config.loadingMessage ?? 'Loading'}
1458
1589
  .noMatchMessage=${config.noMatchMessage ?? 'No matching rows'}
1459
- style=${gridStyle}
1590
+ style=${gridChrome}
1460
1591
  ></nile-data-grid>`;
1461
1592
  }
1462
1593
  default: {
@@ -1467,28 +1598,32 @@ let NileChart = class NileChart extends NileElement {
1467
1598
  }
1468
1599
  renderSkeleton() {
1469
1600
  return html `
1470
- <div class="chart-skeleton" aria-busy="true" aria-label="Loading chart">
1471
- <div class="chart-skeleton-body">
1601
+ <div class="nile-chart-skeleton" aria-busy="true" aria-label="Loading chart">
1602
+ <div class="nile-chart-skeleton-body">
1472
1603
  ${[78, 55, 91, 42, 68].map(w => html `
1473
- <div class="chart-skeleton-row">
1474
- <div class="chart-skeleton-ylabel"></div>
1475
- <div class="chart-skeleton-bar" style="--w: ${w}%"></div>
1604
+ <div class="nile-chart-skeleton-row">
1605
+ <div class="nile-chart-skeleton-ylabel"></div>
1606
+ <div class="nile-chart-skeleton-bar" style="--w: ${w}%"></div>
1476
1607
  </div>
1477
1608
  `)}
1478
1609
  </div>
1479
- <div class="chart-skeleton-xaxis-row">
1480
- ${[0, 1, 2, 3, 4].map(i => html `<div class="chart-skeleton-xlabel" style="--d: ${i * 80}ms"></div>`)}
1610
+ <div class="nile-chart-skeleton-xaxis-row">
1611
+ ${[0, 1, 2, 3, 4].map(i => html `<div class="nile-chart-skeleton-xlabel" style="--d: ${i * 80}ms"></div>`)}
1481
1612
  </div>
1482
1613
  </div>
1483
1614
  `;
1484
1615
  }
1485
1616
  render() {
1486
1617
  const isLoading = this.loading || (this.activeConfig?.loading ?? false);
1618
+ const isGrid = this.activeConfig?.type === 'grid';
1619
+ const cardStyle = isGrid && this.activeConfig?.height
1620
+ ? `height:${this.activeConfig.height}`
1621
+ : '';
1487
1622
  return html `
1488
- <div class="chart-card">
1623
+ <div class="nile-chart-card ${isGrid ? 'nile-chart-card--grid' : ''}" style=${cardStyle}>
1489
1624
  ${this.renderHeader()}
1490
- <div class="chart-wrapper">
1491
- <div class="chart-inner ${this.activeConfig?.type === 'kpi' ? 'chart-inner--kpi' : ''}">
1625
+ <div class="nile-chart-wrapper">
1626
+ <div class="nile-chart-inner ${this.activeConfig?.type === 'kpi' ? 'nile-chart-inner--kpi' : ''}">
1492
1627
  ${isLoading
1493
1628
  ? this.renderSkeleton()
1494
1629
  : this.activeConfig
@@ -1515,6 +1650,9 @@ __decorate([
1515
1650
  __decorate([
1516
1651
  property({ type: String })
1517
1652
  ], NileChart.prototype, "summary", void 0);
1653
+ __decorate([
1654
+ property({ type: Object })
1655
+ ], NileChart.prototype, "menu", void 0);
1518
1656
  __decorate([
1519
1657
  state()
1520
1658
  ], NileChart.prototype, "activeType", void 0);
@@ -1527,6 +1665,9 @@ __decorate([
1527
1665
  __decorate([
1528
1666
  state()
1529
1667
  ], NileChart.prototype, "chatOpen", void 0);
1668
+ __decorate([
1669
+ state()
1670
+ ], NileChart.prototype, "_hcChart", void 0);
1530
1671
  __decorate([
1531
1672
  state()
1532
1673
  ], NileChart.prototype, "hasHeaderSlotContent", void 0);