Area Charts¶
Area charts show magnitude with filled shapes, usually under a line or across stacked layers, so they emphasize both trend and accumulated bands; this family includes simple area charts, stacked area charts, and streamgraph-style variants. They are most useful when you want viewers to see changing totals or composition over time, though they trade away some comparison precision compared with line graphs and bar charts.
dbt Charts area charts use a small set of top-level shorthand fields together with style. In most cases, you only need query, type: area, x, and y to get started. Adding color creates overlapping semi-transparent series by default; use style.stack: "zero" (or true) to switch to stacked bands. Area charts are especially useful when total accumulation or composition carries meaning.
A chart's control surface is the full set of authored properties available on a single chart. In dbt Charts, that surface is primarily top-level chart fields plus typed style objects.
This page is intentionally family-oriented rather than exhaustive. For the implementation-backed source of truth, including default ownership and lower-level property coverage, see the YAML Schema Reference.
Minimum Required for an Area Chart¶
These are the minimum fields required to render a basic area chart in dbt Charts.
| dbt Charts field | Maps to Vega-Lite | Allowed values | Notes |
|---|---|---|---|
query |
data.values |
Query name or query reference | Supplies the dataset. |
type: area |
mark.type: "area" |
Literal area |
Selects the area mark. |
x |
encoding.x.field |
Field name | Ordered dimension, usually time. |
y |
encoding.y.field |
Field name | Numeric measure to plot as filled magnitude. |
Minimum Example¶
queries:
weekly_signups:
columns: [week, signups]
values:
- ["2026-01-05", 120]
- ["2026-01-12", 165]
- ["2026-01-19", 150]
- ["2026-01-26", 205]
- ["2026-02-02", 230]
- ["2026-02-09", 260]
charts:
signup_area:
query: weekly_signups
type: area
title: Weekly Signups
x: week
y: signups
rows:
- signup_area
Top-Level Chart Fields¶
These are the top-level chart properties you set directly on an area chart before you get into nested properties under style.
| dbt Charts field | Maps to Vega-Lite | Allowed values | Notes |
|---|---|---|---|
query |
data.values |
Query name or query reference | Query results become the plotted dataset. |
type: area |
mark.type: "area" |
Literal area |
Selects the area mark. |
x |
encoding.x.field |
Field name | Usually a temporal or ordered field. |
y |
encoding.y.field |
Field name or list of field names | A list creates layered multi-metric areas. |
title |
title.text |
String | Chart title. |
notes |
metadata | String | AI search/context metadata. Never rendered. |
color |
encoding.color.field |
Field name | Creates overlapping area series by default; combine with style.stack: "zero" to stack bands. |
x_label |
encoding.x.title |
String | Custom x-axis title. |
y_label |
encoding.y.title |
String | Custom y-axis title. |
field_labels |
legend, tooltip and axis titles | Map of column to text | Display text for a column, painted as written. See Field Labels. |
format |
encoding.y.format and encoding.y.axis.format |
Format string | Numeric formatting for the y channel. |
sort |
categorical axis sort | Sort object | Most useful when the x-axis is categorical. |
projection |
top-level projection |
Vega-Lite projection name | Available for Vega-Lite projection overrides. |
Stacked Composition over Time¶
This example uses color plus style.stack: "zero" to split one area chart into stacked category bands so readers can see both total volume and changing composition over time. Without style.stack, the series overlap as semi-transparent silhouettes instead.
queries:
channel_mix:
columns: [month, channel, signups]
values:
- ["2026-01-01", "Organic", 90]
- ["2026-01-01", "Paid", 40]
- ["2026-01-01", "Partner", 18]
- ["2026-02-01", "Organic", 105]
- ["2026-02-01", "Paid", 48]
- ["2026-02-01", "Partner", 22]
- ["2026-03-01", "Organic", 118]
- ["2026-03-01", "Paid", 52]
- ["2026-03-01", "Partner", 29]
- ["2026-04-01", "Organic", 134]
- ["2026-04-01", "Paid", 58]
- ["2026-04-01", "Partner", 34]
- ["2026-05-01", "Organic", 146]
- ["2026-05-01", "Paid", 63]
- ["2026-05-01", "Partner", 38]
charts:
stacked_area:
query: channel_mix
type: area
title: Signup Mix by Channel
x: month
y: signups
color: channel
style:
stack: "zero"
rows:
- stacked_area
Stacked Area Recipe¶
When style.stack is non-false ("zero", true, "normalize", or "center"), dbt Charts automatically applies the stacked recipe: solid fills (opacity 1.0) with a 1-pixel background-color perimeter stroke separating adjacent bands. This is the same idiom as the stacked-bar border knockout: the separator is the chart background bleeding through the stroke, not a separately painted line, so it reads correctly on any background color.
The default overlap recipe (translucent fill + halo) is suppressed for stacked charts because bands in a stack never cross, so the halo undercoat provides no benefit.
Theme authors can override the stacked recipe via style.charts.marks.area.stacked:
style: charts: marks: area: stacked: opacity: 1.0 stroke: color: theme.background width: 1.5 halo_multiplier: 0.0
A single-series area also takes this recipe in full, even with style.stack left at its default "none". A chart counts as single-series when it has no color, no layers:, and no y: list of two or more measures. With one band there is nothing to overlap and nothing for a trend line to sit on top of, so a single-series area gets the same solid fill, background-color separator stroke, and halo turned off as a real stacked chart.
This means style.charts.marks.area.opacity and style.charts.marks.line.stroke, which configure the multi-series overlap recipe's fill and top-edge trend line, are ignored on a single-series area. Use style.charts.marks.area.stacked.opacity to set its fill opacity and style.charts.marks.area.stacked.stroke to style its edge.
Streamgraph Baseline¶
This example uses style.stack: center to shift a stacked area chart to a centered baseline, producing a streamgraph-style view.
Endpoint labels work on a centered baseline: each label anchors to its band's midpoint at the final x position, so the series names sit on the bands instead of in a side legend. That matters more here than on most charts: streamgraph bands share no common baseline, so a legend forces the reader to match colors across the page.
queries:
listening_mix:
columns: [month, genre, listeners]
values:
- ["2026-01-01", "Ambient", 42]
- ["2026-01-01", "Indie", 58]
- ["2026-01-01", "Jazz", 33]
- ["2026-02-01", "Ambient", 48]
- ["2026-02-01", "Indie", 62]
- ["2026-02-01", "Jazz", 36]
- ["2026-03-01", "Ambient", 54]
- ["2026-03-01", "Indie", 59]
- ["2026-03-01", "Jazz", 41]
- ["2026-04-01", "Ambient", 61]
- ["2026-04-01", "Indie", 55]
- ["2026-04-01", "Jazz", 45]
- ["2026-05-01", "Ambient", 57]
- ["2026-05-01", "Indie", 51]
- ["2026-05-01", "Jazz", 49]
- ["2026-06-01", "Ambient", 50]
- ["2026-06-01", "Indie", 46]
- ["2026-06-01", "Jazz", 53]
charts:
listening_streamgraph:
query: listening_mix
type: area
title: Listening Mix by Genre
x: month
y: listeners
color: genre
style:
stack: center
rows:
- listening_streamgraph
Labels, Formatting, and Style¶
This example shows common top-level chart fields such as labels and numeric formatting, and it also serves as the shared example for basic style and axis-setting controls.
queries:
monthly_revenue:
columns: [month, revenue]
values:
- ["2026-01-01", 420000]
- ["2026-02-01", 455000]
- ["2026-03-01", 480000]
- ["2026-04-01", 510000]
- ["2026-05-01", 548000]
- ["2026-06-01", 592000]
charts:
revenue_area:
query: monthly_revenue
type: area
title: Monthly Revenue
x: month
y: revenue
x_label: Month
y_label: Revenue
style:
number_format: currency_whole
legend:
visible: false
axis:
grid:
visible: false
axis_y:
scale:
continuous:
zero: false
rows:
- revenue_area
Layered Multi-Metric Areas¶
When y is a list, dbt Charts creates layered area charts. This is useful when you want to compare two measures on the same x-axis, though overlap usually makes this a less precise choice than layered lines.
queries:
revenue_and_forecast:
columns: [month, actual, forecast]
values:
- ["2026-01-01", 420000, 405000]
- ["2026-02-01", 455000, 438000]
- ["2026-03-01", 480000, 470000]
- ["2026-04-01", 510000, 500000]
- ["2026-05-01", 548000, 540000]
- ["2026-06-01", 592000, 575000]
charts:
layered_areas:
query: revenue_and_forecast
type: area
title: Actual vs Forecast Revenue
x: month
y: [actual, forecast]
rows:
- layered_areas
Style Fields¶
Use style for dbt Charts shorthand properties that affect presentational defaults such as legend visibility and grid lines.
| dbt Charts field | Maps to Vega-Lite | Allowed values | Notes |
|---|---|---|---|
style.legend.visible |
encoding.color.legend |
true or false |
Typed legend control. false hides the legend. |
style.axis.grid.visible |
axis grid visibility | true or false |
false hides grid lines. Use style.axis.grid.visible: false (nested under grid:). |
style.background |
chart SVG background wrapper | Color value | Applies a chart-level background fill behind the rendered SVG. |
style.marks.area.curve |
area interpolation | linear (default), monotone, step |
Same interpolation options as line graphs; see Smoothing & Step Lines. No connect option on area (unlike line): a disconnected step area is just a bar chart via the wrong primitive. |
Legend and Grid Lines¶
This example reuses the labels-and-formatting chart so you can see the style changes without introducing a second dataset.
queries:
monthly_revenue:
columns: [month, revenue]
values:
- ["2026-01-01", 420000]
- ["2026-02-01", 455000]
- ["2026-03-01", 480000]
- ["2026-04-01", 510000]
- ["2026-05-01", 548000]
- ["2026-06-01", 592000]
charts:
revenue_area:
query: monthly_revenue
type: area
title: Monthly Revenue
x: month
y: revenue
x_label: Month
y_label: Revenue
style:
number_format: currency_whole
legend:
visible: false
axis:
grid:
visible: false
axis_y:
scale:
continuous:
zero: false
rows:
- revenue_area
Axis and Scale Style¶
Use style for axis and scale properties that shape how the area chart is framed and read.
| dbt Charts field | Maps to Vega-Lite | Allowed values | Notes |
|---|---|---|---|
style.axis_x |
config.axisX / encoding.x.axis |
AxisStyle object |
Per-axis styling (format, ticks, labels, grid, title). |
style.axis_y |
config.axisY / encoding.y.axis |
AxisStyle object |
Per-axis styling. |
style.axis_y.scale |
config.axisY.scale |
ScaleStyle object |
Y-axis scale config (zero, nice, domain, clamp). |
style.stack |
encoding.y.stack |
true, false, "zero", "normalize", "center" |
Stacking behavior. "center" for streamgraphs. |
style.stack_order |
encoding.order |
"value" (default), "data", "alphabetical" |
Band order from the baseline up. "value" puts the largest total at the baseline. "data" stacks series in first-appearance order: SQL row order for color, the listed order for y: [a, b, ...] (a measure null in the first rows appears later). "alphabetical" sorts by series name. Ignored when stacking is off or there is only one series. |
Axis and Scale Controls¶
This example reuses the labels-and-formatting chart so the effect of style stays easy to isolate.
queries:
monthly_revenue:
columns: [month, revenue]
values:
- ["2026-01-01", 420000]
- ["2026-02-01", 455000]
- ["2026-03-01", 480000]
- ["2026-04-01", 510000]
- ["2026-05-01", 548000]
- ["2026-06-01", 592000]
charts:
revenue_area:
query: monthly_revenue
type: area
title: Monthly Revenue
x: month
y: revenue
x_label: Month
y_label: Revenue
style:
number_format: currency_whole
legend:
visible: false
axis:
grid:
visible: false
axis_y:
scale:
continuous:
zero: false
rows:
- revenue_area
Endpoint Labels¶
A multi-series area chart names its series on the chart, anchored to each band's final value, rather than in a side legend. This is the default on every built-in theme; you don't switch it on. Set style.endpoint_labels.visible: false to send the names back to a legend.
| dbt Charts field | Allowed values | Notes |
|---|---|---|
style.endpoint_labels.visible |
true or false |
Defaults to true on every built-in theme. Set false per-chart to send the series names back to a legend. |
When the label pane is on, the categorical legend turns off automatically: the two would encode the same series→color mapping twice. The y-axis also auto-flips to the left so it doesn't collide with the right-edge label pane.
On narrow cards, endpoint-label text compacts to fit the available width while its automatic vertical spacing stays readable for closely ending series.
Endpoint labels require a multi-series chart: either a color channel or a y: [field_a, field_b] list. On single-series areas there is only one series to name, so the feature is a no-op.
y: [...] composes with a color: column: the measures are crossed with the column's values, one series per value per measure, each named <value> - <measure> (see Multiple Measures by a Dimension). layers: still cannot combine with y: [...]; dbt Charts rejects that at compile time.
queries:
channel_mix:
columns: [month, channel, signups]
values:
- ["2026-01-01", "Organic", 90]
- ["2026-01-01", "Paid", 40]
- ["2026-01-01", "Partner", 18]
- ["2026-02-01", "Organic", 105]
- ["2026-02-01", "Paid", 48]
- ["2026-02-01", "Partner", 22]
- ["2026-03-01", "Organic", 118]
- ["2026-03-01", "Paid", 52]
- ["2026-03-01", "Partner", 29]
- ["2026-04-01", "Organic", 134]
- ["2026-04-01", "Paid", 58]
- ["2026-04-01", "Partner", 34]
- ["2026-05-01", "Organic", 146]
- ["2026-05-01", "Paid", 63]
- ["2026-05-01", "Partner", 38]
charts:
stacked_area_with_endpoint_labels:
query: channel_mix
type: area
title: Signup Mix by Channel
x: month
y: signups
color: channel
style:
endpoint_labels:
visible: true
rows:
- stacked_area_with_endpoint_labels
Overlays (layers:)¶
Add a layers: list to an area chart to overlay additional marks, a line for a
reference trend, a scatter for individual points, or a second series on a separate
y-axis. The base area chart owns the x-axis, frame, title, legend, and sort. Each layer
contributes its own mark and legend entry.
charts: revenue_with_forecast_line: type: area x: month y: revenue query: monthly style: stack: "zero" layers: - type: line y: forecast label: Forecast style: marks: line: stroke: width: 2 dasharray: "4 2"
Layer fields: type, y, label, color, query, x, axis_y, style (marks-only patch). sort: is base-only; layer x-values extend the base x-scale.
Stacking a y: List in Listed Order¶
Stacked bands default to the largest total at the baseline. Set style.stack_order: data to stack a y: list in the order you wrote it: here subscriptions sits at the baseline even though services is larger.
queries:
revenue_by_line:
columns: [month, subscriptions, services, hardware]
values:
- ["2026-01-01", 40000, 90000, 15000]
- ["2026-02-01", 46000, 92000, 14000]
- ["2026-03-01", 53000, 95000, 16000]
charts:
listed_order_areas:
query: revenue_by_line
type: area
x: month
y: [subscriptions, services, hardware]
style:
stack: zero
stack_order: data
rows:
- listed_order_areas
Authored Surface¶
dbt Charts area charts are authored with type: area plus top-level channels such as x, y, and color. Arbitrary Vega-Lite spec, mark, encoding, config, transform, params, and composition blocks are rejected on the authored surface. Use top-level dbt Charts fields and the typed style: object.