Chart Color Channels¶
Dataface supports color as the primary data channel at chart root.
color accepts a bare field name (string) to encode a column as series grouping.
Static colors and gradient scales go under style.color.
Discrete, rule-driven styling lives in a separate top-level
conditional_formatting: block on the chart (see
Conditional (threshold) below).
Shorthand¶
A plain string binds a column to the color channel:
color: segment
This is the only accepted form at chart root. color does not accept {column: ...}, {value: ...}, or {scale: ...} at chart root — use style.color for static paint or gradient scale.
Literal¶
Fix a channel to a static color via style.color.static:
style: color: static: "#1aff3c"
Gradient scale¶
Map a numeric column to a continuous color range via style.color.gradient:
color: revenue style: color: gradient: palette: ["#ffffff", "#0000ff"] min: 0 max: 1000000
Omit min/max to auto-scale from data. palette must be list[str] for
color channels.
Conditional (threshold)¶
Discrete, rule-driven styling goes under the chart-level
conditional_formatting: block, indexed by column name. Each column entry
carries a single when: list of rules; each rule has exactly one predicate
and one or more style outputs (background, font):
| Predicate | Shape | Matches |
|---|---|---|
eq: x |
any scalar | values equal to x (bool/int cross-match guarded) |
ne: x |
any scalar | values not equal to x |
lt / lte / gt / gte |
number | one-sided numeric comparison (non-numeric never matches) |
between: [low, high] |
two numbers, low <= high |
closed inclusive range |
in: [v1, v2, ...] |
non-empty list | equality against any list element |
is_null: true |
boolean | null/None values |
is_null: false |
boolean | any non-null value (including 0, "", false) |
default: true |
boolean | catch-all — fires when no other rule matched |
chart: type: bar x: quarter y: arr conditional_formatting: arr: when: - gt: 1000000 background: "#166534" font: {color: "#ffffff", weight: bold} - between: [0, 1000000] background: "#dcfce7" - is_null: true background: "#e5e7eb" - default: true background: "#fee2e2" font: {color: "#991b1b"}
Non-default rules are evaluated in list order; later matches override
earlier ones for overlapping style keys. A default: true rule must be the
last entry in its when: list and only fires when no other rule matched
for the current row — it is a true fallback, not a last-match-wins override.
Without a default:, rows that match nothing fall back to the chart's
un-conditional styling.
Channel reference¶
| Channel | Chart types | Value type |
|---|---|---|
color |
All | str (color) |
background |
KPI, table | str (color) |
opacity |
All | float [0, 1] |
stroke.color |
Bar, line, area, arc | str (color) |
stroke.width |
Bar, line, area | float |
Tables¶
On type: table, the table renderer reads conditional_formatting rules
directly from the chart-level block at render time — there is no per-column
when: shape under style.columns. Per-channel color.scale /
background.scale still lower to style.columns[<column>].scale because
scale is a continuous encoding the renderer interpolates per cell.
KPI channels¶
On type: kpi, color controls the value text color and background
controls the card fill; both support literal and gradient modes via the
per-channel shape. Rule-driven overrides (mix of background and font
color/weight per threshold) go under conditional_formatting:. Provide
explicit min/max in gradient scale for KPIs — auto-domain over a
single row always collapses.
Precedence¶
chart.<channel> (data-bound) wins over chart.style.<channel> (literal).
Using a data-bound form under chart.style.<channel> is a validation error.
conditional_formatting rules apply on top of the per-channel encoding
for matching rows.
Legend¶
When color is bound to a series column, Dataface renders a legend mapping
each distinct value to its swatch. Two style.legend fields tune the legend
itself without touching the color scale:
symbol_limit— caps the number of legend entries shown. Useful for a high-cardinality series that would otherwise overflow the legend area.values— an explicit list pinning which entries appear in the legend and in what order, overriding the default order Dataface infers from the color scale's domain. This only reorders/filters the legend itself — it does not filter which rows are plotted on the chart.
queries:
revenue_by_channel:
columns: [month, channel, revenue]
values:
- ["2026-01", "Organic", 42000]
- ["2026-01", "Paid", 18000]
- ["2026-01", "Referral", 9000]
- ["2026-02", "Organic", 47000]
- ["2026-02", "Paid", 21000]
- ["2026-02", "Referral", 8500]
charts:
channel_revenue:
query: revenue_by_channel
type: bar
title: Revenue by Channel
x: month
y: revenue
color: channel
style:
legend:
values: ["Paid", "Organic", "Referral"] # pin legend order
symbol_limit: 5
rows:
- channel_revenue