@aquera/nile-visualization 1.8.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.
- package/dist/src/index.d.ts +1 -1
- package/dist/src/internal/highcharts-provider.d.ts +6 -0
- package/dist/src/internal/highcharts-provider.js +32 -0
- package/dist/src/internal/types/aq-config.type.d.ts +5 -0
- package/dist/src/nile-chart/index.d.ts +1 -1
- package/dist/src/nile-chart/nile-chart-config.d.ts +69 -1
- package/dist/src/nile-chart/nile-chart.css.d.ts +1 -0
- package/dist/src/nile-chart/nile-chart.css.js +175 -85
- package/dist/src/nile-chart/nile-chart.d.ts +25 -6
- package/dist/src/nile-chart/nile-chart.js +196 -55
- package/dist/src/nile-kpi-chart/nile-kpi-chart.css.js +47 -3
- package/dist/src/nile-kpi-chart/nile-kpi-chart.d.ts +29 -1
- package/dist/src/nile-kpi-chart/nile-kpi-chart.js +164 -9
- package/package.json +1 -1
|
@@ -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.
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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}${
|
|
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
|
|
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);
|