@allternit/viz 0.1.0 → 0.1.1
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/README.md +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/types.d.ts +1 -1
- package/dist/types.js +1 -1
- package/package.json +4 -12
- package/src/index.ts +2 -2
- package/src/types.ts +1 -1
- package/tsconfig.tsbuildinfo +1 -0
- package/dist/charts/canvas-renderer.d.ts.bak +0 -40
- package/dist/charts/canvas-renderer.js.bak +0 -580
- package/dist/charts/svg-renderer.d.ts.bak +0 -21
- package/dist/charts/svg-renderer.js.bak +0 -285
- package/dist/index.d.ts.bak +0 -34
- package/dist/index.js.bak +0 -35
- package/dist/types.d.ts.bak +0 -342
- package/dist/types.js.bak +0 -39
- package/dist/utils/data-processor.d.ts.bak +0 -64
- package/dist/utils/data-processor.js.bak +0 -326
- package/src/charts/canvas-renderer.ts.bak +0 -735
- package/src/charts/svg-renderer.test.ts.bak +0 -837
- package/src/charts/svg-renderer.ts.bak +0 -380
- package/src/index.ts.bak +0 -64
- package/src/types.ts.bak +0 -410
- package/src/utils/data-processor.test.ts.bak +0 -720
- package/src/utils/data-processor.ts.bak +0 -420
package/dist/types.js.bak
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* A2R Data Visualization Types
|
|
3
|
-
*/
|
|
4
|
-
/** Predefined palettes */
|
|
5
|
-
export const palettes = {
|
|
6
|
-
default: {
|
|
7
|
-
primary: ['#3b82f6', '#10b981', '#f59e0b', '#ef4444', '#8b5cf6', '#ec4899'],
|
|
8
|
-
secondary: ['#60a5fa', '#34d399', '#fbbf24', '#f87171', '#a78bfa', '#f472b6'],
|
|
9
|
-
semantic: {
|
|
10
|
-
success: '#10b981',
|
|
11
|
-
warning: '#f59e0b',
|
|
12
|
-
error: '#ef4444',
|
|
13
|
-
info: '#3b82f6',
|
|
14
|
-
},
|
|
15
|
-
background: ['#ffffff', '#f3f4f6', '#e5e7eb', '#d1d5db'],
|
|
16
|
-
text: {
|
|
17
|
-
primary: '#111827',
|
|
18
|
-
secondary: '#4b5563',
|
|
19
|
-
muted: '#9ca3af',
|
|
20
|
-
},
|
|
21
|
-
},
|
|
22
|
-
dark: {
|
|
23
|
-
primary: ['#60a5fa', '#34d399', '#fbbf24', '#f87171', '#a78bfa', '#f472b6'],
|
|
24
|
-
secondary: ['#93c5fd', '#6ee7b7', '#fcd34d', '#fca5a5', '#c4b5fd', '#fbcfe8'],
|
|
25
|
-
semantic: {
|
|
26
|
-
success: '#34d399',
|
|
27
|
-
warning: '#fbbf24',
|
|
28
|
-
error: '#f87171',
|
|
29
|
-
info: '#60a5fa',
|
|
30
|
-
},
|
|
31
|
-
background: ['#1f2937', '#111827', '#374151', '#4b5563'],
|
|
32
|
-
text: {
|
|
33
|
-
primary: '#f9fafb',
|
|
34
|
-
secondary: '#d1d5db',
|
|
35
|
-
muted: '#9ca3af',
|
|
36
|
-
},
|
|
37
|
-
},
|
|
38
|
-
};
|
|
39
|
-
//# sourceMappingURL=types.js.map
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Data Processor Utility
|
|
3
|
-
*
|
|
4
|
-
* Provides data transformation and normalization functions for charts.
|
|
5
|
-
*/
|
|
6
|
-
import type { DataPoint, DataSeries } from '../types';
|
|
7
|
-
/**
|
|
8
|
-
* Normalize data points to standard format
|
|
9
|
-
*/
|
|
10
|
-
export declare function normalizeDataPoints(data: DataPoint[]): DataPoint[];
|
|
11
|
-
/**
|
|
12
|
-
* Normalize data series
|
|
13
|
-
*/
|
|
14
|
-
export declare function normalizeSeries(series: DataSeries[]): DataSeries[];
|
|
15
|
-
/**
|
|
16
|
-
* Aggregate data by categories
|
|
17
|
-
*/
|
|
18
|
-
export declare function aggregateByCategory(data: DataPoint[], aggregator?: 'sum' | 'avg' | 'min' | 'max' | 'count'): Map<string, number>;
|
|
19
|
-
/**
|
|
20
|
-
* Sort data points by value or category
|
|
21
|
-
*/
|
|
22
|
-
export declare function sortDataPoints(data: DataPoint[], by?: 'value' | 'category', order?: 'asc' | 'desc'): DataPoint[];
|
|
23
|
-
/**
|
|
24
|
-
* Filter data points by value range
|
|
25
|
-
*/
|
|
26
|
-
export declare function filterByRange(data: DataPoint[], min?: number, max?: number): DataPoint[];
|
|
27
|
-
/**
|
|
28
|
-
* Calculate statistics for data points
|
|
29
|
-
*/
|
|
30
|
-
export declare function calculateStats(data: DataPoint[]): {
|
|
31
|
-
min: number;
|
|
32
|
-
max: number;
|
|
33
|
-
sum: number;
|
|
34
|
-
avg: number;
|
|
35
|
-
count: number;
|
|
36
|
-
};
|
|
37
|
-
/**
|
|
38
|
-
* Process time series data
|
|
39
|
-
*/
|
|
40
|
-
export declare function processTimeSeries(data: DataPoint[], options?: {
|
|
41
|
-
interval?: 'hour' | 'day' | 'week' | 'month' | 'year';
|
|
42
|
-
fillGaps?: boolean;
|
|
43
|
-
aggregation?: 'sum' | 'avg' | 'last';
|
|
44
|
-
}): DataPoint[];
|
|
45
|
-
/**
|
|
46
|
-
* Calculate moving average
|
|
47
|
-
*/
|
|
48
|
-
export declare function movingAverage(data: DataPoint[], windowSize: number): DataPoint[];
|
|
49
|
-
/**
|
|
50
|
-
* Detect outliers using IQR method
|
|
51
|
-
*/
|
|
52
|
-
export declare function detectOutliers(data: DataPoint[], threshold?: number): {
|
|
53
|
-
inliers: DataPoint[];
|
|
54
|
-
outliers: DataPoint[];
|
|
55
|
-
};
|
|
56
|
-
/**
|
|
57
|
-
* Normalize values to 0-1 range
|
|
58
|
-
*/
|
|
59
|
-
export declare function normalizeValues(data: DataPoint[], min?: number, max?: number): DataPoint[];
|
|
60
|
-
/**
|
|
61
|
-
* Calculate percent change between consecutive points
|
|
62
|
-
*/
|
|
63
|
-
export declare function calculatePercentChange(data: DataPoint[]): DataPoint[];
|
|
64
|
-
//# sourceMappingURL=data-processor.d.ts.map
|
|
@@ -1,326 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Data Processor Utility
|
|
3
|
-
*
|
|
4
|
-
* Provides data transformation and normalization functions for charts.
|
|
5
|
-
*/
|
|
6
|
-
/**
|
|
7
|
-
* Normalize data points to standard format
|
|
8
|
-
*/
|
|
9
|
-
export function normalizeDataPoints(data) {
|
|
10
|
-
return data.map((point) => ({
|
|
11
|
-
...point,
|
|
12
|
-
y: point.y ?? point.value ?? 0,
|
|
13
|
-
x: point.x ?? point.name ?? '',
|
|
14
|
-
}));
|
|
15
|
-
}
|
|
16
|
-
/**
|
|
17
|
-
* Normalize data series
|
|
18
|
-
*/
|
|
19
|
-
export function normalizeSeries(series) {
|
|
20
|
-
return series.map((s) => ({
|
|
21
|
-
...s,
|
|
22
|
-
data: normalizeDataPoints(s.data),
|
|
23
|
-
}));
|
|
24
|
-
}
|
|
25
|
-
/**
|
|
26
|
-
* Aggregate data by categories
|
|
27
|
-
*/
|
|
28
|
-
export function aggregateByCategory(data, aggregator = 'sum') {
|
|
29
|
-
const groups = new Map();
|
|
30
|
-
// Group values by category
|
|
31
|
-
for (const point of data) {
|
|
32
|
-
const key = String(point.x ?? point.name ?? 'unknown');
|
|
33
|
-
const value = Number(point.y ?? point.value ?? 0);
|
|
34
|
-
if (!groups.has(key)) {
|
|
35
|
-
groups.set(key, []);
|
|
36
|
-
}
|
|
37
|
-
groups.get(key).push(value);
|
|
38
|
-
}
|
|
39
|
-
// Apply aggregation
|
|
40
|
-
const result = new Map();
|
|
41
|
-
for (const [key, values] of groups) {
|
|
42
|
-
switch (aggregator) {
|
|
43
|
-
case 'sum':
|
|
44
|
-
result.set(key, values.reduce((a, b) => a + b, 0));
|
|
45
|
-
break;
|
|
46
|
-
case 'avg':
|
|
47
|
-
result.set(key, values.reduce((a, b) => a + b, 0) / values.length);
|
|
48
|
-
break;
|
|
49
|
-
case 'min':
|
|
50
|
-
result.set(key, Math.min(...values));
|
|
51
|
-
break;
|
|
52
|
-
case 'max':
|
|
53
|
-
result.set(key, Math.max(...values));
|
|
54
|
-
break;
|
|
55
|
-
case 'count':
|
|
56
|
-
result.set(key, values.length);
|
|
57
|
-
break;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
return result;
|
|
61
|
-
}
|
|
62
|
-
/**
|
|
63
|
-
* Sort data points by value or category
|
|
64
|
-
*/
|
|
65
|
-
export function sortDataPoints(data, by = 'value', order = 'desc') {
|
|
66
|
-
const sorted = [...data];
|
|
67
|
-
sorted.sort((a, b) => {
|
|
68
|
-
let comparison = 0;
|
|
69
|
-
if (by === 'value') {
|
|
70
|
-
const aVal = Number(a.y ?? a.value ?? 0);
|
|
71
|
-
const bVal = Number(b.y ?? b.value ?? 0);
|
|
72
|
-
comparison = aVal - bVal;
|
|
73
|
-
}
|
|
74
|
-
else {
|
|
75
|
-
const aCat = String(a.x ?? a.name ?? '');
|
|
76
|
-
const bCat = String(b.x ?? b.name ?? '');
|
|
77
|
-
comparison = aCat.localeCompare(bCat);
|
|
78
|
-
}
|
|
79
|
-
return order === 'asc' ? comparison : -comparison;
|
|
80
|
-
});
|
|
81
|
-
return sorted;
|
|
82
|
-
}
|
|
83
|
-
/**
|
|
84
|
-
* Filter data points by value range
|
|
85
|
-
*/
|
|
86
|
-
export function filterByRange(data, min, max) {
|
|
87
|
-
return data.filter((point) => {
|
|
88
|
-
const value = Number(point.y ?? point.value ?? 0);
|
|
89
|
-
if (min !== undefined && value < min)
|
|
90
|
-
return false;
|
|
91
|
-
if (max !== undefined && value > max)
|
|
92
|
-
return false;
|
|
93
|
-
return true;
|
|
94
|
-
});
|
|
95
|
-
}
|
|
96
|
-
/**
|
|
97
|
-
* Calculate statistics for data points
|
|
98
|
-
*/
|
|
99
|
-
export function calculateStats(data) {
|
|
100
|
-
const values = data.map((p) => Number(p.y ?? p.value ?? 0));
|
|
101
|
-
if (values.length === 0) {
|
|
102
|
-
return { min: 0, max: 0, sum: 0, avg: 0, count: 0 };
|
|
103
|
-
}
|
|
104
|
-
const min = Math.min(...values);
|
|
105
|
-
const max = Math.max(...values);
|
|
106
|
-
const sum = values.reduce((a, b) => a + b, 0);
|
|
107
|
-
const avg = sum / values.length;
|
|
108
|
-
return { min, max, sum, avg, count: values.length };
|
|
109
|
-
}
|
|
110
|
-
/**
|
|
111
|
-
* Process time series data
|
|
112
|
-
*/
|
|
113
|
-
export function processTimeSeries(data, options = {}) {
|
|
114
|
-
const { interval = 'day', fillGaps = false, aggregation = 'sum' } = options;
|
|
115
|
-
// Sort by date
|
|
116
|
-
const sorted = [...data].sort((a, b) => {
|
|
117
|
-
const aDate = new Date(a.x).getTime();
|
|
118
|
-
const bDate = new Date(b.x).getTime();
|
|
119
|
-
return aDate - bDate;
|
|
120
|
-
});
|
|
121
|
-
if (!fillGaps) {
|
|
122
|
-
return sorted;
|
|
123
|
-
}
|
|
124
|
-
// Group by interval
|
|
125
|
-
const grouped = new Map();
|
|
126
|
-
for (const point of sorted) {
|
|
127
|
-
const date = new Date(point.x);
|
|
128
|
-
const key = formatDateToInterval(date, interval);
|
|
129
|
-
const value = Number(point.y ?? point.value ?? 0);
|
|
130
|
-
if (!grouped.has(key)) {
|
|
131
|
-
grouped.set(key, []);
|
|
132
|
-
}
|
|
133
|
-
grouped.get(key).push(value);
|
|
134
|
-
}
|
|
135
|
-
// Apply aggregation and fill gaps
|
|
136
|
-
const result = [];
|
|
137
|
-
if (sorted.length === 0)
|
|
138
|
-
return result;
|
|
139
|
-
const startDate = new Date(sorted[0].x);
|
|
140
|
-
const endDate = new Date(sorted[sorted.length - 1].x);
|
|
141
|
-
// Normalize dates to the start of their interval for proper gap filling
|
|
142
|
-
let currentDate = normalizeToIntervalStart(startDate, interval);
|
|
143
|
-
const normalizedEndDate = normalizeToIntervalStart(endDate, interval);
|
|
144
|
-
while (currentDate <= normalizedEndDate) {
|
|
145
|
-
const key = formatDateToInterval(currentDate, interval);
|
|
146
|
-
const values = grouped.get(key) ?? [];
|
|
147
|
-
let value;
|
|
148
|
-
if (values.length === 0) {
|
|
149
|
-
value = 0;
|
|
150
|
-
}
|
|
151
|
-
else {
|
|
152
|
-
switch (aggregation) {
|
|
153
|
-
case 'sum':
|
|
154
|
-
value = values.reduce((a, b) => a + b, 0);
|
|
155
|
-
break;
|
|
156
|
-
case 'avg':
|
|
157
|
-
value = values.reduce((a, b) => a + b, 0) / values.length;
|
|
158
|
-
break;
|
|
159
|
-
case 'last':
|
|
160
|
-
value = values[values.length - 1];
|
|
161
|
-
break;
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
result.push({ x: key, y: value });
|
|
165
|
-
// Advance to next interval
|
|
166
|
-
currentDate = addInterval(currentDate, interval);
|
|
167
|
-
}
|
|
168
|
-
return result;
|
|
169
|
-
}
|
|
170
|
-
/**
|
|
171
|
-
* Calculate moving average
|
|
172
|
-
*/
|
|
173
|
-
export function movingAverage(data, windowSize) {
|
|
174
|
-
if (windowSize <= 1 || data.length < windowSize) {
|
|
175
|
-
return data;
|
|
176
|
-
}
|
|
177
|
-
const result = [];
|
|
178
|
-
for (let i = 0; i < data.length; i++) {
|
|
179
|
-
if (i < windowSize - 1) {
|
|
180
|
-
result.push(data[i]);
|
|
181
|
-
continue;
|
|
182
|
-
}
|
|
183
|
-
let sum = 0;
|
|
184
|
-
for (let j = 0; j < windowSize; j++) {
|
|
185
|
-
sum += Number(data[i - j].y ?? data[i - j].value ?? 0);
|
|
186
|
-
}
|
|
187
|
-
result.push({
|
|
188
|
-
...data[i],
|
|
189
|
-
y: sum / windowSize,
|
|
190
|
-
});
|
|
191
|
-
}
|
|
192
|
-
return result;
|
|
193
|
-
}
|
|
194
|
-
/**
|
|
195
|
-
* Detect outliers using IQR method
|
|
196
|
-
*/
|
|
197
|
-
export function detectOutliers(data, threshold = 1.5) {
|
|
198
|
-
const values = data.map((p) => Number(p.y ?? p.value ?? 0));
|
|
199
|
-
const sorted = [...values].sort((a, b) => a - b);
|
|
200
|
-
const q1Index = Math.floor(sorted.length * 0.25);
|
|
201
|
-
const q3Index = Math.floor(sorted.length * 0.75);
|
|
202
|
-
const q1 = sorted[q1Index];
|
|
203
|
-
const q3 = sorted[q3Index];
|
|
204
|
-
const iqr = q3 - q1;
|
|
205
|
-
const lowerBound = q1 - threshold * iqr;
|
|
206
|
-
const upperBound = q3 + threshold * iqr;
|
|
207
|
-
const inliers = [];
|
|
208
|
-
const outliers = [];
|
|
209
|
-
for (const point of data) {
|
|
210
|
-
const value = Number(point.y ?? point.value ?? 0);
|
|
211
|
-
if (value >= lowerBound && value <= upperBound) {
|
|
212
|
-
inliers.push(point);
|
|
213
|
-
}
|
|
214
|
-
else {
|
|
215
|
-
outliers.push(point);
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
return { inliers, outliers };
|
|
219
|
-
}
|
|
220
|
-
/**
|
|
221
|
-
* Normalize values to 0-1 range
|
|
222
|
-
*/
|
|
223
|
-
export function normalizeValues(data, min, max) {
|
|
224
|
-
const values = data.map((p) => Number(p.y ?? p.value ?? 0));
|
|
225
|
-
const dataMin = min ?? Math.min(...values);
|
|
226
|
-
const dataMax = max ?? Math.max(...values);
|
|
227
|
-
const range = dataMax - dataMin;
|
|
228
|
-
if (range === 0) {
|
|
229
|
-
return data.map((p) => ({ ...p, y: 0 }));
|
|
230
|
-
}
|
|
231
|
-
return data.map((p) => ({
|
|
232
|
-
...p,
|
|
233
|
-
y: (Number(p.y ?? p.value ?? 0) - dataMin) / range,
|
|
234
|
-
}));
|
|
235
|
-
}
|
|
236
|
-
/**
|
|
237
|
-
* Calculate percent change between consecutive points
|
|
238
|
-
*/
|
|
239
|
-
export function calculatePercentChange(data) {
|
|
240
|
-
if (data.length === 0)
|
|
241
|
-
return data;
|
|
242
|
-
if (data.length === 1) {
|
|
243
|
-
return [{ ...data[0], y: 0 }];
|
|
244
|
-
}
|
|
245
|
-
const result = [];
|
|
246
|
-
for (let i = 0; i < data.length; i++) {
|
|
247
|
-
if (i === 0) {
|
|
248
|
-
result.push({ ...data[i], y: 0 });
|
|
249
|
-
continue;
|
|
250
|
-
}
|
|
251
|
-
const current = Number(data[i].y ?? data[i].value ?? 0);
|
|
252
|
-
const previous = Number(data[i - 1].y ?? data[i - 1].value ?? 0);
|
|
253
|
-
const change = previous !== 0 ? ((current - previous) / previous) * 100 : 0;
|
|
254
|
-
result.push({ ...data[i], y: change });
|
|
255
|
-
}
|
|
256
|
-
return result;
|
|
257
|
-
}
|
|
258
|
-
// Helper functions
|
|
259
|
-
function formatDateToInterval(date, interval) {
|
|
260
|
-
// Use UTC methods to avoid timezone issues
|
|
261
|
-
switch (interval) {
|
|
262
|
-
case 'hour':
|
|
263
|
-
return `${date.getUTCFullYear()}-${String(date.getUTCMonth() + 1).padStart(2, '0')}-${String(date.getUTCDate()).padStart(2, '0')} ${String(date.getUTCHours()).padStart(2, '0')}:00`;
|
|
264
|
-
case 'day':
|
|
265
|
-
return `${date.getUTCFullYear()}-${String(date.getUTCMonth() + 1).padStart(2, '0')}-${String(date.getUTCDate()).padStart(2, '0')}`;
|
|
266
|
-
case 'week': {
|
|
267
|
-
const weekStart = new Date(date);
|
|
268
|
-
weekStart.setUTCDate(date.getUTCDate() - date.getUTCDay());
|
|
269
|
-
return `${weekStart.getUTCFullYear()}-${String(weekStart.getUTCMonth() + 1).padStart(2, '0')}-${String(weekStart.getUTCDate()).padStart(2, '0')}`;
|
|
270
|
-
}
|
|
271
|
-
case 'month':
|
|
272
|
-
return `${date.getUTCFullYear()}-${String(date.getUTCMonth() + 1).padStart(2, '0')}`;
|
|
273
|
-
case 'year':
|
|
274
|
-
return String(date.getUTCFullYear());
|
|
275
|
-
default:
|
|
276
|
-
return date.toISOString();
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
function addInterval(date, interval) {
|
|
280
|
-
const result = new Date(date);
|
|
281
|
-
switch (interval) {
|
|
282
|
-
case 'hour':
|
|
283
|
-
result.setUTCHours(result.getUTCHours() + 1);
|
|
284
|
-
break;
|
|
285
|
-
case 'day':
|
|
286
|
-
result.setUTCDate(result.getUTCDate() + 1);
|
|
287
|
-
break;
|
|
288
|
-
case 'week':
|
|
289
|
-
result.setUTCDate(result.getUTCDate() + 7);
|
|
290
|
-
break;
|
|
291
|
-
case 'month':
|
|
292
|
-
result.setUTCMonth(result.getUTCMonth() + 1);
|
|
293
|
-
break;
|
|
294
|
-
case 'year':
|
|
295
|
-
result.setUTCFullYear(result.getUTCFullYear() + 1);
|
|
296
|
-
break;
|
|
297
|
-
}
|
|
298
|
-
return result;
|
|
299
|
-
}
|
|
300
|
-
function normalizeToIntervalStart(date, interval) {
|
|
301
|
-
const result = new Date(date);
|
|
302
|
-
switch (interval) {
|
|
303
|
-
case 'hour':
|
|
304
|
-
result.setUTCMinutes(0, 0, 0);
|
|
305
|
-
break;
|
|
306
|
-
case 'day':
|
|
307
|
-
result.setUTCHours(0, 0, 0, 0);
|
|
308
|
-
break;
|
|
309
|
-
case 'week': {
|
|
310
|
-
const dayOfWeek = result.getUTCDay();
|
|
311
|
-
result.setUTCDate(result.getUTCDate() - dayOfWeek);
|
|
312
|
-
result.setUTCHours(0, 0, 0, 0);
|
|
313
|
-
break;
|
|
314
|
-
}
|
|
315
|
-
case 'month':
|
|
316
|
-
result.setUTCDate(1);
|
|
317
|
-
result.setUTCHours(0, 0, 0, 0);
|
|
318
|
-
break;
|
|
319
|
-
case 'year':
|
|
320
|
-
result.setUTCMonth(0, 1);
|
|
321
|
-
result.setUTCHours(0, 0, 0, 0);
|
|
322
|
-
break;
|
|
323
|
-
}
|
|
324
|
-
return result;
|
|
325
|
-
}
|
|
326
|
-
//# sourceMappingURL=data-processor.js.map
|