0
# Data Formatting
1
2
This module provides comprehensive number and time formatting capabilities for Superset applications. It includes extensible formatter registries, D3-based formatters, smart formatters that adapt to data ranges, and specialized formatters for different data types and locales.
3
4
## Overview
5
6
The data formatting system is built around two core formatter types: NumberFormatter for numeric data and TimeFormatter for temporal data. Both support format string specifications, custom format functions, and are managed through registries that enable dynamic registration and retrieval of formatters.
7
8
## Number Formatting
9
10
### NumberFormatter Class { .api }
11
12
Core class for formatting numeric values with configurable options:
13
14
```typescript
15
import { NumberFormatter, PREVIEW_VALUE } from '@superset-ui/core';
16
17
interface NumberFormatterConfig {
18
id: string; // Unique identifier for the formatter
19
label?: string; // Human-readable name
20
description?: string; // Formatter description
21
formatFunc: NumberFormatFunction; // Function that performs formatting
22
isInvalid?: boolean; // Whether formatter is invalid/deprecated
23
}
24
25
// Formatter function type
26
type NumberFormatFunction = (value: number) => string;
27
28
class NumberFormatter extends ExtensibleFunction {
29
readonly id: string;
30
readonly label: string;
31
readonly description: string;
32
readonly formatFunc: NumberFormatFunction;
33
readonly isInvalid: boolean;
34
35
constructor(config: NumberFormatterConfig);
36
37
// Format a number (also callable as function)
38
format(value: number | null | undefined): string;
39
40
// Preview formatter output with sample value
41
preview(): string;
42
}
43
44
// Preview value constant
45
const PREVIEW_VALUE = 12345.432;
46
47
// Formatter is also callable as function
48
interface NumberFormatter {
49
(value: number | null | undefined): string;
50
}
51
```
52
53
### Number Formatter Registry { .api }
54
55
Registry system for managing number formatters with singleton access:
56
57
```typescript
58
import {
59
getNumberFormatterRegistry,
60
formatNumber,
61
getNumberFormatter,
62
NumberFormatterRegistry
63
} from '@superset-ui/core';
64
65
// Get global registry instance
66
function getNumberFormatterRegistry(): NumberFormatterRegistry;
67
68
// Format number using registered formatter
69
function formatNumber(format: string, value: number): string;
70
71
// Get specific formatter by ID
72
function getNumberFormatter(format: string): NumberFormatter;
73
74
// Registry class for number formatters
75
class NumberFormatterRegistry extends RegistryWithDefaultKey<NumberFormatter> {
76
constructor();
77
78
// Format value using specific formatter
79
format(key: string, value: number): string;
80
81
// Get default formatter
82
getDefaultKey(): string;
83
}
84
```
85
86
### Number Format Factory Functions { .api }
87
88
Factory functions for creating different types of number formatters:
89
90
```typescript
91
import {
92
createD3NumberFormatter,
93
createDurationFormatter,
94
createSiAtMostNDigitFormatter,
95
createSmartNumberFormatter
96
} from '@superset-ui/core';
97
98
// D3-based number formatter
99
function createD3NumberFormatter(config: {
100
description?: string;
101
formatString: string; // D3 format string (e.g., '.2f', ',.0f')
102
label?: string;
103
locale?: Locale; // D3 locale for internationalization
104
}): NumberFormatter;
105
106
// Duration formatter (for time durations in seconds)
107
function createDurationFormatter(config: {
108
description?: string;
109
formatString: string; // Duration format string
110
label?: string;
111
}): NumberFormatter;
112
113
// SI unit formatter with digit constraints
114
function createSiAtMostNDigitFormatter(config: {
115
description?: string;
116
id: string;
117
label?: string;
118
maxSignificantDigits: number; // Maximum significant digits
119
}): NumberFormatter;
120
121
// Smart formatter that adapts to number ranges
122
function createSmartNumberFormatter(config: {
123
description?: string;
124
id: string;
125
label?: string;
126
signed?: boolean; // Whether to show sign for positive numbers
127
}): NumberFormatter;
128
```
129
130
## Time Formatting
131
132
### TimeFormatter Class { .api }
133
134
Core class for formatting temporal values with timezone support:
135
136
```typescript
137
import { TimeFormatter, PREVIEW_TIME } from '@superset-ui/core';
138
139
interface TimeFormatterConfig {
140
id: string; // Unique identifier
141
label?: string; // Human-readable name
142
description?: string; // Formatter description
143
formatFunc: TimeFormatFunction; // Function that performs formatting
144
useLocalTime?: boolean; // Use local time vs UTC
145
}
146
147
// Time formatter function type
148
type TimeFormatFunction = (value: Date) => string;
149
150
class TimeFormatter extends ExtensibleFunction {
151
readonly id: string;
152
readonly label: string;
153
readonly description: string;
154
readonly formatFunc: TimeFormatFunction;
155
readonly useLocalTime: boolean;
156
157
constructor(config: TimeFormatterConfig);
158
159
// Format a date/time (also callable as function)
160
format(value: Date | number | null | undefined): string;
161
162
// Preview formatter output with sample time
163
preview(): string;
164
}
165
166
// Preview time constant
167
const PREVIEW_TIME = new Date(Date.UTC(2017, 1, 14, 11, 22, 33));
168
169
// Formatter is also callable as function
170
interface TimeFormatter {
171
(value: Date | number | null | undefined): string;
172
}
173
```
174
175
### Time Formatter Registry { .api }
176
177
Registry system and utility functions for time formatting:
178
179
```typescript
180
import {
181
getTimeFormatterRegistry,
182
formatTime,
183
formatTimeRange,
184
getTimeFormatter,
185
getTimeFormatterForGranularity,
186
getTimeRangeFormatter,
187
LOCAL_PREFIX
188
} from '@superset-ui/core';
189
190
// Get global time formatter registry
191
function getTimeFormatterRegistry(): RegistryWithDefaultKey<TimeFormatter>;
192
193
// Format single time value
194
function formatTime(format: string, value: Date | number | null | undefined): string;
195
196
// Format time range
197
function formatTimeRange(
198
format: string,
199
values: (Date | number | null | undefined)[]
200
): string;
201
202
// Get specific time formatter
203
function getTimeFormatter(format: string): TimeFormatter;
204
205
// Get formatter appropriate for time granularity
206
function getTimeFormatterForGranularity(granularity: string): TimeFormatter;
207
208
// Get time range formatter
209
function getTimeRangeFormatter(format?: string): TimeFormatter;
210
211
// Local time format prefix constant
212
const LOCAL_PREFIX = 'local!';
213
```
214
215
### Time Format Factory Functions { .api }
216
217
Factory functions for creating specialized time formatters:
218
219
```typescript
220
import {
221
createD3TimeFormatter,
222
createMultiFormatter,
223
smartDateFormatter,
224
smartDateDetailedFormatter,
225
smartDateVerboseFormatter
226
} from '@superset-ui/core';
227
228
// D3-based time formatter
229
function createD3TimeFormatter(config: {
230
description?: string;
231
formatString: string; // D3 time format string
232
label?: string;
233
locale?: Locale; // D3 time locale
234
useLocalTime?: boolean; // Use local vs UTC time
235
}): TimeFormatter;
236
237
// Multi-granularity formatter that adapts format based on time range
238
function createMultiFormatter(config: {
239
description?: string;
240
formats: { [key: string]: string }; // Format strings for different granularities
241
id: string;
242
label?: string;
243
useLocalTime?: boolean;
244
}): TimeFormatter;
245
246
// Smart date formatters with different verbosity levels
247
function smartDateFormatter(value: Date): string;
248
function smartDateDetailedFormatter(value: Date): string;
249
function smartDateVerboseFormatter(value: Date): string;
250
```
251
252
## Format Constants and Enumerations
253
254
### NumberFormats { .api }
255
256
Enumeration of standard number format identifiers:
257
258
```typescript
259
import { NumberFormats } from '@superset-ui/core';
260
261
// Standard number formats
262
const NumberFormats = {
263
PERCENT: '.1%',
264
PERCENT_1_DECIMAL: '.1%',
265
PERCENT_2_DECIMAL: '.2%',
266
PERCENT_3_DECIMAL: '.3%',
267
268
INTEGER: ',d',
269
FLOAT: ',.1f',
270
FLOAT_2_DECIMAL: ',.2f',
271
FLOAT_3_DECIMAL: ',.3f',
272
273
CURRENCY: '$,.0f',
274
CURRENCY_2_DECIMAL: '$,.2f',
275
276
SCIENTIFIC: '.2e',
277
278
// Duration formats
279
DURATION: 'duration',
280
DURATION_SUB: 'duration_sub',
281
282
// SI unit formats
283
SI: '.3s',
284
SI_2_DECIMAL: '.2s'
285
} as const;
286
```
287
288
### TimeFormats { .api }
289
290
Enumeration of standard time format identifiers:
291
292
```typescript
293
import { TimeFormats, LOCAL_PREFIX } from '@superset-ui/core';
294
295
// Standard time formats
296
const TimeFormats = {
297
// Database formats
298
DATABASE_DATE: '%Y-%m-%d',
299
DATABASE_DATETIME: '%Y-%m-%d %H:%M:%S',
300
301
// US formats
302
US_DATE: '%m/%d/%Y',
303
US_DATETIME: '%m/%d/%Y %I:%M:%S %p',
304
305
// International formats
306
INTERNATIONAL_DATE: '%d/%m/%Y',
307
308
// Time only
309
TIME: '%H:%M:%S',
310
TIME_12_HOUR: '%I:%M:%S %p',
311
312
// Smart formatters
313
SMART_DATE: 'smart_date',
314
SMART_DATE_DETAILED: 'smart_date_detailed',
315
SMART_DATE_VERBOSE: 'smart_date_verbose'
316
} as const;
317
318
// Prefix for local time formats
319
const LOCAL_PREFIX = 'local!';
320
```
321
322
## Usage Examples
323
324
### Basic Number Formatting
325
326
```typescript
327
import {
328
formatNumber,
329
getNumberFormatter,
330
NumberFormats
331
} from '@superset-ui/core';
332
333
// Format using format strings
334
const percentage = formatNumber('.1%', 0.1234); // "12.3%"
335
const currency = formatNumber('$,.2f', 1234.567); // "$1,234.57"
336
const integer = formatNumber(',d', 1234.567); // "1,235"
337
const scientific = formatNumber('.2e', 1234567); // "1.23e+6"
338
339
// Format using predefined constants
340
const percent = formatNumber(NumberFormats.PERCENT, 0.456); // "45.6%"
341
const money = formatNumber(NumberFormats.CURRENCY_2_DECIMAL, 99.99); // "$99.99"
342
343
// Get formatter instance for reuse
344
const currencyFormatter = getNumberFormatter('$,.2f');
345
const price1 = currencyFormatter(29.99); // "$29.99"
346
const price2 = currencyFormatter(149.50); // "$149.50"
347
```
348
349
### Basic Time Formatting
350
351
```typescript
352
import {
353
formatTime,
354
getTimeFormatter,
355
TimeFormats,
356
LOCAL_PREFIX
357
} from '@superset-ui/core';
358
359
const date = new Date('2024-03-15T14:30:00Z');
360
361
// Format using format strings
362
const dbFormat = formatTime('%Y-%m-%d %H:%M:%S', date); // "2024-03-15 14:30:00"
363
const usFormat = formatTime('%m/%d/%Y %I:%M:%S %p', date); // "03/15/2024 02:30:00 PM"
364
const timeOnly = formatTime('%H:%M', date); // "14:30"
365
366
// Format using predefined constants
367
const dbDate = formatTime(TimeFormats.DATABASE_DATE, date); // "2024-03-15"
368
const usDateTime = formatTime(TimeFormats.US_DATETIME, date); // "03/15/2024 02:30:00 PM"
369
370
// Local time formatting (converts from UTC to local timezone)
371
const localFormat = formatTime(LOCAL_PREFIX + '%Y-%m-%d %H:%M', date);
372
373
// Smart formatters adapt based on context
374
const smartDate = formatTime('smart_date', date);
375
const detailedDate = formatTime('smart_date_detailed', date);
376
```
377
378
### Custom Number Formatters
379
380
```typescript
381
import {
382
NumberFormatter,
383
createD3NumberFormatter,
384
createSmartNumberFormatter,
385
getNumberFormatterRegistry
386
} from '@superset-ui/core';
387
388
// Create custom D3 formatter
389
const customPercentFormatter = createD3NumberFormatter({
390
formatString: '+.2%',
391
label: 'Signed Percentage',
392
description: 'Percentage with explicit positive sign'
393
});
394
395
// Create smart formatter for large numbers
396
const smartLargeNumbers = createSmartNumberFormatter({
397
id: 'smart_large',
398
label: 'Smart Large Numbers',
399
description: 'Automatically formats large numbers with appropriate units',
400
signed: false
401
});
402
403
// Register custom formatters
404
const registry = getNumberFormatterRegistry();
405
registry.registerValue('custom_percent', customPercentFormatter);
406
registry.registerValue('smart_large', smartLargeNumbers);
407
408
// Use custom formatters
409
const result1 = formatNumber('custom_percent', 0.123); // "+12.30%"
410
const result2 = formatNumber('smart_large', 1234567); // "1.23M"
411
```
412
413
### Custom Time Formatters
414
415
```typescript
416
import {
417
TimeFormatter,
418
createD3TimeFormatter,
419
createMultiFormatter,
420
getTimeFormatterRegistry
421
} from '@superset-ui/core';
422
423
// Create custom D3 time formatter
424
const customDateFormatter = createD3TimeFormatter({
425
formatString: '%A, %B %d, %Y',
426
label: 'Full Date',
427
description: 'Full weekday and month names',
428
useLocalTime: true
429
});
430
431
// Create multi-level formatter for different granularities
432
const adaptiveFormatter = createMultiFormatter({
433
id: 'adaptive_time',
434
label: 'Adaptive Time Format',
435
description: 'Changes format based on time granularity',
436
formats: {
437
'second': '%H:%M:%S',
438
'minute': '%H:%M',
439
'hour': '%m/%d %H:00',
440
'day': '%m/%d/%Y',
441
'month': '%Y-%m',
442
'year': '%Y'
443
},
444
useLocalTime: true
445
});
446
447
// Register custom formatters
448
const timeRegistry = getTimeFormatterRegistry();
449
timeRegistry.registerValue('full_date', customDateFormatter);
450
timeRegistry.registerValue('adaptive', adaptiveFormatter);
451
452
// Use custom formatters
453
const date = new Date('2024-03-15T14:30:00Z');
454
const fullDate = formatTime('full_date', date); // "Friday, March 15, 2024"
455
const adaptive = formatTime('adaptive', date); // Format depends on context
456
```
457
458
### Duration Formatting
459
460
```typescript
461
import { createDurationFormatter, formatNumber } from '@superset-ui/core';
462
463
// Create duration formatter for seconds
464
const durationFormatter = createDurationFormatter({
465
formatString: 'duration',
466
label: 'Duration (HMS)',
467
description: 'Formats seconds as hours:minutes:seconds'
468
});
469
470
// Register and use
471
getNumberFormatterRegistry().registerValue('duration_hms', durationFormatter);
472
473
const duration1 = formatNumber('duration_hms', 3661); // "1:01:01"
474
const duration2 = formatNumber('duration_hms', 125.5); // "2:05.5"
475
const duration3 = formatNumber('duration_hms', 45); // "45s"
476
```
477
478
### SI Unit Formatting
479
480
```typescript
481
import { createSiAtMostNDigitFormatter } from '@superset-ui/core';
482
483
// Create SI formatter with 3 significant digits maximum
484
const siFormatter = createSiAtMostNDigitFormatter({
485
id: 'si_3_digits',
486
label: 'SI Units (3 digits)',
487
description: 'SI units with at most 3 significant digits',
488
maxSignificantDigits: 3
489
});
490
491
getNumberFormatterRegistry().registerValue('si_3', siFormatter);
492
493
const large1 = formatNumber('si_3', 1234567); // "1.23M"
494
const large2 = formatNumber('si_3', 999999999); // "1.00G"
495
const small = formatNumber('si_3', 0.00123); // "1.23m"
496
```
497
498
### Time Range Formatting
499
500
```typescript
501
import { formatTimeRange, getTimeRangeFormatter } from '@superset-ui/core';
502
503
const startDate = new Date('2024-03-01T00:00:00Z');
504
const endDate = new Date('2024-03-15T23:59:59Z');
505
506
// Format time range with specific formatter
507
const range1 = formatTimeRange('%Y-%m-%d', [startDate, endDate]);
508
// "2024-03-01 ~ 2024-03-15"
509
510
// Get dedicated time range formatter
511
const rangeFormatter = getTimeRangeFormatter('smart_date');
512
const range2 = rangeFormatter([startDate, endDate]);
513
// Smart formatting based on range duration
514
```
515
516
### Granularity-Aware Formatting
517
518
```typescript
519
import { getTimeFormatterForGranularity } from '@superset-ui/core';
520
521
// Get formatter appropriate for specific time granularity
522
const secondFormatter = getTimeFormatterForGranularity('second');
523
const dayFormatter = getTimeFormatterForGranularity('day');
524
const monthFormatter = getTimeFormatterForGranularity('month');
525
526
const timestamp = new Date('2024-03-15T14:30:25Z');
527
528
const secondFormat = secondFormatter(timestamp); // "14:30:25"
529
const dayFormat = dayFormatter(timestamp); // "Mar 15"
530
const monthFormat = monthFormatter(timestamp); // "Mar 2024"
531
```
532
533
### Locale-Specific Formatting
534
535
```typescript
536
import { createD3NumberFormatter, createD3TimeFormatter } from '@superset-ui/core';
537
538
// German number formatting
539
const germanNumberFormatter = createD3NumberFormatter({
540
formatString: ',.2f',
541
label: 'German Numbers',
542
locale: {
543
decimal: ',',
544
thousands: '.',
545
grouping: [3],
546
currency: ['€', '']
547
}
548
});
549
550
// German time formatting
551
const germanTimeFormatter = createD3TimeFormatter({
552
formatString: '%d.%m.%Y %H:%M',
553
label: 'German Date/Time',
554
locale: {
555
dateTime: '%A, der %e. %B %Y, %X',
556
date: '%d.%m.%Y',
557
time: '%H:%M:%S',
558
periods: ['AM', 'PM'], // Not used in German
559
days: ['Sonntag', 'Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag'],
560
shortDays: ['So', 'Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa'],
561
months: ['Januar', 'Februar', 'März', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember'],
562
shortMonths: ['Jan', 'Feb', 'Mär', 'Apr', 'Mai', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dez']
563
}
564
});
565
566
// Register and use locale-specific formatters
567
getNumberFormatterRegistry().registerValue('de_numbers', germanNumberFormatter);
568
getTimeFormatterRegistry().registerValue('de_datetime', germanTimeFormatter);
569
570
const germanNumber = formatNumber('de_numbers', 1234.56); // "1.234,56"
571
const germanDate = formatTime('de_datetime', new Date()); // "15.03.2024 14:30"
572
```
573
574
## Related Documentation
575
576
- [Core Models & Utilities](./core-models.md) - Registry system and ExtensibleFunction base class
577
- [Plugin System](./plugin-system.md) - Chart plugin integration with formatters
578
- [UI & Styling](./ui-styling.md) - Theme integration for formatter display
579
- [Dashboard Components](./dashboard.md) - Dashboard usage of formatting