0
# Utility Functions
1
2
Vega's comprehensive utility library provides type checking, data manipulation, mathematical operations, string handling, configuration management, and general-purpose helper functions for visualization development.
3
4
## Capabilities
5
6
### Type Checking
7
8
Comprehensive type checking utilities for data validation.
9
10
```typescript { .api }
11
/**
12
* Check if value is an array
13
* @param value - Value to test
14
* @returns True if value is an array
15
*/
16
function isArray(value: any): value is any[];
17
18
/**
19
* Check if value is a boolean
20
* @param value - Value to test
21
* @returns True if value is a boolean
22
*/
23
function isBoolean(value: any): value is boolean;
24
25
/**
26
* Check if value is a Date object
27
* @param value - Value to test
28
* @returns True if value is a Date
29
*/
30
function isDate(value: any): value is Date;
31
32
/**
33
* Check if value is a function
34
* @param value - Value to test
35
* @returns True if value is a function
36
*/
37
function isFunction(value: any): value is Function;
38
39
/**
40
* Check if value is iterable
41
* @param value - Value to test
42
* @returns True if value is iterable
43
*/
44
function isIterable(value: any): boolean;
45
46
/**
47
* Check if value is a number
48
* @param value - Value to test
49
* @returns True if value is a number
50
*/
51
function isNumber(value: any): value is number;
52
53
/**
54
* Check if value is an object
55
* @param value - Value to test
56
* @returns True if value is an object
57
*/
58
function isObject(value: any): value is object;
59
60
/**
61
* Check if value is a RegExp
62
* @param value - Value to test
63
* @returns True if value is a RegExp
64
*/
65
function isRegExp(value: any): value is RegExp;
66
67
/**
68
* Check if value is a string
69
* @param value - Value to test
70
* @returns True if value is a string
71
*/
72
function isString(value: any): value is string;
73
```
74
75
### Accessor Functions
76
77
Field accessor creation and manipulation utilities.
78
79
```typescript { .api }
80
/**
81
* Create field accessor function
82
* @param field - Field name or accessor expression
83
* @param name - Optional accessor name
84
* @returns Field accessor function
85
*/
86
function accessor(field: string | Function, name?: string): Function;
87
88
/**
89
* Get name of an accessor function
90
* @param accessor - Accessor function
91
* @returns Accessor name or field string
92
*/
93
function accessorName(accessor: Function): string;
94
95
/**
96
* Get field names referenced by an accessor
97
* @param accessor - Accessor function
98
* @returns Array of field names
99
*/
100
function accessorFields(accessor: Function): string[];
101
102
/**
103
* Create field accessor by name
104
* @param name - Field name
105
* @returns Field accessor function
106
*/
107
function field(name: string): (datum: any) => any;
108
109
/**
110
* Create key function from field names
111
* @param fields - Array of field names
112
* @returns Key function that creates composite keys
113
*/
114
function key(fields: string[]): (datum: any) => string;
115
116
/**
117
* Identity function - returns input unchanged
118
* @param value - Input value
119
* @returns Same value
120
*/
121
function identity<T>(value: T): T;
122
123
/**
124
* Create ID accessor function
125
* @returns Function that gets or generates unique IDs
126
*/
127
function id(): (datum: any) => any;
128
129
/**
130
* Constant function that always returns zero
131
* @returns Zero
132
*/
133
function zero(): number;
134
135
/**
136
* Constant function that always returns one
137
* @returns One
138
*/
139
function one(): number;
140
141
/**
142
* Constant function that always returns true
143
* @returns True
144
*/
145
function truthy(): boolean;
146
147
/**
148
* Constant function that always returns false
149
* @returns False
150
*/
151
function falsy(): boolean;
152
```
153
154
### Data Manipulation
155
156
Core data structure operations and array utilities.
157
158
```typescript { .api }
159
/**
160
* Ensure value is an array
161
* @param value - Value to arrayify
162
* @returns Array containing the value or the value itself if already array
163
*/
164
function array<T>(value: T | T[]): T[];
165
166
/**
167
* Compare two values for sorting
168
* @param a - First value
169
* @param b - Second value
170
* @returns Comparison result (-1, 0, 1)
171
*/
172
function compare(a: any, b: any): number;
173
174
/**
175
* Ascending comparison function
176
* @param a - First value
177
* @param b - Second value
178
* @returns Comparison result for ascending order
179
*/
180
function ascending(a: any, b: any): number;
181
182
/**
183
* Extend target object with properties from source objects
184
* @param target - Target object
185
* @param sources - Source objects
186
* @returns Extended target object
187
*/
188
function extend(target: any, ...sources: any[]): any;
189
190
/**
191
* Merge objects recursively
192
* @param target - Target object
193
* @param source - Source object to merge
194
* @returns Merged object
195
*/
196
function merge(target: any, source: any): any;
197
198
/**
199
* Visit all items in nested arrays
200
* @param array - Array to visit
201
* @param visitor - Visitor function
202
*/
203
function visitArray(array: any[], visitor: (item: any, index: number) => void): void;
204
205
/**
206
* Peek at the last item in an array
207
* @param array - Array to peek
208
* @returns Last item or undefined
209
*/
210
function peek<T>(array: T[]): T | undefined;
211
212
/**
213
* Split accessor path into components
214
* @param path - Dot-separated path string
215
* @returns Array of path components
216
*/
217
function splitAccessPath(path: string): string[];
218
```
219
220
### Mathematical Utilities
221
222
Mathematical operations and range utilities.
223
224
```typescript { .api }
225
/**
226
* Clamp range to specified bounds
227
* @param range - Range tuple [min, max]
228
* @param min - Minimum bound
229
* @param max - Maximum bound
230
* @returns Clamped range
231
*/
232
function clampRange(range: [number, number], min: number, max: number): [number, number];
233
234
/**
235
* Calculate extent (min, max) of values
236
* @param values - Array of values
237
* @param accessor - Optional value accessor function
238
* @returns Extent tuple [min, max]
239
*/
240
function extent(values: any[], accessor?: Function): [any, any];
241
242
/**
243
* Calculate extent and return indices of min/max values
244
* @param values - Array of values
245
* @param accessor - Optional value accessor function
246
* @returns Object with extent values and indices
247
*/
248
function extentIndex(values: any[], accessor?: Function): {
249
extent: [any, any];
250
minIndex: number;
251
maxIndex: number;
252
};
253
254
/**
255
* Check if value is within range
256
* @param value - Value to test
257
* @param range - Range tuple [min, max]
258
* @param left - Left bound inclusion (default: true)
259
* @param right - Right bound inclusion (default: true)
260
* @returns True if value is in range
261
*/
262
function inrange(value: number, range: [number, number], left?: boolean, right?: boolean): boolean;
263
264
/**
265
* Linear interpolation between two values
266
* @param a - Start value
267
* @param b - End value
268
* @returns Interpolation function
269
*/
270
function lerp(a: number, b: number): (t: number) => number;
271
272
/**
273
* Calculate span (max - min) of range
274
* @param range - Range tuple [min, max]
275
* @returns Span value
276
*/
277
function span(range: [number, number]): number;
278
```
279
280
### String Operations
281
282
String manipulation and formatting utilities.
283
284
```typescript { .api }
285
/**
286
* Pad string to specified length
287
* @param str - String to pad
288
* @param length - Target length
289
* @param character - Padding character (default: ' ')
290
* @param align - Alignment ('left', 'right', 'center')
291
* @returns Padded string
292
*/
293
function pad(str: string, length: number, character?: string, align?: 'left' | 'right' | 'center'): string;
294
295
/**
296
* Repeat string specified number of times
297
* @param str - String to repeat
298
* @param count - Number of repetitions
299
* @returns Repeated string
300
*/
301
function repeat(str: string, count: number): string;
302
303
/**
304
* Convert value to string representation
305
* @param value - Value to convert
306
* @returns String representation
307
*/
308
function stringValue(value: any): string;
309
310
/**
311
* Convert value to string with null safety
312
* @param value - Value to convert
313
* @returns String or empty string for null/undefined
314
*/
315
function toString(value: any): string;
316
317
/**
318
* Truncate string to maximum length
319
* @param str - String to truncate
320
* @param length - Maximum length
321
* @param align - Truncation alignment
322
* @param ellipsis - Ellipsis string (default: '...')
323
* @returns Truncated string
324
*/
325
function truncate(str: string, length: number, align?: 'left' | 'right' | 'center', ellipsis?: string): string;
326
```
327
328
### Type Conversion
329
330
Type conversion utilities with safe defaults.
331
332
```typescript { .api }
333
/**
334
* Convert value to boolean
335
* @param value - Value to convert
336
* @returns Boolean value
337
*/
338
function toBoolean(value: any): boolean;
339
340
/**
341
* Convert value to Date
342
* @param value - Value to convert
343
* @returns Date object or null
344
*/
345
function toDate(value: any): Date | null;
346
347
/**
348
* Convert value to number
349
* @param value - Value to convert
350
* @returns Number value or NaN
351
*/
352
function toNumber(value: any): number;
353
354
/**
355
* Convert array or iterable to Set
356
* @param values - Values to convert
357
* @returns Set containing the values
358
*/
359
function toSet<T>(values: Iterable<T>): Set<T>;
360
```
361
362
### Utility Functions
363
364
General-purpose utility functions for common operations.
365
366
```typescript { .api }
367
/**
368
* Create constant function that returns the same value
369
* @param value - Value to return
370
* @returns Function that returns the constant value
371
*/
372
function constant<T>(value: T): () => T;
373
374
/**
375
* Debounce function calls
376
* @param func - Function to debounce
377
* @param wait - Wait time in milliseconds
378
* @param immediate - Execute immediately on first call
379
* @returns Debounced function
380
*/
381
function debounce<T extends Function>(func: T, wait: number, immediate?: boolean): T;
382
383
/**
384
* Throw an error with specified message
385
* @param message - Error message
386
* @throws Error with the specified message
387
*/
388
function error(message: string): never;
389
390
/**
391
* Create fast map for object key-value operations
392
* @returns Map-like object with fast access
393
*/
394
function fastmap(): FastMap;
395
396
/**
397
* Flush pending operations (implementation specific)
398
*/
399
function flush(): void;
400
401
/**
402
* Check if object has own property
403
* @param object - Object to check
404
* @param property - Property name
405
* @returns True if object has own property
406
*/
407
function hasOwnProperty(object: any, property: string): boolean;
408
409
/**
410
* Set up prototype inheritance
411
* @param child - Child constructor
412
* @param parent - Parent constructor
413
*/
414
function inherits(child: Function, parent: Function): void;
415
416
/**
417
* Create LRU (Least Recently Used) cache
418
* @param maxSize - Maximum cache size
419
* @returns LRU cache instance
420
*/
421
function lruCache<K, V>(maxSize?: number): LRUCache<K, V>;
422
423
interface FastMap {
424
has(key: string): boolean;
425
get(key: string): any;
426
set(key: string, value: any): FastMap;
427
delete(key: string): boolean;
428
clear(): void;
429
size: number;
430
}
431
432
interface LRUCache<K, V> {
433
has(key: K): boolean;
434
get(key: K): V | undefined;
435
set(key: K, value: V): LRUCache<K, V>;
436
delete(key: K): boolean;
437
clear(): void;
438
size: number;
439
}
440
```
441
442
### Configuration Management
443
444
Configuration merging and writing utilities.
445
446
```typescript { .api }
447
/**
448
* Merge configuration objects
449
* @param configs - Configuration objects to merge
450
* @returns Merged configuration
451
*/
452
function mergeConfig(...configs: any[]): any;
453
454
/**
455
* Write configuration to storage or output
456
* @param config - Configuration object
457
* @param options - Write options
458
*/
459
function writeConfig(config: any, options?: WriteConfigOptions): void;
460
461
interface WriteConfigOptions {
462
/** Output format */
463
format?: 'json' | 'yaml' | 'js';
464
465
/** Pretty print */
466
pretty?: boolean;
467
468
/** Output path */
469
path?: string;
470
}
471
```
472
473
### Logging System
474
475
Logging interface and level management.
476
477
```typescript { .api }
478
/**
479
* Logger interface for debugging and monitoring
480
*/
481
class logger {
482
/**
483
* Create new logger instance
484
* @param level - Initial logging level
485
*/
486
constructor(level?: number);
487
488
/** Current logging level */
489
level(): number;
490
level(level: number): logger;
491
492
/**
493
* Log error message
494
* @param message - Error message
495
* @param data - Optional data
496
*/
497
error(message: string, data?: any): void;
498
499
/**
500
* Log warning message
501
* @param message - Warning message
502
* @param data - Optional data
503
*/
504
warn(message: string, data?: any): void;
505
506
/**
507
* Log info message
508
* @param message - Info message
509
* @param data - Optional data
510
*/
511
info(message: string, data?: any): void;
512
513
/**
514
* Log debug message
515
* @param message - Debug message
516
* @param data - Optional data
517
*/
518
debug(message: string, data?: any): void;
519
}
520
521
/** Logging level constants */
522
const None: 0;
523
const Error: 1;
524
const Warn: 2;
525
const Info: 3;
526
const Debug: 4;
527
```
528
529
## Usage Examples
530
531
### Type Checking
532
533
```typescript
534
import { isArray, isString, isNumber, isObject } from "vega";
535
536
const data = [
537
{ name: "Alice", age: 25, scores: [85, 90, 92] },
538
{ name: "Bob", age: "30", scores: null },
539
{ name: null, age: 35, scores: [78, 82] }
540
];
541
542
data.forEach(person => {
543
console.log('Name valid:', isString(person.name));
544
console.log('Age is number:', isNumber(person.age));
545
console.log('Scores is array:', isArray(person.scores));
546
console.log('Person is object:', isObject(person));
547
});
548
```
549
550
### Data Manipulation
551
552
```typescript
553
import { extend, merge, array, extent, field } from "vega";
554
555
// Object extension
556
const base = { a: 1, b: 2 };
557
const extended = extend({}, base, { c: 3, d: 4 });
558
console.log(extended); // { a: 1, b: 2, c: 3, d: 4 }
559
560
// Array operations
561
const values = [5, 2, 8, 1, 9, 3];
562
const [min, max] = extent(values);
563
console.log(`Range: ${min} to ${max}`); // Range: 1 to 9
564
565
// Field accessors
566
const data = [
567
{ name: 'Alice', score: 85 },
568
{ name: 'Bob', score: 92 },
569
{ name: 'Carol', score: 78 }
570
];
571
572
const getName = field('name');
573
const getScore = field('score');
574
575
data.forEach(d => {
576
console.log(`${getName(d)}: ${getScore(d)}`);
577
});
578
```
579
580
### String Operations
581
582
```typescript
583
import { pad, truncate, repeat } from "vega";
584
585
// Padding
586
console.log(pad('Hello', 10, '*', 'center')); // "**Hello***"
587
console.log(pad('123', 5, '0', 'left')); // "00123"
588
589
// Truncation
590
console.log(truncate('This is a long string', 10)); // "This is..."
591
console.log(truncate('Short', 10)); // "Short"
592
593
// Repetition
594
console.log(repeat('Ha', 3)); // "HaHaHa"
595
console.log(repeat('-', 20)); // "--------------------"
596
```
597
598
### Mathematical Utilities
599
600
```typescript
601
import { clampRange, inrange, lerp } from "vega";
602
603
// Range clamping
604
const range = clampRange([0, 100], 10, 90);
605
console.log(range); // [10, 90]
606
607
// Range checking
608
console.log(inrange(50, [0, 100])); // true
609
console.log(inrange(150, [0, 100])); // false
610
611
// Linear interpolation
612
const interpolator = lerp(0, 100);
613
console.log(interpolator(0.0)); // 0
614
console.log(interpolator(0.5)); // 50
615
console.log(interpolator(1.0)); // 100
616
```
617
618
### Type Conversion
619
620
```typescript
621
import { toBoolean, toNumber, toDate, toSet } from "vega";
622
623
// Safe type conversions
624
console.log(toBoolean('true')); // true
625
console.log(toBoolean('false')); // false
626
console.log(toBoolean(1)); // true
627
console.log(toBoolean(0)); // false
628
629
console.log(toNumber('42')); // 42
630
console.log(toNumber('invalid')); // NaN
631
console.log(toNumber(null)); // 0
632
633
const date = toDate('2023-06-15');
634
console.log(date); // Date object
635
636
const uniqueValues = toSet([1, 2, 2, 3, 3, 3]);
637
console.log(uniqueValues); // Set {1, 2, 3}
638
```
639
640
### Utility Functions
641
642
```typescript
643
import { constant, debounce, fastmap, lruCache } from "vega";
644
645
// Constant function
646
const getPI = constant(Math.PI);
647
console.log(getPI()); // 3.14159...
648
649
// Debounced function
650
const debouncedLog = debounce(console.log, 100);
651
debouncedLog('Message 1'); // Will be ignored
652
debouncedLog('Message 2'); // Will be ignored
653
debouncedLog('Message 3'); // Will execute after 100ms
654
655
// Fast map
656
const map = fastmap();
657
map.set('key1', 'value1');
658
map.set('key2', 'value2');
659
console.log(map.get('key1')); // 'value1'
660
console.log(map.has('key3')); // false
661
662
// LRU Cache
663
const cache = lruCache(3);
664
cache.set('a', 1);
665
cache.set('b', 2);
666
cache.set('c', 3);
667
cache.set('d', 4); // 'a' will be evicted
668
console.log(cache.has('a')); // false
669
console.log(cache.has('d')); // true
670
```
671
672
### Configuration Management
673
674
```typescript
675
import { mergeConfig, writeConfig } from "vega";
676
677
const baseConfig = {
678
view: { width: 400, height: 300 },
679
mark: { fill: 'steelblue' }
680
};
681
682
const themeConfig = {
683
view: { background: '#f5f5f5' },
684
mark: { stroke: 'white', strokeWidth: 2 }
685
};
686
687
const userConfig = {
688
view: { width: 600 },
689
axis: { labelFontSize: 12 }
690
};
691
692
// Merge configurations
693
const finalConfig = mergeConfig(baseConfig, themeConfig, userConfig);
694
console.log(finalConfig);
695
// {
696
// view: { width: 600, height: 300, background: '#f5f5f5' },
697
// mark: { fill: 'steelblue', stroke: 'white', strokeWidth: 2 },
698
// axis: { labelFontSize: 12 }
699
// }
700
701
// Write configuration
702
writeConfig(finalConfig, {
703
format: 'json',
704
pretty: true,
705
path: 'config.json'
706
});
707
```
708
709
### Logging
710
711
```typescript
712
import { logger, None, Error, Warn, Info, Debug } from "vega";
713
714
// Create logger
715
const log = new logger(Info);
716
717
// Log messages at different levels
718
log.error('This is an error'); // Will show
719
log.warn('This is a warning'); // Will show
720
log.info('This is info'); // Will show
721
log.debug('This is debug'); // Will NOT show (level is Info)
722
723
// Change logging level
724
log.level(Debug);
725
log.debug('Now debug messages show'); // Will show
726
727
// Log with additional data
728
log.info('User action', {
729
action: 'click',
730
element: 'button',
731
timestamp: Date.now()
732
});
733
```
734
735
### Advanced Accessor Usage
736
737
```typescript
738
import { accessor, accessorName, accessorFields, key } from "vega";
739
740
// Create complex accessor
741
const complexAccessor = accessor('d => d.nested.value * 2');
742
console.log(accessorName(complexAccessor)); // Function source or name
743
744
// Field names from accessor
745
const fields = accessorFields(complexAccessor);
746
console.log(fields); // ['nested.value']
747
748
// Composite key function
749
const keyFunc = key(['category', 'year']);
750
const data = [
751
{ category: 'A', year: 2020, value: 100 },
752
{ category: 'B', year: 2020, value: 200 },
753
{ category: 'A', year: 2021, value: 150 }
754
];
755
756
const grouped = new Map();
757
data.forEach(d => {
758
const k = keyFunc(d);
759
if (!grouped.has(k)) {
760
grouped.set(k, []);
761
}
762
grouped.get(k).push(d);
763
});
764
765
console.log(Array.from(grouped.keys())); // ['A|2020', 'B|2020', 'A|2021']
766
```
767
768
### Array Processing
769
770
```typescript
771
import { visitArray, peek, extent, compare, ascending } from "vega";
772
773
const nestedData = [
774
[1, [2, 3]],
775
[4, [5, [6, 7]]],
776
8
777
];
778
779
// Visit all nested items
780
visitArray(nestedData, (item, index) => {
781
console.log(`Item ${index}:`, item);
782
});
783
784
// Peek at array
785
const numbers = [1, 2, 3, 4, 5];
786
console.log(peek(numbers)); // 5
787
788
// Sorting with comparisons
789
const unsorted = [3, 1, 4, 1, 5, 9, 2, 6];
790
const sorted = unsorted.slice().sort(ascending);
791
console.log(sorted); // [1, 1, 2, 3, 4, 5, 6, 9]
792
793
// Custom comparison
794
const people = [
795
{ name: 'Alice', age: 30 },
796
{ name: 'Bob', age: 25 },
797
{ name: 'Carol', age: 35 }
798
];
799
800
people.sort((a, b) => compare(a.age, b.age));
801
console.log(people); // Sorted by age
802
```