Tables and Text¶
Tables present values directly in rows and columns, making lookup, exact reading, and dense comparison possible; this family includes plain text tables, colored tables, and spark tables. They are most useful when the reader needs exact numbers, many values at once, or a structured reference view rather than a strongly shaped visual pattern.
This page will also cover other data-powered text-like outputs that are not really Vega-Lite charts at all, such as KPI blocks, large single-value callouts, and future narrative or AI-generated summary text. In other words, this family is not just about tables as rows and columns; it is about text-oriented outputs that are driven by data and are often used when exact reading, summarization, or direct communication matters more than visual encoding.
A chart's control surface is the full set of authored properties available on a single chart. In Dataface, that surface is primarily top-level chart fields plus a typed style object.
This page is intentionally family-oriented rather than exhaustive. For the implementation-backed source of truth, including table, KPI, spark, and spark_bar property coverage, see the Single-Chart Property Catalog.
Table Charts¶
Use type: table when exact values, scanning, and dense comparison matter more than mark-based trend reading.
Minimum Required for a Table¶
| Dataface field | Maps to renderer behavior | Allowed values | Notes |
|---|---|---|---|
query |
table data rows | Query name or query reference | Supplies the dataset. |
type: table |
table SVG renderer | Literal table |
Selects the table renderer. |
Table-Specific Style¶
| Dataface field | Maps to renderer behavior | Allowed values | Notes |
|---|---|---|---|
style.columns |
typed table-column config list | List of column config objects | Lets you choose columns explicitly and configure labels, formatting, width, alignment, header links, and inline sparks. |
style.header_overflow |
header overflow behavior | clip, truncate, wrap-two, or wrap |
Controls how long table headers clip, truncate with ellipsis, or wrap. |
style.background |
chart SVG background wrapper | Color value | Applies a chart-level background fill behind the rendered table SVG. |
Row Presentation (style.table.row)¶
The style.table.row block controls body-row defaults and per-role overrides for summary and total rows. The singular row name avoids confusion with the face-level rows: layout key.
| Dataface field | Maps to renderer behavior | Allowed values | Notes |
|---|---|---|---|
style.table.row.role |
column id for per-row role | Column name (string) | Per-row value: value, summary, or total. Supersedes flat row_role. |
style.table.row.height |
body row height (px) | Number | Overrides flat row_height. |
style.table.row.rule.width |
row separator width (px) | Number | Overrides flat row_rule_width. |
style.table.row.rule.color |
row separator color | Color value | Overrides flat rule_color. |
style.table.row.roles.summary.font.weight |
summary row font weight | "400", "500", "600", "700" |
Overrides flat summary_font_weight for summary rows. |
style.table.row.roles.summary.background |
summary row fill | Color value | Fill behind summary rows. |
style.table.row.roles.total.font.weight |
total row font weight | "400", "500", "600", "700" |
Overrides flat summary_font_weight for total rows specifically. |
style.table.row.roles.total.background |
total row fill | Color value | Fill behind total rows. |
style: table: row: role: kind # column whose per-row value is the role height: 15 rule: width: 2 color: "#D32F2F" roles: summary: font: weight: "500" total: font: weight: "700" background: "#F5F5F5"
Note: style.table.row.role and the flat style.table.row_role both point at the role column. When both are present, row.role wins. The flat key is kept for backward compatibility.
Row Numbers (style.table.row_numbers)¶
The style.table.row_numbers block injects a synthetic leading column that numbers data rows 1, 2, 3, ... — the same presentation as Excel, Google Sheets, and Looker's show_row_numbers. The column is transparent to style.columns (authors don't list it), to conditional_formatting rules keyed by column name (no rules target it), and to the data pipeline (it is a chart-layer concern, not a query column).
| Dataface field | Maps to renderer behavior | Allowed values | Notes |
|---|---|---|---|
style.table.row_numbers.show |
toggle on/off | true or false |
Default false — off unless set. |
style.table.row_numbers.header |
column header text | String | Default "#". |
style.table.row_numbers.align |
cell text alignment | left or right |
Default right, matching numeric convention. |
style: table: row_numbers: show: true # minimum v1 opt-in header: "#" # defaults; include to override align: right
Pagination behavior: numbering is continuous across pages. Page 2 of a 100-per-page table starts at row 101; it never resets to 1. The column width sizes against the total row count (not the per-page count), so page 1 and page 5 of a 200-row table have the same row-number column width.
Summary / total rows: the row-number cell is blank on rows tagged as summary or total (via style.table.row.role). The sequence counts data rows only.
Table Pagination¶
Tables support client-side row pagination via style.pagination. This controls how many rows are visible per page — it is a presentation concern, distinct from query-level limit which controls how many rows are fetched.
| Dataface field | Maps to renderer behavior | Allowed values | Notes |
|---|---|---|---|
style.pagination |
enables row paging | Object, integer, or boolean | See forms below. |
style.pagination.enabled |
toggle pagination on/off | true or false |
Defaults to true when pagination is present. |
style.pagination.page_size |
rows per page | Positive integer | Optional; when omitted the renderer uses its default. |
Supported forms (shorthand + full):
# Full form style: pagination: enabled: true page_size: 25 # Shorthand — integer sets page_size (enabled implied) style: pagination: 25 # Shorthand — boolean toggles enabled style: pagination: true
Design note: style.pagination is purely presentational. Use query-level limit when the intent is to fetch fewer rows. The Looker migration exporter maps limit_displayed_rows / num_rows to style.pagination.page_size, preserving the distinction between data truncation and UI paging.
Conditional Formatting (conditional_formatting)¶
Tables (and other chart types) support cell-level conditional styling through the chart-level conditional_formatting: block — keyed by query column name, with a when: list evaluated top-to-bottom like spreadsheet rules. This is the canonical mechanism for changing a cell's background, font.color, or font.weight based on its value. There is no separate cell_style field on style.columns[]; cell-level decisions live here.
| Predicate | Meaning |
|---|---|
gte: <number> |
value is greater than or equal to |
gt: <number> |
value is strictly greater than |
lte: <number> |
value is less than or equal to |
lt: <number> |
value is strictly less than |
eq: <value> |
value equals (string or number) |
default: true |
catch-all; place last |
Each when entry can set background (color), font.color (color), and font.weight ("400" … "700"). Rules are evaluated per-row, per-column; the first matching predicate wins.
charts: cf_revenue_table: type: table query: product_category_revenue conditional_formatting: revenue: when: - gte: 50000 background: "#dcfce7" font: color: "#166534" weight: "bold" - gte: 30000 background: "#e0f2fe" - default: true background: "#fef3c7" category: when: - eq: Electronics background: "#ede9fe" - eq: Accessories background: "#cffafe" - default: true background: "#f4f4f5"
Why chart-level, not column-level: rules are keyed by column name inside the conditional_formatting block, which keeps style.columns[] focused on layout (label, format, width, align, link, spark) and conditional decoration discoverable in one place. Authors who think "I want red below zero on the revenue column" find one block instead of digging into per-column blocks.
For value-driven gradients (continuous color across a numeric range), see the scale: config — separate from when: rules. Both compose under conditional_formatting.
Table Column Config¶
Each style.columns[] entry can include:
fieldlabelformatwidthalignheader_linklink— cell-level hyperlink; supports a static URL, a column ID (uses per-row value), or a template with{{ column_id }}placeholdersspark
Inline spark configs support small in-cell statistical marks such as line, area, bars, and progress-style indicators.
KPI Charts¶
Use type: kpi when the output is fundamentally one important value rather than a plotted series.
Minimum Required for a KPI¶
| Dataface field | Maps to renderer behavior | Allowed values | Notes |
|---|---|---|---|
query |
KPI data row | Query name or query reference | Supplies the dataset. |
type: kpi |
KPI renderer | Literal kpi |
Selects the KPI renderer. |
value |
KPI value binding | Field name, number, or string literal | Chooses the value to display. |
format is especially important for KPIs because it controls how that single value is rendered.
Spark Bar Charts¶
Use type: spark_bar when you want a compact ranked text-plus-bar display rather than a standard Vega-Lite chart.
Spark-Bar Style¶
| Dataface field | Maps to renderer behavior | Allowed values | Notes |
|---|---|---|---|
style.max_bars |
row cap | Integer | Maximum number of visible rows before truncation. |
style.labels_hidden |
left label visibility | true or false |
Set true to hide labels beside the bars (default: false). |
style.counts_hidden |
right count visibility | true or false |
Set true to hide right-side numeric counts (default: false). |
style.bar_height |
row/bar height | Integer | Controls compactness of the display. |
style.bar_color |
bar fill color | Color value | Spark-bar paint surface. |
style.bar_background |
bar track color | Color value | Spark-bar background/track paint surface. |