Widgets & charts
Five widget types. A widget's renderConfig shape depends on its type.
kpi_card
interface KpiCardRenderConfig {
format?: 'number' | 'currency' | 'percentage';
currencySymbol?: string; // falls back to settings.numberFormat.currencySymbol
prefix?: string;
suffix?: string;
comparison?: { field: string; type: 'percentage' | 'absolute' };
variant?: 'solid' | 'gradient';
icon?: 'trending_up' | 'dollar' | 'users' | 'package' | 'activity' | 'percent' | 'gauge';
}
echarts
interface EchartsRenderConfig {
chartType: ChartType; // see the catalog below
smooth?: boolean; // line/area
showArea?: boolean; // line/area
stacked?: boolean; // bar
seriesStyles?: { field: string; color?: string; aggregation?: Aggregation }[];
xAxisLabel?: string;
yAxisLabel?: string;
legendPosition?: 'top' | 'bottom' | 'none';
showGridLines?: boolean;
gaugeMin?: number; // gauge only
gaugeMax?: number; // gauge only
funnelSort?: 'ascending' | 'descending' | 'none'; // funnel only
showInsight?: boolean; // auto-written English caption, default true
echartsOptionsCustom?: Record<string, unknown>; // merged over the generated option
}
The 25-chart catalog
| Group | Chart types |
|---|---|
| Trend | line, area, stacked_area |
| Comparison | bar, horizontal_bar, stacked_bar, waterfall |
| Part-to-whole | pie, donut, rose, treemap, sunburst |
| Correlation | scatter, bubble |
| Multi-dimensional | radar, polar_bar |
| Distribution licensed | heatmap, calendar_heatmap, boxplot |
| Relationships & flow licensed | graph, sankey, parallel |
| Specialized licensed | gauge, funnel, candlestick |
Sub-categories. Standard-axis charts (line/bar/…) accept a second dimension: the first becomes the x-axis, the second pivots into one series per value (e.g. region × product). Treemap and sunburst instead accept an ordered list of dimensions — each one nests a level deeper (region → product → SKU), with no limit on depth.
graph and sankey read dimensions[0] as the
source field and dimensions[1] as the target field, with the first metric as
edge weight. candlestick reads its four metrics in
[open, close, low, high] order.
table
interface TableRenderConfig {
columns: TableColumn[];
virtualScroll?: boolean; // windows over the full filtered set client-side
showQuickFilter?: boolean;
striped?: boolean;
compact?: boolean;
rowClickable?: boolean; // emits a row_click DashboardActionEvent
defaultSort?: { field: string; direction: 'asc' | 'desc' };
rowHeight?: number; // default 36 (28 when compact)
}
interface TableColumn {
field: string;
header: string;
width?: number;
align?: 'left' | 'center' | 'right';
sortable?: boolean;
format?: 'text' | 'number' | 'currency' | 'percentage' | 'date' | 'chip' | 'image';
decimals?: number; // number/currency/percentage, default 2
pinned?: boolean;
colorField?: string; // another field holding a CSS color for this cell/chip
}
format: 'chip' renders the value as a colored pill — explicit color via
colorField, or a deterministic hash of the text when unset.
format: 'image' renders the cell value as a thumbnail <img> src.
filter_panel
interface FilterPanelRenderConfig {
filterRefIds: string[]; // which globalFilters this panel renders controls for
}
markdown
interface MarkdownRenderConfig {
content: string; // headings, **bold**, *italic*, [links](url) — minimal, dependency-free
}