CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-superset-ui--core

Core utilities and components for Apache Superset's frontend UI framework providing data visualization, formatting, and chart composition capabilities

Pending
Overview
Eval results
Files

data-formatting.mddocs/

Data Formatting

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.

Overview

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.

Number Formatting

NumberFormatter Class { .api }

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;
}

Number Formatter Registry { .api }

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;
}

Number Format Factory Functions { .api }

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;

Time Formatting

TimeFormatter Class { .api }

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;
}

Time Formatter Registry { .api }

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!';

Time Format Factory Functions { .api }

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;

Format Constants and Enumerations

NumberFormats { .api }

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;

TimeFormats { .api }

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!';

Usage Examples

Basic Number Formatting

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"

Basic Time Formatting

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);

Custom Number Formatters

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"

Custom Time Formatters

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 context

Duration Formatting

import { 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"

SI Unit Formatting

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"

Time Range Formatting

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 duration

Granularity-Aware Formatting

import { 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"

Locale-Specific Formatting

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"

Related Documentation

  • Core Models & Utilities - Registry system and ExtensibleFunction base class
  • Plugin System - Chart plugin integration with formatters
  • UI & Styling - Theme integration for formatter display
  • Dashboard Components - Dashboard usage of formatting

Install with Tessl CLI

npx tessl i tessl/npm-superset-ui--core

docs

core-models.md

dashboard.md

data-connection.md

data-formatting.md

index.md

plugin-system.md

translation.md

ui-styling.md

validation-math.md

tile.json