@aquera/nile-visualization 0.1.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 +35 -0
- package/dist/src/index.js +20 -0
- package/dist/src/internal/chart-adapters.d.ts +11 -0
- package/dist/src/internal/chart-adapters.js +159 -0
- package/dist/src/internal/highcharts-provider.d.ts +14 -0
- package/dist/src/internal/highcharts-provider.js +56 -0
- package/dist/src/internal/nile-element.d.ts +8 -0
- package/dist/src/internal/nile-element.js +21 -0
- package/dist/src/internal/utils.d.ts +1 -0
- package/dist/src/internal/utils.js +23 -0
- package/dist/src/nile-ai-panel/index.d.ts +1 -0
- package/dist/src/nile-ai-panel/index.js +2 -0
- package/dist/src/nile-ai-panel/nile-ai-panel.css.d.ts +1 -0
- package/dist/src/nile-ai-panel/nile-ai-panel.css.js +73 -0
- package/dist/src/nile-ai-panel/nile-ai-panel.d.ts +29 -0
- package/dist/src/nile-ai-panel/nile-ai-panel.js +98 -0
- package/dist/src/nile-ai-sender/index.d.ts +1 -0
- package/dist/src/nile-ai-sender/index.js +2 -0
- package/dist/src/nile-ai-sender/nile-ai-sender.css.d.ts +1 -0
- package/dist/src/nile-ai-sender/nile-ai-sender.css.js +71 -0
- package/dist/src/nile-ai-sender/nile-ai-sender.d.ts +20 -0
- package/dist/src/nile-ai-sender/nile-ai-sender.js +77 -0
- package/dist/src/nile-anomaly-chart/index.d.ts +2 -0
- package/dist/src/nile-anomaly-chart/index.js +2 -0
- package/dist/src/nile-anomaly-chart/nile-anomaly-chart.css.d.ts +1 -0
- package/dist/src/nile-anomaly-chart/nile-anomaly-chart.css.js +28 -0
- package/dist/src/nile-anomaly-chart/nile-anomaly-chart.d.ts +59 -0
- package/dist/src/nile-anomaly-chart/nile-anomaly-chart.js +268 -0
- package/dist/src/nile-area-chart/index.d.ts +2 -0
- package/dist/src/nile-area-chart/index.js +2 -0
- package/dist/src/nile-area-chart/nile-area-chart.css.d.ts +1 -0
- package/dist/src/nile-area-chart/nile-area-chart.css.js +28 -0
- package/dist/src/nile-area-chart/nile-area-chart.d.ts +37 -0
- package/dist/src/nile-area-chart/nile-area-chart.js +122 -0
- package/dist/src/nile-bar-chart/index.d.ts +2 -0
- package/dist/src/nile-bar-chart/index.js +2 -0
- package/dist/src/nile-bar-chart/nile-bar-chart.css.d.ts +1 -0
- package/dist/src/nile-bar-chart/nile-bar-chart.css.js +28 -0
- package/dist/src/nile-bar-chart/nile-bar-chart.d.ts +44 -0
- package/dist/src/nile-bar-chart/nile-bar-chart.js +185 -0
- package/dist/src/nile-bubble-chart/index.d.ts +2 -0
- package/dist/src/nile-bubble-chart/index.js +2 -0
- package/dist/src/nile-bubble-chart/nile-bubble-chart.css.d.ts +1 -0
- package/dist/src/nile-bubble-chart/nile-bubble-chart.css.js +28 -0
- package/dist/src/nile-bubble-chart/nile-bubble-chart.d.ts +36 -0
- package/dist/src/nile-bubble-chart/nile-bubble-chart.js +123 -0
- package/dist/src/nile-chart/index.d.ts +3 -0
- package/dist/src/nile-chart/index.js +3 -0
- package/dist/src/nile-chart/nile-chart-config.d.ts +58 -0
- package/dist/src/nile-chart/nile-chart-config.js +2 -0
- package/dist/src/nile-chart/nile-chart.css.d.ts +1 -0
- package/dist/src/nile-chart/nile-chart.css.js +298 -0
- package/dist/src/nile-chart/nile-chart.d.ts +51 -0
- package/dist/src/nile-chart/nile-chart.js +303 -0
- package/dist/src/nile-column-chart/index.d.ts +2 -0
- package/dist/src/nile-column-chart/index.js +2 -0
- package/dist/src/nile-column-chart/nile-column-chart.css.d.ts +1 -0
- package/dist/src/nile-column-chart/nile-column-chart.css.js +28 -0
- package/dist/src/nile-column-chart/nile-column-chart.d.ts +36 -0
- package/dist/src/nile-column-chart/nile-column-chart.js +118 -0
- package/dist/src/nile-donut-chart/index.d.ts +2 -0
- package/dist/src/nile-donut-chart/index.js +2 -0
- package/dist/src/nile-donut-chart/nile-donut-chart.css.d.ts +1 -0
- package/dist/src/nile-donut-chart/nile-donut-chart.css.js +28 -0
- package/dist/src/nile-donut-chart/nile-donut-chart.d.ts +40 -0
- package/dist/src/nile-donut-chart/nile-donut-chart.js +131 -0
- package/dist/src/nile-gauge-chart/index.d.ts +2 -0
- package/dist/src/nile-gauge-chart/index.js +2 -0
- package/dist/src/nile-gauge-chart/nile-gauge-chart.css.d.ts +1 -0
- package/dist/src/nile-gauge-chart/nile-gauge-chart.css.js +28 -0
- package/dist/src/nile-gauge-chart/nile-gauge-chart.d.ts +38 -0
- package/dist/src/nile-gauge-chart/nile-gauge-chart.js +149 -0
- package/dist/src/nile-kpi-chart/index.d.ts +2 -0
- package/dist/src/nile-kpi-chart/index.js +2 -0
- package/dist/src/nile-kpi-chart/nile-kpi-chart.css.d.ts +1 -0
- package/dist/src/nile-kpi-chart/nile-kpi-chart.css.js +165 -0
- package/dist/src/nile-kpi-chart/nile-kpi-chart.d.ts +80 -0
- package/dist/src/nile-kpi-chart/nile-kpi-chart.js +335 -0
- package/dist/src/nile-line-chart/index.d.ts +2 -0
- package/dist/src/nile-line-chart/index.js +2 -0
- package/dist/src/nile-line-chart/nile-line-chart.css.d.ts +1 -0
- package/dist/src/nile-line-chart/nile-line-chart.css.js +28 -0
- package/dist/src/nile-line-chart/nile-line-chart.d.ts +36 -0
- package/dist/src/nile-line-chart/nile-line-chart.js +115 -0
- package/dist/src/nile-pie-chart/index.d.ts +2 -0
- package/dist/src/nile-pie-chart/index.js +2 -0
- package/dist/src/nile-pie-chart/nile-pie-chart.css.d.ts +1 -0
- package/dist/src/nile-pie-chart/nile-pie-chart.css.js +28 -0
- package/dist/src/nile-pie-chart/nile-pie-chart.d.ts +48 -0
- package/dist/src/nile-pie-chart/nile-pie-chart.js +197 -0
- package/dist/src/nile-radar-chart/index.d.ts +2 -0
- package/dist/src/nile-radar-chart/index.js +2 -0
- package/dist/src/nile-radar-chart/nile-radar-chart.css.d.ts +1 -0
- package/dist/src/nile-radar-chart/nile-radar-chart.css.js +28 -0
- package/dist/src/nile-radar-chart/nile-radar-chart.d.ts +36 -0
- package/dist/src/nile-radar-chart/nile-radar-chart.js +137 -0
- package/dist/src/nile-scatter-chart/index.d.ts +2 -0
- package/dist/src/nile-scatter-chart/index.js +2 -0
- package/dist/src/nile-scatter-chart/nile-scatter-chart.css.d.ts +1 -0
- package/dist/src/nile-scatter-chart/nile-scatter-chart.css.js +28 -0
- package/dist/src/nile-scatter-chart/nile-scatter-chart.d.ts +36 -0
- package/dist/src/nile-scatter-chart/nile-scatter-chart.js +124 -0
- package/dist/src/nile-spline-chart/index.d.ts +2 -0
- package/dist/src/nile-spline-chart/index.js +2 -0
- package/dist/src/nile-spline-chart/nile-spline-chart.css.d.ts +1 -0
- package/dist/src/nile-spline-chart/nile-spline-chart.css.js +28 -0
- package/dist/src/nile-spline-chart/nile-spline-chart.d.ts +36 -0
- package/dist/src/nile-spline-chart/nile-spline-chart.js +118 -0
- package/dist/src/nile-trendline-chart/index.d.ts +2 -0
- package/dist/src/nile-trendline-chart/index.js +2 -0
- package/dist/src/nile-trendline-chart/nile-trendline-chart.css.d.ts +1 -0
- package/dist/src/nile-trendline-chart/nile-trendline-chart.css.js +28 -0
- package/dist/src/nile-trendline-chart/nile-trendline-chart.d.ts +59 -0
- package/dist/src/nile-trendline-chart/nile-trendline-chart.js +246 -0
- package/dist/src/nile-waterfall-chart/index.d.ts +2 -0
- package/dist/src/nile-waterfall-chart/index.js +2 -0
- package/dist/src/nile-waterfall-chart/nile-waterfall-chart.css.d.ts +1 -0
- package/dist/src/nile-waterfall-chart/nile-waterfall-chart.css.js +28 -0
- package/dist/src/nile-waterfall-chart/nile-waterfall-chart.d.ts +37 -0
- package/dist/src/nile-waterfall-chart/nile-waterfall-chart.js +137 -0
- package/package.json +62 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export { NileBarChart } from './nile-bar-chart/index.js';
|
|
2
|
+
export type { BarChartSeriesData } from './nile-bar-chart/index.js';
|
|
3
|
+
export { NilePieChart } from './nile-pie-chart/index.js';
|
|
4
|
+
export type { PieChartSeriesData } from './nile-pie-chart/index.js';
|
|
5
|
+
export { NileTrendlineChart } from './nile-trendline-chart/index.js';
|
|
6
|
+
export type { TrendlineSeriesData, ForecastConfig } from './nile-trendline-chart/index.js';
|
|
7
|
+
export { NileAnomalyChart } from './nile-anomaly-chart/index.js';
|
|
8
|
+
export type { AnomalySeriesData, AnomalyConfig } from './nile-anomaly-chart/index.js';
|
|
9
|
+
export { NileChart } from './nile-chart/index.js';
|
|
10
|
+
export type { NileChartConfig, NileBarChartConfig, NilePieChartConfig, NileTrendlineChartConfig, NileAnomalyChartConfig, ChartType, SwitchAggregation, NileAiConfig, } from './nile-chart/index.js';
|
|
11
|
+
export { convertConfig, registerAdapter } from './nile-chart/index.js';
|
|
12
|
+
export { NileLineChart } from './nile-line-chart/index.js';
|
|
13
|
+
export type { LineChartSeriesData } from './nile-line-chart/index.js';
|
|
14
|
+
export { NileAreaChart } from './nile-area-chart/index.js';
|
|
15
|
+
export type { AreaChartSeriesData } from './nile-area-chart/index.js';
|
|
16
|
+
export { NileColumnChart } from './nile-column-chart/index.js';
|
|
17
|
+
export type { ColumnChartSeriesData } from './nile-column-chart/index.js';
|
|
18
|
+
export { NileDonutChart } from './nile-donut-chart/index.js';
|
|
19
|
+
export type { DonutChartSeriesData } from './nile-donut-chart/index.js';
|
|
20
|
+
export { NileScatterChart } from './nile-scatter-chart/index.js';
|
|
21
|
+
export type { ScatterChartSeriesData } from './nile-scatter-chart/index.js';
|
|
22
|
+
export { NileBubbleChart } from './nile-bubble-chart/index.js';
|
|
23
|
+
export type { BubbleChartSeriesData } from './nile-bubble-chart/index.js';
|
|
24
|
+
export { NileSplineChart } from './nile-spline-chart/index.js';
|
|
25
|
+
export type { SplineChartSeriesData } from './nile-spline-chart/index.js';
|
|
26
|
+
export { NileRadarChart } from './nile-radar-chart/index.js';
|
|
27
|
+
export type { RadarChartSeriesData } from './nile-radar-chart/index.js';
|
|
28
|
+
export { NileGaugeChart } from './nile-gauge-chart/index.js';
|
|
29
|
+
export type { GaugeBand } from './nile-gauge-chart/index.js';
|
|
30
|
+
export { NileWaterfallChart } from './nile-waterfall-chart/index.js';
|
|
31
|
+
export type { WaterfallDataPoint } from './nile-waterfall-chart/index.js';
|
|
32
|
+
export { NileKpiChart } from './nile-kpi-chart/index.js';
|
|
33
|
+
export type { KpiConfig, TrendDirection, KpiVariant } from './nile-kpi-chart/index.js';
|
|
34
|
+
export { NileAiSender } from './nile-ai-sender/index.js';
|
|
35
|
+
export { NileAiPanel } from './nile-ai-panel/index.js';
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export { NileBarChart } from './nile-bar-chart/index.js';
|
|
2
|
+
export { NilePieChart } from './nile-pie-chart/index.js';
|
|
3
|
+
export { NileTrendlineChart } from './nile-trendline-chart/index.js';
|
|
4
|
+
export { NileAnomalyChart } from './nile-anomaly-chart/index.js';
|
|
5
|
+
export { NileChart } from './nile-chart/index.js';
|
|
6
|
+
export { convertConfig, registerAdapter } from './nile-chart/index.js';
|
|
7
|
+
export { NileLineChart } from './nile-line-chart/index.js';
|
|
8
|
+
export { NileAreaChart } from './nile-area-chart/index.js';
|
|
9
|
+
export { NileColumnChart } from './nile-column-chart/index.js';
|
|
10
|
+
export { NileDonutChart } from './nile-donut-chart/index.js';
|
|
11
|
+
export { NileScatterChart } from './nile-scatter-chart/index.js';
|
|
12
|
+
export { NileBubbleChart } from './nile-bubble-chart/index.js';
|
|
13
|
+
export { NileSplineChart } from './nile-spline-chart/index.js';
|
|
14
|
+
export { NileRadarChart } from './nile-radar-chart/index.js';
|
|
15
|
+
export { NileGaugeChart } from './nile-gauge-chart/index.js';
|
|
16
|
+
export { NileWaterfallChart } from './nile-waterfall-chart/index.js';
|
|
17
|
+
export { NileKpiChart } from './nile-kpi-chart/index.js';
|
|
18
|
+
export { NileAiSender } from './nile-ai-sender/index.js';
|
|
19
|
+
export { NileAiPanel } from './nile-ai-panel/index.js';
|
|
20
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { NileChartConfig, ChartType } from '../nile-chart/nile-chart-config.js';
|
|
2
|
+
type AdapterFn = (config: NileChartConfig) => NileChartConfig;
|
|
3
|
+
/**
|
|
4
|
+
* Register a custom adapter for converting between chart types.
|
|
5
|
+
*/
|
|
6
|
+
export declare function registerAdapter(fromType: ChartType, toType: ChartType, adapter: AdapterFn): void;
|
|
7
|
+
/**
|
|
8
|
+
* Convert a chart config from one type to another using registered adapters.
|
|
9
|
+
*/
|
|
10
|
+
export declare function convertConfig(config: NileChartConfig, toType: ChartType): NileChartConfig;
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
// ── Bar → Pie helpers ───────────────────────────────────────────────
|
|
2
|
+
function barToPieByCategory(data, categories) {
|
|
3
|
+
return categories.map((cat, i) => ({
|
|
4
|
+
name: cat,
|
|
5
|
+
y: data.reduce((sum, series) => sum + (series.data[i] ?? 0), 0),
|
|
6
|
+
}));
|
|
7
|
+
}
|
|
8
|
+
function barToPieBySeries(data) {
|
|
9
|
+
return data.map(series => ({
|
|
10
|
+
name: series.name,
|
|
11
|
+
y: series.data.reduce((sum, val) => sum + val, 0),
|
|
12
|
+
color: series.color,
|
|
13
|
+
}));
|
|
14
|
+
}
|
|
15
|
+
function barToPieFlatten(data, categories) {
|
|
16
|
+
const slices = [];
|
|
17
|
+
for (const series of data) {
|
|
18
|
+
for (let i = 0; i < categories.length; i++) {
|
|
19
|
+
slices.push({
|
|
20
|
+
name: `${series.name} – ${categories[i]}`,
|
|
21
|
+
y: series.data[i] ?? 0,
|
|
22
|
+
color: series.color,
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return slices;
|
|
27
|
+
}
|
|
28
|
+
function barLikeToPie(data, categories, aggregation) {
|
|
29
|
+
switch (aggregation) {
|
|
30
|
+
case 'by-series':
|
|
31
|
+
return barToPieBySeries(data);
|
|
32
|
+
case 'flatten':
|
|
33
|
+
return barToPieFlatten(data, categories);
|
|
34
|
+
case 'by-category':
|
|
35
|
+
default:
|
|
36
|
+
return barToPieByCategory(data, categories);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
// ── Pie → Bar-like helper ───────────────────────────────────────────
|
|
40
|
+
function pieToBarLike(data, seriesName) {
|
|
41
|
+
return {
|
|
42
|
+
categories: data.map(d => d.name),
|
|
43
|
+
data: [
|
|
44
|
+
{
|
|
45
|
+
name: seriesName || 'Value',
|
|
46
|
+
data: data.map(d => d.y),
|
|
47
|
+
},
|
|
48
|
+
],
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
const adapters = {
|
|
52
|
+
// ── Bar ↔ Pie ──
|
|
53
|
+
'bar->pie': (config) => {
|
|
54
|
+
if (config.type !== 'bar')
|
|
55
|
+
throw new Error('Expected bar config');
|
|
56
|
+
const agg = config.switchAggregation ?? 'by-category';
|
|
57
|
+
return {
|
|
58
|
+
...config,
|
|
59
|
+
type: 'pie',
|
|
60
|
+
data: barLikeToPie(config.data, config.categories ?? [], agg),
|
|
61
|
+
seriesName: config.chartTitle || 'Series',
|
|
62
|
+
};
|
|
63
|
+
},
|
|
64
|
+
'pie->bar': (config) => {
|
|
65
|
+
if (config.type !== 'pie')
|
|
66
|
+
throw new Error('Expected pie config');
|
|
67
|
+
const { data, categories } = pieToBarLike(config.data, config.seriesName);
|
|
68
|
+
return { ...config, type: 'bar', data, categories };
|
|
69
|
+
},
|
|
70
|
+
// ── Bar ↔ Trendline (same data shape, direct pass-through) ──
|
|
71
|
+
'bar->trendline': (config) => {
|
|
72
|
+
if (config.type !== 'bar')
|
|
73
|
+
throw new Error('Expected bar config');
|
|
74
|
+
return { ...config, type: 'trendline', data: config.data, categories: config.categories };
|
|
75
|
+
},
|
|
76
|
+
'trendline->bar': (config) => {
|
|
77
|
+
if (config.type !== 'trendline')
|
|
78
|
+
throw new Error('Expected trendline config');
|
|
79
|
+
return { ...config, type: 'bar', data: config.data, categories: config.categories };
|
|
80
|
+
},
|
|
81
|
+
// ── Bar ↔ Anomaly (same data shape, direct pass-through) ──
|
|
82
|
+
'bar->anomaly': (config) => {
|
|
83
|
+
if (config.type !== 'bar')
|
|
84
|
+
throw new Error('Expected bar config');
|
|
85
|
+
return { ...config, type: 'anomaly', data: config.data, categories: config.categories };
|
|
86
|
+
},
|
|
87
|
+
'anomaly->bar': (config) => {
|
|
88
|
+
if (config.type !== 'anomaly')
|
|
89
|
+
throw new Error('Expected anomaly config');
|
|
90
|
+
return { ...config, type: 'bar', data: config.data, categories: config.categories };
|
|
91
|
+
},
|
|
92
|
+
// ── Pie ↔ Trendline ──
|
|
93
|
+
'pie->trendline': (config) => {
|
|
94
|
+
if (config.type !== 'pie')
|
|
95
|
+
throw new Error('Expected pie config');
|
|
96
|
+
const { data, categories } = pieToBarLike(config.data, config.seriesName);
|
|
97
|
+
return { ...config, type: 'trendline', data, categories };
|
|
98
|
+
},
|
|
99
|
+
'trendline->pie': (config) => {
|
|
100
|
+
if (config.type !== 'trendline')
|
|
101
|
+
throw new Error('Expected trendline config');
|
|
102
|
+
const agg = config.switchAggregation ?? 'by-category';
|
|
103
|
+
return {
|
|
104
|
+
...config,
|
|
105
|
+
type: 'pie',
|
|
106
|
+
data: barLikeToPie(config.data, config.categories ?? [], agg),
|
|
107
|
+
seriesName: config.chartTitle || 'Series',
|
|
108
|
+
};
|
|
109
|
+
},
|
|
110
|
+
// ── Pie ↔ Anomaly ──
|
|
111
|
+
'pie->anomaly': (config) => {
|
|
112
|
+
if (config.type !== 'pie')
|
|
113
|
+
throw new Error('Expected pie config');
|
|
114
|
+
const { data, categories } = pieToBarLike(config.data, config.seriesName);
|
|
115
|
+
return { ...config, type: 'anomaly', data, categories };
|
|
116
|
+
},
|
|
117
|
+
'anomaly->pie': (config) => {
|
|
118
|
+
if (config.type !== 'anomaly')
|
|
119
|
+
throw new Error('Expected anomaly config');
|
|
120
|
+
const agg = config.switchAggregation ?? 'by-category';
|
|
121
|
+
return {
|
|
122
|
+
...config,
|
|
123
|
+
type: 'pie',
|
|
124
|
+
data: barLikeToPie(config.data, config.categories ?? [], agg),
|
|
125
|
+
seriesName: config.chartTitle || 'Series',
|
|
126
|
+
};
|
|
127
|
+
},
|
|
128
|
+
// ── Trendline ↔ Anomaly (identical data shape) ──
|
|
129
|
+
'trendline->anomaly': (config) => {
|
|
130
|
+
if (config.type !== 'trendline')
|
|
131
|
+
throw new Error('Expected trendline config');
|
|
132
|
+
return { ...config, type: 'anomaly', data: config.data, categories: config.categories };
|
|
133
|
+
},
|
|
134
|
+
'anomaly->trendline': (config) => {
|
|
135
|
+
if (config.type !== 'anomaly')
|
|
136
|
+
throw new Error('Expected anomaly config');
|
|
137
|
+
return { ...config, type: 'trendline', data: config.data, categories: config.categories };
|
|
138
|
+
},
|
|
139
|
+
};
|
|
140
|
+
/**
|
|
141
|
+
* Register a custom adapter for converting between chart types.
|
|
142
|
+
*/
|
|
143
|
+
export function registerAdapter(fromType, toType, adapter) {
|
|
144
|
+
adapters[`${fromType}->${toType}`] = adapter;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Convert a chart config from one type to another using registered adapters.
|
|
148
|
+
*/
|
|
149
|
+
export function convertConfig(config, toType) {
|
|
150
|
+
if (config.type === toType)
|
|
151
|
+
return config;
|
|
152
|
+
const key = `${config.type}->${toType}`;
|
|
153
|
+
const adapter = adapters[key];
|
|
154
|
+
if (!adapter) {
|
|
155
|
+
throw new Error(`No adapter registered for converting "${config.type}" to "${toType}"`);
|
|
156
|
+
}
|
|
157
|
+
return adapter(config);
|
|
158
|
+
}
|
|
159
|
+
//# sourceMappingURL=chart-adapters.js.map
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Highcharts provider that works in both npm/bundler and CDN/browser contexts.
|
|
3
|
+
*
|
|
4
|
+
* - npm users: their bundler resolves `import('highcharts')` from node_modules.
|
|
5
|
+
* - CDN users: the dynamic import fails (bare specifier), falls back to `window.Highcharts`.
|
|
6
|
+
* Consumer must load Highcharts via `<script>` before nile-visualization.
|
|
7
|
+
*/
|
|
8
|
+
type HighchartsStatic = typeof import('highcharts');
|
|
9
|
+
/**
|
|
10
|
+
* Returns a promise that resolves to the Highcharts instance.
|
|
11
|
+
* The initialization runs only once and is shared across all callers.
|
|
12
|
+
*/
|
|
13
|
+
export declare function getHighcharts(): Promise<HighchartsStatic>;
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Highcharts provider that works in both npm/bundler and CDN/browser contexts.
|
|
3
|
+
*
|
|
4
|
+
* - npm users: their bundler resolves `import('highcharts')` from node_modules.
|
|
5
|
+
* - CDN users: the dynamic import fails (bare specifier), falls back to `window.Highcharts`.
|
|
6
|
+
* Consumer must load Highcharts via `<script>` before nile-visualization.
|
|
7
|
+
*/
|
|
8
|
+
let _Highcharts;
|
|
9
|
+
let _initPromise = null;
|
|
10
|
+
async function init() {
|
|
11
|
+
if (_Highcharts)
|
|
12
|
+
return _Highcharts;
|
|
13
|
+
try {
|
|
14
|
+
// Try ES module import first (works in npm/bundler context)
|
|
15
|
+
const mod = await import('highcharts');
|
|
16
|
+
_Highcharts = (mod.default || mod);
|
|
17
|
+
try {
|
|
18
|
+
const more = await import('highcharts/highcharts-more.js');
|
|
19
|
+
if (typeof more.default === 'function') {
|
|
20
|
+
more.default(_Highcharts);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
// highcharts-more not available — consumer may have loaded it globally
|
|
25
|
+
}
|
|
26
|
+
try {
|
|
27
|
+
const solidGauge = await import('highcharts/modules/solid-gauge.js');
|
|
28
|
+
if (typeof solidGauge.default === 'function') {
|
|
29
|
+
solidGauge.default(_Highcharts);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
// solid-gauge not available — consumer may have loaded it globally
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
// Fallback to global (works in CDN/browser context)
|
|
38
|
+
_Highcharts = globalThis.Highcharts;
|
|
39
|
+
}
|
|
40
|
+
if (!_Highcharts) {
|
|
41
|
+
throw new Error('Highcharts is required. Either install it via npm (`npm i highcharts`) ' +
|
|
42
|
+
'or load it globally via <script> before nile-visualization.');
|
|
43
|
+
}
|
|
44
|
+
return _Highcharts;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Returns a promise that resolves to the Highcharts instance.
|
|
48
|
+
* The initialization runs only once and is shared across all callers.
|
|
49
|
+
*/
|
|
50
|
+
export function getHighcharts() {
|
|
51
|
+
if (!_initPromise) {
|
|
52
|
+
_initPromise = init();
|
|
53
|
+
}
|
|
54
|
+
return _initPromise;
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=highcharts-provider.js.map
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { LitElement } from 'lit';
|
|
2
|
+
export default class NileElement extends LitElement {
|
|
3
|
+
protected BUBBLES: boolean;
|
|
4
|
+
protected COMPOSED: boolean;
|
|
5
|
+
protected CANCELABLE: boolean;
|
|
6
|
+
/** Emits a custom event with more convenient defaults. */
|
|
7
|
+
emit(name: string, detail?: any, bubbles?: boolean, composed?: boolean, cancelable?: boolean): CustomEvent<any>;
|
|
8
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { LitElement } from 'lit';
|
|
2
|
+
export default class NileElement extends LitElement {
|
|
3
|
+
constructor() {
|
|
4
|
+
super(...arguments);
|
|
5
|
+
this.BUBBLES = true;
|
|
6
|
+
this.COMPOSED = true;
|
|
7
|
+
this.CANCELABLE = false;
|
|
8
|
+
}
|
|
9
|
+
/** Emits a custom event with more convenient defaults. */
|
|
10
|
+
emit(name, detail, bubbles, composed, cancelable) {
|
|
11
|
+
const event = new CustomEvent(name, {
|
|
12
|
+
bubbles: bubbles ?? this.BUBBLES,
|
|
13
|
+
cancelable: cancelable ?? this.CANCELABLE,
|
|
14
|
+
composed: composed ?? this.COMPOSED,
|
|
15
|
+
detail,
|
|
16
|
+
});
|
|
17
|
+
this.dispatchEvent(event);
|
|
18
|
+
return event;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=nile-element.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function deepMerge(target: any, source: any): any;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
function isObject(item) {
|
|
2
|
+
return item !== null && typeof item === 'object' && !Array.isArray(item);
|
|
3
|
+
}
|
|
4
|
+
export function deepMerge(target, source) {
|
|
5
|
+
const output = { ...target };
|
|
6
|
+
if (isObject(target) && isObject(source)) {
|
|
7
|
+
Object.keys(source).forEach(key => {
|
|
8
|
+
if (isObject(source[key])) {
|
|
9
|
+
if (!(key in target)) {
|
|
10
|
+
Object.assign(output, { [key]: source[key] });
|
|
11
|
+
}
|
|
12
|
+
else {
|
|
13
|
+
output[key] = deepMerge(target[key], source[key]);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
Object.assign(output, { [key]: source[key] });
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
return output;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { NileAiPanel } from './nile-ai-panel.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const styles: import("lit").CSSResult;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { css } from 'lit';
|
|
2
|
+
export const styles = css `
|
|
3
|
+
:host {
|
|
4
|
+
display: flex;
|
|
5
|
+
flex-direction: column;
|
|
6
|
+
height: 100%;
|
|
7
|
+
overflow: hidden;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.messages {
|
|
11
|
+
flex: 1;
|
|
12
|
+
overflow-y: auto;
|
|
13
|
+
padding: var(--nile-spacing-xl, var(--ng-spacing-xl)) var(--nile-spacing-2xl, var(--ng-spacing-2xl));
|
|
14
|
+
display: flex;
|
|
15
|
+
flex-direction: column;
|
|
16
|
+
gap: var(--nile-spacing-lg, var(--ng-spacing-lg));
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.message {
|
|
20
|
+
max-width: 85%;
|
|
21
|
+
padding: var(--nile-spacing-md, var(--ng-spacing-md)) var(--nile-spacing-14px, var(--ng-spacing-3-5));
|
|
22
|
+
border-radius: var(--nile-radius-radius-3xl, var(--ng-radius-xl));
|
|
23
|
+
font-family: var(--nile-font-family-serif, var(--ng-font-family-body));
|
|
24
|
+
font-size: var(--nile-type-scale-3, var(--ng-font-size-text-sm));
|
|
25
|
+
line-height: 1.5;
|
|
26
|
+
word-wrap: break-word;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.message--user {
|
|
30
|
+
align-self: flex-end;
|
|
31
|
+
background: var(--nile-colors-primary-600, var(--ng-colors-fg-brand-primary-600));
|
|
32
|
+
color: var(--nile-colors-white-base, var(--ng-colors-bg-primary));
|
|
33
|
+
border-bottom-right-radius: var(--nile-radius-radius-sm, var(--ng-radius-xs));
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.message--assistant {
|
|
37
|
+
align-self: flex-start;
|
|
38
|
+
background: var(--nile-colors-neutral-100, var(--ng-colors-bg-secondary));
|
|
39
|
+
color: var(--nile-colors-dark-900, var(--ng-colors-text-primary-900));
|
|
40
|
+
border-bottom-left-radius: var(--nile-radius-radius-sm, var(--ng-radius-xs));
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.typing {
|
|
44
|
+
align-self: flex-start;
|
|
45
|
+
padding: var(--nile-spacing-md, var(--ng-spacing-md)) var(--nile-spacing-14px, var(--ng-spacing-3-5));
|
|
46
|
+
display: flex;
|
|
47
|
+
gap: var(--nile-spacing-xs, var(--ng-spacing-xs));
|
|
48
|
+
align-items: center;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.typing-dot {
|
|
52
|
+
width: var(--nile-width-6px, var(--ng-width-1-5));
|
|
53
|
+
height: var(--nile-height-6px, var(--ng-height-6px));
|
|
54
|
+
border-radius: 50%;
|
|
55
|
+
background: var(--nile-colors-neutral-500, var(--ng-colors-text-placeholder));
|
|
56
|
+
animation: typing-bounce 1.2s infinite;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.typing-dot:nth-child(2) { animation-delay: 0.2s; }
|
|
60
|
+
.typing-dot:nth-child(3) { animation-delay: 0.4s; }
|
|
61
|
+
|
|
62
|
+
@keyframes typing-bounce {
|
|
63
|
+
0%, 60%, 100% { transform: translateY(0); }
|
|
64
|
+
30% { transform: translateY(-4px); }
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
.sender-wrapper {
|
|
68
|
+
padding: var(--nile-spacing-lg, var(--ng-spacing-lg)) var(--nile-spacing-xl, var(--ng-spacing-xl));
|
|
69
|
+
border-top: var(--nile-border-width-1, var(--ng-stroke-width-1)) solid var(--nile-colors-neutral-400, var(--ng-colors-border-secondary));
|
|
70
|
+
background: var(--nile-colors-white-base, var(--ng-colors-bg-primary));
|
|
71
|
+
}
|
|
72
|
+
`;
|
|
73
|
+
//# sourceMappingURL=nile-ai-panel.css.js.map
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { CSSResultGroup, TemplateResult } from 'lit';
|
|
2
|
+
import NileElement from '../internal/nile-element.js';
|
|
3
|
+
import '../nile-ai-sender/index.js';
|
|
4
|
+
export declare class NileAiPanel extends NileElement {
|
|
5
|
+
static styles: CSSResultGroup;
|
|
6
|
+
/** Placeholder text passed to nile-ai-sender. */
|
|
7
|
+
placeholder: string;
|
|
8
|
+
/** Welcome message shown when the panel opens. */
|
|
9
|
+
welcomeMessage: string;
|
|
10
|
+
private messages;
|
|
11
|
+
private loading;
|
|
12
|
+
private messagesEl;
|
|
13
|
+
/** Add a user message to the conversation. */
|
|
14
|
+
addUserMessage(text: string): void;
|
|
15
|
+
/** Add an assistant response to the conversation. */
|
|
16
|
+
addAssistantMessage(text: string): void;
|
|
17
|
+
/** Show or hide the typing indicator. */
|
|
18
|
+
setLoading(val: boolean): void;
|
|
19
|
+
/** Clear all messages. */
|
|
20
|
+
clear(): void;
|
|
21
|
+
private scrollToBottom;
|
|
22
|
+
private handleSend;
|
|
23
|
+
render(): TemplateResult;
|
|
24
|
+
}
|
|
25
|
+
declare global {
|
|
26
|
+
interface HTMLElementTagNameMap {
|
|
27
|
+
'nile-ai-panel': NileAiPanel;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { __decorate } from "tslib";
|
|
2
|
+
import { customElement, property, query, state } from 'lit/decorators.js';
|
|
3
|
+
import { html, nothing } from 'lit';
|
|
4
|
+
import NileElement from '../internal/nile-element.js';
|
|
5
|
+
import { styles } from './nile-ai-panel.css.js';
|
|
6
|
+
import '../nile-ai-sender/index.js';
|
|
7
|
+
let NileAiPanel = class NileAiPanel extends NileElement {
|
|
8
|
+
constructor() {
|
|
9
|
+
super(...arguments);
|
|
10
|
+
/** Placeholder text passed to nile-ai-sender. */
|
|
11
|
+
this.placeholder = 'Ask about this chart...';
|
|
12
|
+
/** Welcome message shown when the panel opens. */
|
|
13
|
+
this.welcomeMessage = '';
|
|
14
|
+
this.messages = [];
|
|
15
|
+
this.loading = false;
|
|
16
|
+
}
|
|
17
|
+
/** Add a user message to the conversation. */
|
|
18
|
+
addUserMessage(text) {
|
|
19
|
+
this.messages = [...this.messages, { role: 'user', text }];
|
|
20
|
+
this.scrollToBottom();
|
|
21
|
+
}
|
|
22
|
+
/** Add an assistant response to the conversation. */
|
|
23
|
+
addAssistantMessage(text) {
|
|
24
|
+
this.loading = false;
|
|
25
|
+
this.messages = [...this.messages, { role: 'assistant', text }];
|
|
26
|
+
this.scrollToBottom();
|
|
27
|
+
}
|
|
28
|
+
/** Show or hide the typing indicator. */
|
|
29
|
+
setLoading(val) {
|
|
30
|
+
this.loading = val;
|
|
31
|
+
if (val)
|
|
32
|
+
this.scrollToBottom();
|
|
33
|
+
}
|
|
34
|
+
/** Clear all messages. */
|
|
35
|
+
clear() {
|
|
36
|
+
this.messages = [];
|
|
37
|
+
this.loading = false;
|
|
38
|
+
}
|
|
39
|
+
scrollToBottom() {
|
|
40
|
+
requestAnimationFrame(() => {
|
|
41
|
+
if (this.messagesEl) {
|
|
42
|
+
this.messagesEl.scrollTop = this.messagesEl.scrollHeight;
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
handleSend(e) {
|
|
47
|
+
e.stopPropagation();
|
|
48
|
+
const { message } = e.detail;
|
|
49
|
+
this.addUserMessage(message);
|
|
50
|
+
this.setLoading(true);
|
|
51
|
+
this.emit('nile-ai-send', { message });
|
|
52
|
+
}
|
|
53
|
+
render() {
|
|
54
|
+
return html `
|
|
55
|
+
<div class="messages">
|
|
56
|
+
${this.welcomeMessage
|
|
57
|
+
? html `<div class="message message--assistant">${this.welcomeMessage}</div>`
|
|
58
|
+
: nothing}
|
|
59
|
+
${this.messages.map(m => html `<div class="message message--${m.role}">${m.text}</div>`)}
|
|
60
|
+
${this.loading
|
|
61
|
+
? html `<div class="typing">
|
|
62
|
+
<span class="typing-dot"></span>
|
|
63
|
+
<span class="typing-dot"></span>
|
|
64
|
+
<span class="typing-dot"></span>
|
|
65
|
+
</div>`
|
|
66
|
+
: nothing}
|
|
67
|
+
</div>
|
|
68
|
+
<div class="sender-wrapper">
|
|
69
|
+
<nile-ai-sender
|
|
70
|
+
.placeholder=${this.placeholder}
|
|
71
|
+
.disabled=${this.loading}
|
|
72
|
+
@nile-ai-send=${this.handleSend}
|
|
73
|
+
></nile-ai-sender>
|
|
74
|
+
</div>
|
|
75
|
+
`;
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
NileAiPanel.styles = styles;
|
|
79
|
+
__decorate([
|
|
80
|
+
property({ type: String })
|
|
81
|
+
], NileAiPanel.prototype, "placeholder", void 0);
|
|
82
|
+
__decorate([
|
|
83
|
+
property({ type: String, attribute: 'welcome-message' })
|
|
84
|
+
], NileAiPanel.prototype, "welcomeMessage", void 0);
|
|
85
|
+
__decorate([
|
|
86
|
+
state()
|
|
87
|
+
], NileAiPanel.prototype, "messages", void 0);
|
|
88
|
+
__decorate([
|
|
89
|
+
state()
|
|
90
|
+
], NileAiPanel.prototype, "loading", void 0);
|
|
91
|
+
__decorate([
|
|
92
|
+
query('.messages')
|
|
93
|
+
], NileAiPanel.prototype, "messagesEl", void 0);
|
|
94
|
+
NileAiPanel = __decorate([
|
|
95
|
+
customElement('nile-ai-panel')
|
|
96
|
+
], NileAiPanel);
|
|
97
|
+
export { NileAiPanel };
|
|
98
|
+
//# sourceMappingURL=nile-ai-panel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { NileAiSender } from './nile-ai-sender.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const styles: import("lit").CSSResult;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { css } from 'lit';
|
|
2
|
+
export const styles = css `
|
|
3
|
+
:host {
|
|
4
|
+
display: block;
|
|
5
|
+
width: 100%;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.sender {
|
|
9
|
+
display: flex;
|
|
10
|
+
align-items: center;
|
|
11
|
+
gap: var(--nile-spacing-md, var(--ng-spacing-md));
|
|
12
|
+
padding: var(--nile-spacing-md, var(--ng-spacing-md)) var(--nile-spacing-lg, var(--ng-spacing-lg));
|
|
13
|
+
background: var(--nile-colors-white-base, var(--ng-colors-bg-primary));
|
|
14
|
+
border: var(--nile-border-width-1, var(--ng-stroke-width-1)) solid var(--nile-colors-neutral-400, var(--ng-colors-border-secondary));
|
|
15
|
+
border-radius: var(--nile-radius-radius-3xl, var(--ng-radius-xl));
|
|
16
|
+
transition: border-color var(--nile-transition-duration-short, var(--ng-transition-duration-fast)) ease, box-shadow var(--nile-transition-duration-short, var(--ng-transition-duration-fast)) ease;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.sender:focus-within {
|
|
20
|
+
border-color: var(--nile-colors-primary-600, var(--ng-colors-fg-brand-primary-600));
|
|
21
|
+
box-shadow: var(--nile-box-shadow-3, var(--ng-shadow-sm));
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.sender-input {
|
|
25
|
+
flex: 1;
|
|
26
|
+
border: none;
|
|
27
|
+
outline: none;
|
|
28
|
+
background: none;
|
|
29
|
+
font-family: var(--nile-font-family-serif, var(--ng-font-family-body));
|
|
30
|
+
font-size: var(--nile-type-scale-3, var(--ng-font-size-text-sm));
|
|
31
|
+
color: var(--nile-colors-dark-900, var(--ng-colors-text-primary-900));
|
|
32
|
+
line-height: 1.5;
|
|
33
|
+
min-height: var(--nile-height-20px, var(--ng-height-20px));
|
|
34
|
+
resize: none;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.sender-input::placeholder {
|
|
38
|
+
color: var(--nile-colors-neutral-500, var(--ng-colors-text-placeholder));
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.sender-btn {
|
|
42
|
+
display: flex;
|
|
43
|
+
align-items: center;
|
|
44
|
+
justify-content: center;
|
|
45
|
+
width: var(--nile-width-32px, var(--ng-height-32px));
|
|
46
|
+
height: var(--nile-width-32px, var(--ng-height-32px));
|
|
47
|
+
padding: 0;
|
|
48
|
+
border: none;
|
|
49
|
+
border-radius: 50%;
|
|
50
|
+
background: var(--nile-colors-primary-600, var(--ng-colors-fg-brand-primary-600));
|
|
51
|
+
color: var(--nile-colors-white-base, var(--ng-colors-bg-primary));
|
|
52
|
+
cursor: pointer;
|
|
53
|
+
flex-shrink: 0;
|
|
54
|
+
transition: background var(--nile-transition-duration-short, var(--ng-transition-duration-fast)) ease, opacity var(--nile-transition-duration-short, var(--ng-transition-duration-fast)) ease;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.sender-btn:hover:not(:disabled) {
|
|
58
|
+
background: var(--nile-colors-primary-700, var(--ng-colors-bg-brand-solid-hover));
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.sender-btn:disabled {
|
|
62
|
+
opacity: var(--nile-opacity-40, var(--ng-opacity-40));
|
|
63
|
+
cursor: not-allowed;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.sender-btn:focus-visible {
|
|
67
|
+
outline: var(--nile-border-width-2, var(--ng-stroke-width-2)) solid var(--nile-colors-primary-600, var(--ng-colors-fg-brand-primary-600));
|
|
68
|
+
outline-offset: var(--nile-spacing-2px, var(--ng-outline-offset-2));
|
|
69
|
+
}
|
|
70
|
+
`;
|
|
71
|
+
//# sourceMappingURL=nile-ai-sender.css.js.map
|