@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
@@ -47,7 +47,7 @@ export const styles = css `
47
47
  --nile-kpi-label-color: var(--nile-colors-neutral-700, var(--ng-colors-text-secondary-700));
48
48
  --nile-kpi-label-font-size: var(--nile-type-scale-3, var(--ng-font-size-text-sm));
49
49
  --nile-kpi-label-font-weight: var(--nile-font-weight-medium, var(--ng-font-weight-medium));
50
- --nile-kpi-value-font-size: clamp(1.25rem, 2.5vw + 0.75rem, 36px);
50
+ --nile-kpi-value-font-size: clamp(1.25rem, 5cqi + 0.5rem, 36px);
51
51
  --nile-kpi-value-color: var(--nile-colors-dark-900, var(--ng-colors-text-primary-900));
52
52
  --nile-kpi-prefix-suffix-font-size: var(--nile-type-scale-6, var(--ng-font-size-text-xl));
53
53
  --nile-kpi-prefix-suffix-color: var(--nile-colors-neutral-700, var(--ng-colors-text-secondary-700));
@@ -59,14 +59,24 @@ export const styles = css `
59
59
  display: flex;
60
60
  flex-direction: column;
61
61
  width: 100%;
62
+ min-width: 160px;
62
63
  position: relative;
63
64
  box-sizing: border-box;
65
+ overflow: hidden;
66
+ container-type: inline-size;
64
67
  }
65
68
 
66
69
  :host([hidden]) {
67
70
  display: none;
68
71
  }
69
72
 
73
+ /* Fit-to-container mode (set by nile-widget-viewer) — fills the allotted
74
+ cell so the KPI card never overflows and overlaps neighbors. The .kpi
75
+ element is already flex:1, so it stretches with the host. */
76
+ :host([fit]) {
77
+ height: 100%;
78
+ }
79
+
70
80
  /* Card / gauge chrome on the host when used alone (inside nile-chart, embed-in-nile-chart skips this). */
71
81
  :host([variant='card']:not([embed-in-nile-chart])),
72
82
  :host([variant='gauge']:not([embed-in-nile-chart])) {
@@ -82,12 +92,29 @@ export const styles = css `
82
92
  box-shadow: var(--nile-kpi-card-shadow-hover);
83
93
  }
84
94
 
95
+ /* Accent variant — card chrome with a prominent left colour bar. */
96
+ :host([variant='accent']:not([embed-in-nile-chart])) {
97
+ --nile-kpi-accent-color: #005EA6;
98
+ background: var(--nile-kpi-card-bg);
99
+ border: var(--nile-kpi-card-border-width) solid var(--nile-kpi-card-border-color);
100
+ border-left: 4px solid var(--nile-kpi-accent-color);
101
+ border-radius: var(--nile-kpi-card-border-radius);
102
+ box-shadow: var(--nile-kpi-card-shadow);
103
+ transition: box-shadow var(--nile-transition-duration-default, var(--ng-transition-duration-default)) ease;
104
+ }
105
+
106
+ :host([variant='accent']:not([embed-in-nile-chart]):hover) {
107
+ box-shadow: var(--nile-kpi-card-shadow-hover);
108
+ }
109
+
85
110
  .kpi {
86
111
  flex: 1 1 auto;
87
112
  display: flex;
88
113
  flex-direction: column;
89
114
  gap: var(--nile-kpi-content-gap);
90
115
  padding: var(--nile-kpi-padding-v) var(--nile-kpi-padding-h);
116
+ min-width: 0;
117
+ overflow: hidden;
91
118
  }
92
119
 
93
120
  .kpi-label {
@@ -97,13 +124,20 @@ export const styles = css `
97
124
  font-weight: var(--nile-kpi-label-font-weight);
98
125
  color: var(--nile-kpi-label-color);
99
126
  line-height: 1.4;
127
+ white-space: nowrap;
128
+ overflow: hidden;
129
+ text-overflow: ellipsis;
130
+ min-width: 0;
131
+ width: 100%;
100
132
  }
101
133
 
102
134
  .kpi-value-row {
103
135
  display: flex;
104
- align-items: baseline;
136
+ align-items: center;
105
137
  gap: var(--nile-spacing-md, var(--ng-spacing-md));
106
- flex-wrap: wrap;
138
+ flex-wrap: nowrap;
139
+ min-width: 0;
140
+ overflow: hidden;
107
141
  }
108
142
 
109
143
  .kpi-value {
@@ -114,6 +148,8 @@ export const styles = css `
114
148
  color: var(--nile-kpi-value-color);
115
149
  line-height: 1.2;
116
150
  cursor: default;
151
+ white-space: nowrap;
152
+ flex-shrink: 0;
117
153
  }
118
154
 
119
155
  .kpi-prefix,
@@ -134,6 +170,16 @@ export const styles = css `
134
170
  font-size: var(--nile-type-scale-2, var(--ng-font-size-text-xs));
135
171
  font-weight: var(--nile-font-weight-medium, var(--ng-font-weight-medium));
136
172
  line-height: 1;
173
+ flex-shrink: 1;
174
+ min-width: 0;
175
+ overflow: hidden;
176
+ white-space: nowrap;
177
+ }
178
+
179
+ @container (max-width: 240px) {
180
+ .kpi-trend {
181
+ display: none;
182
+ }
137
183
  }
138
184
 
139
185
  .kpi-trend--up {
@@ -169,6 +215,11 @@ export const styles = css `
169
215
  font-size: var(--nile-kpi-description-font-size);
170
216
  color: var(--nile-kpi-description-color);
171
217
  line-height: 1.5;
218
+ white-space: nowrap;
219
+ overflow: hidden;
220
+ text-overflow: ellipsis;
221
+ min-width: 0;
222
+ width: 100%;
172
223
  }
173
224
 
174
225
  .kpi-sparkline {
@@ -3,8 +3,9 @@ import type Highcharts from 'highcharts';
3
3
  import NileElement from '../internal/nile-element.js';
4
4
  import type { AqConfigType } from '../internal/types/aq-config.type.js';
5
5
  export type TrendDirection = 'up' | 'down' | 'neutral';
6
- export type KpiVariant = 'default' | 'card' | 'gauge';
6
+ export type KpiVariant = 'default' | 'card' | 'gauge' | 'accent';
7
7
  export type SparklineType = 'area' | 'line';
8
+ export type KpiValueFormat = 'auto' | 'K' | 'M' | 'B' | 'T' | 'none';
8
9
  /** `chart` slice for `<nile-kpi-chart>.config` (discriminated by `type: 'kpi'`). */
9
10
  export interface ChartKpiSeparatedPayload {
10
11
  type: 'kpi';
@@ -63,6 +64,8 @@ export interface ChartKpiSeparatedPayload {
63
64
  loadingText?: string;
64
65
  /** Whether the hover tooltip is shown on value / sparkline / gauge (default: true). */
65
66
  tooltipEnabled?: boolean;
67
+ /** Accent bar colour for the 'accent' variant (default: brand blue). */
68
+ accentColor?: string;
66
69
  cardBackground?: string;
67
70
  cardBorderColor?: string;
68
71
  cardBorderWidth?: string | number;
@@ -86,6 +89,18 @@ export interface ChartKpiSeparatedPayload {
86
89
  options?: Highcharts.Options;
87
90
  /** Box size when a height is set (host min-height and height). */
88
91
  height?: string | number;
92
+ /** How to abbreviate the display value. 'auto' picks K/M/B/T by magnitude. Default: 'auto'. */
93
+ valueFormat?: KpiValueFormat;
94
+ /** Decimal places for the abbreviated value. Auto-selects 0–2 when omitted. */
95
+ precision?: number;
96
+ /** BCP 47 locale for number formatting, e.g. 'en-IN'. Defaults to browser locale. */
97
+ locale?: string;
98
+ /**
99
+ * Base unit appended after the magnitude prefix — e.g. `'L'` + `valueFormat: 'auto'` on 1500
100
+ * renders `"1.5KL"` on the card and `"1,500L"` in the tooltip. Use for physical units
101
+ * (L, g, m, Pa, Hz, B, etc.). For non-unit suffix text (%, /day), use `suffix` instead.
102
+ */
103
+ unit?: string;
89
104
  }
90
105
  /** Separated `{ chart, aq }` input for `<nile-kpi-chart>`. */
91
106
  export interface NileKpiConfigInputType {
@@ -196,6 +211,8 @@ export declare class NileKpiChart extends NileElement {
196
211
  cardPaddingVertical: string | number;
197
212
  cardPaddingHorizontal: string | number;
198
213
  contentGap: string | number;
214
+ /** Accent bar colour for the 'accent' variant. */
215
+ accentColor: string;
199
216
  labelColor: string;
200
217
  labelFontSize: string | number;
201
218
  labelFontWeight: string | number;
@@ -210,6 +227,14 @@ export declare class NileKpiChart extends NileElement {
210
227
  loading: boolean;
211
228
  /** Highcharts options override for the sparkline or gauge. */
212
229
  options: Highcharts.Options;
230
+ /** How to abbreviate the numeric value. 'auto' picks K/M/B/T by magnitude. Default: 'auto'. */
231
+ valueFormat: KpiValueFormat;
232
+ /** Base unit combined with the magnitude prefix (e.g. 'L' → "1.5KL"). */
233
+ unit: string;
234
+ /** Decimal places for the abbreviated value. null = auto (0–2 by magnitude). */
235
+ precision: number | null;
236
+ /** BCP 47 locale for number formatting, e.g. 'en-IN'. Defaults to browser locale. */
237
+ locale: string;
213
238
  /**
214
239
  * Set by nile-chart: skip host border/shadow (variant card/gauge) so the parent chart-card is the only frame.
215
240
  */
@@ -223,6 +248,7 @@ export declare class NileKpiChart extends NileElement {
223
248
  private formatTooltipNumber;
224
249
  private inferSparklineTooltipScale;
225
250
  private getTooltipContent;
251
+ private formatValue;
226
252
  private applyConfig;
227
253
  connectedCallback(): void;
228
254
  disconnectedCallback(): void;
@@ -240,6 +266,8 @@ export declare class NileKpiChart extends NileElement {
240
266
  private destroyGauge;
241
267
  private destroyCharts;
242
268
  private _onValueEnter;
269
+ private _onDescEnter;
270
+ private _onLabelEnter;
243
271
  private _onGaugeEnter;
244
272
  private _onTipLeave;
245
273
  private renderTrend;
@@ -106,6 +106,8 @@ let NileKpiChart = class NileKpiChart extends NileElement {
106
106
  this.cardPaddingVertical = '';
107
107
  this.cardPaddingHorizontal = '';
108
108
  this.contentGap = '';
109
+ /** Accent bar colour for the 'accent' variant. */
110
+ this.accentColor = '';
109
111
  // ── Label ──
110
112
  this.labelColor = '';
111
113
  this.labelFontSize = '';
@@ -124,6 +126,14 @@ let NileKpiChart = class NileKpiChart extends NileElement {
124
126
  this.loading = false;
125
127
  /** Highcharts options override for the sparkline or gauge. */
126
128
  this.options = {};
129
+ /** How to abbreviate the numeric value. 'auto' picks K/M/B/T by magnitude. Default: 'auto'. */
130
+ this.valueFormat = 'auto';
131
+ /** Base unit combined with the magnitude prefix (e.g. 'L' → "1.5KL"). */
132
+ this.unit = '';
133
+ /** Decimal places for the abbreviated value. null = auto (0–2 by magnitude). */
134
+ this.precision = null;
135
+ /** BCP 47 locale for number formatting, e.g. 'en-IN'. Defaults to browser locale. */
136
+ this.locale = '';
127
137
  /**
128
138
  * Set by nile-chart: skip host border/shadow (variant card/gauge) so the parent chart-card is the only frame.
129
139
  */
@@ -160,7 +170,25 @@ let NileKpiChart = class NileKpiChart extends NileElement {
160
170
  // ── Value / Gauge hover handlers ─────────────────────────────────────────
161
171
  this._onValueEnter = (e) => {
162
172
  const rect = e.currentTarget.getBoundingClientRect();
163
- this._showTip(this.getTooltipContent(), rect.left + rect.width / 2, rect.top);
173
+ const rawNum = this.parseNumericValue(this.value);
174
+ const full = rawNum != null ? this.formatValue(rawNum).full : String(this.value ?? '');
175
+ const prefix = this.prefix ?? '';
176
+ const suffix = this.suffix ?? '';
177
+ this._showTip(`${prefix}${full}${suffix}`.trim(), rect.left + rect.width / 2, rect.top);
178
+ };
179
+ this._onDescEnter = (e) => {
180
+ const el = e.currentTarget;
181
+ if (el.scrollWidth <= el.clientWidth)
182
+ return;
183
+ const rect = el.getBoundingClientRect();
184
+ this._showTip(this.description ?? '', rect.left + rect.width / 2, rect.top);
185
+ };
186
+ this._onLabelEnter = (e) => {
187
+ const el = e.currentTarget;
188
+ if (el.scrollWidth <= el.clientWidth)
189
+ return;
190
+ const rect = el.getBoundingClientRect();
191
+ this._showTip(this.label ?? '', rect.left + rect.width / 2, rect.top);
164
192
  };
165
193
  this._onGaugeEnter = (e) => {
166
194
  const rect = e.currentTarget.getBoundingClientRect();
@@ -203,6 +231,7 @@ let NileKpiChart = class NileKpiChart extends NileElement {
203
231
  this.style.removeProperty(prop);
204
232
  };
205
233
  const len = (val) => this.formatCssLength(val) ?? '';
234
+ set('--nile-kpi-accent-color', this.accentColor);
206
235
  set('--nile-kpi-card-bg', this.cardBackground);
207
236
  set('--nile-kpi-card-border-color', this.cardBorderColor);
208
237
  set('--nile-kpi-card-border-width', len(this.cardBorderWidth));
@@ -252,11 +281,12 @@ let NileKpiChart = class NileKpiChart extends NileElement {
252
281
  }
253
282
  formatTooltipNumber(n) {
254
283
  const maxFractionDigits = Number.isInteger(n) ? 0 : 6;
255
- return new Intl.NumberFormat(undefined, {
284
+ const grouped = new Intl.NumberFormat(this.locale || undefined, {
256
285
  useGrouping: true,
257
286
  minimumFractionDigits: 0,
258
287
  maximumFractionDigits: maxFractionDigits,
259
288
  }).format(n);
289
+ return `${grouped}${this.unit ?? ''}`;
260
290
  }
261
291
  inferSparklineTooltipScale() {
262
292
  if (!this.sparkline?.length)
@@ -284,6 +314,85 @@ let NileKpiChart = class NileKpiChart extends NileElement {
284
314
  : this.formatTooltipNumber(numeric);
285
315
  return `${prefix}${valueText}${suffix}`.trim();
286
316
  }
317
+ formatValue(raw) {
318
+ const fmt = this.valueFormat;
319
+ const baseUnit = this.unit ?? '';
320
+ const abs = Math.abs(raw);
321
+ const sign = raw < 0 ? '-' : '';
322
+ const maxFrac = Number.isInteger(raw) ? 0 : 6;
323
+ const tooltipLocale = this.locale || undefined;
324
+ const displayLocale = this.locale || undefined;
325
+ const full = `${new Intl.NumberFormat(tooltipLocale, {
326
+ useGrouping: true, minimumFractionDigits: 0, maximumFractionDigits: maxFrac,
327
+ }).format(raw)}${baseUnit}`;
328
+ const display0 = `${new Intl.NumberFormat(displayLocale, {
329
+ useGrouping: true, minimumFractionDigits: 0, maximumFractionDigits: maxFrac,
330
+ }).format(raw)}${baseUnit}`;
331
+ if (fmt === 'none')
332
+ return { display: display0, full, abbreviated: false };
333
+ let divisor = 0;
334
+ let magnitude = '';
335
+ if (fmt === 'K') {
336
+ divisor = 1e3;
337
+ magnitude = 'K';
338
+ }
339
+ else if (fmt === 'M') {
340
+ divisor = 1e6;
341
+ magnitude = 'M';
342
+ }
343
+ else if (fmt === 'B') {
344
+ divisor = 1e9;
345
+ magnitude = 'B';
346
+ }
347
+ else if (fmt === 'T') {
348
+ divisor = 1e12;
349
+ magnitude = 'T';
350
+ }
351
+ else {
352
+ if (abs >= 1e12) {
353
+ divisor = 1e12;
354
+ magnitude = 'T';
355
+ }
356
+ else if (abs >= 1e9) {
357
+ divisor = 1e9;
358
+ magnitude = 'B';
359
+ }
360
+ else if (abs >= 1e6) {
361
+ divisor = 1e6;
362
+ magnitude = 'M';
363
+ }
364
+ else if (abs >= 1e3) {
365
+ divisor = 1e3;
366
+ magnitude = 'K';
367
+ }
368
+ }
369
+ if (!divisor)
370
+ return { display: display0, full, abbreviated: false };
371
+ const divided = abs / divisor;
372
+ let decimals;
373
+ if (this.precision !== null) {
374
+ decimals = Math.max(0, Math.floor(this.precision));
375
+ }
376
+ else {
377
+ decimals = divided >= 100 ? 0 : divided >= 10 ? 1 : 2;
378
+ }
379
+ let numStr;
380
+ if (this._hc) {
381
+ numStr = this._hc.numberFormat(divided, decimals, undefined, '');
382
+ if (this.precision === null) {
383
+ const dec = this._hc.options?.lang?.decimalPoint ?? '.';
384
+ const escapedDec = dec.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
385
+ numStr = numStr.replace(new RegExp(`${escapedDec}0*$`), '').replace(new RegExp(`${escapedDec}$`), '');
386
+ }
387
+ }
388
+ else {
389
+ numStr = divided.toFixed(decimals);
390
+ if (this.precision === null && numStr.includes('.')) {
391
+ numStr = numStr.replace(/\.?0+$/, '');
392
+ }
393
+ }
394
+ return { display: `${sign}${numStr}${magnitude}${baseUnit}`, full, abbreviated: true };
395
+ }
287
396
  // ── Config ───────────────────────────────────────────────────────────────
288
397
  applyConfig(cfg) {
289
398
  const { chart: c, aq } = cfg;
@@ -358,6 +467,8 @@ let NileKpiChart = class NileKpiChart extends NileElement {
358
467
  this.loadingText = c.loadingText;
359
468
  if (c.tooltipEnabled !== undefined)
360
469
  this.tooltipEnabled = c.tooltipEnabled;
470
+ if (c.accentColor !== undefined)
471
+ this.accentColor = c.accentColor;
361
472
  if (c.cardBackground !== undefined)
362
473
  this.cardBackground = c.cardBackground;
363
474
  if (c.cardBorderColor !== undefined)
@@ -400,6 +511,14 @@ let NileKpiChart = class NileKpiChart extends NileElement {
400
511
  this.loading = c.loading;
401
512
  if (c.options !== undefined)
402
513
  this.options = c.options;
514
+ if (c.valueFormat !== undefined)
515
+ this.valueFormat = c.valueFormat;
516
+ if (c.precision !== undefined)
517
+ this.precision = c.precision;
518
+ if (c.locale !== undefined)
519
+ this.locale = c.locale;
520
+ if (c.unit !== undefined)
521
+ this.unit = c.unit;
403
522
  if ('height' in c) {
404
523
  const h = this.formatCssLength(c.height);
405
524
  if (h) {
@@ -426,6 +545,9 @@ let NileKpiChart = class NileKpiChart extends NileElement {
426
545
  super.connectedCallback();
427
546
  ensureTooltipStyles();
428
547
  this._createTipEl();
548
+ if (!this._hc) {
549
+ getHighcharts().then(hc => { this._hc = hc; this.requestUpdate(); });
550
+ }
429
551
  if (this.config)
430
552
  this.applyConfig(this.config);
431
553
  }
@@ -460,7 +582,7 @@ let NileKpiChart = class NileKpiChart extends NileElement {
460
582
  this.initSparkline();
461
583
  }
462
584
  }
463
- const cssVarProps = ['cardBackground', 'cardBorderColor', 'cardBorderWidth', 'cardBorderRadius',
585
+ const cssVarProps = ['accentColor', 'cardBackground', 'cardBorderColor', 'cardBorderWidth', 'cardBorderRadius',
464
586
  'cardShadow', 'cardShadowHover', 'cardPaddingVertical', 'cardPaddingHorizontal', 'contentGap',
465
587
  'labelColor', 'labelFontSize', 'labelFontWeight', 'descriptionColor', 'descriptionFontSize',
466
588
  'prefixSuffixColor', 'prefixSuffixFontSize', 'trendUpColor', 'trendDownColor', 'trendNeutralColor',
@@ -589,7 +711,13 @@ let NileKpiChart = class NileKpiChart extends NileElement {
589
711
  borderWidth: 0,
590
712
  y: this.gaugeLabelYOffset,
591
713
  useHTML: true,
592
- format: `<div style="text-align:center"><span style="font-size:${labelFontSize};font-weight:${labelFontWeight};color:${labelColor}">${this.prefix}{y}${this.suffix}</span></div>`,
714
+ formatter: (() => {
715
+ const self = this;
716
+ return function () {
717
+ const fmtResult = self.formatValue(this.y ?? 0);
718
+ return `<div style="text-align:center"><span style="font-size:${labelFontSize};font-weight:${labelFontWeight};color:${labelColor}">${self.prefix}${fmtResult.display}${self.suffix}</span></div>`;
719
+ };
720
+ })(),
593
721
  },
594
722
  rounded: this.gaugeRounded,
595
723
  linecap: 'round',
@@ -675,9 +803,17 @@ let NileKpiChart = class NileKpiChart extends NileElement {
675
803
  return html `<div class="chart-loading">${this.loadingText}</div>`;
676
804
  }
677
805
  const isGauge = this.variant === 'gauge';
806
+ const rawNum = this.parseNumericValue(this.value);
807
+ const fmt = rawNum != null ? this.formatValue(rawNum) : null;
808
+ const displayValue = fmt ? fmt.display : String(this.value ?? '');
809
+ const showTooltip = !!fmt && fmt.display !== fmt.full;
678
810
  return html `
679
811
  <div class="kpi ${isGauge ? 'kpi--gauge' : ''}">
680
- ${this.label ? html `<p class="kpi-label">${this.label}</p>` : nothing}
812
+ ${this.label ? html `<p
813
+ class="kpi-label"
814
+ @mouseenter=${this._onLabelEnter}
815
+ @mouseleave=${this._onTipLeave}
816
+ >${this.label}</p>` : nothing}
681
817
 
682
818
  ${isGauge ? html `
683
819
  <div
@@ -691,10 +827,10 @@ let NileKpiChart = class NileKpiChart extends NileElement {
691
827
  ${!isGauge ? html `
692
828
  <h2
693
829
  class="kpi-value"
694
- @mouseenter=${this._onValueEnter}
695
- @mouseleave=${this._onTipLeave}
830
+ @mouseenter=${showTooltip ? this._onValueEnter : nothing}
831
+ @mouseleave=${showTooltip ? this._onTipLeave : nothing}
696
832
  >
697
- ${this.prefix ? html `<span class="kpi-prefix">${this.prefix}</span>` : nothing}${this.value}${this.suffix ? html `<span class="kpi-suffix">${this.suffix}</span>` : nothing}
833
+ ${this.prefix ? html `<span class="kpi-prefix">${this.prefix}</span>` : nothing}${displayValue}${this.suffix ? html `<span class="kpi-suffix">${this.suffix}</span>` : nothing}
698
834
  </h2>
699
835
  ` : nothing}
700
836
  ${!isGauge ? this.renderTrend() : nothing}
@@ -702,7 +838,11 @@ let NileKpiChart = class NileKpiChart extends NileElement {
702
838
 
703
839
  ${isGauge ? this.renderTrend() : nothing}
704
840
 
705
- ${this.description ? html `<p class="kpi-description">${this.description}</p>` : nothing}
841
+ ${this.description ? html `<p
842
+ class="kpi-description"
843
+ @mouseenter=${this._onDescEnter}
844
+ @mouseleave=${this._onTipLeave}
845
+ >${this.description}</p>` : nothing}
706
846
 
707
847
  ${this.sparkline.length && !isGauge ? html `<div class="kpi-sparkline"></div>` : nothing}
708
848
  </div>
@@ -851,6 +991,9 @@ __decorate([
851
991
  __decorate([
852
992
  property({ type: String, attribute: 'content-gap' })
853
993
  ], NileKpiChart.prototype, "contentGap", void 0);
994
+ __decorate([
995
+ property({ type: String, attribute: 'accent-color' })
996
+ ], NileKpiChart.prototype, "accentColor", void 0);
854
997
  __decorate([
855
998
  property({ type: String, attribute: 'label-color' })
856
999
  ], NileKpiChart.prototype, "labelColor", void 0);
@@ -887,6 +1030,18 @@ __decorate([
887
1030
  __decorate([
888
1031
  property({ type: Object })
889
1032
  ], NileKpiChart.prototype, "options", void 0);
1033
+ __decorate([
1034
+ property({ type: String, attribute: 'value-format' })
1035
+ ], NileKpiChart.prototype, "valueFormat", void 0);
1036
+ __decorate([
1037
+ property({ type: String })
1038
+ ], NileKpiChart.prototype, "unit", void 0);
1039
+ __decorate([
1040
+ property({ type: Number })
1041
+ ], NileKpiChart.prototype, "precision", void 0);
1042
+ __decorate([
1043
+ property({ type: String })
1044
+ ], NileKpiChart.prototype, "locale", void 0);
890
1045
  __decorate([
891
1046
  property({ type: Boolean, reflect: true, attribute: 'embed-in-nile-chart' })
892
1047
  ], NileKpiChart.prototype, "embedInNileChart", void 0);
@@ -13,6 +13,7 @@ export const styles = css `
13
13
  --nile-chart-loading-bg: transparent;
14
14
  display: block;
15
15
  width: 100%;
16
+ height: 100%;
16
17
  position: relative;
17
18
  }
18
19
 
@@ -22,6 +23,7 @@ export const styles = css `
22
23
 
23
24
  .chart-container {
24
25
  width: 100%;
26
+ height: 100%;
25
27
  min-height: var(--nile-chart-min-height);
26
28
  background: var(--nile-chart-bg);
27
29
  border-radius: var(--nile-chart-border-radius);
@@ -150,7 +150,7 @@ let NileLineChart = class NileLineChart extends NileElement {
150
150
  buildOptions() {
151
151
  const self = this;
152
152
  return deepMerge({
153
- chart: { type: 'line', height: this.height },
153
+ chart: { type: 'line', ...(this.height ? { height: this.height } : {}) },
154
154
  title: { text: this.chartTitle || undefined },
155
155
  subtitle: { text: this.chartSubtitle || undefined },
156
156
  xAxis: { categories: this.categories },
@@ -13,6 +13,7 @@ export const styles = css `
13
13
  --nile-chart-loading-bg: transparent;
14
14
  display: block;
15
15
  width: 100%;
16
+ height: 100%;
16
17
  position: relative;
17
18
  }
18
19
 
@@ -22,6 +23,7 @@ export const styles = css `
22
23
 
23
24
  .chart-container {
24
25
  width: 100%;
26
+ height: 100%;
25
27
  min-height: var(--nile-chart-min-height);
26
28
  background: var(--nile-chart-bg);
27
29
  border-radius: var(--nile-chart-border-radius);
@@ -124,7 +124,7 @@ let NileLineColumnChart = class NileLineColumnChart extends NileElement {
124
124
  const col = this.columnSeries;
125
125
  const line = this.lineSeries;
126
126
  return deepMerge({
127
- chart: { height: this.height },
127
+ chart: { ...(this.height ? { height: this.height } : {}) },
128
128
  title: { text: this.chartTitle || undefined },
129
129
  subtitle: { text: this.chartSubtitle || undefined },
130
130
  xAxis: { categories: this.categories, crosshair: true },
@@ -13,6 +13,7 @@ export const styles = css `
13
13
  --nile-chart-loading-bg: transparent;
14
14
  display: block;
15
15
  width: 100%;
16
+ height: 100%;
16
17
  position: relative;
17
18
  }
18
19
 
@@ -22,6 +23,7 @@ export const styles = css `
22
23
 
23
24
  .chart-container {
24
25
  width: 100%;
26
+ height: 100%;
25
27
  min-height: var(--nile-chart-min-height);
26
28
  background: var(--nile-chart-bg);
27
29
  border-radius: var(--nile-chart-border-radius);
@@ -127,7 +127,7 @@ let NileLollipopChart = class NileLollipopChart extends NileElement {
127
127
  });
128
128
  }
129
129
  return deepMerge({
130
- chart: { height: this.height },
130
+ chart: { ...(this.height ? { height: this.height } : {}) },
131
131
  title: { text: this.chartTitle || undefined },
132
132
  subtitle: { text: this.chartSubtitle || undefined },
133
133
  xAxis: { categories: this.categories },
@@ -13,6 +13,7 @@ export const styles = css `
13
13
  --nile-chart-loading-bg: transparent;
14
14
  display: block;
15
15
  width: 100%;
16
+ height: 100%;
16
17
  position: relative;
17
18
  }
18
19
 
@@ -22,6 +23,7 @@ export const styles = css `
22
23
 
23
24
  .chart-container {
24
25
  width: 100%;
26
+ height: 100%;
25
27
  min-height: var(--nile-chart-min-height);
26
28
  background: var(--nile-chart-bg);
27
29
  border-radius: var(--nile-chart-border-radius);
@@ -206,7 +206,7 @@ let NileMapChart = class NileMapChart extends NileElement {
206
206
  const self = this;
207
207
  const defaults = {
208
208
  chart: {
209
- height: this.height,
209
+ ...(this.height ? { height: this.height } : {}),
210
210
  },
211
211
  title: {
212
212
  text: this.chartTitle || undefined,
@@ -13,6 +13,7 @@ export const styles = css `
13
13
  --nile-chart-loading-bg: transparent;
14
14
  display: block;
15
15
  width: 100%;
16
+ height: 100%;
16
17
  position: relative;
17
18
  }
18
19
 
@@ -22,6 +23,7 @@ export const styles = css `
22
23
 
23
24
  .chart-container {
24
25
  width: 100%;
26
+ height: 100%;
25
27
  min-height: var(--nile-chart-min-height);
26
28
  background: var(--nile-chart-bg);
27
29
  border-radius: var(--nile-chart-border-radius);
@@ -139,7 +139,7 @@ let NileOrganizationChart = class NileOrganizationChart extends NileElement {
139
139
  });
140
140
  return deepMerge({
141
141
  chart: {
142
- height: this.height,
142
+ ...(this.height ? { height: this.height } : {}),
143
143
  inverted: this.inverted,
144
144
  },
145
145
  title: { text: this.chartTitle || undefined },
@@ -13,6 +13,7 @@ export const styles = css `
13
13
  --nile-chart-loading-bg: transparent;
14
14
  display: block;
15
15
  width: 100%;
16
+ height: 100%;
16
17
  position: relative;
17
18
  }
18
19
 
@@ -22,6 +23,7 @@ export const styles = css `
22
23
 
23
24
  .chart-container {
24
25
  width: 100%;
26
+ height: 100%;
25
27
  min-height: var(--nile-chart-min-height);
26
28
  background: var(--nile-chart-bg);
27
29
  border-radius: var(--nile-chart-border-radius);
@@ -178,7 +178,7 @@ let NilePieChart = class NilePieChart extends NileElement {
178
178
  const defaults = {
179
179
  chart: {
180
180
  type: 'pie',
181
- height: this.height,
181
+ ...(this.height ? { height: this.height } : {}),
182
182
  },
183
183
  title: {
184
184
  text: this.chartTitle || undefined,
@@ -13,6 +13,7 @@ export const styles = css `
13
13
  --nile-chart-loading-bg: transparent;
14
14
  display: block;
15
15
  width: 100%;
16
+ height: 100%;
16
17
  position: relative;
17
18
  }
18
19
 
@@ -22,6 +23,7 @@ export const styles = css `
22
23
 
23
24
  .chart-container {
24
25
  width: 100%;
26
+ height: 100%;
25
27
  min-height: var(--nile-chart-min-height);
26
28
  background: var(--nile-chart-bg);
27
29
  border-radius: var(--nile-chart-border-radius);
@@ -116,7 +116,7 @@ let NilePolygonChart = class NilePolygonChart extends NileElement {
116
116
  buildOptions() {
117
117
  const self = this;
118
118
  return deepMerge({
119
- chart: { height: this.height },
119
+ chart: { ...(this.height ? { height: this.height } : {}) },
120
120
  title: { text: this.chartTitle || undefined },
121
121
  subtitle: { text: this.chartSubtitle || undefined },
122
122
  xAxis: { title: { text: this.xAxisTitle || undefined } },