@smartnet360/svelte-components 0.0.2 → 0.0.4

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.
@@ -25,17 +25,20 @@
25
25
  if (!chartDiv || !data?.length) return;
26
26
 
27
27
  const traces: any[] = [];
28
+ let colorIndex = 0;
28
29
 
29
30
  // Add left Y-axis traces
30
31
  chart.yLeft.forEach(kpi => {
31
- const trace = createTimeSeriesTrace(data, kpi, 'TIMESTAMP', 'y1');
32
+ const trace = createTimeSeriesTrace(data, kpi, 'TIMESTAMP', 'y1', colorIndex);
32
33
  traces.push(trace);
34
+ colorIndex++;
33
35
  });
34
36
 
35
37
  // Add right Y-axis traces
36
38
  chart.yRight.forEach(kpi => {
37
- const trace = createTimeSeriesTrace(data, kpi, 'TIMESTAMP', 'y2');
39
+ const trace = createTimeSeriesTrace(data, kpi, 'TIMESTAMP', 'y2', colorIndex);
38
40
  traces.push(trace);
41
+ colorIndex++;
39
42
  });
40
43
 
41
44
  // Create default modern layout
@@ -56,7 +59,14 @@
56
59
  y: 1,
57
60
  xanchor: 'right',
58
61
  yanchor: 'top',
59
- font: { size: 12 }
62
+ font: {
63
+ family: 'Inter, Segoe UI, Tahoma, Geneva, Verdana, sans-serif',
64
+ size: 11,
65
+ color: '#6B7280'
66
+ },
67
+ bgcolor: 'rgba(255,255,255,0.9)',
68
+ bordercolor: '#6B7280',
69
+ borderwidth: 1
60
70
  },
61
71
  xaxis: {
62
72
  showgrid: true,
@@ -77,7 +87,17 @@
77
87
  margin: { l: 60, r: 60, t: 60, b: 50 },
78
88
  paper_bgcolor: 'rgba(0,0,0,0)',
79
89
  plot_bgcolor: 'rgba(0,0,0,0)',
80
- font: { family: 'Inter, -apple-system, BlinkMacSystemFont, sans-serif' }
90
+ font: { family: 'Inter, -apple-system, BlinkMacSystemFont, sans-serif' },
91
+ hovermode: 'x unified',
92
+ hoverlabel: {
93
+ font: {
94
+ family: 'Inter, Segoe UI, Tahoma, Geneva, Verdana, sans-serif',
95
+ size: 11,
96
+ color: '#6B7280'
97
+ },
98
+ bgcolor: 'rgba(255,255,255,0.9)',
99
+ bordercolor: '#6B7280'
100
+ }
81
101
  };
82
102
 
83
103
  // Add second Y-axis if we have right-side KPIs
@@ -1,7 +1,7 @@
1
1
  <svelte:options runes={true} />
2
2
 
3
3
  <script lang="ts">
4
- import type { Layout, Mode, ChartMarker } from './charts.model.js';
4
+ import type { Layout, Mode, ChartMarker, Section } from './charts.model.js';
5
5
  import ChartCard from './ChartCard.svelte';
6
6
 
7
7
  interface Props {
@@ -19,6 +19,17 @@
19
19
  let activeTabId = $state(layout.sections[0]?.id || '');
20
20
  </script>
21
21
 
22
+ <!-- Reusable chart grid snippet -->
23
+ {#snippet chartGrid(section: Section)}
24
+ <div class="chart-grid">
25
+ {#each section.charts as chart}
26
+ <div class="chart-slot">
27
+ <ChartCard {chart} {data} {markers} {plotlyLayout} {enableAdaptation} />
28
+ </div>
29
+ {/each}
30
+ </div>
31
+ {/snippet}
32
+
22
33
  <div class="chart-component">
23
34
  {#if mode === 'tabs'}
24
35
  <!-- Tab Mode with Navigation -->
@@ -50,13 +61,7 @@
50
61
  data-section-id="{section.id}"
51
62
  >
52
63
  <!-- 2x2 Grid -->
53
- <div class="chart-grid">
54
- {#each section.charts as chart}
55
- <div class="chart-slot">
56
- <ChartCard {chart} {data} {plotlyLayout} />
57
- </div>
58
- {/each}
59
- </div>
64
+ {@render chartGrid(section)}
60
65
  </div>
61
66
  {/each}
62
67
  </div>
@@ -80,13 +85,7 @@
80
85
  {#each layout.sections as section}
81
86
  <div class="section-content" id="{section.id}">
82
87
  <!-- 2x2 Grid -->
83
- <div class="chart-grid">
84
- {#each section.charts as chart}
85
- <div class="chart-slot">
86
- <ChartCard {chart} {data} {markers} {plotlyLayout} {enableAdaptation} />
87
- </div>
88
- {/each}
89
- </div>
88
+ {@render chartGrid(section)}
90
89
  </div>
91
90
  {/each}
92
91
  </div>
@@ -90,7 +90,10 @@ export function adaptPlotlyLayout(baseLayout, containerSize, chartInfo, config =
90
90
  // Adaptive legend font size
91
91
  if (adaptedLayout.legend?.font && adaptedLayout.showlegend) {
92
92
  if (isSmall) {
93
- adaptedLayout.legend.font.size = 10;
93
+ adaptedLayout.legend.font.size = 9;
94
+ }
95
+ else {
96
+ adaptedLayout.legend.font.size = 11;
94
97
  }
95
98
  }
96
99
  return adaptedLayout;
@@ -154,24 +157,22 @@ export function createMarkerAnnotations(markers, containerSize, enableAdaptation
154
157
  else if (sizeCategory === 'large')
155
158
  fontSize = 10;
156
159
  }
157
- // Adaptive label positioning
158
- const yPosition = sizeCategory === 'small' ? 0.95 : 0.9;
159
160
  return {
160
161
  x: marker.date,
161
- y: yPosition,
162
+ y: 1, // Top of chart area
162
163
  yref: 'paper',
163
164
  text: marker.label,
164
- showarrow: true,
165
- arrowhead: 2,
166
- arrowcolor: marker.color || '#ff0000',
167
- arrowsize: sizeCategory === 'small' ? 0.8 : 1,
165
+ showarrow: false, // Remove arrow
166
+ yanchor: 'bottom', // Anchor to bottom so text appears below the top line
167
+ xanchor: 'center', // Center the text horizontally
168
168
  font: {
169
169
  size: fontSize,
170
170
  color: marker.color || '#ff0000'
171
171
  },
172
- bgcolor: 'rgba(255,255,255,0.8)',
172
+ bgcolor: 'rgba(255,255,255,0.9)', // More opaque background
173
173
  bordercolor: marker.color || '#ff0000',
174
- borderwidth: 1
174
+ borderwidth: 1,
175
+ borderpad: 2
175
176
  };
176
177
  });
177
178
  }
@@ -1,12 +1,10 @@
1
1
  export type Scale = "percent" | "absolute";
2
- export type Aggregation = "avg" | "max" | "min" | "sum";
3
2
  export interface KPI {
4
3
  rawName: string;
5
4
  name: string;
6
5
  scale: Scale;
7
6
  unit: string;
8
7
  color?: string;
9
- aggregation: Aggregation;
10
8
  }
11
9
  export interface Chart {
12
10
  pos: 1 | 2 | 3 | 4;
@@ -1,13 +1,6 @@
1
1
  import type { KPI } from './charts.model.js';
2
- export type AggregationType = 'avg' | 'sum' | 'max' | 'min';
3
- export declare function aggregateValue(values: number[], aggregation: AggregationType): number;
4
- export declare function processKPIData(data: any[], kpi: KPI): {
5
- values: number[];
6
- aggregated: number;
7
- };
8
- export declare function createTimeSeriesTrace(data: any[], kpi: KPI, timestampField?: string, yaxis?: 'y1' | 'y2'): any;
9
- export declare function createBarTrace(data: any[], kpi: KPI, timestampField?: string, yaxis?: 'y1' | 'y2'): any;
10
- export declare function createPieTrace(data: any[], kpi: KPI, timestampField?: string): any;
2
+ export declare function processKPIData(data: any[], kpi: KPI): number[];
3
+ export declare function createTimeSeriesTrace(data: any[], kpi: KPI, timestampField?: string, yaxis?: 'y1' | 'y2', colorIndex?: number): any;
11
4
  export declare function getYAxisTitle(kpis: KPI[]): string;
12
5
  export declare function formatValue(value: number, scale: 'percent' | 'absolute', unit: string): string;
13
6
  export declare function createDefaultPlotlyLayout(title?: string): any;
@@ -1,77 +1,46 @@
1
- export function aggregateValue(values, aggregation) {
2
- switch (aggregation) {
3
- case 'avg':
4
- return values.reduce((sum, val) => sum + val, 0) / values.length;
5
- case 'sum':
6
- return values.reduce((sum, val) => sum + val, 0);
7
- case 'max':
8
- return Math.max(...values);
9
- case 'min':
10
- return Math.min(...values);
11
- default:
12
- return values[0] || 0;
13
- }
14
- }
1
+ // Modern color palette similar to Chart.js
2
+ const modernColors = [
3
+ '#3B82F6', // Blue
4
+ '#EF4444', // Red
5
+ '#10B981', // Emerald
6
+ '#F59E0B', // Amber
7
+ '#8B5CF6', // Violet
8
+ '#06B6D4', // Cyan
9
+ '#F97316', // Orange
10
+ '#84CC16', // Lime
11
+ '#EC4899', // Pink
12
+ '#6B7280' // Gray
13
+ ];
15
14
  export function processKPIData(data, kpi) {
16
- const rawValues = data
15
+ return data
17
16
  .map(row => {
18
17
  const val = row[kpi.rawName];
19
18
  return typeof val === 'number' ? val : parseFloat(val);
20
19
  })
21
20
  .filter(val => !isNaN(val));
22
- const aggregated = aggregateValue(rawValues, kpi.aggregation);
23
- return {
24
- values: rawValues,
25
- aggregated
26
- };
27
21
  }
28
- export function createTimeSeriesTrace(data, kpi, timestampField = 'TIMESTAMP', yaxis = 'y1') {
29
- const processed = processKPIData(data, kpi);
22
+ export function createTimeSeriesTrace(data, kpi, timestampField = 'TIMESTAMP', yaxis = 'y1', colorIndex = 0) {
23
+ const values = processKPIData(data, kpi);
30
24
  const timestamps = data.map(row => row[timestampField]);
25
+ // Use KPI color if provided, otherwise cycle through modern colors
26
+ const traceColor = kpi.color || modernColors[colorIndex % modernColors.length];
31
27
  return {
32
28
  x: timestamps,
33
- y: processed.values,
29
+ y: values,
34
30
  type: 'scatter',
35
- mode: 'lines+markers',
31
+ mode: 'lines', // Only lines, no markers
36
32
  name: kpi.name,
37
33
  yaxis: yaxis,
38
34
  line: {
39
- color: kpi.color || '#1f77b4',
40
- width: 2
35
+ color: traceColor,
36
+ width: 3,
37
+ shape: 'spline',
38
+ smoothing: 0.3,
39
+ dash: yaxis === 'y1' ? 'solid' : 'dot' // Y1 = solid, Y2 = dotted
41
40
  },
42
- marker: {
43
- size: 4
44
- }
45
- };
46
- }
47
- export function createBarTrace(data, kpi, timestampField = 'TIMESTAMP', yaxis = 'y1') {
48
- const processed = processKPIData(data, kpi);
49
- const timestamps = data.map(row => row[timestampField]);
50
- return {
51
- x: timestamps,
52
- y: processed.values,
53
- type: 'bar',
54
- name: kpi.name,
55
- yaxis: yaxis,
56
- marker: {
57
- color: kpi.color || '#1f77b4'
58
- }
59
- };
60
- }
61
- export function createPieTrace(data, kpi, timestampField = 'TIMESTAMP') {
62
- const processed = processKPIData(data, kpi);
63
- const timestamps = data.map(row => row[timestampField]);
64
- // For pie charts, we'll show the latest value
65
- const latestValue = processed.values[processed.values.length - 1];
66
- const latestTimestamp = timestamps[timestamps.length - 1];
67
- return {
68
- values: [latestValue],
69
- labels: [kpi.name],
70
- type: 'pie',
71
- name: `${kpi.name} (${latestTimestamp})`,
72
- marker: {
73
- colors: [kpi.color || '#1f77b4']
74
- }
41
+ hovertemplate: `<b> ${kpi.name}</b><br>` +
42
+ `Value: %{y:,.2f} ${kpi.unit}<br>` +
43
+ '<extra></extra>'
75
44
  };
76
45
  }
77
46
  export function getYAxisTitle(kpis) {
@@ -105,7 +74,14 @@ export function createDefaultPlotlyLayout(title) {
105
74
  y: 1,
106
75
  xanchor: 'right',
107
76
  yanchor: 'top',
108
- font: { size: 12 }
77
+ font: {
78
+ family: 'Inter, Segoe UI, Tahoma, Geneva, Verdana, sans-serif',
79
+ size: 11,
80
+ color: '#6B7280'
81
+ },
82
+ bgcolor: 'rgba(255,255,255,0.9)',
83
+ bordercolor: '#6B7280',
84
+ borderwidth: 1
109
85
  },
110
86
  xaxis: {
111
87
  title: {
@@ -126,6 +102,16 @@ export function createDefaultPlotlyLayout(title) {
126
102
  margin: { l: 60, r: 60, t: 60, b: 50 },
127
103
  paper_bgcolor: 'rgba(0,0,0,0)',
128
104
  plot_bgcolor: 'rgba(0,0,0,0)',
129
- font: { family: 'Inter, -apple-system, BlinkMacSystemFont, sans-serif' }
105
+ font: { family: 'Inter, -apple-system, BlinkMacSystemFont, sans-serif' },
106
+ hovermode: 'x unified',
107
+ hoverlabel: {
108
+ font: {
109
+ family: 'Inter, Segoe UI, Tahoma, Geneva, Verdana, sans-serif',
110
+ size: 11,
111
+ color: '#6B7280'
112
+ },
113
+ bgcolor: 'rgba(255,255,255,0.9)',
114
+ bordercolor: '#6B7280'
115
+ }
130
116
  };
131
117
  }
@@ -1,7 +1,6 @@
1
1
  export { default as ChartComponent } from './ChartComponent.svelte';
2
2
  export { default as ChartCard } from './ChartCard.svelte';
3
- export type { Layout, Section, Chart, KPI, Mode, Scale, Aggregation, ChartMarker } from './charts.model.js';
4
- export { createTimeSeriesTrace, createBarTrace, createPieTrace, getYAxisTitle, formatValue, aggregateValue, processKPIData, createDefaultPlotlyLayout } from './data-utils.js';
5
- export type { AggregationType } from './data-utils.js';
3
+ export type { Layout, Section, Chart, KPI, Mode, Scale, ChartMarker } from './charts.model.js';
4
+ export { createTimeSeriesTrace, getYAxisTitle, formatValue, processKPIData, createDefaultPlotlyLayout } from './data-utils.js';
6
5
  export { adaptPlotlyLayout, getSizeCategory, createMarkerShapes, createMarkerAnnotations, addMarkersToLayout } from './adapt.js';
7
6
  export type { ContainerSize, ChartInfo, AdaptationConfig } from './adapt.js';
@@ -1,4 +1,4 @@
1
1
  export { default as ChartComponent } from './ChartComponent.svelte';
2
2
  export { default as ChartCard } from './ChartCard.svelte';
3
- export { createTimeSeriesTrace, createBarTrace, createPieTrace, getYAxisTitle, formatValue, aggregateValue, processKPIData, createDefaultPlotlyLayout } from './data-utils.js';
3
+ export { createTimeSeriesTrace, getYAxisTitle, formatValue, processKPIData, createDefaultPlotlyLayout } from './data-utils.js';
4
4
  export { adaptPlotlyLayout, getSizeCategory, createMarkerShapes, createMarkerAnnotations, addMarkersToLayout } from './adapt.js';
package/dist/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  export { Half, Quarter, ResizeHandle, resizeStore, Desktop, GridSelector, GridRenderer, GridViewer, type ComponentConfig, getAllLayouts, getLayoutById, getLayoutsByCategory, getLayoutsOrdered, validateComponentAssignments, createGridConfiguration, type GridLayoutDefinition, type GridSlot, type ComponentAssignment, type GridConfiguration, createWindowLauncher, createTabLauncher, createNavigationLauncher, createModalLauncher } from './Desktop/index.js';
2
- export { ChartComponent, ChartCard, type Layout, type Section, type Chart, type KPI, type Mode, type Scale, type Aggregation, createTimeSeriesTrace, createBarTrace, createPieTrace, getYAxisTitle, formatValue, aggregateValue, processKPIData, createDefaultPlotlyLayout, type AggregationType } from './Charts/index.js';
2
+ export { ChartComponent, ChartCard, type Layout, type Section, type Chart, type KPI, type Mode, type Scale, type ChartMarker, createTimeSeriesTrace, getYAxisTitle, formatValue, processKPIData, createDefaultPlotlyLayout } from './Charts/index.js';
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
1
  export { Half, Quarter, ResizeHandle, resizeStore, Desktop, GridSelector, GridRenderer, GridViewer, getAllLayouts, getLayoutById, getLayoutsByCategory, getLayoutsOrdered, validateComponentAssignments, createGridConfiguration, createWindowLauncher, createTabLauncher, createNavigationLauncher, createModalLauncher } from './Desktop/index.js';
2
- export { ChartComponent, ChartCard, createTimeSeriesTrace, createBarTrace, createPieTrace, getYAxisTitle, formatValue, aggregateValue, processKPIData, createDefaultPlotlyLayout } from './Charts/index.js';
2
+ export { ChartComponent, ChartCard, createTimeSeriesTrace, getYAxisTitle, formatValue, processKPIData, createDefaultPlotlyLayout } from './Charts/index.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@smartnet360/svelte-components",
3
- "version": "0.0.2",
3
+ "version": "0.0.4",
4
4
  "scripts": {
5
5
  "dev": "vite dev",
6
6
  "build": "vite build && npm run prepack",
@@ -32,7 +32,8 @@
32
32
  }
33
33
  },
34
34
  "peerDependencies": {
35
- "svelte": "^5.0.0"
35
+ "svelte": "^5.0.0",
36
+ "plotly.js-dist-min": "^3.1.0"
36
37
  },
37
38
  "devDependencies": {
38
39
  "@eslint/compat": "^1.2.5",