Comprehensive formatting system for numbers, dates, timestamps, currencies, and custom formats with expression support.
Lightdash provides extensive formatting capabilities to display data values in human-readable formats:
The main function for formatting any field value according to its type and format configuration. This is the primary formatting function used throughout Lightdash to convert raw database values into human-readable strings.
function formatItemValue(
item: Field | Dimension | AdditionalMetric | TableCalculation | CustomDimension | undefined,
value: unknown,
convertToUTC?: boolean,
parameters?: Record<string, unknown>
): string;Parameters:
Returns: Formatted string representation of the value
Special Return Values:
'∅' for null values'-' for undefined values'' for empty string valuesBehavior:
format property on item) and applies them if validformatOptions (CustomFormat) if presentExample:
import { formatItemValue } from '@lightdash/common';
// Format a numeric metric
const formatted = formatItemValue(revenueMetric, 1234567.89);
// Returns: "$1,234,567.89" (if metric has currency format)
// Format a date dimension
const formattedDate = formatItemValue(dateDimension, '2024-01-15');
// Returns: "January 15, 2024" (based on dimension's date format)
// Format with UTC conversion for timestamps
const utcValue = formatItemValue(timestampField, value, true);
// Converts to UTC before formattingFormats numeric values with extensive options.
function formatNumberValue(
value: number,
format?: CustomFormat
): string;Example:
import {
formatNumberValue,
NumberSeparator,
CustomFormatType,
} from '@lightdash/common';
// Basic number with custom format
formatNumberValue(1234567.89, {
type: CustomFormatType.NUMBER,
round: 2,
separator: NumberSeparator.COMMA_PERIOD,
});
// Returns: "1,234,567.89"
// Currency formatting
formatNumberValue(1234.56, {
type: CustomFormatType.CURRENCY,
round: 2,
currency: 'USD',
separator: NumberSeparator.COMMA_PERIOD,
});
// Returns: "$1,234.56"
// Note: Compact notation, prefix, and suffix properties are defined in the
// CustomFormat interface but are not currently implemented in formatNumberValue.
// They may be planned for future releases.enum NumberSeparator {
DEFAULT = 'default',
COMMA_PERIOD = 'commaPeriod', // 1,234.56
SPACE_PERIOD = 'spacePeriod', // 1 234.56
PERIOD_COMMA = 'periodComma', // 1.234,56
NO_SEPARATOR_PERIOD = 'noSeparatorPeriod', // 1234.56
}Note: The Compact enum and related types are defined in the package, but the compact property in CustomFormat is not currently implemented in the formatting functions. This feature may be added in future releases.
enum Compact {
THOUSANDS = 'thousands',
MILLIONS = 'millions',
BILLIONS = 'billions',
TRILLIONS = 'trillions',
KILOBYTES = 'kilobytes',
MEGABYTES = 'megabytes',
GIGABYTES = 'gigabytes',
TERABYTES = 'terabytes',
PETABYTES = 'petabytes',
KIBIBYTES = 'kibibytes',
MEBIBYTES = 'mebibytes',
GIBIBYTES = 'gibibytes',
TEBIBYTES = 'tebibytes',
PEBIBYTES = 'pebibytes',
}
interface CompactConfig {
compact: Compact;
alias: string[];
orderOfMagnitude: number;
convertFn: (value: number) => number;
label: string;
suffix: string;
}
const CompactConfigMap: Record<Compact, CompactConfig>;
const IECByteCompacts: Compact[];
function findCompactConfig(compact: Compact | undefined): CompactConfig | undefined;
function getCompactOptionsForFormatType(formatType: CustomFormatType): Compact[];Array of supported ISO 4217 currency codes for currency formatting.
export const currencies: readonly string[];Supported currencies (35 total): USD, EUR, GBP, JPY, DKK, CHF, CAD, AUD, CNY, ARS, BRL, CLP, COP, CZK, HKD, HUF, INR, ILS, KRW, MYR, MXN, MAD, NZD, NOK, PHP, PLN, RUB, SAR, SGD, ZAR, SEK, TWD, THB, TRY, VND
Usage Example:
import { formatNumberValue, currencies, CustomFormatType } from '@lightdash/common';
// Validate currency code
const isValidCurrency = (code: string) => currencies.includes(code);
if (isValidCurrency('USD')) {
console.log('Valid currency');
}
// Format with different currencies
formatNumberValue(1234.56, {
type: CustomFormatType.CURRENCY,
currency: 'USD',
round: 2
});
// Returns: "$1,234.56"
formatNumberValue(1234.56, {
type: CustomFormatType.CURRENCY,
currency: 'EUR',
round: 2
});
// Returns: "€1,234.56"
formatNumberValue(1234.56, {
type: CustomFormatType.CURRENCY,
currency: 'GBP',
round: 2
});
// Returns: "£1,234.56"
// Japanese Yen (no decimal places typically)
formatNumberValue(1234, {
type: CustomFormatType.CURRENCY,
currency: 'JPY',
round: 0
});
// Returns: "¥1,234"
// Programmatically use first currency
const defaultCurrency = currencies[0]; // 'USD'
formatNumberValue(999.99, {
type: CustomFormatType.CURRENCY,
currency: defaultCurrency,
round: 2
});Formats date values using TimeFrames for predefined date intervals.
function formatDate(
date: Date | string | number,
timeInterval?: TimeFrames,
convertToUTC?: boolean
): string;
function getDateFormat(
timeInterval?: TimeFrames
): string;
function parseDate(
str: string,
timeInterval?: TimeFrames
): Date;Parameters:
Example:
import { formatDate, getDateFormat, TimeFrames } from '@lightdash/common';
// Format with default format (DAY)
formatDate('2024-01-15');
// Returns: "2024-01-15"
// Format with specific time interval
formatDate('2024-01-15', TimeFrames.MONTH);
// Returns: "2024-01" (month format)
formatDate('2024-01-15', TimeFrames.YEAR);
// Returns: "2024" (year format)
// Convert to UTC before formatting
formatDate('2024-01-15T14:30:00Z', TimeFrames.DAY, true);
// Returns date in UTC timezone
// Get format for a dimension
const format = getDateFormat(dateDimension);
// Returns format string based on timeIntervalFormats timestamp values using TimeFrames for predefined time intervals.
function formatTimestamp(
value: Date | string | number,
timeInterval?: TimeFrames,
convertToUTC?: boolean
): string;
function parseTimestamp(
str: string,
timeInterval?: TimeFrames
): Date;
function getLocalTimeDisplay(
date: Date | string,
showTimezone?: boolean
): string;Parameters:
Example:
import { formatTimestamp, getLocalTimeDisplay, TimeFrames } from '@lightdash/common';
// Format with default format (MILLISECOND)
formatTimestamp('2024-01-15T14:30:00.123Z');
// Returns: "2024-01-15 14:30:00.123"
// Format with specific time interval
formatTimestamp('2024-01-15T14:30:00Z', TimeFrames.SECOND);
// Returns: "2024-01-15 14:30:00"
formatTimestamp('2024-01-15T14:30:00Z', TimeFrames.MINUTE);
// Returns: "2024-01-15 14:30"
// Convert to UTC before formatting
formatTimestamp('2024-01-15T14:30:00Z', TimeFrames.SECOND, true);
// Returns timestamp in UTC timezone
// Get local time display
const localTime = getLocalTimeDisplay('2024-01-15T14:30:00Z');
// Returns: "January 15, 2024 at 2:30 PM" (in browser timezone)function formatBoolean(value: unknown): string;Example:
import { formatBoolean } from '@lightdash/common';
formatBoolean(true); // Returns: "True"
formatBoolean(false); // Returns: "False"
formatBoolean(1); // Returns: "True"
formatBoolean(0); // Returns: "False"
formatBoolean(null); // Returns: "False"enum CustomFormatType {
DEFAULT = 'default',
PERCENT = 'percent',
CURRENCY = 'currency',
NUMBER = 'number',
ID = 'id',
DATE = 'date',
TIMESTAMP = 'timestamp',
BYTES_SI = 'bytes_si',
BYTES_IEC = 'bytes_iec',
CUSTOM = 'custom',
}
interface CustomFormat {
type: CustomFormatType;
round?: number;
separator?: NumberSeparator;
currency?: string;
compact?: Compact; // Note: Not currently implemented in formatNumberValue
prefix?: string; // Note: Not currently implemented in formatNumberValue
suffix?: string; // Note: Not currently implemented in formatNumberValue
timeInterval?: TimeFrames;
custom?: string;
}function applyCustomFormat(
value: unknown,
customFormat?: CustomFormat
): string;
function getCustomFormat(
item: Field | Metric | AdditionalMetric | undefined
): CustomFormat | undefined;
function hasFormatting(
item: Field | Metric | TableCalculation | undefined
): boolean;
function getCustomFormatFromLegacy({
format,
compact,
round
}: {
format?: Format | string;
compact?: CompactOrAlias;
round?: number;
}): CustomFormat;Example:
import {
applyCustomFormat,
getCustomFormat,
CustomFormatType,
NumberSeparator,
Compact,
} from '@lightdash/common';
// Define custom format
const customFormat: CustomFormat = {
type: CustomFormatType.CURRENCY,
currency: 'USD',
round: 2,
separator: NumberSeparator.COMMA_PERIOD,
};
// Apply to value
const formatted = applyCustomFormat(1500000, customFormat);
// Returns: "$1,500,000.00"
// Get format from item and apply
const format = getCustomFormat(metric);
if (format) {
const value = applyCustomFormat(rawValue, format);
}Custom format expressions allow advanced formatting logic.
function formatValueWithExpression(
expression: string,
value: unknown
): string;
function hasValidFormatExpression(
item: Field | Metric | TableCalculation | undefined
): boolean;
function convertCustomFormatToFormatExpression(
customFormat: CustomFormat
): string | undefined;
function getFormatExpression(
item: Field | Metric | TableCalculation | undefined
): string | undefined;Example:
import {
formatValueWithExpression,
hasValidFormatExpression,
} from '@lightdash/common';
// Format with expression
const expression = 'IF(value > 1000, "High", "Low")';
const result = formatValueWithExpression(1500, expression);
// Returns: "High"
// Check if item has valid expression
if (hasValidFormatExpression(field)) {
const formatted = formatValueWithExpression(
value,
field.customFormat.expression
);
}
// Expression with parameters
const paramExpression = 'IF(value > ${threshold}, "Above", "Below")';
const withParams = formatValueWithExpression(
500,
paramExpression,
{ threshold: 1000 }
);
// Returns: "Below"Applies default formatting based on field type.
function applyDefaultFormat(
value: unknown
): string;Example:
import { applyDefaultFormat } from '@lightdash/common';
// Formats values with default formatting
// Returns '∅' for null, '-' for undefined, formats numbers with default options
const formatted = applyDefaultFormat(1234.5); // "1,234.5"
const nullFormatted = applyDefaultFormat(null); // "∅"
const undefinedFormatted = applyDefaultFormat(undefined); // "-"function valueIsNaN(value: unknown): boolean;
function isNumber(value: unknown): value is number;
function isMomentInput(value: unknown): value is moment.MomentInput;Utility functions for type checking values.
Example:
import { valueIsNaN, isNumber, isMomentInput } from '@lightdash/common';
if (isNumber(value) && !valueIsNaN(value)) {
// Safe to format as number
const formatted = formatNumberValue(value);
}
if (isMomentInput(dateValue)) {
// dateValue can be used with moment/dayjs
const formatted = formatDate(dateValue);
}Formats multiple rows of raw database values into ResultRow format with both raw and formatted values for each field.
/**
* Formats multiple rows from raw warehouse format to ResultRow format
* @param rows - Array of raw database rows (column name → raw value)
* @param itemsMap - Map of field definitions for formatting
* @param pivotValuesColumns - Optional pivot column configuration
* @param parameters - Optional parameter values for format expressions
* @returns Array of ResultRow with both raw and formatted values
*/
function formatRows(
rows: { [col: string]: any }[],
itemsMap: ItemsMap,
pivotValuesColumns?: Record<string, PivotValuesColumn> | null,
parameters?: Record<string, unknown>
): ResultRow[];Returns: Array of ResultRow objects with structure:
{
[columnName]: {
value: {
raw: unknown, // Raw value (with timestamp normalization)
formatted: string // Human-readable formatted string
}
}
}Example:
import {
formatRows,
getItemMap,
type MetricQueryResponse,
} from '@lightdash/common';
function displayQueryResults(response: MetricQueryResponse, explore: Explore) {
// Build items map
const itemsMap = getItemMap(
explore,
response.metricQuery.additionalMetrics,
response.metricQuery.tableCalculations,
response.metricQuery.customDimensions
);
// Format all rows from raw warehouse format
const rawRows = [
{
'customers_customer_id': 123,
'customers_total_revenue': 1234567.89,
'orders_created_at': '2024-01-15T10:30:00Z'
}
];
const formattedRows = formatRows(rawRows, itemsMap);
// Each row now has both raw and formatted values
formattedRows.forEach(row => {
Object.entries(row).forEach(([fieldId, cellValue]) => {
console.log(`${fieldId}:`);
console.log(` Raw: ${cellValue.value.raw}`);
console.log(` Formatted: ${cellValue.value.formatted}`);
});
});
return formattedRows;
}Formats a single row of raw database values into ResultRow format.
/**
* Formats a single row from raw warehouse format to ResultRow format
* @param row - Raw database row (column name → raw value)
* @param itemsMap - Map of field definitions for formatting
* @param pivotValuesColumns - Optional pivot column configuration
* @param parameters - Optional parameter values for format expressions
* @returns ResultRow with both raw and formatted values
*/
function formatRow(
row: { [col: string]: any },
itemsMap: ItemsMap,
pivotValuesColumns?: Record<string, PivotValuesColumn> | null,
parameters?: Record<string, unknown>
): ResultRow;Behavior:
formatRawValue() for the raw value (handles timestamp normalization)formatItemValue() for the formatted stringExample:
import { formatRow, getItemMap } from '@lightdash/common';
const rawRow = {
'customers_customer_id': 123,
'customers_total_revenue': 1234567.89,
'orders_created_at': '2024-01-15T10:30:00Z'
};
const itemsMap = getItemMap(explore, additionalMetrics, tableCalculations);
const formattedRow = formatRow(rawRow, itemsMap);
// Result structure:
// {
// 'customers_customer_id': {
// value: {
// raw: 123,
// formatted: '123'
// }
// },
// 'customers_total_revenue': {
// value: {
// raw: 1234567.89,
// formatted: '$1,234,567.89'
// }
// },
// 'orders_created_at': {
// value: {
// raw: '2024-01-15T10:30:00.000Z',
// formatted: 'January 15, 2024'
// }
// }
// }Formats raw database rows by normalizing raw values (primarily for timestamp handling) without creating the full ResultRow structure.
/**
* Formats raw values in rows (normalizes timestamps to UTC)
* @param rows - Array of raw database rows
* @param itemsMap - Map of field definitions
* @returns Array of rows with normalized raw values
*/
function formatRawRows(
rows: { [col: string]: any }[],
itemsMap: ItemsMap
): Record<string, unknown>[];Purpose: Normalizes raw values from the warehouse, particularly converting date/timestamp values to UTC format. This is used internally to ensure consistent raw value handling before full formatting.
Note: The comment in source code explains: "We format raw values so we can't use the values directly from the warehouse to compare with subtotals of date dimensions"
Example:
import { formatRawRows, getItemMap } from '@lightdash/common';
const rawRows = [
{ 'date_field': '2024-01-15T10:30:00Z', 'metric': 100 },
{ 'date_field': '2024-01-16T14:20:00Z', 'metric': 150 }
];
const itemsMap = getItemMap(explore);
const normalizedRows = formatRawRows(rawRows, itemsMap);
// Timestamps are normalized to UTC, other values pass through
// [
// { 'date_field': '2024-01-15T10:30:00.000Z', 'metric': 100 },
// { 'date_field': '2024-01-16T14:20:00.000Z', 'metric': 150 }
// ]Formats a single raw value, primarily handling timestamp conversion to UTC to avoid timezone issues.
/**
* Formats a raw value (normalizes timestamps to UTC)
* @param field - Field definition (can be Field, Metric, TableCalculation, or CustomDimension)
* @param value - Raw value to format
* @returns Normalized value (timestamps converted to UTC, others passed through)
*/
function formatRawValue(
field: Field | Metric | TableCalculation | CustomDimension | undefined,
value: any
): any;Behavior:
dayjs(value).utc(true).format() to avoid timezone issues in frontend (e.g., chart tooltips)Purpose: Ensures consistent timestamp handling across the application by normalizing all date/timestamp values to UTC format in the raw value representation.
Example:
import { formatRawValue } from '@lightdash/common';
// Timestamp field
const timestampField = {
type: DimensionType.TIMESTAMP,
// ... other field properties
};
const rawTimestamp = '2024-01-15T10:30:00Z';
const formatted = formatRawValue(timestampField, rawTimestamp);
// Returns: '2024-01-15T10:30:00.000Z' (normalized UTC)
// Non-timestamp field
const numberField = { type: DimensionType.NUMBER };
const rawNumber = 123.45;
const formatted2 = formatRawValue(numberField, rawNumber);
// Returns: 123.45 (unchanged)Functions for transforming query result data into formats suitable for visualization and analysis.
Converts result rows into an array of value objects, optionally calculating min/max values for each field and excluding null values.
function getResultValueArray(
rows: ResultRow[],
preferRaw?: boolean,
calculateMinAndMax?: boolean,
excludeNulls?: boolean
): {
results: Record<string, unknown>[];
minsAndMaxes?: Record<string, { min: number; max: number }>;
};Parameters:
Returns: Object containing:
Example:
import { getResultValueArray, type ResultRow } from '@lightdash/common';
const queryResults: ResultRow[] = [
{
'customers.revenue': { value: { raw: 1000, formatted: '$1,000' } },
'customers.orders': { value: { raw: 5, formatted: '5' } },
},
{
'customers.revenue': { value: { raw: 2500, formatted: '$2,500' } },
'customers.orders': { value: { raw: 10, formatted: '10' } },
},
];
// Get formatted values with min/max calculation
const { results, minsAndMaxes } = getResultValueArray(
queryResults,
false, // Use formatted values
true, // Calculate min/max
false // Include nulls
);
// results = [
// { 'customers.revenue': '$1,000', 'customers.orders': '5' },
// { 'customers.revenue': '$2,500', 'customers.orders': '10' }
// ]
//
// minsAndMaxes = {
// 'customers.revenue': { min: 1000, max: 2500 },
// 'customers.orders': { min: 5, max: 10 }
// }
// Get raw values without min/max
const { results: rawResults } = getResultValueArray(
queryResults,
true, // Use raw values
false // Don't calculate min/max
);
// rawResults = [
// { 'customers.revenue': 1000, 'customers.orders': 5 },
// { 'customers.revenue': 2500, 'customers.orders': 10 }
// ]Extracts a clean label from a date or timestamp dimension that has been grouped by a time interval, removing the time interval suffix from the label.
function getDateGroupLabel(axisItem: ItemsMap[string]): string | undefined;Parameters:
Returns: Clean label string with time interval removed, or undefined if the item is not a grouped date/timestamp dimension
Example:
import { getDateGroupLabel, type Dimension, DimensionType, FieldType, TimeFrames } from '@lightdash/common';
const dateDimension: Dimension = {
fieldType: FieldType.DIMENSION,
type: DimensionType.DATE,
name: 'created_at',
label: 'Order created day',
table: 'orders',
tableLabel: 'Orders',
sql: '${TABLE}.created_at',
timeInterval: TimeFrames.DAY,
group: 'day',
// ... other properties
};
const label = getDateGroupLabel(dateDimension);
// Returns: "Order created" (removes " day" suffix)
const monthDimension: Dimension = {
// ...
label: 'Customer signup month',
timeInterval: TimeFrames.MONTH,
group: 'month',
};
const monthLabel = getDateGroupLabel(monthDimension);
// Returns: "Customer signup" (removes " month" suffix)Determines the appropriate name for a chart axis based on series configuration, axis settings, and field metadata. Handles both single and multiple series scenarios.
function getAxisName(params: {
isAxisTheSameForAllSeries: boolean;
selectedAxisIndex: number;
axisReference: 'yRef' | 'xRef';
axisIndex: number;
axisName?: string;
series?: Series[];
itemsMap: ItemsMap | undefined;
}): string | undefined;Parameters:
Returns: Axis name string, or undefined if no appropriate name can be determined
Example:
import { getAxisName, type Series, type ItemsMap } from '@lightdash/common';
const series: Series[] = [
{
name: 'Revenue',
encode: {
xRef: { field: 'customers.created_at' },
yRef: { field: 'customers.revenue' },
},
// ... other properties
},
];
const itemsMap: ItemsMap = {
'customers.revenue': {
fieldType: FieldType.METRIC,
name: 'revenue',
label: 'Total Revenue',
// ...
},
'customers.created_at': {
fieldType: FieldType.DIMENSION,
type: DimensionType.DATE,
label: 'Customer created day',
timeInterval: TimeFrames.DAY,
// ...
},
};
// Get y-axis name
const yAxisName = getAxisName({
isAxisTheSameForAllSeries: true,
selectedAxisIndex: 0,
axisReference: 'yRef',
axisIndex: 0,
series,
itemsMap,
});
// Returns: "Revenue" (from series name)
// Get x-axis name with date grouping
const xAxisName = getAxisName({
isAxisTheSameForAllSeries: true,
selectedAxisIndex: 0,
axisReference: 'xRef',
axisIndex: 0,
series,
itemsMap,
});
// Returns: "Customer created" (date group label with time interval removed)
// With explicit axis name
const customAxisName = getAxisName({
isAxisTheSameForAllSeries: true,
selectedAxisIndex: 0,
axisReference: 'yRef',
axisIndex: 0,
axisName: 'Sales Performance',
series,
itemsMap,
});
// Returns: "Sales Performance" (uses explicit name)import {
formatItemValue,
type Metric,
CustomFormatType,
NumberSeparator,
Compact,
} from '@lightdash/common';
const revenueMetric: Metric = {
// ... field properties
formatOptions: {
type: CustomFormatType.CURRENCY,
currency: 'USD',
round: 2,
separator: NumberSeparator.COMMA_PERIOD,
},
};
const formatted = formatItemValue(revenueMetric, 1234567.89);
// Returns: "$1,234,567.89"
// Note: compact property is not currently implemented
// Values are formatted with full precision according to round and separator settingsimport {
formatItemValue,
type Metric,
CustomFormatType,
} from '@lightdash/common';
const percentMetric: Metric = {
// ... field properties
formatOptions: {
type: CustomFormatType.PERCENT,
round: 1,
},
};
// Value is 0.75 (75%)
const formatted = formatItemValue(percentMetric, 0.75);
// Returns: "75.0%"import {
formatItemValue,
type Dimension,
DimensionType,
TimeFrames,
} from '@lightdash/common';
const dateDimension: Dimension = {
// ... field properties
type: DimensionType.DATE,
timeInterval: TimeFrames.DAY,
};
const formatted = formatItemValue(dateDimension, '2024-01-15');
// Returns: "January 15, 2024" (based on day interval)
const monthDimension: Dimension = {
// ... field properties
type: DimensionType.DATE,
timeInterval: TimeFrames.MONTH,
};
const monthFormatted = formatItemValue(monthDimension, '2024-01-15');
// Returns: "January 2024"import {
type Metric,
CustomFormatType,
} from '@lightdash/common';
const statusMetric: Metric = {
// ... field properties
formatOptions: {
type: CustomFormatType.NUMBER,
expression: `
IF(value >= 90, "Excellent",
IF(value >= 75, "Good",
IF(value >= 60, "Fair", "Poor")
)
)
`,
},
};
const formatted = formatItemValue(statusMetric, 85);
// Returns: "Good"import {
formatItemValue,
type Dimension,
CustomFormatType,
} from '@lightdash/common';
const idDimension: Dimension = {
// ... field properties
customFormat: {
type: CustomFormatType.ID,
},
};
// IDs are not formatted with separators
const formatted = formatItemValue(idDimension, 1234567);
// Returns: "1234567" (no thousand separators)import {
formatRows,
formatItemValue,
getItemMap,
type MetricQueryResponse,
} from '@lightdash/common';
function formatAndDisplayResults(
response: MetricQueryResponse,
explore: Explore
) {
const itemsMap = getItemMap(
explore,
response.metricQuery.additionalMetrics,
response.metricQuery.tableCalculations,
response.metricQuery.customDimensions
);
// Format all rows at once
const formattedRows = formatRows(response.rows, itemsMap);
// Display formatted results
formattedRows.forEach(row => {
console.log('Row:');
Object.entries(row).forEach(([fieldId, cellValue]) => {
const item = itemsMap[fieldId];
console.log(` ${item?.label || fieldId}: ${cellValue.formatted}`);
});
});
return formattedRows;
}Conditional formatting functions for creating and applying color-based formatting rules to visualizations.
function createConditionalFormattingRuleWithValues(): ConditionalFormattingWithFilterOperator;
function createConditionalFormattingRuleWithCompareTarget(): ConditionalFormattingWithCompareTarget;
function createConditionalFormattingRuleWithCompareTargetValues(): ConditionalFormattingWithCompareTarget;Create conditional formatting rules with different comparison strategies.
Example:
import {
createConditionalFormattingRuleWithValues,
createConditionalFormattingRuleWithCompareTarget,
FilterOperator,
} from '@lightdash/common';
// Rule comparing field to specific values
const valueRule = createConditionalFormattingRuleWithValues();
valueRule.operator = FilterOperator.GREATER_THAN;
valueRule.values = [100];
// Rule comparing field to another field
const compareRule = createConditionalFormattingRuleWithCompareTarget();
compareRule.operator = FilterOperator.GREATER_THAN;
compareRule.compareTarget = { fieldId: 'customers.budget' };
// Rule comparing target field to values
const compareWithValuesRule = createConditionalFormattingRuleWithCompareTargetValues();
compareWithValuesRule.operator = FilterOperator.EQUALS;
compareWithValuesRule.compareTarget = { fieldId: 'orders.status' };
compareWithValuesRule.values = ['completed', 'shipped'];function createConditionalFormattingConfigWithSingleColor(
defaultColor: string,
target: FieldTarget | null = null
): ConditionalFormattingConfigWithSingleColor;
function createConditionalFormattingConfigWithColorRange(
defaultColor: string,
target: FieldTarget | null = null
): ConditionalFormattingConfigWithColorRange;Create conditional formatting configurations with single colors or color ranges.
Example:
import {
createConditionalFormattingConfigWithSingleColor,
createConditionalFormattingConfigWithColorRange,
} from '@lightdash/common';
// Single color config (e.g., highlight high values in red)
const singleColorConfig = createConditionalFormattingConfigWithSingleColor(
'#FF0000',
{ fieldId: 'customers.total_revenue' }
);
// Color range config (e.g., gradient from white to blue)
const colorRangeConfig = createConditionalFormattingConfigWithColorRange(
'#0000FF',
{ fieldId: 'orders.quantity' }
);
// Default range: white (#ffffff) to specified colorfunction hasPercentageFormat(
field: ItemsMap[string] | undefined
): boolean;
function convertFormattedValue<T>(
value: T,
field: ItemsMap[string] | undefined
): T | number;Check for percentage formatting and convert values accordingly.
Example:
import { hasPercentageFormat, convertFormattedValue } from '@lightdash/common';
// Check if field has percentage format
if (hasPercentageFormat(field)) {
// Convert 0.75 to 75 for percentage display
const converted = convertFormattedValue(0.75, field);
// Returns: 75
}function getMinMaxFromMinMaxMap(
minMaxMap: ConditionalFormattingMinMaxMap
): ConditionalFormattingMinMax;Extract overall min and max values from a min/max map.
Example:
import { getMinMaxFromMinMaxMap } from '@lightdash/common';
const minMaxMap = {
'customers.revenue': { min: 100, max: 10000 },
'customers.orders': { min: 1, max: 500 },
};
const overall = getMinMaxFromMinMaxMap(minMaxMap);
// Returns: { min: 1, max: 10000 }function hasMatchingConditionalRules(
field: ItemsMap[string],
value: unknown,
minMaxMap: ConditionalFormattingMinMaxMap,
config: ConditionalFormattingConfig | undefined,
rowFields?: ConditionalFormattingRowFields
): boolean;
function getConditionalFormattingConfig(args: {
field: ItemsMap[string] | undefined;
value: unknown | undefined;
minMaxMap: ConditionalFormattingMinMaxMap | undefined;
conditionalFormattings: ConditionalFormattingConfig[] | undefined;
rowFields?: ConditionalFormattingRowFields;
}): ConditionalFormattingConfig | undefined;Check if a value matches conditional formatting rules.
Example:
import {
hasMatchingConditionalRules,
getConditionalFormattingConfig,
} from '@lightdash/common';
const configs = [highValueConfig, lowValueConfig];
// Find matching config for a value
const matchingConfig = getConditionalFormattingConfig(
field,
value,
minMaxMap,
configs,
rowFields
);
if (matchingConfig) {
console.log('Value matches conditional formatting rules');
}
// Check if specific config matches
if (hasMatchingConditionalRules(field, value, minMaxMap, highValueConfig)) {
console.log('Value matches high value rules');
}function getConditionalFormattingColor(args: {
field: ItemsMap[string] | undefined;
value: unknown;
config: ConditionalFormattingConfig | undefined;
minMaxMap: ConditionalFormattingMinMaxMap | undefined;
getColorFromRange: (args: {
color: ConditionalFormattingColorRange;
min: number;
max: number;
value: number;
}) => string;
}): string | undefined;
function getConditionalFormattingColorWithSingleColor(args: {
config: ConditionalFormattingConfigWithSingleColor;
}): string;
function getConditionalFormattingColorWithColorRange(args: {
field: ItemsMap[string] | undefined;
value: unknown;
config: ConditionalFormattingConfigWithColorRange;
minMaxMap: ConditionalFormattingMinMaxMap | undefined;
getColorFromRange: (args: {
color: ConditionalFormattingColorRange;
min: number;
max: number;
value: number;
}) => string;
}): string | undefined;Get the appropriate color for a value based on conditional formatting config.
Example:
import {
getConditionalFormattingColor,
getConditionalFormattingColorWithSingleColor,
getConditionalFormattingColorWithColorRange,
} from '@lightdash/common';
// Get color for any config type
const color = getConditionalFormattingColor(
field,
1500,
minMaxMap,
config,
rowFields
);
// Get color from single color config
if (isSingleColorConfig(config)) {
const singleColor = getConditionalFormattingColorWithSingleColor(config);
// Returns: the configured color (e.g., '#FF0000')
}
// Get color from color range config (gradient)
if (isColorRangeConfig(config)) {
const rangeColor = getConditionalFormattingColorWithColorRange(
field,
75,
minMaxMap,
config
);
// Returns: interpolated color based on value position in range
}function getConditionalFormattingDescription(
config: ConditionalFormattingConfig
): string;Get human-readable description of conditional formatting rules.
Example:
import { getConditionalFormattingDescription } from '@lightdash/common';
const description = getConditionalFormattingDescription(config);
// Returns: "Color red when value is greater than 100"class ConditionalFormattingError extends LightdashError {
constructor(message: string);
}Error class for conditional formatting validation and application errors.
Example:
import { ConditionalFormattingError } from '@lightdash/common';
throw new ConditionalFormattingError(
'Invalid conditional formatting configuration'
);import {
createConditionalFormattingConfigWithSingleColor,
createConditionalFormattingRuleWithValues,
getConditionalFormattingColor,
FilterOperator,
type ItemsMap,
} from '@lightdash/common';
// Create a config to highlight high revenue in green
const highRevenueConfig = createConditionalFormattingConfigWithSingleColor(
'#00FF00',
{ fieldId: 'customers.total_revenue' }
);
// Add rule: revenue > 10000
const highRevenueRule = createConditionalFormattingRuleWithValues();
highRevenueRule.operator = FilterOperator.GREATER_THAN;
highRevenueRule.values = [10000];
highRevenueConfig.rules = [highRevenueRule];
// Apply conditional formatting to table cells
function applyCellFormatting(
field: ItemsMap[string],
value: number,
minMaxMap: ConditionalFormattingMinMaxMap
) {
const color = getConditionalFormattingColor(
field,
value,
minMaxMap,
highRevenueConfig
);
if (color) {
return { value, backgroundColor: color };
}
return { value };
}
// Use in rendering
const formattedCell = applyCellFormatting(revenueField, 15000, minMaxMap);
// Returns: { value: 15000, backgroundColor: '#00FF00' }