Core utilities and components for Apache Superset's frontend UI framework providing data visualization, formatting, and chart composition capabilities
—
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.
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.
Core class for formatting numeric values with configurable options:
import { NumberFormatter, PREVIEW_VALUE } from '@superset-ui/core';
interface NumberFormatterConfig {
id: string; // Unique identifier for the formatter
label?: string; // Human-readable name
description?: string; // Formatter description
formatFunc: NumberFormatFunction; // Function that performs formatting
isInvalid?: boolean; // Whether formatter is invalid/deprecated
}
// Formatter function type
type NumberFormatFunction = (value: number) => string;
class NumberFormatter extends ExtensibleFunction {
readonly id: string;
readonly label: string;
readonly description: string;
readonly formatFunc: NumberFormatFunction;
readonly isInvalid: boolean;
constructor(config: NumberFormatterConfig);
// Format a number (also callable as function)
format(value: number | null | undefined): string;
// Preview formatter output with sample value
preview(): string;
}
// Preview value constant
const PREVIEW_VALUE = 12345.432;
// Formatter is also callable as function
interface NumberFormatter {
(value: number | null | undefined): string;
}Registry system for managing number formatters with singleton access:
import {
getNumberFormatterRegistry,
formatNumber,
getNumberFormatter,
NumberFormatterRegistry
} from '@superset-ui/core';
// Get global registry instance
function getNumberFormatterRegistry(): NumberFormatterRegistry;
// Format number using registered formatter
function formatNumber(format: string, value: number): string;
// Get specific formatter by ID
function getNumberFormatter(format: string): NumberFormatter;
// Registry class for number formatters
class NumberFormatterRegistry extends RegistryWithDefaultKey<NumberFormatter> {
constructor();
// Format value using specific formatter
format(key: string, value: number): string;
// Get default formatter
getDefaultKey(): string;
}Factory functions for creating different types of number formatters:
import {
createD3NumberFormatter,
createDurationFormatter,
createSiAtMostNDigitFormatter,
createSmartNumberFormatter
} from '@superset-ui/core';
// D3-based number formatter
function createD3NumberFormatter(config: {
description?: string;
formatString: string; // D3 format string (e.g., '.2f', ',.0f')
label?: string;
locale?: Locale; // D3 locale for internationalization
}): NumberFormatter;
// Duration formatter (for time durations in seconds)
function createDurationFormatter(config: {
description?: string;
formatString: string; // Duration format string
label?: string;
}): NumberFormatter;
// SI unit formatter with digit constraints
function createSiAtMostNDigitFormatter(config: {
description?: string;
id: string;
label?: string;
maxSignificantDigits: number; // Maximum significant digits
}): NumberFormatter;
// Smart formatter that adapts to number ranges
function createSmartNumberFormatter(config: {
description?: string;
id: string;
label?: string;
signed?: boolean; // Whether to show sign for positive numbers
}): NumberFormatter;Core class for formatting temporal values with timezone support:
import { TimeFormatter, PREVIEW_TIME } from '@superset-ui/core';
interface TimeFormatterConfig {
id: string; // Unique identifier
label?: string; // Human-readable name
description?: string; // Formatter description
formatFunc: TimeFormatFunction; // Function that performs formatting
useLocalTime?: boolean; // Use local time vs UTC
}
// Time formatter function type
type TimeFormatFunction = (value: Date) => string;
class TimeFormatter extends ExtensibleFunction {
readonly id: string;
readonly label: string;
readonly description: string;
readonly formatFunc: TimeFormatFunction;
readonly useLocalTime: boolean;
constructor(config: TimeFormatterConfig);
// Format a date/time (also callable as function)
format(value: Date | number | null | undefined): string;
// Preview formatter output with sample time
preview(): string;
}
// Preview time constant
const PREVIEW_TIME = new Date(Date.UTC(2017, 1, 14, 11, 22, 33));
// Formatter is also callable as function
interface TimeFormatter {
(value: Date | number | null | undefined): string;
}Registry system and utility functions for time formatting:
import {
getTimeFormatterRegistry,
formatTime,
formatTimeRange,
getTimeFormatter,
getTimeFormatterForGranularity,
getTimeRangeFormatter,
LOCAL_PREFIX
} from '@superset-ui/core';
// Get global time formatter registry
function getTimeFormatterRegistry(): RegistryWithDefaultKey<TimeFormatter>;
// Format single time value
function formatTime(format: string, value: Date | number | null | undefined): string;
// Format time range
function formatTimeRange(
format: string,
values: (Date | number | null | undefined)[]
): string;
// Get specific time formatter
function getTimeFormatter(format: string): TimeFormatter;
// Get formatter appropriate for time granularity
function getTimeFormatterForGranularity(granularity: string): TimeFormatter;
// Get time range formatter
function getTimeRangeFormatter(format?: string): TimeFormatter;
// Local time format prefix constant
const LOCAL_PREFIX = 'local!';Factory functions for creating specialized time formatters:
import {
createD3TimeFormatter,
createMultiFormatter,
smartDateFormatter,
smartDateDetailedFormatter,
smartDateVerboseFormatter
} from '@superset-ui/core';
// D3-based time formatter
function createD3TimeFormatter(config: {
description?: string;
formatString: string; // D3 time format string
label?: string;
locale?: Locale; // D3 time locale
useLocalTime?: boolean; // Use local vs UTC time
}): TimeFormatter;
// Multi-granularity formatter that adapts format based on time range
function createMultiFormatter(config: {
description?: string;
formats: { [key: string]: string }; // Format strings for different granularities
id: string;
label?: string;
useLocalTime?: boolean;
}): TimeFormatter;
// Smart date formatters with different verbosity levels
function smartDateFormatter(value: Date): string;
function smartDateDetailedFormatter(value: Date): string;
function smartDateVerboseFormatter(value: Date): string;Enumeration of standard number format identifiers:
import { NumberFormats } from '@superset-ui/core';
// Standard number formats
const NumberFormats = {
PERCENT: '.1%',
PERCENT_1_DECIMAL: '.1%',
PERCENT_2_DECIMAL: '.2%',
PERCENT_3_DECIMAL: '.3%',
INTEGER: ',d',
FLOAT: ',.1f',
FLOAT_2_DECIMAL: ',.2f',
FLOAT_3_DECIMAL: ',.3f',
CURRENCY: '$,.0f',
CURRENCY_2_DECIMAL: '$,.2f',
SCIENTIFIC: '.2e',
// Duration formats
DURATION: 'duration',
DURATION_SUB: 'duration_sub',
// SI unit formats
SI: '.3s',
SI_2_DECIMAL: '.2s'
} as const;Enumeration of standard time format identifiers:
import { TimeFormats, LOCAL_PREFIX } from '@superset-ui/core';
// Standard time formats
const TimeFormats = {
// Database formats
DATABASE_DATE: '%Y-%m-%d',
DATABASE_DATETIME: '%Y-%m-%d %H:%M:%S',
// US formats
US_DATE: '%m/%d/%Y',
US_DATETIME: '%m/%d/%Y %I:%M:%S %p',
// International formats
INTERNATIONAL_DATE: '%d/%m/%Y',
// Time only
TIME: '%H:%M:%S',
TIME_12_HOUR: '%I:%M:%S %p',
// Smart formatters
SMART_DATE: 'smart_date',
SMART_DATE_DETAILED: 'smart_date_detailed',
SMART_DATE_VERBOSE: 'smart_date_verbose'
} as const;
// Prefix for local time formats
const LOCAL_PREFIX = 'local!';import {
formatNumber,
getNumberFormatter,
NumberFormats
} from '@superset-ui/core';
// Format using format strings
const percentage = formatNumber('.1%', 0.1234); // "12.3%"
const currency = formatNumber('$,.2f', 1234.567); // "$1,234.57"
const integer = formatNumber(',d', 1234.567); // "1,235"
const scientific = formatNumber('.2e', 1234567); // "1.23e+6"
// Format using predefined constants
const percent = formatNumber(NumberFormats.PERCENT, 0.456); // "45.6%"
const money = formatNumber(NumberFormats.CURRENCY_2_DECIMAL, 99.99); // "$99.99"
// Get formatter instance for reuse
const currencyFormatter = getNumberFormatter('$,.2f');
const price1 = currencyFormatter(29.99); // "$29.99"
const price2 = currencyFormatter(149.50); // "$149.50"import {
formatTime,
getTimeFormatter,
TimeFormats,
LOCAL_PREFIX
} from '@superset-ui/core';
const date = new Date('2024-03-15T14:30:00Z');
// Format using format strings
const dbFormat = formatTime('%Y-%m-%d %H:%M:%S', date); // "2024-03-15 14:30:00"
const usFormat = formatTime('%m/%d/%Y %I:%M:%S %p', date); // "03/15/2024 02:30:00 PM"
const timeOnly = formatTime('%H:%M', date); // "14:30"
// Format using predefined constants
const dbDate = formatTime(TimeFormats.DATABASE_DATE, date); // "2024-03-15"
const usDateTime = formatTime(TimeFormats.US_DATETIME, date); // "03/15/2024 02:30:00 PM"
// Local time formatting (converts from UTC to local timezone)
const localFormat = formatTime(LOCAL_PREFIX + '%Y-%m-%d %H:%M', date);
// Smart formatters adapt based on context
const smartDate = formatTime('smart_date', date);
const detailedDate = formatTime('smart_date_detailed', date);import {
NumberFormatter,
createD3NumberFormatter,
createSmartNumberFormatter,
getNumberFormatterRegistry
} from '@superset-ui/core';
// Create custom D3 formatter
const customPercentFormatter = createD3NumberFormatter({
formatString: '+.2%',
label: 'Signed Percentage',
description: 'Percentage with explicit positive sign'
});
// Create smart formatter for large numbers
const smartLargeNumbers = createSmartNumberFormatter({
id: 'smart_large',
label: 'Smart Large Numbers',
description: 'Automatically formats large numbers with appropriate units',
signed: false
});
// Register custom formatters
const registry = getNumberFormatterRegistry();
registry.registerValue('custom_percent', customPercentFormatter);
registry.registerValue('smart_large', smartLargeNumbers);
// Use custom formatters
const result1 = formatNumber('custom_percent', 0.123); // "+12.30%"
const result2 = formatNumber('smart_large', 1234567); // "1.23M"import {
TimeFormatter,
createD3TimeFormatter,
createMultiFormatter,
getTimeFormatterRegistry
} from '@superset-ui/core';
// Create custom D3 time formatter
const customDateFormatter = createD3TimeFormatter({
formatString: '%A, %B %d, %Y',
label: 'Full Date',
description: 'Full weekday and month names',
useLocalTime: true
});
// Create multi-level formatter for different granularities
const adaptiveFormatter = createMultiFormatter({
id: 'adaptive_time',
label: 'Adaptive Time Format',
description: 'Changes format based on time granularity',
formats: {
'second': '%H:%M:%S',
'minute': '%H:%M',
'hour': '%m/%d %H:00',
'day': '%m/%d/%Y',
'month': '%Y-%m',
'year': '%Y'
},
useLocalTime: true
});
// Register custom formatters
const timeRegistry = getTimeFormatterRegistry();
timeRegistry.registerValue('full_date', customDateFormatter);
timeRegistry.registerValue('adaptive', adaptiveFormatter);
// Use custom formatters
const date = new Date('2024-03-15T14:30:00Z');
const fullDate = formatTime('full_date', date); // "Friday, March 15, 2024"
const adaptive = formatTime('adaptive', date); // Format depends on contextimport { createDurationFormatter, formatNumber } from '@superset-ui/core';
// Create duration formatter for seconds
const durationFormatter = createDurationFormatter({
formatString: 'duration',
label: 'Duration (HMS)',
description: 'Formats seconds as hours:minutes:seconds'
});
// Register and use
getNumberFormatterRegistry().registerValue('duration_hms', durationFormatter);
const duration1 = formatNumber('duration_hms', 3661); // "1:01:01"
const duration2 = formatNumber('duration_hms', 125.5); // "2:05.5"
const duration3 = formatNumber('duration_hms', 45); // "45s"import { createSiAtMostNDigitFormatter } from '@superset-ui/core';
// Create SI formatter with 3 significant digits maximum
const siFormatter = createSiAtMostNDigitFormatter({
id: 'si_3_digits',
label: 'SI Units (3 digits)',
description: 'SI units with at most 3 significant digits',
maxSignificantDigits: 3
});
getNumberFormatterRegistry().registerValue('si_3', siFormatter);
const large1 = formatNumber('si_3', 1234567); // "1.23M"
const large2 = formatNumber('si_3', 999999999); // "1.00G"
const small = formatNumber('si_3', 0.00123); // "1.23m"import { formatTimeRange, getTimeRangeFormatter } from '@superset-ui/core';
const startDate = new Date('2024-03-01T00:00:00Z');
const endDate = new Date('2024-03-15T23:59:59Z');
// Format time range with specific formatter
const range1 = formatTimeRange('%Y-%m-%d', [startDate, endDate]);
// "2024-03-01 ~ 2024-03-15"
// Get dedicated time range formatter
const rangeFormatter = getTimeRangeFormatter('smart_date');
const range2 = rangeFormatter([startDate, endDate]);
// Smart formatting based on range durationimport { getTimeFormatterForGranularity } from '@superset-ui/core';
// Get formatter appropriate for specific time granularity
const secondFormatter = getTimeFormatterForGranularity('second');
const dayFormatter = getTimeFormatterForGranularity('day');
const monthFormatter = getTimeFormatterForGranularity('month');
const timestamp = new Date('2024-03-15T14:30:25Z');
const secondFormat = secondFormatter(timestamp); // "14:30:25"
const dayFormat = dayFormatter(timestamp); // "Mar 15"
const monthFormat = monthFormatter(timestamp); // "Mar 2024"import { createD3NumberFormatter, createD3TimeFormatter } from '@superset-ui/core';
// German number formatting
const germanNumberFormatter = createD3NumberFormatter({
formatString: ',.2f',
label: 'German Numbers',
locale: {
decimal: ',',
thousands: '.',
grouping: [3],
currency: ['€', '']
}
});
// German time formatting
const germanTimeFormatter = createD3TimeFormatter({
formatString: '%d.%m.%Y %H:%M',
label: 'German Date/Time',
locale: {
dateTime: '%A, der %e. %B %Y, %X',
date: '%d.%m.%Y',
time: '%H:%M:%S',
periods: ['AM', 'PM'], // Not used in German
days: ['Sonntag', 'Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag'],
shortDays: ['So', 'Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa'],
months: ['Januar', 'Februar', 'März', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember'],
shortMonths: ['Jan', 'Feb', 'Mär', 'Apr', 'Mai', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dez']
}
});
// Register and use locale-specific formatters
getNumberFormatterRegistry().registerValue('de_numbers', germanNumberFormatter);
getTimeFormatterRegistry().registerValue('de_datetime', germanTimeFormatter);
const germanNumber = formatNumber('de_numbers', 1234.56); // "1.234,56"
const germanDate = formatTime('de_datetime', new Date()); // "15.03.2024 14:30"Install with Tessl CLI
npx tessl i tessl/npm-superset-ui--core