@aquera/nile-visualization 2.9.8 → 2.9.10

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.
@@ -117,6 +117,7 @@ export interface NileAiConfig {
117
117
  export interface NileChartConfigBase {
118
118
  chartTitle?: string;
119
119
  chartSubtitle?: string;
120
+ noHeader?: boolean;
120
121
  height?: string;
121
122
  loading?: boolean;
122
123
  options?: import('highcharts').Options;
@@ -0,0 +1,2 @@
1
+ import { type TemplateResult } from 'lit';
2
+ export declare function renderChartSkeleton(chartType: string | undefined): TemplateResult;
@@ -0,0 +1,184 @@
1
+ import { html } from 'lit';
2
+ const SKELETON_TYPE_MAP = {
3
+ column: 'columns', stacked: 'columns', cluster: 'columns', histogram: 'columns',
4
+ waterfall: 'columns', funnel: 'columns', columnPyramid: 'columns',
5
+ columnRange: 'columns', columnDrilldown: 'columns', lollipop: 'columns',
6
+ line: 'line', area: 'line', spline: 'line', areaSpline: 'line',
7
+ invertedArea: 'line', areaNegative: 'line', areaRange: 'line',
8
+ fan: 'line', bellcurve: 'line',
9
+ trendline: 'trendline', anomaly: 'anomaly',
10
+ pie: 'pie', donut: 'pie', variablePie: 'pie', radialBar: 'pie', gauge: 'pie', euler: 'pie',
11
+ scatter: 'scatter', bubble: 'scatter', dumbbell: 'scatter', boxplot: 'scatter',
12
+ heatmap: 'heatmap', flame: 'heatmap',
13
+ radar: 'radar', spiderweb: 'radar',
14
+ timeline: 'timeline', xrange: 'timeline',
15
+ kpi: 'kpi', grid: 'grid', filter: 'filter',
16
+ };
17
+ const SCATTER_DOTS = [
18
+ [12, 70, 8], [22, 45, 10], [28, 78, 6], [38, 30, 12], [46, 58, 7],
19
+ [54, 22, 9], [62, 65, 11], [70, 40, 7], [78, 75, 10], [88, 35, 8],
20
+ [18, 30, 6], [50, 80, 8],
21
+ ];
22
+ const TIMELINE_BARS = [
23
+ [5, 38], [22, 28], [12, 55], [40, 22], [30, 40], [55, 30],
24
+ ];
25
+ const sk = (variant, width, height, borderRadius) => borderRadius
26
+ ? html `<nile-skeleton-loader part="skeleton-loader" variant=${variant} width=${width} height=${height} border-radius=${borderRadius}></nile-skeleton-loader>`
27
+ : html `<nile-skeleton-loader part="skeleton-loader" variant=${variant} width=${width} height=${height}></nile-skeleton-loader>`;
28
+ const repeat = (n, fn) => Array.from({ length: n }, (_, i) => fn(i));
29
+ const xaxis = (n = 5) => html `
30
+ <div class="nile-chart-skeleton-xaxis-row">
31
+ ${repeat(n, () => html `<div part="skeleton-chip" class="nile-chart-skeleton-xaxis-chip"></div>`)}
32
+ </div>
33
+ `;
34
+ function variantFor(type) {
35
+ return (type && SKELETON_TYPE_MAP[type]) || 'bars';
36
+ }
37
+ function renderBody(v) {
38
+ switch (v) {
39
+ case 'columns':
40
+ return html `
41
+ <div class="nile-chart-skeleton-columns">
42
+ ${[58, 82, 44, 91, 67, 35, 76, 50].map(h => html `<div class="nile-chart-skeleton-col-cell" style="height:${h}%"><div part="skeleton-fill" class="nile-chart-skeleton-fill"></div></div>`)}
43
+ </div>
44
+ <div class="nile-chart-skeleton-xaxis-row nile-chart-skeleton-xaxis-row--columns">
45
+ ${repeat(8, () => html `<div part="skeleton-chip" class="nile-chart-skeleton-xaxis-chip"></div>`)}
46
+ </div>
47
+ `;
48
+ case 'line':
49
+ return html `
50
+ <div class="nile-chart-skeleton-line">
51
+ <svg viewBox="0 0 100 40" preserveAspectRatio="none" aria-hidden="true">
52
+ <path part="skeleton-line skeleton-line-area" class="nile-chart-skeleton-line-area" d="M0,30 C10,20 18,32 28,22 C38,12 48,28 60,18 C72,8 82,24 92,14 L100,16 L100,40 L0,40 Z"></path>
53
+ <path part="skeleton-line skeleton-line-stroke" class="nile-chart-skeleton-line-stroke" d="M0,30 C10,20 18,32 28,22 C38,12 48,28 60,18 C72,8 82,24 92,14 L100,16"></path>
54
+ </svg>
55
+ </div>
56
+ ${xaxis()}
57
+ `;
58
+ case 'trendline':
59
+ // Solid actuals (0–60%) + a dashed straight forecast continuation (60–100%)
60
+ // along the trend, plus a faint trend line through it.
61
+ return html `
62
+ <div class="nile-chart-skeleton-line">
63
+ <svg viewBox="0 0 100 40" preserveAspectRatio="none" aria-hidden="true">
64
+ <line part="skeleton-trend-line" class="nile-chart-skeleton-trend-line" x1="0" y1="28" x2="100" y2="10"></line>
65
+ <path part="skeleton-line skeleton-line-stroke" class="nile-chart-skeleton-line-stroke" d="M0,30 C8,24 14,30 22,22 C30,16 38,24 46,18 C52,14 56,20 60,16"></path>
66
+ <path part="skeleton-line skeleton-trend-forecast" class="nile-chart-skeleton-trend-forecast" d="M60,16 L72,13 L84,11 L100,8"></path>
67
+ </svg>
68
+ </div>
69
+ ${xaxis()}
70
+ `;
71
+ case 'anomaly':
72
+ // Smooth line with a few highlighted anomaly markers off-trend.
73
+ return html `
74
+ <div class="nile-chart-skeleton-line">
75
+ <svg viewBox="0 0 100 40" preserveAspectRatio="none" aria-hidden="true">
76
+ <path class="nile-chart-skeleton-line-stroke" d="M0,26 C10,22 18,24 26,20 C34,16 42,22 50,18 C58,14 66,18 74,16 C82,14 90,16 100,14"></path>
77
+ ${[[18, 6], [50, 32], [74, 4]].map(([x, y]) => html `<circle class="nile-chart-skeleton-anomaly-dot" cx=${x} cy=${y} r="2.5"></circle>`)}
78
+ ${[[18, 6], [50, 32], [74, 4]].map(([x, y]) => html `<circle class="nile-chart-skeleton-anomaly-halo" cx=${x} cy=${y} r="5"></circle>`)}
79
+ </svg>
80
+ </div>
81
+ ${xaxis()}
82
+ `;
83
+ case 'pie':
84
+ return html `
85
+ <div class="nile-chart-skeleton-pie-wrap">
86
+ <div class="nile-chart-skeleton-pie"></div>
87
+ <div class="nile-chart-skeleton-legend">
88
+ ${repeat(4, () => html `<div class="nile-chart-skeleton-legend-row">${sk('circular', 10, 10)}${sk('rounded', 70, 8)}</div>`)}
89
+ </div>
90
+ </div>
91
+ `;
92
+ case 'scatter':
93
+ return html `
94
+ <div class="nile-chart-skeleton-scatter">
95
+ ${SCATTER_DOTS.map(([x, y, r]) => html `<span class="nile-chart-skeleton-dot-pos" style="left:${x}%;top:${y}%;">${sk('circular', r, r)}</span>`)}
96
+ </div>
97
+ ${xaxis()}
98
+ `;
99
+ case 'heatmap':
100
+ return html `
101
+ <div class="nile-chart-skeleton-heatmap">
102
+ ${repeat(4, () => html `<div class="nile-chart-skeleton-heatmap-row">${repeat(7, () => html `<div class="nile-chart-skeleton-heatmap-cell"><div part="skeleton-fill" class="nile-chart-skeleton-fill"></div></div>`)}</div>`)}
103
+ </div>
104
+ `;
105
+ case 'radar': {
106
+ // Pentagon vertices (5-sided radar) at radii 40/27/14 around center (50,50).
107
+ const ring = (r) => [-90, -18, 54, 126, 198]
108
+ .map(deg => {
109
+ const rad = (deg * Math.PI) / 180;
110
+ return `${(50 + r * Math.cos(rad)).toFixed(2)},${(50 + r * Math.sin(rad)).toFixed(2)}`;
111
+ })
112
+ .join(' ');
113
+ const outer = ring(40);
114
+ const data = [35, 22, 30, 18, 28]
115
+ .map((r, i) => {
116
+ const deg = [-90, -18, 54, 126, 198][i];
117
+ const rad = (deg * Math.PI) / 180;
118
+ return `${(50 + r * Math.cos(rad)).toFixed(2)},${(50 + r * Math.sin(rad)).toFixed(2)}`;
119
+ })
120
+ .join(' ');
121
+ const spokes = [-90, -18, 54, 126, 198].map(deg => {
122
+ const rad = (deg * Math.PI) / 180;
123
+ return [50 + 40 * Math.cos(rad), 50 + 40 * Math.sin(rad)];
124
+ });
125
+ return html `
126
+ <div class="nile-chart-skeleton-radar-wrap">
127
+ <svg class="nile-chart-skeleton-radar-svg" viewBox="0 0 100 100" aria-hidden="true">
128
+ <polygon class="nile-chart-skeleton-radar-grid" points=${outer}></polygon>
129
+ <polygon class="nile-chart-skeleton-radar-grid" points=${ring(27)}></polygon>
130
+ <polygon class="nile-chart-skeleton-radar-grid" points=${ring(14)}></polygon>
131
+ ${spokes.map(([x, y]) => html `<line class="nile-chart-skeleton-radar-spoke" x1="50" y1="50" x2=${x.toFixed(2)} y2=${y.toFixed(2)}></line>`)}
132
+ <polygon class="nile-chart-skeleton-radar-data" points=${data}></polygon>
133
+ ${spokes.map(([x, y]) => html `<circle class="nile-chart-skeleton-radar-dot" cx=${x.toFixed(2)} cy=${y.toFixed(2)} r="1.6"></circle>`)}
134
+ </svg>
135
+ </div>
136
+ `;
137
+ }
138
+ case 'timeline':
139
+ return html `
140
+ <div class="nile-chart-skeleton-timeline">
141
+ ${TIMELINE_BARS.map(([x, w]) => html `<div class="nile-chart-skeleton-tl-row"><span class="nile-chart-skeleton-tl-bar-pos" style="left:${x}%;width:${w}%;"><div part="skeleton-fill" class="nile-chart-skeleton-fill"></div></span></div>`)}
142
+ </div>
143
+ ${xaxis()}
144
+ `;
145
+ case 'kpi':
146
+ return html `
147
+ <div class="nile-chart-skeleton-kpi">
148
+ ${sk('rounded', '40%', 10)}${sk('rounded', '60%', 28)}${sk('rounded', '30%', 10)}
149
+ <svg class="nile-chart-skeleton-kpi-spark" viewBox="0 0 100 20" preserveAspectRatio="none" aria-hidden="true">
150
+ <path d="M0,14 L14,10 L28,12 L42,6 L56,9 L70,4 L84,7 L100,2"></path>
151
+ </svg>
152
+ </div>
153
+ `;
154
+ case 'grid':
155
+ return html `
156
+ <div class="nile-chart-skeleton-grid">
157
+ <div class="nile-chart-skeleton-grid-head">${repeat(4, () => sk('rounded', '100%', 12))}</div>
158
+ ${repeat(5, () => html `<div class="nile-chart-skeleton-grid-row">${repeat(4, () => sk('text', '100%', 10))}</div>`)}
159
+ </div>
160
+ `;
161
+ case 'filter':
162
+ return html `
163
+ <div class="nile-chart-skeleton-filter">
164
+ ${sk('rounded', '100%', 36)}
165
+ </div>
166
+ `;
167
+ case 'bars':
168
+ default:
169
+ return html `
170
+ <div class="nile-chart-skeleton-body">
171
+ ${[96, 88, 94, 84, 92].map(w => html `<div class="nile-chart-skeleton-row">
172
+ <nile-skeleton-loader class="nile-chart-skeleton-ylabel-sk" variant="rounded" width="100%" height="10"></nile-skeleton-loader>
173
+ <nile-skeleton-loader class="nile-chart-skeleton-bar-sk" variant="rounded" width="100%" height="18" style="flex:0 1 ${w}%;min-width:0;"></nile-skeleton-loader>
174
+ </div>`)}
175
+ </div>
176
+ ${xaxis()}
177
+ `;
178
+ }
179
+ }
180
+ export function renderChartSkeleton(chartType) {
181
+ const v = variantFor(chartType);
182
+ return html `<div part="skeleton skeleton-${v}" class="nile-chart-skeleton nile-chart-skeleton--${v}" aria-busy="true" aria-label="Loading chart">${renderBody(v)}</div>`;
183
+ }
184
+ //# sourceMappingURL=nile-chart-skeleton.js.map