@aquera/nile-visualization 0.5.0 → 0.7.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 +8 -2
- package/dist/src/index.js +3 -0
- package/dist/src/internal/dashboard-adapters.d.ts +13 -0
- package/dist/src/internal/dashboard-adapters.js +123 -0
- package/dist/src/internal/highcharts-provider.js +27 -0
- package/dist/src/internal/types/chart-config.type.d.ts +2 -1
- package/dist/src/internal/types/chart-map-config.type.d.ts +29 -0
- package/dist/src/internal/types/chart-map-config.type.js +2 -0
- package/dist/src/internal/types/dashboard-config.type.d.ts +8 -0
- package/dist/src/internal/types/dashboard-config.type.js +2 -0
- package/dist/src/internal/types/index.d.ts +1 -0
- package/dist/src/internal/types/nile-chart-config-input.type.d.ts +6 -2
- package/dist/src/internal/types/widget-config.type.d.ts +23 -0
- package/dist/src/internal/types/widget-config.type.js +2 -0
- package/dist/src/internal/types/widget-layout.type.d.ts +11 -0
- package/dist/src/internal/types/widget-layout.type.js +2 -0
- package/dist/src/nile-chart/index.d.ts +2 -2
- package/dist/src/nile-chart/nile-chart-config-builder.js +2 -1
- package/dist/src/nile-chart/nile-chart-config.d.ts +119 -30
- package/dist/src/nile-chart/nile-chart.css.js +20 -6
- package/dist/src/nile-chart/nile-chart.d.ts +11 -0
- package/dist/src/nile-chart/nile-chart.js +39 -2
- package/dist/src/nile-dashboard-viewer/index.d.ts +2 -0
- package/dist/src/nile-dashboard-viewer/index.js +2 -0
- package/dist/src/nile-dashboard-viewer/nile-dashboard-viewer.css.d.ts +1 -0
- package/dist/src/nile-dashboard-viewer/nile-dashboard-viewer.css.js +29 -0
- package/dist/src/nile-dashboard-viewer/nile-dashboard-viewer.d.ts +43 -0
- package/dist/src/nile-dashboard-viewer/nile-dashboard-viewer.js +84 -0
- package/dist/src/nile-kpi-chart/nile-kpi-chart.css.js +19 -11
- package/dist/src/nile-kpi-chart/nile-kpi-chart.d.ts +8 -2
- package/dist/src/nile-kpi-chart/nile-kpi-chart.js +43 -9
- package/dist/src/nile-map-chart/index.d.ts +2 -0
- package/dist/src/nile-map-chart/index.js +2 -0
- package/dist/src/nile-map-chart/nile-map-chart.css.d.ts +1 -0
- package/dist/src/nile-map-chart/nile-map-chart.css.js +28 -0
- package/dist/src/nile-map-chart/nile-map-chart.d.ts +74 -0
- package/dist/src/nile-map-chart/nile-map-chart.js +263 -0
- package/dist/src/nile-widget-viewer/index.d.ts +3 -0
- package/dist/src/nile-widget-viewer/index.js +2 -0
- package/dist/src/nile-widget-viewer/nile-widget-viewer.css.d.ts +1 -0
- package/dist/src/nile-widget-viewer/nile-widget-viewer.css.js +20 -0
- package/dist/src/nile-widget-viewer/nile-widget-viewer.d.ts +33 -0
- package/dist/src/nile-widget-viewer/nile-widget-viewer.js +50 -0
- package/package.json +4 -2
|
@@ -16,6 +16,7 @@ import '../nile-spline-chart/index.js';
|
|
|
16
16
|
import '../nile-radar-chart/index.js';
|
|
17
17
|
import '../nile-gauge-chart/index.js';
|
|
18
18
|
import '../nile-waterfall-chart/index.js';
|
|
19
|
+
import '../nile-map-chart/index.js';
|
|
19
20
|
import '../nile-cluster-chart/index.js';
|
|
20
21
|
import '../nile-stacked-chart/index.js';
|
|
21
22
|
import '../nile-histogram-chart/index.js';
|
|
@@ -58,6 +59,11 @@ export declare class NileChart extends NileElement {
|
|
|
58
59
|
*/
|
|
59
60
|
chartTypeAttr: string;
|
|
60
61
|
/** Summary/insight text — shown as the AI panel's opening message when the chat is opened. */
|
|
62
|
+
/**
|
|
63
|
+
* When set, fills `chart.type` if the config omits it (same values as `chart.type`, e.g. `stacked`, `pie`).
|
|
64
|
+
* Usage: `<nile-chart chart-type="pie" />` plus `config.chart` with series data only.
|
|
65
|
+
*/
|
|
66
|
+
/** Summary/insight text — shown as the AI panel's opening message when the chat is opened. */
|
|
61
67
|
summary: string;
|
|
62
68
|
private activeType;
|
|
63
69
|
private activeConfig;
|
|
@@ -67,9 +73,12 @@ export declare class NileChart extends NileElement {
|
|
|
67
73
|
private hasHeaderSlotContent;
|
|
68
74
|
/** True when elements are projected into `header-actions` (used to show the header row). */
|
|
69
75
|
private hasHeaderActionsSlot;
|
|
76
|
+
/** True when elements are projected into the `header` slot (default title/subtitle hidden). */
|
|
77
|
+
/** True when elements are projected into `header-actions` (used to show the header row). */
|
|
70
78
|
private aiPanel;
|
|
71
79
|
private get effectiveSummary();
|
|
72
80
|
/** AI panel shows when ai.enabled is true OR when a summary is provided. */
|
|
81
|
+
/** AI panel shows when ai.enabled is true OR when a summary is provided. */
|
|
73
82
|
private get aiEnabled();
|
|
74
83
|
private handleOutsideClick;
|
|
75
84
|
connectedCallback(): void;
|
|
@@ -91,6 +100,8 @@ export declare class NileChart extends NileElement {
|
|
|
91
100
|
private onHeaderActionsSlotChange;
|
|
92
101
|
private syncHeaderSlots;
|
|
93
102
|
protected firstUpdated(changedProperties: PropertyValues): void;
|
|
103
|
+
/** Direct children with `slot=` — header row renders on first paint before slot assignment runs. */
|
|
104
|
+
private lightDomHasSlot;
|
|
94
105
|
private shouldShowHeader;
|
|
95
106
|
private renderTypeSwitcher;
|
|
96
107
|
private renderAiTrigger;
|
|
@@ -19,6 +19,7 @@ import '../nile-spline-chart/index.js';
|
|
|
19
19
|
import '../nile-radar-chart/index.js';
|
|
20
20
|
import '../nile-gauge-chart/index.js';
|
|
21
21
|
import '../nile-waterfall-chart/index.js';
|
|
22
|
+
import '../nile-map-chart/index.js';
|
|
22
23
|
import '../nile-cluster-chart/index.js';
|
|
23
24
|
import '../nile-stacked-chart/index.js';
|
|
24
25
|
import '../nile-histogram-chart/index.js';
|
|
@@ -66,6 +67,7 @@ const CORE_CHART_LABELS = {
|
|
|
66
67
|
radar: 'Radar',
|
|
67
68
|
gauge: 'Gauge',
|
|
68
69
|
waterfall: 'Waterfall',
|
|
70
|
+
map: 'Map',
|
|
69
71
|
stacked: 'Stacked column',
|
|
70
72
|
cluster: 'Cluster',
|
|
71
73
|
histogram: 'Histogram',
|
|
@@ -107,6 +109,11 @@ let NileChart = class NileChart extends NileElement {
|
|
|
107
109
|
*/
|
|
108
110
|
this.chartTypeAttr = '';
|
|
109
111
|
/** Summary/insight text — shown as the AI panel's opening message when the chat is opened. */
|
|
112
|
+
/**
|
|
113
|
+
* When set, fills `chart.type` if the config omits it (same values as `chart.type`, e.g. `stacked`, `pie`).
|
|
114
|
+
* Usage: `<nile-chart chart-type="pie" />` plus `config.chart` with series data only.
|
|
115
|
+
*/
|
|
116
|
+
/** Summary/insight text — shown as the AI panel's opening message when the chat is opened. */
|
|
110
117
|
this.summary = '';
|
|
111
118
|
this.activeType = null;
|
|
112
119
|
this.activeConfig = null;
|
|
@@ -120,6 +127,7 @@ let NileChart = class NileChart extends NileElement {
|
|
|
120
127
|
if (!this.contains(e.target)) {
|
|
121
128
|
this.menuOpen = false;
|
|
122
129
|
this.chatOpen = false;
|
|
130
|
+
this.chatOpen = false;
|
|
123
131
|
}
|
|
124
132
|
};
|
|
125
133
|
this.resolvedConfig = null;
|
|
@@ -128,8 +136,10 @@ let NileChart = class NileChart extends NileElement {
|
|
|
128
136
|
return this.resolvedConfig?.summary ?? this.summary;
|
|
129
137
|
}
|
|
130
138
|
/** AI panel shows when ai.enabled is true OR when a summary is provided. */
|
|
139
|
+
/** AI panel shows when ai.enabled is true OR when a summary is provided. */
|
|
131
140
|
get aiEnabled() {
|
|
132
141
|
return this.resolvedConfig?.ai?.enabled === true || !!this.effectiveSummary;
|
|
142
|
+
return this.resolvedConfig?.ai?.enabled === true || !!this.effectiveSummary;
|
|
133
143
|
}
|
|
134
144
|
connectedCallback() {
|
|
135
145
|
super.connectedCallback();
|
|
@@ -248,12 +258,22 @@ let NileChart = class NileChart extends NileElement {
|
|
|
248
258
|
super.firstUpdated(changedProperties);
|
|
249
259
|
this.syncHeaderSlots();
|
|
250
260
|
}
|
|
261
|
+
/** Direct children with `slot=` — header row renders on first paint before slot assignment runs. */
|
|
262
|
+
lightDomHasSlot(name) {
|
|
263
|
+
for (let i = 0; i < this.children.length; i++) {
|
|
264
|
+
if (this.children[i].getAttribute('slot') === name)
|
|
265
|
+
return true;
|
|
266
|
+
}
|
|
267
|
+
return false;
|
|
268
|
+
}
|
|
251
269
|
shouldShowHeader() {
|
|
252
270
|
const hasTitles = !!(this.headerTitle || this.headerSubtitle);
|
|
253
271
|
const hasBuiltinActions = this.aiEnabled || (this.resolvedConfig?.switchableTypes?.length ?? 0) > 0;
|
|
254
272
|
return (hasTitles ||
|
|
255
273
|
this.hasHeaderSlotContent ||
|
|
256
274
|
this.hasHeaderActionsSlot ||
|
|
275
|
+
this.lightDomHasSlot('header') ||
|
|
276
|
+
this.lightDomHasSlot('header-actions') ||
|
|
257
277
|
hasBuiltinActions);
|
|
258
278
|
}
|
|
259
279
|
renderTypeSwitcher() {
|
|
@@ -309,13 +329,14 @@ let NileChart = class NileChart extends NileElement {
|
|
|
309
329
|
const title = this.headerTitle;
|
|
310
330
|
const subtitle = this.headerSubtitle;
|
|
311
331
|
const showDefaultTitles = !this.hasHeaderSlotContent && !!(title || subtitle);
|
|
332
|
+
const headerCompact = !subtitle?.trim();
|
|
312
333
|
return html `
|
|
313
|
-
<div class="chart-header">
|
|
334
|
+
<div class="chart-header ${headerCompact ? 'chart-header--compact' : ''}">
|
|
314
335
|
<div class="chart-header-titles">
|
|
315
336
|
<slot name="header" @slotchange=${this.onHeaderSlotChange}></slot>
|
|
316
337
|
${showDefaultTitles
|
|
317
338
|
? html `
|
|
318
|
-
${title ? html `<
|
|
339
|
+
${title ? html `<p class="chart-header-title">${title}</p>` : nothing}
|
|
319
340
|
${subtitle ? html `<p class="chart-header-subtitle">${subtitle}</p>` : nothing}
|
|
320
341
|
`
|
|
321
342
|
: nothing}
|
|
@@ -429,6 +450,7 @@ let NileChart = class NileChart extends NileElement {
|
|
|
429
450
|
.height=${config.height ?? '400px'}
|
|
430
451
|
.innerSize=${config.innerSize ?? '50%'}
|
|
431
452
|
.semiCircle=${config.semiCircle ?? false}
|
|
453
|
+
.semiCircle=${config.semiCircle ?? false}
|
|
432
454
|
.showDataLabels=${config.showDataLabels ?? true}
|
|
433
455
|
.showLegend=${config.showLegend ?? true}
|
|
434
456
|
.options=${mergedOptions}
|
|
@@ -489,6 +511,17 @@ let NileChart = class NileChart extends NileElement {
|
|
|
489
511
|
.options=${mergedOptions}
|
|
490
512
|
.loading=${config.loading ?? false}
|
|
491
513
|
></nile-waterfall-chart>`;
|
|
514
|
+
case 'map':
|
|
515
|
+
return html `<nile-map-chart
|
|
516
|
+
.data=${config.data}
|
|
517
|
+
.mapData=${config.mapData ?? null}
|
|
518
|
+
.joinBy=${config.joinBy ?? ['hc-key', 'hc-key']}
|
|
519
|
+
.seriesType=${config.seriesType ?? 'map'}
|
|
520
|
+
.zoom=${config.zoom ?? true}
|
|
521
|
+
.height=${config.height ?? '500px'}
|
|
522
|
+
.options=${mergedOptions}
|
|
523
|
+
.loading=${config.loading ?? false}
|
|
524
|
+
></nile-map-chart>`;
|
|
492
525
|
case 'stacked':
|
|
493
526
|
return html `<nile-stacked-chart
|
|
494
527
|
.data=${config.data}
|
|
@@ -819,6 +852,7 @@ let NileChart = class NileChart extends NileElement {
|
|
|
819
852
|
case 'kpi': {
|
|
820
853
|
const k = config;
|
|
821
854
|
return html `<nile-kpi-chart
|
|
855
|
+
embed-in-nile-chart
|
|
822
856
|
.config=${{
|
|
823
857
|
chart: {
|
|
824
858
|
type: 'kpi',
|
|
@@ -859,6 +893,9 @@ let NileChart = class NileChart extends NileElement {
|
|
|
859
893
|
${this.renderHeader()}
|
|
860
894
|
<div class="chart-wrapper">
|
|
861
895
|
<div class="chart-inner">
|
|
896
|
+
<div
|
|
897
|
+
class="chart-inner ${this.activeConfig?.type === 'kpi' ? 'chart-inner--kpi' : ''}"
|
|
898
|
+
>
|
|
862
899
|
${this.activeConfig ? this.renderChartContent() : html `<slot></slot>`}
|
|
863
900
|
${this.renderAiPanel()}
|
|
864
901
|
</div>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const styles: import("lit").CSSResult;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { css } from 'lit';
|
|
2
|
+
export const styles = css `
|
|
3
|
+
:host {
|
|
4
|
+
display: block;
|
|
5
|
+
width: 100%;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
:host([hidden]) {
|
|
9
|
+
display: none;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.dashboard-grid {
|
|
13
|
+
display: grid;
|
|
14
|
+
width: 100%;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.dashboard-cell {
|
|
18
|
+
overflow: hidden;
|
|
19
|
+
min-height: 0;
|
|
20
|
+
min-width: 0;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
nile-widget-viewer {
|
|
24
|
+
display: block;
|
|
25
|
+
width: 100%;
|
|
26
|
+
height: 100%;
|
|
27
|
+
}
|
|
28
|
+
`;
|
|
29
|
+
//# sourceMappingURL=nile-dashboard-viewer.css.js.map
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { nothing } from 'lit';
|
|
2
|
+
import type { CSSResultGroup, TemplateResult } from 'lit';
|
|
3
|
+
import NileElement from '../internal/nile-element.js';
|
|
4
|
+
import type { NileDashboardConfig } from '../internal/types/dashboard-config.type.js';
|
|
5
|
+
import '../nile-widget-viewer/index.js';
|
|
6
|
+
/**
|
|
7
|
+
* Renders a full dashboard grid of widgets. Each widget is positioned using CSS Grid
|
|
8
|
+
* with the `layout: { x, y, w, h }` values from its config.
|
|
9
|
+
*
|
|
10
|
+
* - `x` / `w` → `grid-column: (x+1) / span w`
|
|
11
|
+
* - `y` / `h` → `grid-row: (y+1) / span h`
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```html
|
|
15
|
+
* <nile-dashboard-viewer columns="12" cell-height="80" gap="8"></nile-dashboard-viewer>
|
|
16
|
+
* ```
|
|
17
|
+
* ```js
|
|
18
|
+
* el.config = {
|
|
19
|
+
* name: 'My Dashboard',
|
|
20
|
+
* widgets: [
|
|
21
|
+
* { type: 'chart', layout: { x: 0, y: 0, w: 6, h: 4 }, nileConfig: { chart: { type: 'pie', data: [...] } } },
|
|
22
|
+
* { type: 'kpi', layout: { x: 0, y: 4, w: 3, h: 2 }, nileConfig: { chart: { type: 'kpi', label: 'Revenue', value: '$1.2M' } } },
|
|
23
|
+
* ]
|
|
24
|
+
* };
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export declare class NileDashboardViewer extends NileElement {
|
|
28
|
+
static styles: CSSResultGroup;
|
|
29
|
+
/** Dashboard configuration containing all widget configs. */
|
|
30
|
+
config: NileDashboardConfig | null;
|
|
31
|
+
/** Total number of grid columns. Default: 12. */
|
|
32
|
+
columns: number;
|
|
33
|
+
/** Height of a single grid row in pixels. Default: 80. */
|
|
34
|
+
cellHeight: number;
|
|
35
|
+
/** Gap between grid cells in pixels. Default: 8. */
|
|
36
|
+
gap: number;
|
|
37
|
+
render(): TemplateResult | typeof nothing;
|
|
38
|
+
}
|
|
39
|
+
declare global {
|
|
40
|
+
interface HTMLElementTagNameMap {
|
|
41
|
+
'nile-dashboard-viewer': NileDashboardViewer;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { __decorate } from "tslib";
|
|
2
|
+
import { customElement, property } from 'lit/decorators.js';
|
|
3
|
+
import { html, nothing } from 'lit';
|
|
4
|
+
import NileElement from '../internal/nile-element.js';
|
|
5
|
+
import { styles } from './nile-dashboard-viewer.css.js';
|
|
6
|
+
import '../nile-widget-viewer/index.js';
|
|
7
|
+
/**
|
|
8
|
+
* Renders a full dashboard grid of widgets. Each widget is positioned using CSS Grid
|
|
9
|
+
* with the `layout: { x, y, w, h }` values from its config.
|
|
10
|
+
*
|
|
11
|
+
* - `x` / `w` → `grid-column: (x+1) / span w`
|
|
12
|
+
* - `y` / `h` → `grid-row: (y+1) / span h`
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```html
|
|
16
|
+
* <nile-dashboard-viewer columns="12" cell-height="80" gap="8"></nile-dashboard-viewer>
|
|
17
|
+
* ```
|
|
18
|
+
* ```js
|
|
19
|
+
* el.config = {
|
|
20
|
+
* name: 'My Dashboard',
|
|
21
|
+
* widgets: [
|
|
22
|
+
* { type: 'chart', layout: { x: 0, y: 0, w: 6, h: 4 }, nileConfig: { chart: { type: 'pie', data: [...] } } },
|
|
23
|
+
* { type: 'kpi', layout: { x: 0, y: 4, w: 3, h: 2 }, nileConfig: { chart: { type: 'kpi', label: 'Revenue', value: '$1.2M' } } },
|
|
24
|
+
* ]
|
|
25
|
+
* };
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
let NileDashboardViewer = class NileDashboardViewer extends NileElement {
|
|
29
|
+
constructor() {
|
|
30
|
+
super(...arguments);
|
|
31
|
+
/** Dashboard configuration containing all widget configs. */
|
|
32
|
+
this.config = null;
|
|
33
|
+
/** Total number of grid columns. Default: 12. */
|
|
34
|
+
this.columns = 12;
|
|
35
|
+
/** Height of a single grid row in pixels. Default: 80. */
|
|
36
|
+
this.cellHeight = 80;
|
|
37
|
+
/** Gap between grid cells in pixels. Default: 8. */
|
|
38
|
+
this.gap = 8;
|
|
39
|
+
}
|
|
40
|
+
render() {
|
|
41
|
+
if (!this.config?.widgets?.length)
|
|
42
|
+
return nothing;
|
|
43
|
+
return html `
|
|
44
|
+
<div
|
|
45
|
+
class="dashboard-grid"
|
|
46
|
+
style="
|
|
47
|
+
grid-template-columns: repeat(${this.columns}, 1fr);
|
|
48
|
+
grid-auto-rows: ${this.cellHeight}px;
|
|
49
|
+
gap: ${this.gap}px;
|
|
50
|
+
"
|
|
51
|
+
>
|
|
52
|
+
${this.config.widgets.map((widget) => html `
|
|
53
|
+
<div
|
|
54
|
+
class="dashboard-cell"
|
|
55
|
+
style="
|
|
56
|
+
grid-column: ${widget.layout.x + 1} / span ${widget.layout.w};
|
|
57
|
+
grid-row: ${widget.layout.y + 1} / span ${widget.layout.h};
|
|
58
|
+
"
|
|
59
|
+
>
|
|
60
|
+
<nile-widget-viewer .config=${widget}></nile-widget-viewer>
|
|
61
|
+
</div>
|
|
62
|
+
`)}
|
|
63
|
+
</div>
|
|
64
|
+
`;
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
NileDashboardViewer.styles = styles;
|
|
68
|
+
__decorate([
|
|
69
|
+
property({ type: Object })
|
|
70
|
+
], NileDashboardViewer.prototype, "config", void 0);
|
|
71
|
+
__decorate([
|
|
72
|
+
property({ type: Number })
|
|
73
|
+
], NileDashboardViewer.prototype, "columns", void 0);
|
|
74
|
+
__decorate([
|
|
75
|
+
property({ type: Number, attribute: 'cell-height' })
|
|
76
|
+
], NileDashboardViewer.prototype, "cellHeight", void 0);
|
|
77
|
+
__decorate([
|
|
78
|
+
property({ type: Number })
|
|
79
|
+
], NileDashboardViewer.prototype, "gap", void 0);
|
|
80
|
+
NileDashboardViewer = __decorate([
|
|
81
|
+
customElement('nile-dashboard-viewer')
|
|
82
|
+
], NileDashboardViewer);
|
|
83
|
+
export { NileDashboardViewer };
|
|
84
|
+
//# sourceMappingURL=nile-dashboard-viewer.js.map
|
|
@@ -1,18 +1,20 @@
|
|
|
1
1
|
import { css } from 'lit';
|
|
2
2
|
export const styles = css `
|
|
3
3
|
:host {
|
|
4
|
-
display:
|
|
4
|
+
display: flex;
|
|
5
|
+
flex-direction: column;
|
|
5
6
|
width: 100%;
|
|
6
7
|
position: relative;
|
|
8
|
+
box-sizing: border-box;
|
|
7
9
|
}
|
|
8
10
|
|
|
9
11
|
:host([hidden]) {
|
|
10
12
|
display: none;
|
|
11
13
|
}
|
|
12
14
|
|
|
13
|
-
/*
|
|
14
|
-
|
|
15
|
-
|
|
15
|
+
/* Card / gauge chrome on the host when used alone (inside nile-chart, embed-in-nile-chart skips this). */
|
|
16
|
+
:host([variant='card']:not([embed-in-nile-chart])),
|
|
17
|
+
:host([variant='gauge']:not([embed-in-nile-chart])) {
|
|
16
18
|
background: transparent;
|
|
17
19
|
border: var(--nile-border-width-1, var(--ng-stroke-width-1)) solid var(--nile-colors-neutral-400, var(--ng-colors-border-secondary));
|
|
18
20
|
border-radius: var(--nile-radius-radius-3xl, var(--ng-radius-xl));
|
|
@@ -20,13 +22,14 @@ export const styles = css `
|
|
|
20
22
|
transition: box-shadow var(--nile-transition-duration-default, var(--ng-transition-duration-default)) ease;
|
|
21
23
|
}
|
|
22
24
|
|
|
23
|
-
|
|
25
|
+
:host([variant='card']:not([embed-in-nile-chart]):hover),
|
|
26
|
+
:host([variant='gauge']:not([embed-in-nile-chart]):hover) {
|
|
24
27
|
box-shadow: var(--nile-box-shadow-7, var(--ng-shadow-md));
|
|
25
28
|
}
|
|
26
29
|
|
|
27
|
-
/* ── Base layout ── */
|
|
28
|
-
|
|
29
30
|
.kpi {
|
|
31
|
+
flex: 1 1 auto;
|
|
32
|
+
|
|
30
33
|
display: flex;
|
|
31
34
|
flex-direction: column;
|
|
32
35
|
gap: var(--nile-spacing-md, var(--ng-spacing-md));
|
|
@@ -52,7 +55,7 @@ export const styles = css `
|
|
|
52
55
|
.kpi-value {
|
|
53
56
|
margin: 0;
|
|
54
57
|
font-family: var(--nile-font-family-serif-colfax-medium, var(--ng-font-family-display));
|
|
55
|
-
font-size: 36px;
|
|
58
|
+
font-size: clamp(1.25rem, 2.5vw + 0.75rem, 36px);
|
|
56
59
|
font-weight: var(--nile-font-weight-semi-bold, var(--ng-font-weight-semibold));
|
|
57
60
|
color: var(--nile-colors-dark-900, var(--ng-colors-text-primary-900));
|
|
58
61
|
line-height: 1.2;
|
|
@@ -115,7 +118,8 @@ export const styles = css `
|
|
|
115
118
|
|
|
116
119
|
.kpi-sparkline {
|
|
117
120
|
width: 100%;
|
|
118
|
-
|
|
121
|
+
flex: 0 1 48px;
|
|
122
|
+
min-height: 22px;
|
|
119
123
|
margin-top: var(--nile-spacing-xs, var(--ng-spacing-xs));
|
|
120
124
|
}
|
|
121
125
|
|
|
@@ -127,8 +131,11 @@ export const styles = css `
|
|
|
127
131
|
}
|
|
128
132
|
|
|
129
133
|
.kpi-gauge-container {
|
|
130
|
-
width:
|
|
131
|
-
|
|
134
|
+
width: 100%;
|
|
135
|
+
max-width: 160px;
|
|
136
|
+
aspect-ratio: 1;
|
|
137
|
+
flex: 0 1 160px;
|
|
138
|
+
min-width: 72px;
|
|
132
139
|
margin: 0 auto;
|
|
133
140
|
}
|
|
134
141
|
|
|
@@ -153,6 +160,7 @@ export const styles = css `
|
|
|
153
160
|
/* ── Loading state ── */
|
|
154
161
|
|
|
155
162
|
.chart-loading {
|
|
163
|
+
flex: 1 1 auto;
|
|
156
164
|
display: flex;
|
|
157
165
|
align-items: center;
|
|
158
166
|
justify-content: center;
|
|
@@ -24,8 +24,8 @@ export interface ChartKpiSeparatedPayload {
|
|
|
24
24
|
gaugeColor?: string;
|
|
25
25
|
loading?: boolean;
|
|
26
26
|
options?: Highcharts.Options;
|
|
27
|
-
/**
|
|
28
|
-
height?: string;
|
|
27
|
+
/** Box size when a height is set (host min-height and height). */
|
|
28
|
+
height?: string | number;
|
|
29
29
|
}
|
|
30
30
|
/** Separated `{ chart, aq }` input for `<nile-kpi-chart>`. */
|
|
31
31
|
export interface NileKpiConfigInputType {
|
|
@@ -89,12 +89,18 @@ export declare class NileKpiChart extends NileElement {
|
|
|
89
89
|
loading: boolean;
|
|
90
90
|
/** Highcharts options override for the sparkline or gauge. */
|
|
91
91
|
options: Highcharts.Options;
|
|
92
|
+
/**
|
|
93
|
+
* Set by nile-chart: skip host border/shadow (variant card/gauge) so the parent chart-card is the only frame.
|
|
94
|
+
*/
|
|
95
|
+
embedInNileChart: boolean;
|
|
96
|
+
private formatCssLength;
|
|
92
97
|
/** Apply `{ chart, aq }` to individual properties. */
|
|
93
98
|
private applyConfig;
|
|
94
99
|
connectedCallback(): void;
|
|
95
100
|
disconnectedCallback(): void;
|
|
96
101
|
protected firstUpdated(): void;
|
|
97
102
|
protected updated(changedProperties: PropertyValues): void;
|
|
103
|
+
private syncSparklineChartSize;
|
|
98
104
|
private setupResizeObserver;
|
|
99
105
|
private buildSparklineOptions;
|
|
100
106
|
private buildGaugeOptions;
|
|
@@ -47,6 +47,23 @@ let NileKpiChart = class NileKpiChart extends NileElement {
|
|
|
47
47
|
this.loading = false;
|
|
48
48
|
/** Highcharts options override for the sparkline or gauge. */
|
|
49
49
|
this.options = {};
|
|
50
|
+
/**
|
|
51
|
+
* Set by nile-chart: skip host border/shadow (variant card/gauge) so the parent chart-card is the only frame.
|
|
52
|
+
*/
|
|
53
|
+
this.embedInNileChart = false;
|
|
54
|
+
}
|
|
55
|
+
formatCssLength(value) {
|
|
56
|
+
if (value == null)
|
|
57
|
+
return null;
|
|
58
|
+
if (typeof value === 'number') {
|
|
59
|
+
return Number.isFinite(value) ? `${value}px` : null;
|
|
60
|
+
}
|
|
61
|
+
const s = String(value).trim();
|
|
62
|
+
if (!s)
|
|
63
|
+
return null;
|
|
64
|
+
if (/^-?\d*\.?\d+$/.test(s))
|
|
65
|
+
return `${s}px`;
|
|
66
|
+
return s;
|
|
50
67
|
}
|
|
51
68
|
/** Apply `{ chart, aq }` to individual properties. */
|
|
52
69
|
applyConfig(cfg) {
|
|
@@ -86,11 +103,19 @@ let NileKpiChart = class NileKpiChart extends NileElement {
|
|
|
86
103
|
this.loading = c.loading;
|
|
87
104
|
if (c.options !== undefined)
|
|
88
105
|
this.options = c.options;
|
|
89
|
-
if (
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
106
|
+
if ('height' in c) {
|
|
107
|
+
const h = this.formatCssLength(c.height);
|
|
108
|
+
if (h) {
|
|
109
|
+
/* min-height only: host can grow with content; sparkline shrinks via flex + setSize */
|
|
110
|
+
this.style.minHeight = h;
|
|
111
|
+
this.style.removeProperty('height');
|
|
112
|
+
this.style.removeProperty('max-height');
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
93
115
|
this.style.removeProperty('min-height');
|
|
116
|
+
this.style.removeProperty('height');
|
|
117
|
+
this.style.removeProperty('max-height');
|
|
118
|
+
}
|
|
94
119
|
}
|
|
95
120
|
}
|
|
96
121
|
if (aq) {
|
|
@@ -125,6 +150,7 @@ let NileKpiChart = class NileKpiChart extends NileElement {
|
|
|
125
150
|
if (sparklineProps.some(p => changedProperties.has(p))) {
|
|
126
151
|
if (this.sparklineChart) {
|
|
127
152
|
this.sparklineChart.update(this.buildSparklineOptions(), true, true);
|
|
153
|
+
requestAnimationFrame(() => this.syncSparklineChartSize());
|
|
128
154
|
}
|
|
129
155
|
else {
|
|
130
156
|
this.initSparkline();
|
|
@@ -140,9 +166,16 @@ let NileKpiChart = class NileKpiChart extends NileElement {
|
|
|
140
166
|
}
|
|
141
167
|
}
|
|
142
168
|
}
|
|
169
|
+
syncSparklineChartSize() {
|
|
170
|
+
if (!this.sparklineChart || !this.sparklineContainer)
|
|
171
|
+
return;
|
|
172
|
+
const rect = this.sparklineContainer.getBoundingClientRect();
|
|
173
|
+
const h = Math.max(22, Math.round(rect.height));
|
|
174
|
+
this.sparklineChart.setSize(null, h, false);
|
|
175
|
+
}
|
|
143
176
|
setupResizeObserver() {
|
|
144
177
|
this.resizeObserver = new ResizeObserver(() => {
|
|
145
|
-
this.
|
|
178
|
+
this.syncSparklineChartSize();
|
|
146
179
|
this.gaugeChart?.reflow();
|
|
147
180
|
});
|
|
148
181
|
if (this.sparklineContainer)
|
|
@@ -252,6 +285,7 @@ let NileKpiChart = class NileKpiChart extends NileElement {
|
|
|
252
285
|
this._hc = await getHighcharts();
|
|
253
286
|
this.destroySparkline();
|
|
254
287
|
this.sparklineChart = this._hc.chart(this.sparklineContainer, this.buildSparklineOptions());
|
|
288
|
+
requestAnimationFrame(() => this.syncSparklineChartSize());
|
|
255
289
|
this.emit('nile-chart-ready', { chart: this.sparklineChart });
|
|
256
290
|
}
|
|
257
291
|
async initGauge() {
|
|
@@ -326,10 +360,7 @@ let NileKpiChart = class NileKpiChart extends NileElement {
|
|
|
326
360
|
if (this.loading) {
|
|
327
361
|
return html `<div class="chart-loading">Loading...</div>`;
|
|
328
362
|
}
|
|
329
|
-
|
|
330
|
-
if (useCard) {
|
|
331
|
-
return html `<div class="kpi-card">${this.renderContent()}</div>`;
|
|
332
|
-
}
|
|
363
|
+
/* Same DOM as inside nile-chart: one surface; card/gauge chrome is on :host when standalone. */
|
|
333
364
|
return this.renderContent();
|
|
334
365
|
}
|
|
335
366
|
};
|
|
@@ -394,6 +425,9 @@ __decorate([
|
|
|
394
425
|
__decorate([
|
|
395
426
|
property({ type: Object })
|
|
396
427
|
], NileKpiChart.prototype, "options", void 0);
|
|
428
|
+
__decorate([
|
|
429
|
+
property({ type: Boolean, reflect: true, attribute: 'embed-in-nile-chart' })
|
|
430
|
+
], NileKpiChart.prototype, "embedInNileChart", void 0);
|
|
397
431
|
NileKpiChart = __decorate([
|
|
398
432
|
customElement('nile-kpi-chart')
|
|
399
433
|
], NileKpiChart);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const styles: import("lit").CSSResult;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { css } from 'lit';
|
|
2
|
+
export const styles = css `
|
|
3
|
+
:host {
|
|
4
|
+
display: block;
|
|
5
|
+
width: 100%;
|
|
6
|
+
position: relative;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
:host([hidden]) {
|
|
10
|
+
display: none;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.chart-container {
|
|
14
|
+
width: 100%;
|
|
15
|
+
min-height: var(--nile-height-200px, var(--ng-height-200px));
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.chart-loading {
|
|
19
|
+
display: flex;
|
|
20
|
+
align-items: center;
|
|
21
|
+
justify-content: center;
|
|
22
|
+
min-height: inherit;
|
|
23
|
+
color: var(--nile-colors-neutral-700, var(--ng-colors-text-secondary-700));
|
|
24
|
+
font-family: var(--nile-font-family-serif, var(--ng-font-family-body));
|
|
25
|
+
font-size: var(--nile-type-scale-3, var(--ng-font-size-text-sm));
|
|
26
|
+
}
|
|
27
|
+
`;
|
|
28
|
+
//# sourceMappingURL=nile-map-chart.css.js.map
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import type { CSSResultGroup, PropertyValues, TemplateResult } from 'lit';
|
|
2
|
+
import type Highcharts from 'highcharts';
|
|
3
|
+
import NileElement from '../internal/nile-element.js';
|
|
4
|
+
import type { NileChartConfigInputType } from '../internal/types/index.js';
|
|
5
|
+
export interface MapChartDataPoint {
|
|
6
|
+
/** Highcharts map key matching the map topology (e.g. 'us-ca'). */
|
|
7
|
+
'hc-key'?: string;
|
|
8
|
+
value: number;
|
|
9
|
+
name?: string;
|
|
10
|
+
color?: string;
|
|
11
|
+
[key: string]: unknown;
|
|
12
|
+
}
|
|
13
|
+
export declare class NileMapChart extends NileElement {
|
|
14
|
+
static styles: CSSResultGroup;
|
|
15
|
+
private _hc;
|
|
16
|
+
private chart;
|
|
17
|
+
private resizeObserver;
|
|
18
|
+
private chartContainer;
|
|
19
|
+
/** Full chart configuration. Accepts separated { chart, aq } input. */
|
|
20
|
+
config: NileChartConfigInputType | null;
|
|
21
|
+
/** The chart title displayed above the chart. */
|
|
22
|
+
chartTitle: string;
|
|
23
|
+
/** The subtitle displayed below the title. */
|
|
24
|
+
chartSubtitle: string;
|
|
25
|
+
/**
|
|
26
|
+
* Array of data points. Each point should have a value and a key matching the
|
|
27
|
+
* map topology (e.g. `{ 'hc-key': 'us-ca', value: 42 }`).
|
|
28
|
+
*/
|
|
29
|
+
data: MapChartDataPoint[];
|
|
30
|
+
/**
|
|
31
|
+
* GeoJSON or Highcharts topology object describing the map shapes.
|
|
32
|
+
* Obtain from https://code.highcharts.com/mapdata/ or supply your own.
|
|
33
|
+
*/
|
|
34
|
+
mapData: object | null;
|
|
35
|
+
/**
|
|
36
|
+
* How to join `data` with `mapData`. Defaults to `['hc-key', 'hc-key']`.
|
|
37
|
+
* Pass a single string to match by that property name on both sides,
|
|
38
|
+
* or a two-element array `[mapKey, dataKey]` for different key names.
|
|
39
|
+
*/
|
|
40
|
+
joinBy: string | string[];
|
|
41
|
+
/** Deep-merge override object for full Highcharts options. */
|
|
42
|
+
options: Highcharts.Options;
|
|
43
|
+
/** Whether to show a loading indicator instead of the chart. */
|
|
44
|
+
loading: boolean;
|
|
45
|
+
/** CSS height for the chart container. */
|
|
46
|
+
height: string;
|
|
47
|
+
/** Enable mouse-wheel zoom, double-click zoom, and +/− zoom buttons. Default: true. */
|
|
48
|
+
zoom: boolean;
|
|
49
|
+
/**
|
|
50
|
+
* Type of the primary map series.
|
|
51
|
+
* - `'map'` (default) — choropleth/filled regions
|
|
52
|
+
* - `'mapline'` — line/route overlay
|
|
53
|
+
* - `'mappoint'` — scatter points on map
|
|
54
|
+
* - `'mapbubble'` — sized bubbles on map
|
|
55
|
+
* For multi-series or `tiledwebmap`, pass `options.series` directly (it replaces the default series).
|
|
56
|
+
*/
|
|
57
|
+
seriesType: 'map' | 'mapline' | 'mappoint' | 'mapbubble' | 'tiledwebmap';
|
|
58
|
+
/** Apply { chart, aq } config to individual properties. */
|
|
59
|
+
private applyConfig;
|
|
60
|
+
connectedCallback(): void;
|
|
61
|
+
disconnectedCallback(): void;
|
|
62
|
+
protected firstUpdated(): void;
|
|
63
|
+
protected updated(changedProperties: PropertyValues): void;
|
|
64
|
+
private setupResizeObserver;
|
|
65
|
+
private buildOptions;
|
|
66
|
+
private initChart;
|
|
67
|
+
private destroyChart;
|
|
68
|
+
render(): TemplateResult;
|
|
69
|
+
}
|
|
70
|
+
declare global {
|
|
71
|
+
interface HTMLElementTagNameMap {
|
|
72
|
+
'nile-map-chart': NileMapChart;
|
|
73
|
+
}
|
|
74
|
+
}
|