@aquera/nile-visualization 2.9.5 → 2.9.7
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/nile-chart/nile-chart-config.d.ts +2 -0
- package/dist/src/nile-chart/nile-chart-skeleton.d.ts +2 -0
- package/dist/src/nile-chart/nile-chart-skeleton.js +188 -0
- package/dist/src/nile-chart/nile-chart.css.js +399 -36
- package/dist/src/nile-chart/nile-chart.js +3 -16
- package/dist/src/nile-filter-chart/nile-filter-chart.css.js +11 -18
- package/dist/src/nile-filter-chart/nile-filter-chart.d.ts +5 -0
- package/dist/src/nile-filter-chart/nile-filter-chart.js +28 -0
- package/dist/src/nile-filter-chart/utils/prompt.js +120 -44
- package/dist/src/nile-filter-chart/utils/types.d.ts +4 -0
- package/dist/src/nile-kpi-chart/nile-kpi-chart.css.js +310 -17
- package/dist/src/nile-kpi-chart/nile-kpi-chart.d.ts +4 -2
- package/dist/src/nile-kpi-chart/nile-kpi-chart.js +145 -26
- package/package.json +1 -1
|
@@ -524,6 +524,8 @@ export interface NileKpiChartConfig extends NileChartConfigBase {
|
|
|
524
524
|
cardPaddingVertical?: string | number;
|
|
525
525
|
cardPaddingHorizontal?: string | number;
|
|
526
526
|
contentGap?: string | number;
|
|
527
|
+
/** Accent bar colour for the 'accent' variant. */
|
|
528
|
+
accentColor?: string;
|
|
527
529
|
/** Abbreviation scale. Default 'auto'. */
|
|
528
530
|
valueFormat?: KpiValueFormat;
|
|
529
531
|
/** Decimal places on the abbreviated value. */
|
|
@@ -0,0 +1,188 @@
|
|
|
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 variant=${variant} width=${width} height=${height} border-radius=${borderRadius}></nile-skeleton-loader>`
|
|
27
|
+
: html `<nile-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, w = 30) => html `
|
|
30
|
+
<div class="nile-chart-skeleton-xaxis-row">
|
|
31
|
+
${repeat(n, () => sk('rounded', w, 10))}
|
|
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}%">${sk('rectangular', '100%', '100%')}</div>`)}
|
|
43
|
+
</div>
|
|
44
|
+
<div class="nile-chart-skeleton-xaxis-row nile-chart-skeleton-xaxis-row--columns">
|
|
45
|
+
${repeat(8, () => sk('rounded', 24, 10))}
|
|
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 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 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 class="nile-chart-skeleton-trend-line" x1="0" y1="28" x2="100" y2="10"></line>
|
|
65
|
+
<path 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 class="nile-chart-skeleton-trend-forecast" d="M60,16 L72,13 L84,11 L100,8"></path>
|
|
67
|
+
<line class="nile-chart-skeleton-trend-divider" x1="60" y1="0" x2="60" y2="40"></line>
|
|
68
|
+
</svg>
|
|
69
|
+
</div>
|
|
70
|
+
${xaxis()}
|
|
71
|
+
`;
|
|
72
|
+
case 'anomaly':
|
|
73
|
+
// Smooth line with a few highlighted anomaly markers off-trend.
|
|
74
|
+
return html `
|
|
75
|
+
<div class="nile-chart-skeleton-line">
|
|
76
|
+
<svg viewBox="0 0 100 40" preserveAspectRatio="none" aria-hidden="true">
|
|
77
|
+
<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>
|
|
78
|
+
${[[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>`)}
|
|
79
|
+
${[[18, 6], [50, 32], [74, 4]].map(([x, y]) => html `<circle class="nile-chart-skeleton-anomaly-halo" cx=${x} cy=${y} r="5"></circle>`)}
|
|
80
|
+
</svg>
|
|
81
|
+
</div>
|
|
82
|
+
${xaxis()}
|
|
83
|
+
`;
|
|
84
|
+
case 'pie':
|
|
85
|
+
return html `
|
|
86
|
+
<div class="nile-chart-skeleton-pie-wrap">
|
|
87
|
+
<div class="nile-chart-skeleton-pie"></div>
|
|
88
|
+
<div class="nile-chart-skeleton-legend">
|
|
89
|
+
${repeat(4, () => html `<div class="nile-chart-skeleton-legend-row">${sk('circular', 10, 10)}${sk('rounded', 70, 8)}</div>`)}
|
|
90
|
+
</div>
|
|
91
|
+
</div>
|
|
92
|
+
`;
|
|
93
|
+
case 'scatter':
|
|
94
|
+
return html `
|
|
95
|
+
<div class="nile-chart-skeleton-scatter">
|
|
96
|
+
${SCATTER_DOTS.map(([x, y, r]) => html `<span class="nile-chart-skeleton-dot-pos" style="left:${x}%;top:${y}%;">${sk('circular', r, r)}</span>`)}
|
|
97
|
+
</div>
|
|
98
|
+
${xaxis()}
|
|
99
|
+
`;
|
|
100
|
+
case 'heatmap':
|
|
101
|
+
return html `
|
|
102
|
+
<div class="nile-chart-skeleton-heatmap">
|
|
103
|
+
${repeat(4, () => html `<div class="nile-chart-skeleton-heatmap-row">${repeat(7, () => html `<div class="nile-chart-skeleton-heatmap-cell">${sk('rounded', '100%', '100%')}</div>`)}</div>`)}
|
|
104
|
+
</div>
|
|
105
|
+
`;
|
|
106
|
+
case 'radar': {
|
|
107
|
+
// Pentagon vertices (5-sided radar) at radii 40/27/14 around center (50,50).
|
|
108
|
+
const ring = (r) => [-90, -18, 54, 126, 198]
|
|
109
|
+
.map(deg => {
|
|
110
|
+
const rad = (deg * Math.PI) / 180;
|
|
111
|
+
return `${(50 + r * Math.cos(rad)).toFixed(2)},${(50 + r * Math.sin(rad)).toFixed(2)}`;
|
|
112
|
+
})
|
|
113
|
+
.join(' ');
|
|
114
|
+
const outer = ring(40);
|
|
115
|
+
const data = [35, 22, 30, 18, 28]
|
|
116
|
+
.map((r, i) => {
|
|
117
|
+
const deg = [-90, -18, 54, 126, 198][i];
|
|
118
|
+
const rad = (deg * Math.PI) / 180;
|
|
119
|
+
return `${(50 + r * Math.cos(rad)).toFixed(2)},${(50 + r * Math.sin(rad)).toFixed(2)}`;
|
|
120
|
+
})
|
|
121
|
+
.join(' ');
|
|
122
|
+
const spokes = [-90, -18, 54, 126, 198].map(deg => {
|
|
123
|
+
const rad = (deg * Math.PI) / 180;
|
|
124
|
+
return [50 + 40 * Math.cos(rad), 50 + 40 * Math.sin(rad)];
|
|
125
|
+
});
|
|
126
|
+
return html `
|
|
127
|
+
<div class="nile-chart-skeleton-radar-wrap">
|
|
128
|
+
<svg class="nile-chart-skeleton-radar-svg" viewBox="0 0 100 100" aria-hidden="true">
|
|
129
|
+
<polygon class="nile-chart-skeleton-radar-grid" points=${outer}></polygon>
|
|
130
|
+
<polygon class="nile-chart-skeleton-radar-grid" points=${ring(27)}></polygon>
|
|
131
|
+
<polygon class="nile-chart-skeleton-radar-grid" points=${ring(14)}></polygon>
|
|
132
|
+
${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>`)}
|
|
133
|
+
<polygon class="nile-chart-skeleton-radar-data" points=${data}></polygon>
|
|
134
|
+
${spokes.map(([x, y]) => html `<circle class="nile-chart-skeleton-radar-dot" cx=${x.toFixed(2)} cy=${y.toFixed(2)} r="1.6"></circle>`)}
|
|
135
|
+
</svg>
|
|
136
|
+
</div>
|
|
137
|
+
`;
|
|
138
|
+
}
|
|
139
|
+
case 'timeline':
|
|
140
|
+
return html `
|
|
141
|
+
<div class="nile-chart-skeleton-timeline">
|
|
142
|
+
${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}%;">${sk('rounded', '100%', 12, '999px')}</span></div>`)}
|
|
143
|
+
</div>
|
|
144
|
+
${xaxis()}
|
|
145
|
+
`;
|
|
146
|
+
case 'kpi':
|
|
147
|
+
return html `
|
|
148
|
+
<div class="nile-chart-skeleton-kpi">
|
|
149
|
+
${sk('rounded', '40%', 10)}${sk('rounded', '60%', 28)}${sk('rounded', '30%', 10)}
|
|
150
|
+
<svg class="nile-chart-skeleton-kpi-spark" viewBox="0 0 100 20" preserveAspectRatio="none" aria-hidden="true">
|
|
151
|
+
<path d="M0,14 L14,10 L28,12 L42,6 L56,9 L70,4 L84,7 L100,2"></path>
|
|
152
|
+
</svg>
|
|
153
|
+
</div>
|
|
154
|
+
`;
|
|
155
|
+
case 'grid':
|
|
156
|
+
return html `
|
|
157
|
+
<div class="nile-chart-skeleton-grid">
|
|
158
|
+
<div class="nile-chart-skeleton-grid-head">${repeat(4, () => sk('rounded', '100%', 12))}</div>
|
|
159
|
+
${repeat(5, () => html `<div class="nile-chart-skeleton-grid-row">${repeat(4, () => sk('text', '100%', 10))}</div>`)}
|
|
160
|
+
</div>
|
|
161
|
+
`;
|
|
162
|
+
case 'filter':
|
|
163
|
+
return html `
|
|
164
|
+
<div class="nile-chart-skeleton-filter">
|
|
165
|
+
${sk('rounded', '100%', 36)}
|
|
166
|
+
<div class="nile-chart-skeleton-filter-chips">
|
|
167
|
+
${[60, 80, 50, 90, 70].map(w => sk('rounded', w, 22, '999px'))}
|
|
168
|
+
</div>
|
|
169
|
+
</div>
|
|
170
|
+
`;
|
|
171
|
+
case 'bars':
|
|
172
|
+
default:
|
|
173
|
+
return html `
|
|
174
|
+
<div class="nile-chart-skeleton-body">
|
|
175
|
+
${[96, 88, 94, 84, 92].map(w => html `<div class="nile-chart-skeleton-row">
|
|
176
|
+
<nile-skeleton-loader class="nile-chart-skeleton-ylabel-sk" variant="rounded" width="100%" height="10"></nile-skeleton-loader>
|
|
177
|
+
<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>
|
|
178
|
+
</div>`)}
|
|
179
|
+
</div>
|
|
180
|
+
${xaxis()}
|
|
181
|
+
`;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
export function renderChartSkeleton(chartType) {
|
|
185
|
+
const v = variantFor(chartType);
|
|
186
|
+
return html `<div class="nile-chart-skeleton nile-chart-skeleton--${v}" aria-busy="true" aria-label="Loading chart">${renderBody(v)}</div>`;
|
|
187
|
+
}
|
|
188
|
+
//# sourceMappingURL=nile-chart-skeleton.js.map
|