This module provides utilities for working with queries, charts, dashboards, and the Metrics Explorer feature. It includes result transformation, chart configuration, axis management, metrics exploration, custom dimension/metric conversion, and subtotal handling.
This module provides the following functionality:
Functions for working with chart configurations.
// From utils/charts.ts
function maybeReplaceFieldsInChartVersion(params: {
fieldsToReplace: ReplaceCustomFields[string];
chartVersion: CreateSavedChartVersion;
}): {
hasChanges: boolean;
chartVersion: CreateSavedChartVersion;
skippedFields: SkippedReplaceCustomFields[string];
};
/**
* Extract custom column labels from table visualization configuration
* @param config - Table visualization configuration
* @returns Object mapping field IDs to custom labels
*/
function getCustomLabelsFromVizTableConfig(
config: VizTableConfig | undefined
): Record<string, string>;
/**
* Get list of hidden field IDs from table visualization configuration
* @param config - Table visualization configuration
* @returns Array of field IDs that should be hidden
*/
function getHiddenFieldsFromVizTableConfig(
config: VizTableConfig | undefined
): string[];
/**
* Get the column order from table visualization configuration
* @param config - Table visualization configuration
* @returns Array of field IDs in the order they should be displayed
*/
function getColumnOrderFromVizTableConfig(
config: VizTableConfig | undefined
): string[];Functions for working with dashboards.
// From utils/dashboard.ts
/**
* Converts chart source type to dashboard tile type
* @param sourceType - ChartSourceType (DBT_EXPLORE or SQL)
* @returns Corresponding DashboardTileTypes (SAVED_CHART or SQL_CHART)
*/
function convertChartSourceTypeToDashboardTileType(
sourceType: ChartSourceType
): DashboardTileTypes;
/**
* Validates that selected tabs exist in dashboard tiles
* @param dashboard - Dashboard to validate
* @param selectedTabs - Tab UUIDs to check
* @throws ParameterError if no selected tabs exist in dashboard
*/
function validateSelectedTabs(
dashboard: Dashboard,
selectedTabs: string[]
): void;Functions for creating and working with field and item maps from explores.
/**
* Create a map of all fields in an explore by field ID
* @param explore - Explore object containing tables and fields
* @param additionalMetrics - Optional array of additional metrics to include
* @returns Record mapping field IDs to CompiledField or AdditionalMetric
*/
function getFieldMap(
explore: Explore,
additionalMetrics?: AdditionalMetric[]
): Record<string, CompiledField | AdditionalMetric>;
/**
* Create a complete items map including fields, metrics, table calculations, and custom dimensions
* @param explore - Explore object containing tables and fields
* @param additionalMetrics - Optional array of additional metrics to include
* @param tableCalculations - Optional array of table calculations to include
* @param customDimensions - Optional array of custom dimensions to include
* @returns ItemsMap containing all items indexed by their IDs
*/
function getItemMap(
explore: Explore,
additionalMetrics?: AdditionalMetric[],
tableCalculations?: TableCalculation[],
customDimensions?: CustomDimension[]
): ItemsMap;
/**
* Extract only dimensions (including custom dimensions) from an items map
* @param itemsMap - Complete items map
* @returns Record of dimensions and custom dimensions only
*/
function getDimensionsFromItemsMap(
itemsMap: ItemsMap
): Record<string, Dimension | CustomDimension>;
/**
* Extract only metrics from an items map with optional filtering
* @param itemsMap - Complete items map
* @param filter - Optional filter function to apply to metrics
* @returns Record of metrics only
*/
function getMetricsFromItemsMap(
itemsMap: ItemsMap,
filter?: (value: ItemsMap[string]) => boolean
): Record<string, Metric>;
/**
* Extract only table calculations from an items map
* @param itemsMap - Complete items map
* @returns Record of table calculations only
*/
function getTableCalculationsFromItemsMap(
itemsMap?: ItemsMap
): Record<string, TableCalculation>;
/**
* Generate a hash string for a pivot reference for caching and lookup purposes
* Combines field ID with pivot values to create a unique identifier
* @param reference - Pivot reference object containing field and optional pivot values
* @returns Hash string in format "field" or "field.pivotField1.value1.pivotField2.value2"
*/
function hashFieldReference(reference: PivotReference): string;Example:
import {
getFieldMap,
getItemMap,
getDimensionsFromItemsMap,
getMetricsFromItemsMap,
getTableCalculationsFromItemsMap,
} from '@lightdash/common';
// Get field map (dimensions and metrics only)
const fieldMap = getFieldMap(explore, additionalMetrics);
const customerNameField = fieldMap['customers_customer_name'];
// Get complete items map with all types
const itemsMap = getItemMap(
explore,
additionalMetrics,
tableCalculations,
customDimensions
);
// Extract dimensions only
const dimensions = getDimensionsFromItemsMap(itemsMap);
console.log(Object.keys(dimensions));
// ['customers_customer_id', 'customers_customer_name', 'orders_order_date', ...]
// Extract metrics only
const metrics = getMetricsFromItemsMap(itemsMap);
console.log(Object.keys(metrics));
// ['orders_total_revenue', 'customers_count', ...]
// Extract metrics with custom filter
const numericMetrics = getMetricsFromItemsMap(
itemsMap,
(metric) => isMetric(metric) && metric.type === MetricType.NUMBER
);
// Extract table calculations
const tableCalcs = getTableCalculationsFromItemsMap(itemsMap);
console.log(Object.keys(tableCalcs));
// ['growth_rate', 'percent_of_total', ...]Functions for transforming and working with query result data.
function getResultValueArray(
rows: ResultRow[],
preferRaw?: boolean,
calculateMinAndMax?: boolean,
excludeNulls?: boolean
): {
results: Record<string, unknown>[];
minsAndMaxes?: Record<string, { min: number; max: number }>;
};
function formatRawValue(
field: Field | Metric | TableCalculation | CustomDimension | undefined,
value: AnyType
): AnyType;
function formatRawRows(
rows: { [col: string]: AnyType }[],
itemsMap: ItemsMap
): Record<string, unknown>[];
function formatRow(
row: { [col: string]: AnyType },
itemsMap: ItemsMap,
pivotValuesColumns?: Record<string, PivotValuesColumn> | null,
parameters?: Record<string, unknown>
): ResultRow;
function formatRows(
rows: { [col: string]: AnyType }[],
itemsMap: ItemsMap,
pivotValuesColumns?: Record<string, PivotValuesColumn> | null,
parameters?: Record<string, unknown>
): ResultRow[];
/**
* Extracts all field IDs from a metric query
* @param metricQuery - Optional metric query object
* @returns Array of field IDs including metrics, dimensions, and table calculation names
*/
function itemsInMetricQuery(metricQuery?: MetricQuery): string[];Example:
import {
getResultValueArray,
formatRawValue,
formatRawRows,
formatRow,
formatRows,
itemsInMetricQuery
} from '@lightdash/common';
// Extract values from result rows with min/max calculation
const { results, minsAndMaxes } = getResultValueArray(
resultRows,
true, // preferRaw
true, // calculateMinAndMax
false // excludeNulls
);
// Format a single raw value (handles date/timestamp UTC conversion)
const formatted = formatRawValue(field, rawValue);
// Format raw rows to records
const formattedRows = formatRawRows(rawRows, itemsMap);
// Format a single row with pivot support
const row = formatRow(rawRow, itemsMap, pivotValuesColumns, parameters);
// Format multiple rows
const rows = formatRows(rawRows, itemsMap, pivotValuesColumns, parameters);
// Get all field IDs used in a metric query
const fieldIds = itemsInMetricQuery(metricQuery);
// Returns: [...metrics, ...dimensions, ...tableCalculation names]
// Handle undefined metric query
const emptyFieldIds = itemsInMetricQuery(undefined);
// Returns: []
// Example with a complete metric query
const query: MetricQuery = {
exploreName: 'orders',
dimensions: ['customers.country', 'customers.city'],
metrics: ['orders.total_revenue', 'orders.count'],
tableCalculations: [
{ name: 'revenue_per_order', displayName: 'Revenue per Order', sql: '${orders.total_revenue} / ${orders.count}' }
],
filters: {},
sorts: [],
limit: 100
};
const allFieldIds = itemsInMetricQuery(query);
// Returns: ['orders.total_revenue', 'orders.count', 'customers.country', 'customers.city', 'revenue_per_order']Functions for working with chart axis labels and configurations.
function getDateGroupLabel(axisItem: ItemsMap[string]): string | undefined;
function getAxisName(options: {
isAxisTheSameForAllSeries: boolean;
selectedAxisIndex: number;
axisReference: 'yRef' | 'xRef';
axisIndex: number;
axisName?: string;
series?: Series[];
itemsMap: ItemsMap | undefined;
}): string | undefined;Example:
import { getDateGroupLabel, getAxisName } from '@lightdash/common';
// Get label for date-grouped dimension
const label = getDateGroupLabel(axisItem);
// For "Order created day" returns "Order created"
// Get appropriate axis name based on series configuration
const axisLabel = getAxisName({
isAxisTheSameForAllSeries: false,
selectedAxisIndex: 0,
axisReference: 'yRef',
axisIndex: 0,
axisName: 'Revenue',
series: chartSeries,
itemsMap: explore.itemsMap
});function getSubtotalKey(dimensions: string[]): string;Generates a unique key for subtotal rows based on dimension field IDs.
Example:
import { getSubtotalKey } from '@lightdash/common';
const dimensions = ['customers.country', 'customers.city'];
const key = getSubtotalKey(dimensions);
// Returns unique key for this dimension combinationUtilities for the Metrics Explorer feature including time dimension helpers, date range filters, and data point extraction.
/**
* Throws error for unsupported timeframes in Metrics Explorer
*/
function assertUnimplementedTimeframe(timeframe: UnimplementedTimeframe): never;
/**
* Gets field ID for a date dimension at a specific timeframe
* @param fieldId - Base field ID
* @param timeframe - Time granularity (DAY, WEEK, MONTH, YEAR)
* @returns Suffixed field ID like "created_at_day", "created_at_month"
*/
function getFieldIdForDateDimension(fieldId: string, timeframe: TimeFrames): string;
/**
* Gets date calculation utilities for forward/backward date navigation
* @param timeFrame - Primary timeframe for calculation
* @param grain - Optional granularity for the calculation
* @returns Object with forward() and back() functions for date manipulation
*/
function getDateCalcUtils(
timeFrame: TimeFrames,
grain?: TimeFrames
): {
forward: (date: Date) => Date;
back: (date: Date) => Date;
};
/**
* Date format constant for Metrics Explorer
*/
const METRICS_EXPLORER_DATE_FORMAT: 'YYYY-MM-DD';
/**
* Converts string date range to Date objects
* @param dateRange - Tuple of date strings [start, end]
* @param timeFrame - Time granularity
* @returns Tuple of Date objects
*/
function getDateRangeFromString(
dateRange: [string, string],
timeFrame: TimeFrames
): [Date, Date];
/**
* Determines appropriate granularity for a date range
* @param dateRange - Date range to analyze
* @returns Suggested TimeFrame for the range
*/
function getGrainForDateRange(dateRange: MetricExplorerDateRange): TimeFrames;
/**
* Creates segment dimension filters for Metrics Explorer
* @param segmentDimension - Dimension to segment by
* @param values - Values to filter on
* @returns Filter rules for the segments
*/
function getMetricsExplorerSegmentFilters(
segmentDimension: CompiledDimension | undefined,
values: string[]
): FilterRule[];
/**
* Creates date range filters for Metrics Explorer queries
* @param timeDimensionBaseField - Base time dimension
* @param dateRange - Date range to filter on
* @param timeInterval - Time granularity
* @returns Filter rules for the date range
*/
function getMetricExplorerDateRangeFilters(
timeDimensionBaseField: string | undefined,
dateRange: MetricExplorerDateRange,
timeInterval: TimeFrames
): FilterRule[];
/**
* Parses metric value from unknown type to number or null
* @param value - Value to parse
* @returns Parsed number or null if invalid
*/
function parseMetricValue(value: unknown): number | null;
/**
* Maximum unique values for segment dimensions
*/
const MAX_SEGMENT_DIMENSION_UNIQUE_VALUES: 10;
/**
* Extracts data points from query results for Metrics Explorer
* @param rows - Query result rows
* @param query - Metrics Explorer query
* @returns Array of metric data points
*/
function getMetricExplorerDataPoints(
rows: ResultRow[],
query: MetricExplorerQuery
): MetricExploreDataPoint[];
/**
* Extracts data points with comparison data
* @param rows - Query result rows
* @param query - Metrics Explorer query with comparison
* @returns Array of metric data points with comparison values
*/
function getMetricExplorerDataPointsWithCompare(
rows: ResultRow[],
query: MetricExplorerQuery
): MetricExploreDataPoint[];
/**
* Gets default date range based on time interval
* @param interval - Time interval
* @returns Default date range for the interval
*/
function getDefaultDateRangeFromInterval(interval: TimeFrames): MetricExplorerDateRange;
/**
* Gets default date range for metric tree node
* @param interval - Time interval
* @returns Default date range
*/
function getDefaultMetricTreeNodeDateRange(interval: TimeFrames): MetricExplorerDateRange;
/**
* Default time interval for Metrics Explorer
*/
const DEFAULT_METRICS_EXPLORER_TIME_INTERVAL: TimeFrames.MONTH;
/**
* Gets first available time dimension from tables
* @param tables - Compiled table map
* @returns First available time dimension or undefined
*/
function getFirstAvailableTimeDimension(
tables: Record<string, CompiledTable>
): DefaultTimeDimension | undefined;
/**
* Gets default time dimension for an explore
* @param tables - Compiled table map
* @returns Default time dimension configuration
*/
function getDefaultTimeDimension(
tables: Record<string, CompiledTable>
): DefaultTimeDimension | undefined;
/**
* Gets all available time dimensions from tables
* @param tables - Compiled table map
* @returns Array of time dimensions
*/
function getAvailableTimeDimensionsFromTables(
tables: Record<string, CompiledTable>
): CompiledDimension[];
/**
* Gets available segment dimensions (non-date dimensions)
* @param tables - Compiled table map
* @returns Array of dimensions suitable for segmentation
*/
function getAvailableSegmentDimensions(
tables: Record<string, CompiledTable>
): CompiledDimension[];
/**
* Gets metrics available for comparison in Metrics Explorer
* @param tables - Compiled table map
* @param currentMetric - Currently selected metric
* @returns Array of metrics that can be compared
*/
function getAvailableCompareMetrics(
tables: Record<string, CompiledTable>,
currentMetric?: MetricWithAssociatedTimeDimension
): CompiledMetric[];Example:
import {
getFieldIdForDateDimension,
getMetricExplorerDateRangeFilters,
parseMetricValue,
TimeFrames,
} from '@lightdash/common';
// Get time-granular field ID
const monthlyFieldId = getFieldIdForDateDimension('orders.created_at', TimeFrames.MONTH);
// Returns: 'orders.created_at_month'
// Create date range filters
const filters = getMetricExplorerDateRangeFilters(
'orders.created_at',
{
from: new Date('2024-01-01'),
to: new Date('2024-12-31'),
},
TimeFrames.MONTH
);
// Parse metric values safely
const value = parseMetricValue('123.45'); // Returns: 123.45
const invalid = parseMetricValue('invalid'); // Returns: nullCore types for the metrics explorer feature.
/**
* Comparison modes for metrics explorer
*/
enum MetricExplorerComparison {
NONE = 'none',
PREVIOUS_PERIOD = 'previous_period',
DIFFERENT_METRIC = 'different_metric',
}
/**
* Partial date range where start or end can be null (for in-progress selection)
*/
type MetricExplorerPartialDateRange = [Date | null, Date | null];
/**
* Complete date range for metrics explorer
*/
type MetricExplorerDateRange = [Date, Date];
/**
* Discriminated union for metrics explorer query configuration
*/
type MetricExplorerQuery =
| {
comparison: MetricExplorerComparison.NONE;
segmentDimension: string | null;
}
| {
comparison: MetricExplorerComparison.PREVIOUS_PERIOD;
}
| {
comparison: MetricExplorerComparison.DIFFERENT_METRIC;
metric: {
label: string;
table: string;
name: string;
};
};
/**
* Individual data point in metrics explorer results
*/
type MetricExploreDataPoint = {
date: Date;
segment: string | null;
metric: {
value: number | null;
label: string | null;
};
compareMetric: {
value: number | null;
label: string | null;
};
};
/**
* Data point with numeric date value for charting
*/
type MetricExploreDataPointWithDateValue = MetricExploreDataPoint & {
dateValue: number;
};
/**
* Complete results from metrics explorer query
*/
type MetricsExplorerQueryResults = {
metric: MetricWithAssociatedTimeDimension;
compareMetric: MetricWithAssociatedTimeDimension | null;
segmentDimension: Dimension | null;
fields: ItemsMap;
results: MetricExploreDataPointWithDateValue[];
hasFilteredSeries: boolean;
};
/**
* API response wrapper for metrics explorer query
*/
type ApiMetricsExplorerQueryResults = {
status: 'ok';
results: MetricsExplorerQueryResults;
};
/**
* Comparison types for metric totals
*/
enum MetricTotalComparisonType {
NONE = 'none',
PREVIOUS_PERIOD = 'previous_period',
}
/**
* Total value results for a metric
*/
type MetricTotalResults = {
value: number | null;
comparisonValue: number | null;
metric: MetricWithAssociatedTimeDimension;
};
/**
* API response wrapper for metrics explorer total
*/
type ApiMetricsExplorerTotalResults = {
status: 'ok';
results: MetricTotalResults;
};Utilities for working with the metrics explorer feature, including date range calculations, time dimension management, and segment filtering.
/**
* Asserts that a timeframe is not implemented for metrics explorer.
* Throws an error for unsupported timeframes.
* @param timeframe - The timeframe to check
* @throws Error if timeframe is not supported
*/
function assertUnimplementedTimeframe(timeframe: TimeFrames): never;
/**
* Gets the field ID for a date dimension with the specified timeframe.
* @param fieldId - Base field ID
* @param timeframe - Time granularity (DAY, WEEK, MONTH, YEAR)
* @returns Field ID with timeframe suffix (e.g., "created_at_day")
*/
function getFieldIdForDateDimension(fieldId: string, timeframe: TimeFrames): string;
/**
* Gets date calculation utilities for forward/back navigation in time.
* @param timeFrame - The timeframe to navigate (MONTH, YEAR)
* @param grain - Optional grain for sub-period navigation
* @returns Object with forward() and back() functions for date manipulation
*/
function getDateCalcUtils(
timeFrame: TimeFrames,
grain?: TimeFrames
): { forward: (date: Date) => Date; back: (date: Date) => Date };
/**
* Date format constant for metrics explorer date strings.
*/
const METRICS_EXPLORER_DATE_FORMAT: string; // "YYYY-MM-DD"
/**
* Parses date range from string array to Date array.
* @param dateRange - Array of two date strings in METRICS_EXPLORER_DATE_FORMAT
* @returns Array of two Date objects
*/
function getDateRangeFromString(dateRange: [string, string]): MetricExplorerDateRange;
/**
* Determines appropriate time grain based on date range span.
* @param dateRange - Start and end dates
* @returns Recommended timeframe (DAY, WEEK, MONTH, or YEAR)
*/
function getGrainForDateRange(dateRange: [Date, Date]): TimeFrames;
/**
* Creates filter rules for metric explorer segments.
* @param segmentDimension - Dimension to segment by
* @param segments - Array of segment values to filter
* @returns Array of filter rules
*/
function getMetricsExplorerSegmentFilters(
segmentDimension: string | null,
segments: string[]
): FilterRule[];
/**
* Creates date range filter rules for metric explorer.
* @param timeDimensionConfig - Time dimension configuration
* @param dateRange - Start and end dates
* @returns Array of date filter rules
*/
function getMetricExplorerDateRangeFilters(
timeDimensionConfig: TimeDimensionConfig,
dateRange: MetricExplorerDateRange
): FilterRule[];
/**
* Parses a value to a number for metric calculations.
* @param value - Value to parse
* @returns Number or null if not parseable
*/
function parseMetricValue(value: unknown): number | null;
/**
* Maximum number of unique values for segment dimensions.
*/
const MAX_SEGMENT_DIMENSION_UNIQUE_VALUES: number; // 10
/**
* Gets metric data points from query results.
* @param results - Result rows from query
* @param timeDimensionConfig - Time dimension configuration
* @param metricQuery - Metric query definition
* @returns Array of metric data points
*/
function getMetricExplorerDataPoints(
results: ResultRow[],
timeDimensionConfig: TimeDimensionConfig,
metricQuery: MetricExplorerQuery
): MetricExploreDataPoint[];
/**
* Gets metric data points with comparison data.
* @param results - Result rows from query
* @param compareResults - Comparison period result rows
* @param timeDimensionConfig - Time dimension configuration
* @param metricQuery - Metric query definition
* @returns Array of metric data points with comparison values
*/
function getMetricExplorerDataPointsWithCompare(
results: ResultRow[],
compareResults: ResultRow[],
timeDimensionConfig: TimeDimensionConfig,
metricQuery: MetricExplorerQuery
): MetricExploreDataPoint[];
/**
* Gets default date range from a time interval.
* @param interval - Time interval (e.g., MONTH, YEAR)
* @returns Default date range for the interval
*/
function getDefaultDateRangeFromInterval(interval: TimeFrames): MetricExplorerDateRange;
/**
* Gets default date range for metric tree nodes.
* @returns Default date range for metric tree visualization
*/
function getDefaultMetricTreeNodeDateRange(): MetricExplorerDateRange;
/**
* Default time interval for metrics explorer.
*/
const DEFAULT_METRICS_EXPLORER_TIME_INTERVAL: TimeFrames; // TimeFrames.MONTH
/**
* Time dimension configuration type.
*/
type TimeDimensionConfig = DefaultTimeDimension & { table: string };
/**
* Gets the first available time dimension from explore.
* @param explore - Explore to search
* @returns First time dimension found, or undefined
*/
function getFirstAvailableTimeDimension(explore: Explore): CompiledDimension | undefined;
/**
* Gets the default time dimension for an explore.
* @param explore - Explore to search
* @returns Default or first available time dimension
*/
function getDefaultTimeDimension(explore: Explore): CompiledDimension | undefined;
/**
* Gets all available time dimensions from explore tables.
* @param tables - Explore tables
* @returns Array of time dimension configurations
*/
function getAvailableTimeDimensionsFromTables(
tables: Record<string, CompiledTable>
): TimeDimensionConfig[];
/**
* Gets available segment dimensions from explore.
* @param explore - Explore to search
* @param excludedDimensions - Dimensions to exclude
* @returns Array of available segment dimensions
*/
function getAvailableSegmentDimensions(
explore: Explore,
excludedDimensions?: string[]
): CompiledDimension[];
/**
* Gets metrics available for comparison in metrics explorer.
* @param metric - Primary metric
* @param explore - Explore containing metrics
* @returns Array of comparable metrics
*/
function getAvailableCompareMetrics(
metric: CompiledMetric,
explore: Explore
): CompiledMetric[];Utilities for converting custom dimensions to DBT YAML format.
/**
* Converts a custom SQL dimension to DBT YAML format.
* @param field - Custom SQL dimension definition
* @returns DBT column definition for additional dimension
*/
function convertCustomSqlDimensionToDbt(
field: CustomSqlDimension
): DbtColumnLightdashAdditionalDimension;
/**
* Converts a custom bin dimension to DBT YAML format.
* Supports both custom range and fixed width binning.
* @param customDimension - Custom bin dimension definition
* @param baseDimensionSql - SQL for the base dimension to bin
* @param warehouseSqlBuilder - Warehouse SQL builder for generating SQL
* @returns DBT column definition for additional dimension
* @throws NotImplementedError for FIXED_NUMBER bin type (requires CTE)
*/
function convertCustomBinDimensionToDbt(args: {
customDimension: CustomBinDimension;
baseDimensionSql: string;
warehouseSqlBuilder: WarehouseSqlBuilder;
}): DbtColumnLightdashAdditionalDimension;
/**
* Previews the DBT YAML conversion for a custom dimension.
* @param customDimension - Custom dimension to preview
* @param baseDimensionSql - SQL for the base dimension
* @returns DBT column definition
*/
function previewConvertCustomDimensionToDbt(
customDimension: CustomDimension,
baseDimensionSql: string
): DbtColumnLightdashAdditionalDimension;Utilities for converting custom metrics to DBT YAML format.
/**
* Converts an additional/custom metric to DBT YAML format.
* @param field - Additional metric definition
* @returns DBT column definition for metric
*/
function convertCustomMetricToDbt(field: AdditionalMetric): DbtColumnLightdashMetric;