or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

api

features

charts

charts.mdconditional-formatting.mdvisualizations.md
authorization.mdchangesets.mdcharts-as-code.mdcompiler.mddashboards.mddbt.mdee-features.mdformatting.mdparameters.mdpivot.mdprojects-spaces.mdsql-runner.mdtemplating.mdwarehouse.md
index.md
tile.json

charts.mddocs/api/features/charts/

Chart Configuration

Extensive chart configuration supporting 14 chart types including cartesian (line, bar, area, scatter, mixed), pie, table, big number, funnel, treemap, gauge, map, and custom charts.

Overview

Lightdash supports multiple chart types for visualizing query results:

  • Cartesian charts: Line, bar (vertical/horizontal), area, scatter, mixed
  • Pie charts: Standard pie and donut charts
  • Table charts: Formatted data tables
  • Big number: Single value displays with comparisons
  • Funnel charts: Conversion funnel visualization
  • Treemap charts: Hierarchical data visualization
  • Gauge charts: Progress/KPI indicators
  • Map charts: Geographic data visualization

Chart Types

enum ChartKind {
  LINE = 'line',
  HORIZONTAL_BAR = 'horizontal_bar',
  VERTICAL_BAR = 'vertical_bar',
  SCATTER = 'scatter',
  AREA = 'area',
  MIXED = 'mixed',
  PIE = 'pie',
  TABLE = 'table',
  BIG_NUMBER = 'big_number',
  FUNNEL = 'funnel',
  TREEMAP = 'treemap',
  GAUGE = 'gauge',
  MAP = 'map',
  CUSTOM = 'custom',
}

enum ChartType {
  CARTESIAN = 'cartesian',
  TABLE = 'table',
  BIG_NUMBER = 'big_number',
  PIE = 'pie',
  FUNNEL = 'funnel',
  TREEMAP = 'treemap',
  GAUGE = 'gauge',
  CUSTOM = 'custom',
  MAP = 'map',
}

SavedChart Interface

interface SavedChart {
  uuid: string;
  projectUuid: string;
  name: string;
  description?: string;
  tableName: string;
  metricQuery: MetricQuery;
  chartConfig: ChartConfig;
  tableConfig: TableChart;
  pivotConfig?: PivotConfig;
  parameters?: ParametersValuesMap;
  updatedAt: Date;
  updatedByUser?: UpdatedByUser;
  organizationUuid: string;
  spaceUuid: string;
  spaceName: string;
  pinnedListUuid: string | null;
  pinnedListOrder: number | null;
  dashboardUuid: string | null;
  dashboardName: string | null;
  slug: string;
  views: number;
  firstViewedAt: Date | null;
  validationErrors?: ValidationError[];
  colorPalette: string[];
  isPrivate: boolean;
  access: SpaceShare[];
}

interface CreateSavedChart {
  name: string;
  description?: string;
  tableName: string;
  metricQuery: MetricQuery;
  chartConfig: ChartConfig;
  tableConfig: TableChart;
  pivotConfig?: PivotConfig;
  spaceUuid?: string;
  dashboardUuid?: string | null;
}

interface UpdateSavedChart {
  name?: string;
  description?: string;
  tableName?: string;
  metricQuery?: MetricQuery;
  chartConfig?: ChartConfig;
  tableConfig?: TableChart;
  pivotConfig?: PivotConfig;
  spaceUuid?: string;
}

Chart Configuration Types

type CartesianChartConfig = {
  type: ChartType.CARTESIAN;
  config?: CartesianChart;
};

type PieChartConfig = {
  type: ChartType.PIE;
  config?: PieChart;  // Note: Use string literals for valueLabel and legendPosition
};

type BigNumberConfig = {
  type: ChartType.BIG_NUMBER;
  config?: BigNumber;
};

type ChartConfig =
  | CartesianChartConfig
  | PieChartConfig
  | BigNumberConfig
  | TableChartConfig
  | FunnelChartConfig
  | TreemapChartConfig
  | GaugeChartConfig
  | MapChartConfig
  | CustomChartConfig;

Cartesian Charts

CartesianChart

type CartesianChart = {
  layout: CartesianChartLayout;
  eChartsConfig: EChartsConfig;
  metadata?: Record<string, SeriesMetadata>;
};

enum CartesianSeriesType {
  BAR = 'bar',
  LINE = 'line',
  SCATTER = 'scatter',
  AREA = 'area',
}

interface CartesianChartLayout {
  xField: string;
  yField: string[];
  flipAxes?: boolean;
  showGridX?: boolean;
  showGridY?: boolean;
}

Series Configuration

interface Series {
  encode: {
    xRef: PivotReference;
    yRef: PivotReference;
    x?: string; // hash of xRef
    y?: string; // hash of yRef
  };
  type: CartesianSeriesType;
  stack?: string;
  stackLabel?: {
    show?: boolean;
  };
  label?: {
    show?: boolean;
    position?: string;
  };
  color?: string;
  yAxisIndex?: number;
  name?: string;
  hidden?: boolean;
  areaStyle?: Record<string, unknown>;
  smooth?: boolean;
  showSymbol?: boolean;
  markLine?: MarkLine;
  isFilteredOut?: boolean;
}

interface MarkLine {
  data: MarkLineData[];
  symbol: string[];
  lineStyle: {
    color: string;
    type: string;
    width: number;
  };
  label: {
    position: string;
    formatter: string;
  };
}

interface MarkLineData {
  name: string;
  yAxis: number | string;
  xAxis: number | string;
  label?: {
    formatter?: string;
    position?: string;
  };
}

ECharts Configuration

interface EChartsConfig {
  series?: Series[];
  legend?: EchartsLegend;
  grid?: EchartsGrid;
  xAxis?: XAxis[];
  yAxis?: Axis[];
}

interface EchartsLegend {
  show?: boolean;
  type?: 'plain' | 'scroll';
  orient?: 'horizontal' | 'vertical';
  left?: string | number;
  right?: string | number;
  top?: string | number;
  bottom?: string | number;
  align?: 'left' | 'right';
}

interface EchartsGrid {
  left?: string | number;
  right?: string | number;
  top?: string | number;
  bottom?: string | number;
  containLabel?: boolean;
}

interface Axis {
  name?: string;
  min?: number | string;
  max?: number | string;
  position?: 'left' | 'right';
  type?: 'value' | 'category' | 'time' | 'log';
  gridIndex?: number;
}

interface XAxis extends Axis {
  sortType?: XAxisSortType;
  enableDataZoom?: boolean;
}

enum XAxisSortType {
  DEFAULT = 'default',
  CATEGORY = 'category',
  BAR_TOTALS = 'bar_totals',
}

enum XAxisSort {
  DEFAULT = 'default',
  DEFAULT_REVERSED = 'default_reversed',
  ASCENDING = 'ascending',
  DESCENDING = 'descending',
  BAR_TOTALS_ASCENDING = 'bar_totals_ascending',
  BAR_TOTALS_DESCENDING = 'bar_totals_descending',
}

function getXAxisSort(
  xAxis?: Pick<XAxis, 'sortType' | 'inverse'>
): XAxisSort;

const ECHARTS_DEFAULT_COLORS: string[] = [
  '#5470c6',
  '#fc8452',
  '#91cc75',
  '#fac858',
  '#ee6666',
  '#73c0de',
  '#3ba272',
  '#9a60b4',
  '#ea7ccc',
];

function getDefaultSeriesColor(index: number): string;

Pie Charts

type PieChart = {
  groupFieldIds?: string[];
  metricId?: string;
  isDonut?: boolean;
  valueLabel?: 'hidden' | 'inside' | 'outside';  // PieChartValueLabel enum not exported
  showValue?: boolean;
  showPercentage?: boolean;
  groupLabelOverrides?: Record<string, string>;
  groupColorOverrides?: Record<string, string>;
  groupValueOptionOverrides?: Record<string, Partial<PieChartValueOptions>>;
  groupSortOverrides?: string[];
  showLegend?: boolean;
  legendPosition?: PieChartLegendPosition;
  legendMaxItemLength?: number;
  metadata?: Record<string, SeriesMetadata>;
};

type PieChartValueLabel = 'hidden' | 'inside' | 'outside';
type PieChartLegendPosition = 'horizontal' | 'vertical';

interface PieChartValueOptions {
  valueLabel: PieChartValueLabel;
  showValue: boolean;
  showPercentage: boolean;
}

Table Charts

interface TableChart {
  showColumnCalculation?: boolean;
  showRowCalculation?: boolean;
  showTableNames?: boolean;
  hideRowNumbers?: boolean;
  showResultsTotal?: boolean;
  showSubtotals?: boolean;
  metricsAsRows?: boolean;
  columns?: Record<string, ColumnProperties>;
}

interface ColumnProperties {
  visible?: boolean;
  name?: string;
  frozen?: boolean;
  displayStyle?: 'text' | 'bar';
  color?: string;
}

Big Number Charts

type BigNumber = {
  label?: string;
  style?: CompactOrAlias;
  selectedField?: string;
  showBigNumberLabel?: boolean;
  showTableNamesInLabel?: boolean;
  showComparison?: boolean;
  comparisonFormat?: ComparisonFormatTypes;
  flipColors?: boolean;
  comparisonLabel?: string;
};

enum ComparisonFormatTypes {
  RAW = 'raw',
  PERCENTAGE = 'percentage',
}

Chart Config Union

type ChartConfig =
  | CartesianChart
  | PieChart
  | BigNumber
  | TableChart
  | FunnelChart
  | TreemapChart
  | GaugeChart
  | MapChart
  | CustomVisConfig;

Utility Functions

function isCartesianChartConfig(config: ChartConfig): config is CartesianChart;
function isBigNumberConfig(config: ChartConfig): config is BigNumber;
function isTableChartConfig(config: ChartConfig): config is TableChart;
function isPieChartConfig(config: ChartConfig): config is PieChart;
function getChartType(savedChart: SavedChart): ChartType;
function getChartKind(chartConfig: ChartConfig): ChartKind;
function getEChartsChartTypeFromChartKind(kind: ChartKind): string;
function getSeriesId(series: Series): string;
function getDefaultSeriesColor(index: number): string;
function isSeriesWithMixedChartTypes(series: Series[]): boolean;
function getHiddenTableFields(tableConfig: TableChart): string[];
function getXAxisSort(xAxis?: XAxis[]): XAxisSort | undefined;

Funnel Charts

type FunnelChartConfig = {
  type: ChartType.FUNNEL;
  config?: FunnelChart;
};

type FunnelChart = {
  dataInput?: FunnelChartDataInput;
  fieldId?: string;
  metadata?: Record<string, SeriesMetadata>;
  labelOverrides?: Record<string, string>;
  colorOverrides?: Record<string, string>;
  labels?: {
    position?: FunnelChartLabelPosition;
    showValue?: boolean;
    showPercentage?: boolean;
  };
};

enum FunnelChartDataInput {
  ROW = 'row',
  COLUMN = 'column',
}

enum FunnelChartLabelPosition {
  INSIDE = 'inside',
  LEFT = 'left',
  RIGHT = 'right',
  HIDDEN = 'hidden',
}

Funnel charts visualize conversion funnels and stage-based processes.

Treemap Charts

type TreemapChartConfig = {
  type: ChartType.TREEMAP;
  config?: TreemapChart;
};

type TreemapChart = {
  visibleMin?: number;
  leafDepth?: number;
  groupFieldIds?: string[];
  sizeMetricId?: string;
  colorMetricId?: string;
  startColor?: string;
  endColor?: string;
  useDynamicColors?: boolean;
  startColorThreshold?: number;
  endColorThreshold?: number;
};

Treemap charts display hierarchical data using nested rectangles.

Gauge Charts

type GaugeChartConfig = {
  type: ChartType.GAUGE;
  config?: GaugeChart;
};

type GaugeChart = {
  selectedField?: string;
  min?: number;
  max?: number;
  maxFieldId?: string;
  showAxisLabels?: boolean;
  sections?: GaugeSection[];
  customLabel?: string;
};

type GaugeSection = {
  min: number;
  max: number;
  minFieldId?: string;
  maxFieldId?: string;
  color: string;
};

Gauge charts display progress indicators and KPI metrics with configurable sections and thresholds.

Map Charts

type MapChartConfig = {
  type: ChartType.MAP;
  config?: MapChart;
};

type MapChart = {
  mapType?: MapChartLocation;
  customGeoJsonUrl?: string;
  locationType?: MapChartType;
  // Lat/Long fields
  latitudeFieldId?: string;
  longitudeFieldId?: string;
  // Country/Region field
  locationFieldId?: string;
  // Common fields
  valueFieldId?: string;
  showLegend?: boolean;
  // Color range (array of 2-5 colors for gradient)
  colorRange?: string[];
  // Map extent settings (zoom and center are saved when user enables "save map extent")
  defaultZoom?: number;
  defaultCenterLat?: number;
  defaultCenterLon?: number;
  // Scatter bubble size settings (for lat/long maps)
  minBubbleSize?: number;
  maxBubbleSize?: number;
  sizeFieldId?: string;
  // Tile background
  tileBackground?: MapTileBackground;
  backgroundColor?: string;
};

enum MapChartLocation {
  WORLD = 'world',
  USA = 'usa',
  EUROPE = 'europe',
  CUSTOM = 'custom',
}

enum MapChartType {
  SCATTER = 'scatter',
  AREA = 'area',
  HEATMAP = 'heatmap',
}

Map charts visualize geographic data with support for latitude/longitude coordinates or location-based aggregation.

Custom Charts

type CustomVisConfig = {
  type: ChartType.CUSTOM;
  config?: CustomVis;
};

type CustomVis = {
  spec?: Record<string, unknown>;
};

Custom charts allow integration of custom visualization specifications for advanced use cases.

Complete Chart Example

import {
  type SavedChart,
  type CartesianChart,
  CartesianSeriesType,
  ChartKind,
} from '@lightdash/common';

const lineChart: SavedChart = {
  uuid: 'chart-uuid',
  projectUuid: 'project-uuid',
  organizationUuid: 'org-uuid',
  name: 'Monthly Revenue Trend',
  description: 'Revenue over time by region',
  tableName: 'orders',
  spaceUuid: 'space-uuid',
  spaceName: 'Analytics',
  slug: 'monthly-revenue-trend',
  updatedAt: new Date(),
  views: 0,
  firstViewedAt: null,
  pinnedListUuid: null,
  pinnedListOrder: null,
  dashboardUuid: null,
  dashboardName: null,

  metricQuery: {
    exploreName: 'orders',
    dimensions: ['orders.order_date', 'orders.region'],
    metrics: ['orders.total_revenue'],
    sorts: [{ fieldId: 'orders.order_date', descending: false }],
  },

  chartConfig: {
    layout: {
      xField: 'orders.order_date',
      yField: ['orders.total_revenue'],
      flipAxes: false,
      showGridX: true,
      showGridY: true,
    },
    eChartsConfig: {
      series: [
        {
          encode: {
            xRef: 'orders.order_date',
            yRef: 'orders.total_revenue',
          },
          type: CartesianSeriesType.LINE,
          color: '#4C8BF5',
          smooth: true,
        },
      ],
      legend: {
        show: true,
        orient: 'horizontal',
        bottom: 0,
      },
      grid: {
        left: '10%',
        right: '10%',
        top: '10%',
        bottom: '15%',
        containLabel: true,
      },
    },
  },

  tableConfig: {
    showColumnCalculation: false,
    showResultsTotal: true,
  },
};