@smartnet360/svelte-components 0.0.19 → 0.0.21
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/core/Charts/ChartCard.svelte +49 -9
- package/dist/core/Charts/ChartCard.svelte.d.ts +3 -1
- package/dist/core/Charts/ChartComponent.svelte +4 -0
- package/dist/core/Charts/charts.model.d.ts +10 -0
- package/dist/core/Charts/data-utils.d.ts +17 -0
- package/dist/core/Charts/data-utils.js +73 -0
- package/dist/core/Charts/editor/ChartLayoutEditor.svelte +8 -0
- package/dist/core/Charts/editor/ChartLayoutEditor.svelte.d.ts +5 -1
- package/dist/core/Charts/editor/KPIPicker.svelte +13 -3
- package/dist/core/Charts/editor/KPIPicker.svelte.d.ts +2 -0
- package/dist/core/Charts/editor/exampleKPIs.d.ts +38 -0
- package/dist/core/Charts/editor/exampleKPIs.js +66 -0
- package/dist/core/Charts/index.d.ts +1 -0
- package/dist/core/Charts/index.js +1 -0
- package/package.json +1 -1
@@ -3,8 +3,8 @@
|
|
3
3
|
<script lang="ts">
|
4
4
|
import { onMount, createEventDispatcher } from 'svelte';
|
5
5
|
import Plotly from 'plotly.js-dist-min';
|
6
|
-
import type { Chart as ChartModel, ChartMarker } from './charts.model.js';
|
7
|
-
import {
|
6
|
+
import type { Chart as ChartModel, ChartMarker, MovingAverageConfig } from './charts.model.js';
|
7
|
+
import { createTimeSeriesTraceWithMA, getYAxisTitle, createDefaultPlotlyLayout } from './data-utils.js';
|
8
8
|
import { adaptPlotlyLayout, addMarkersToLayout, type ContainerSize } from './adapt.js';
|
9
9
|
|
10
10
|
const dispatch = createEventDispatcher<{
|
@@ -23,9 +23,11 @@
|
|
23
23
|
plotlyLayout?: any; // Optional custom Plotly layout for styling/theming
|
24
24
|
enableAdaptation?: boolean; // Enable size-based adaptations (default: true)
|
25
25
|
sectionId?: string;
|
26
|
+
sectionMovingAverage?: MovingAverageConfig; // Section-level MA config
|
27
|
+
layoutMovingAverage?: MovingAverageConfig; // Layout-level MA config
|
26
28
|
}
|
27
29
|
|
28
|
-
let { chart, data, markers, plotlyLayout, enableAdaptation = true, sectionId }: Props = $props();
|
30
|
+
let { chart, data, markers, plotlyLayout, enableAdaptation = true, sectionId, sectionMovingAverage, layoutMovingAverage }: Props = $props();
|
29
31
|
|
30
32
|
// Chart container div and state
|
31
33
|
let chartDiv: HTMLElement;
|
@@ -68,17 +70,55 @@
|
|
68
70
|
const traces: any[] = [];
|
69
71
|
let colorIndex = 0;
|
70
72
|
|
71
|
-
//
|
73
|
+
// Helper function to apply MA with full hierarchy:
|
74
|
+
// KPI > Chart > Section > Layout (higher priority wins)
|
75
|
+
const applyMovingAverageHierarchy = (kpi: any) => {
|
76
|
+
// If KPI has its own MA config, use it (highest priority)
|
77
|
+
if (kpi.movingAverage) {
|
78
|
+
return kpi;
|
79
|
+
}
|
80
|
+
|
81
|
+
// Check chart-level MA
|
82
|
+
if (chart.movingAverage) {
|
83
|
+
return {
|
84
|
+
...kpi,
|
85
|
+
movingAverage: chart.movingAverage
|
86
|
+
};
|
87
|
+
}
|
88
|
+
|
89
|
+
// Check section-level MA
|
90
|
+
if (sectionMovingAverage) {
|
91
|
+
return {
|
92
|
+
...kpi,
|
93
|
+
movingAverage: sectionMovingAverage
|
94
|
+
};
|
95
|
+
}
|
96
|
+
|
97
|
+
// Check layout-level MA (lowest priority, global default)
|
98
|
+
if (layoutMovingAverage) {
|
99
|
+
return {
|
100
|
+
...kpi,
|
101
|
+
movingAverage: layoutMovingAverage
|
102
|
+
};
|
103
|
+
}
|
104
|
+
|
105
|
+
// No MA configuration at any level
|
106
|
+
return kpi;
|
107
|
+
};
|
108
|
+
|
109
|
+
// Add left Y-axis traces (with moving average support)
|
72
110
|
chart.yLeft.forEach(kpi => {
|
73
|
-
const
|
74
|
-
|
111
|
+
const kpiWithMA = applyMovingAverageHierarchy(kpi);
|
112
|
+
const kpiTraces = createTimeSeriesTraceWithMA(data, kpiWithMA, 'TIMESTAMP', 'y1', colorIndex);
|
113
|
+
traces.push(...kpiTraces);
|
75
114
|
colorIndex++;
|
76
115
|
});
|
77
116
|
|
78
|
-
// Add right Y-axis traces
|
117
|
+
// Add right Y-axis traces (with moving average support)
|
79
118
|
chart.yRight.forEach(kpi => {
|
80
|
-
const
|
81
|
-
|
119
|
+
const kpiWithMA = applyMovingAverageHierarchy(kpi);
|
120
|
+
const kpiTraces = createTimeSeriesTraceWithMA(data, kpiWithMA, 'TIMESTAMP', 'y2', colorIndex);
|
121
|
+
traces.push(...kpiTraces);
|
82
122
|
colorIndex++;
|
83
123
|
});
|
84
124
|
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import type { Chart as ChartModel, ChartMarker } from './charts.model.js';
|
1
|
+
import type { Chart as ChartModel, ChartMarker, MovingAverageConfig } from './charts.model.js';
|
2
2
|
interface Props {
|
3
3
|
chart: ChartModel;
|
4
4
|
data: any[];
|
@@ -6,6 +6,8 @@ interface Props {
|
|
6
6
|
plotlyLayout?: any;
|
7
7
|
enableAdaptation?: boolean;
|
8
8
|
sectionId?: string;
|
9
|
+
sectionMovingAverage?: MovingAverageConfig;
|
10
|
+
layoutMovingAverage?: MovingAverageConfig;
|
9
11
|
}
|
10
12
|
interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
|
11
13
|
new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
|
@@ -246,6 +246,8 @@
|
|
246
246
|
{plotlyLayout}
|
247
247
|
{enableAdaptation}
|
248
248
|
sectionId={section.id}
|
249
|
+
sectionMovingAverage={section.movingAverage}
|
250
|
+
layoutMovingAverage={layout.movingAverage}
|
249
251
|
on:chartcontextmenu={(event) => handleChartContextMenu(event.detail, section)}
|
250
252
|
/>
|
251
253
|
</div>
|
@@ -343,6 +345,8 @@
|
|
343
345
|
{plotlyLayout}
|
344
346
|
{enableAdaptation}
|
345
347
|
sectionId={activeZoom.section.id}
|
348
|
+
sectionMovingAverage={activeZoom.section.movingAverage}
|
349
|
+
layoutMovingAverage={layout.movingAverage}
|
346
350
|
on:chartcontextmenu={(event) => handleChartContextMenu(event.detail, activeZoom.section)}
|
347
351
|
/>
|
348
352
|
</div>
|
@@ -1,10 +1,17 @@
|
|
1
1
|
export type Scale = "percent" | "absolute";
|
2
|
+
export interface MovingAverageConfig {
|
3
|
+
enabled: boolean;
|
4
|
+
window: number;
|
5
|
+
showOriginal?: boolean;
|
6
|
+
label?: string;
|
7
|
+
}
|
2
8
|
export interface KPI {
|
3
9
|
rawName: string;
|
4
10
|
name: string;
|
5
11
|
scale: Scale;
|
6
12
|
unit: string;
|
7
13
|
color?: string;
|
14
|
+
movingAverage?: MovingAverageConfig;
|
8
15
|
}
|
9
16
|
export type ChartPosition = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9;
|
10
17
|
export type ChartGrid = "2x2" | "3x3" | "4x4" | "1x2" | "1x4" | "1x8";
|
@@ -13,17 +20,20 @@ export interface Chart {
|
|
13
20
|
title: string;
|
14
21
|
yLeft: KPI[];
|
15
22
|
yRight: KPI[];
|
23
|
+
movingAverage?: MovingAverageConfig;
|
16
24
|
}
|
17
25
|
export interface Section {
|
18
26
|
id: string;
|
19
27
|
title: string;
|
20
28
|
charts: Chart[];
|
21
29
|
grid?: ChartGrid;
|
30
|
+
movingAverage?: MovingAverageConfig;
|
22
31
|
}
|
23
32
|
export type Mode = "tabs" | "scrollspy";
|
24
33
|
export interface Layout {
|
25
34
|
layoutName: string;
|
26
35
|
sections: Section[];
|
36
|
+
movingAverage?: MovingAverageConfig;
|
27
37
|
}
|
28
38
|
export interface ChartMarker {
|
29
39
|
date: string | Date;
|
@@ -1,6 +1,23 @@
|
|
1
1
|
import type { KPI } from './charts.model.js';
|
2
2
|
export declare function processKPIData(data: any[], kpi: KPI): number[];
|
3
|
+
/**
|
4
|
+
* Calculate moving average for a series of values
|
5
|
+
* @param values - Array of numeric values
|
6
|
+
* @param window - Number of periods for MA calculation
|
7
|
+
* @returns Array of moving average values (NaN for insufficient data points)
|
8
|
+
*/
|
9
|
+
export declare function calculateMovingAverage(values: number[], window: number): number[];
|
3
10
|
export declare function createTimeSeriesTrace(data: any[], kpi: KPI, timestampField?: string, yaxis?: 'y1' | 'y2', colorIndex?: number): any;
|
11
|
+
/**
|
12
|
+
* Create time series trace(s) with optional moving average
|
13
|
+
* @param data - Raw data array
|
14
|
+
* @param kpi - KPI configuration (may include movingAverage config)
|
15
|
+
* @param timestampField - Field name for timestamp column
|
16
|
+
* @param yaxis - Which Y-axis to use ('y1' or 'y2')
|
17
|
+
* @param colorIndex - Index for color selection
|
18
|
+
* @returns Array of traces (original + MA if configured)
|
19
|
+
*/
|
20
|
+
export declare function createTimeSeriesTraceWithMA(data: any[], kpi: KPI, timestampField?: string, yaxis?: 'y1' | 'y2', colorIndex?: number): any[];
|
4
21
|
export declare function getYAxisTitle(kpis: KPI[]): string;
|
5
22
|
export declare function formatValue(value: number, scale: 'percent' | 'absolute', unit: string): string;
|
6
23
|
export declare function createDefaultPlotlyLayout(title?: string): any;
|
@@ -19,6 +19,28 @@ export function processKPIData(data, kpi) {
|
|
19
19
|
})
|
20
20
|
.filter(val => !isNaN(val));
|
21
21
|
}
|
22
|
+
/**
|
23
|
+
* Calculate moving average for a series of values
|
24
|
+
* @param values - Array of numeric values
|
25
|
+
* @param window - Number of periods for MA calculation
|
26
|
+
* @returns Array of moving average values (NaN for insufficient data points)
|
27
|
+
*/
|
28
|
+
export function calculateMovingAverage(values, window) {
|
29
|
+
const result = [];
|
30
|
+
for (let i = 0; i < values.length; i++) {
|
31
|
+
if (i < window - 1) {
|
32
|
+
// Not enough data points yet - use NaN to skip these points
|
33
|
+
result.push(NaN);
|
34
|
+
}
|
35
|
+
else {
|
36
|
+
// Calculate average of the window
|
37
|
+
const windowValues = values.slice(i - window + 1, i + 1);
|
38
|
+
const sum = windowValues.reduce((a, b) => a + b, 0);
|
39
|
+
result.push(sum / window);
|
40
|
+
}
|
41
|
+
}
|
42
|
+
return result;
|
43
|
+
}
|
22
44
|
export function createTimeSeriesTrace(data, kpi, timestampField = 'TIMESTAMP', yaxis = 'y1', colorIndex = 0) {
|
23
45
|
const values = processKPIData(data, kpi);
|
24
46
|
const timestamps = data.map(row => row[timestampField]);
|
@@ -43,6 +65,57 @@ export function createTimeSeriesTrace(data, kpi, timestampField = 'TIMESTAMP', y
|
|
43
65
|
'<extra></extra>'
|
44
66
|
};
|
45
67
|
}
|
68
|
+
/**
|
69
|
+
* Create time series trace(s) with optional moving average
|
70
|
+
* @param data - Raw data array
|
71
|
+
* @param kpi - KPI configuration (may include movingAverage config)
|
72
|
+
* @param timestampField - Field name for timestamp column
|
73
|
+
* @param yaxis - Which Y-axis to use ('y1' or 'y2')
|
74
|
+
* @param colorIndex - Index for color selection
|
75
|
+
* @returns Array of traces (original + MA if configured)
|
76
|
+
*/
|
77
|
+
export function createTimeSeriesTraceWithMA(data, kpi, timestampField = 'TIMESTAMP', yaxis = 'y1', colorIndex = 0) {
|
78
|
+
const traces = [];
|
79
|
+
const values = processKPIData(data, kpi);
|
80
|
+
const timestamps = data.map(row => row[timestampField]);
|
81
|
+
const traceColor = kpi.color || modernColors[colorIndex % modernColors.length];
|
82
|
+
// Add original trace (unless explicitly disabled)
|
83
|
+
if (!kpi.movingAverage || kpi.movingAverage.showOriginal !== false) {
|
84
|
+
const originalTrace = createTimeSeriesTrace(data, kpi, timestampField, yaxis, colorIndex);
|
85
|
+
// If MA is enabled, make the original line slightly transparent
|
86
|
+
if (kpi.movingAverage?.enabled) {
|
87
|
+
originalTrace.opacity = 0.4;
|
88
|
+
originalTrace.line.width = 2;
|
89
|
+
}
|
90
|
+
traces.push(originalTrace);
|
91
|
+
}
|
92
|
+
// Add moving average trace if configured
|
93
|
+
if (kpi.movingAverage?.enabled) {
|
94
|
+
const maValues = calculateMovingAverage(values, kpi.movingAverage.window);
|
95
|
+
const maLabel = kpi.movingAverage.label ||
|
96
|
+
`${kpi.name} (MA${kpi.movingAverage.window})`;
|
97
|
+
const maTrace = {
|
98
|
+
x: timestamps,
|
99
|
+
y: maValues,
|
100
|
+
type: 'scatter',
|
101
|
+
mode: 'lines',
|
102
|
+
name: maLabel,
|
103
|
+
yaxis: yaxis,
|
104
|
+
line: {
|
105
|
+
color: traceColor,
|
106
|
+
width: 3,
|
107
|
+
shape: 'spline',
|
108
|
+
smoothing: 0.3,
|
109
|
+
dash: yaxis === 'y1' ? 'solid' : 'dot'
|
110
|
+
},
|
111
|
+
hovertemplate: `<b>${maLabel}</b><br>` +
|
112
|
+
`Value: %{y:,.2f} ${kpi.unit}<br>` +
|
113
|
+
'<extra></extra>'
|
114
|
+
};
|
115
|
+
traces.push(maTrace);
|
116
|
+
}
|
117
|
+
return traces;
|
118
|
+
}
|
46
119
|
export function getYAxisTitle(kpis) {
|
47
120
|
if (kpis.length === 0)
|
48
121
|
return '';
|
@@ -6,6 +6,13 @@
|
|
6
6
|
import GridPreview from './GridPreview.svelte';
|
7
7
|
import PropertiesPanel from './PropertiesPanel.svelte';
|
8
8
|
import KPIPicker from './KPIPicker.svelte';
|
9
|
+
import type { KPI } from '../charts.model.js';
|
10
|
+
|
11
|
+
interface Props {
|
12
|
+
availableKPIs: KPI[];
|
13
|
+
}
|
14
|
+
|
15
|
+
let { availableKPIs }: Props = $props();
|
9
16
|
|
10
17
|
let showKPIPicker = $state(false);
|
11
18
|
let showLibrary = $state(false);
|
@@ -180,6 +187,7 @@
|
|
180
187
|
{#if showKPIPicker}
|
181
188
|
<KPIPicker
|
182
189
|
show={showKPIPicker}
|
190
|
+
{availableKPIs}
|
183
191
|
on:select={handleKPISelected}
|
184
192
|
on:close={() => { showKPIPicker = false; kpiPickerContext = null; }}
|
185
193
|
/>
|
@@ -1,3 +1,7 @@
|
|
1
|
-
|
1
|
+
import type { KPI } from '../charts.model.js';
|
2
|
+
interface Props {
|
3
|
+
availableKPIs: KPI[];
|
4
|
+
}
|
5
|
+
declare const ChartLayoutEditor: import("svelte").Component<Props, {}, "">;
|
2
6
|
type ChartLayoutEditor = ReturnType<typeof ChartLayoutEditor>;
|
3
7
|
export default ChartLayoutEditor;
|
@@ -2,22 +2,32 @@
|
|
2
2
|
|
3
3
|
<script lang="ts">
|
4
4
|
import { createEventDispatcher } from 'svelte';
|
5
|
-
import { availableKPIs, searchKPIs } from '../../../../routes/charts/schemas/available-kpis.js';
|
6
5
|
import type { KPI } from '../charts.model.js';
|
7
6
|
|
8
7
|
interface Props {
|
9
8
|
show: boolean;
|
9
|
+
availableKPIs: KPI[];
|
10
10
|
}
|
11
11
|
|
12
|
-
let { show }: Props = $props();
|
12
|
+
let { show, availableKPIs }: Props = $props();
|
13
13
|
|
14
14
|
const dispatch = createEventDispatcher();
|
15
15
|
|
16
16
|
let searchQuery = $state('');
|
17
17
|
let selectedKPI = $state<KPI | null>(null);
|
18
18
|
|
19
|
+
// Local search function
|
20
|
+
function searchKPIs(query: string, kpis: KPI[]): KPI[] {
|
21
|
+
const lowerQuery = query.toLowerCase();
|
22
|
+
return kpis.filter(
|
23
|
+
kpi =>
|
24
|
+
kpi.name.toLowerCase().includes(lowerQuery) ||
|
25
|
+
kpi.rawName.toLowerCase().includes(lowerQuery)
|
26
|
+
);
|
27
|
+
}
|
28
|
+
|
19
29
|
let filteredKPIs = $derived(
|
20
|
-
searchQuery ? searchKPIs(searchQuery) : availableKPIs
|
30
|
+
searchQuery ? searchKPIs(searchQuery, availableKPIs) : availableKPIs
|
21
31
|
);
|
22
32
|
|
23
33
|
function handleSelect(kpi: KPI) {
|
@@ -1,5 +1,7 @@
|
|
1
|
+
import type { KPI } from '../charts.model.js';
|
1
2
|
interface Props {
|
2
3
|
show: boolean;
|
4
|
+
availableKPIs: KPI[];
|
3
5
|
}
|
4
6
|
interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
|
5
7
|
new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
|
@@ -0,0 +1,38 @@
|
|
1
|
+
/**
|
2
|
+
* Example KPI Configuration
|
3
|
+
*
|
4
|
+
* This is a reference example showing the structure for availableKPIs.
|
5
|
+
* In your application, you should:
|
6
|
+
* 1. Load KPIs from your backend API
|
7
|
+
* 2. Store in a JSON file specific to your domain
|
8
|
+
* 3. Generate dynamically based on your data schema
|
9
|
+
*/
|
10
|
+
import type { KPI } from '../charts.model.js';
|
11
|
+
/**
|
12
|
+
* Example KPI list structure
|
13
|
+
* Each KPI must have: rawName, name, scale, unit, and optional color
|
14
|
+
*/
|
15
|
+
export declare const exampleKPIs: KPI[];
|
16
|
+
/**
|
17
|
+
* KPI Interface Reference:
|
18
|
+
*
|
19
|
+
* interface KPI {
|
20
|
+
* rawName: string; // Column name in your data source
|
21
|
+
* name: string; // Display name shown in UI
|
22
|
+
* scale: 'percent' | 'absolute'; // Data type
|
23
|
+
* unit: string; // Unit of measurement (%, GB, users, etc.)
|
24
|
+
* color?: string; // Optional hex color for chart line
|
25
|
+
* }
|
26
|
+
*/
|
27
|
+
/**
|
28
|
+
* Usage Example:
|
29
|
+
*
|
30
|
+
* <script>
|
31
|
+
* import { ChartLayoutEditor } from '..';
|
32
|
+
* import { exampleKPIs } from './exampleKPIs';
|
33
|
+
* // OR load from API:
|
34
|
+
* // const myKPIs = await fetch('/api/kpis').then(r => r.json());
|
35
|
+
* </script>
|
36
|
+
*
|
37
|
+
* <ChartLayoutEditor availableKPIs={exampleKPIs} />
|
38
|
+
*/
|
@@ -0,0 +1,66 @@
|
|
1
|
+
/**
|
2
|
+
* Example KPI Configuration
|
3
|
+
*
|
4
|
+
* This is a reference example showing the structure for availableKPIs.
|
5
|
+
* In your application, you should:
|
6
|
+
* 1. Load KPIs from your backend API
|
7
|
+
* 2. Store in a JSON file specific to your domain
|
8
|
+
* 3. Generate dynamically based on your data schema
|
9
|
+
*/
|
10
|
+
/**
|
11
|
+
* Example KPI list structure
|
12
|
+
* Each KPI must have: rawName, name, scale, unit, and optional color
|
13
|
+
*/
|
14
|
+
export const exampleKPIs = [
|
15
|
+
{
|
16
|
+
rawName: 'CCSR_PC',
|
17
|
+
name: 'CCSR Success Rate',
|
18
|
+
scale: 'percent',
|
19
|
+
unit: '%',
|
20
|
+
color: '#2ca02c' // Optional: hex color for the trace
|
21
|
+
},
|
22
|
+
{
|
23
|
+
rawName: 'DL_GBYTES',
|
24
|
+
name: 'Downlink Traffic',
|
25
|
+
scale: 'absolute',
|
26
|
+
unit: 'GB',
|
27
|
+
color: '#06B6D4'
|
28
|
+
},
|
29
|
+
{
|
30
|
+
rawName: 'UL_GBYTES',
|
31
|
+
name: 'Uplink Traffic',
|
32
|
+
scale: 'absolute',
|
33
|
+
unit: 'GB',
|
34
|
+
color: '#84CC16'
|
35
|
+
},
|
36
|
+
{
|
37
|
+
rawName: 'AVG_USERS',
|
38
|
+
name: 'Average Connected Users',
|
39
|
+
scale: 'absolute',
|
40
|
+
unit: 'users',
|
41
|
+
color: '#EF4444'
|
42
|
+
}
|
43
|
+
];
|
44
|
+
/**
|
45
|
+
* KPI Interface Reference:
|
46
|
+
*
|
47
|
+
* interface KPI {
|
48
|
+
* rawName: string; // Column name in your data source
|
49
|
+
* name: string; // Display name shown in UI
|
50
|
+
* scale: 'percent' | 'absolute'; // Data type
|
51
|
+
* unit: string; // Unit of measurement (%, GB, users, etc.)
|
52
|
+
* color?: string; // Optional hex color for chart line
|
53
|
+
* }
|
54
|
+
*/
|
55
|
+
/**
|
56
|
+
* Usage Example:
|
57
|
+
*
|
58
|
+
* <script>
|
59
|
+
* import { ChartLayoutEditor } from '..';
|
60
|
+
* import { exampleKPIs } from './exampleKPIs';
|
61
|
+
* // OR load from API:
|
62
|
+
* // const myKPIs = await fetch('/api/kpis').then(r => r.json());
|
63
|
+
* </script>
|
64
|
+
*
|
65
|
+
* <ChartLayoutEditor availableKPIs={exampleKPIs} />
|
66
|
+
*/
|
@@ -7,3 +7,4 @@ export type { ContainerSize, ChartInfo, AdaptationConfig } from './adapt.js';
|
|
7
7
|
export { default as ChartLayoutEditor } from './editor/ChartLayoutEditor.svelte';
|
8
8
|
export { editorStore, currentLayout, savedLayouts, selection, isDirty, selectedItem } from './editor/editorState.js';
|
9
9
|
export type { Selection, SelectionType, EditorState } from './editor/editorState.js';
|
10
|
+
export { exampleKPIs } from './editor/exampleKPIs.js';
|
@@ -5,3 +5,4 @@ export { adaptPlotlyLayout, getSizeCategory, createMarkerShapes, createMarkerAnn
|
|
5
5
|
// Editor exports
|
6
6
|
export { default as ChartLayoutEditor } from './editor/ChartLayoutEditor.svelte';
|
7
7
|
export { editorStore, currentLayout, savedLayouts, selection, isDirty, selectedItem } from './editor/editorState.js';
|
8
|
+
export { exampleKPIs } from './editor/exampleKPIs.js';
|