Skip to content

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:

style:
  color: "#1aff3c"

Gradient scale

Map a numeric column to a continuous color range via style.color.scale:

color: revenue
style:
  color:
    scale:
      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.