Skip to content

Bar Charts

Bar charts encode values as lengths measured from a common baseline, which makes them one of the most fundamental tools for comparison; this family includes horizontal bar charts and vertical column charts. Horizontal bars are especially good for ranking categories with long labels, while vertical columns are especially good for showing change over simple time steps.

Dataface bar charts use a small set of top-level shorthand fields together with style. By default, style.orientation is auto: Dataface picks horizontal for categorical x (nominal/string labels) and vertical for continuous x (temporal, quantitative, date-like ordinal, or time-unit bucketed). The rule is type-driven, not viewport-driven — orientation reflects what the data is, not how wide the chart happens to be. Set style.orientation: vertical or style.orientation: horizontal to lock in a specific orientation. See Axis Labels — Smart Layout for how the engine picks orientation and label tilt automatically when style.orientation is left at its default.

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 default ownership and lower-level property coverage, see the YAML Schema Reference.


Minimum Required for a Bar Chart

These are the minimum fields required to render a basic bar chart in Dataface. With a nominal x-axis (category strings), the default result is a horizontal bar chart; with a continuous x-axis (temporal, quantitative, or date-like ordinal), the default is a vertical column chart. See Axis, Scale, and Orientation for the rule, or set style.orientation explicitly to override.

Dataface field Maps to Vega-Lite Allowed values Notes
query data.values Query name or query reference Supplies the dataset.
type: bar mark.type: "bar" Literal bar Selects the bar mark.
x encoding.x.field Field name Category, discrete field, or temporal field.
y encoding.y.field Field name Numeric measure to compare.

Minimum Example

source: examples_db
charts:
  product_revenue_columns:
    query:
      sql: |
        SELECT product, category, SUM(revenue) AS revenue, SUM(units_sold) AS units_sold FROM ecommerce_orders GROUP BY product, category ORDER BY revenue DESC
    type: bar
    title: Revenue by Product
    x: product
    y: revenue
rows:
  - product_revenue_columns
Dataface DF-UNKNOWN-INTERNALChart Error: product_revenue_columnsQuery execution failed: Source 'examples_db' not found. No source profiles are configured. Declare sources under `sources:` in your dataface.yml. (query: _inline_query_product_revenue_columns)https://docs.it-dataface.com/guides/error-handling/?code=DF-UNKNOWN-INTERNAL 2026-07-17 15:04 UTC made with dataface

Top-Level Chart Fields

These are the top-level chart properties you set directly on a bar chart before you get into nested properties under style.

Dataface field Maps to Vega-Lite Allowed values Notes
query data.values Query name or query reference Query results become the plotted dataset. Use pre-aggregated data with one row per plotted key.
type: bar mark.type: "bar" Literal bar Standard bar or column chart.
x encoding.x.field Field name Usually the category field, or a temporal field for time-unit column charts.
y encoding.y.field Field name or list of field names Usually the numeric measure, even when the final chart is horizontal. A list creates layered multi-metric bars.
title title.text String Chart title.
description metadata String Available for tooling and docs.
color encoding.color.field Field name Adds series grouping or composition.
x_label encoding.x.title String Custom x-axis title.
y_label encoding.y.title String Custom y-axis title.
format quantitative value-axis format Format string Numeric formatting for the value axis. In horizontal bars, that value axis is rendered on x.
sort categorical axis sort Sort object Most useful for ranked bar charts.

Vertical Columns and Horizontal Bars

This example shows the family's two main forms side-by-side: a vertical bar chart (also called a column chart), and the same data rendered horizontally. Both pin style.orientation explicitly so the contrast is what's on the page; left at auto, this nominal x would render horizontal by default.

source: examples_db
queries:
  sales_by_product:
    sql: |
      SELECT product, category, SUM(revenue) AS revenue, SUM(units_sold) AS units_sold FROM ecommerce_orders GROUP BY product, category ORDER BY revenue DESC
charts:
  product_revenue_columns:
    query: sales_by_product
    type: bar
    title: Revenue by Product
    x: product
    y: revenue
    style:
      orientation: vertical

  product_revenue_bars:
    query: sales_by_product
    type: bar
    title: Revenue by Product
    x: product
    y: revenue
    style:
      orientation: horizontal
rows:
  - product_revenue_columns
  - product_revenue_bars
Dataface DF-UNKNOWN-INTERNALChart Error: product_revenue_columnsQuery execution failed: Source 'examples_db' not found. No source profiles are configured. Declare sources under `sources:` in your dataface.yml. (query: sales_by_product)https://docs.it-dataface.com/guides/error-handling/?code=DF-UNKNOWN-INTERNALDF-UNKNOWN-INTERNALChart Error: product_revenue_barsQuery execution failed: Source 'examples_db' not found. No source profiles are configured. Declare sources under `sources:` in your dataface.yml. (query: sales_by_product)https://docs.it-dataface.com/guides/error-handling/?code=DF-UNKNOWN-INTERNAL 2026-07-17 15:04 UTC made with dataface

Labels and Ranking

This example keeps the chart definition compact while showing the top-level fields most readers use in practice: labels, formatting, and sorting.

source: examples_db
charts:
  ranked_products:
    query:
      sql: |
        SELECT product, category, SUM(revenue) AS revenue, SUM(units_sold) AS units_sold FROM ecommerce_orders GROUP BY product, category ORDER BY revenue DESC
    type: bar
    title: Top Products by Revenue
    description: A sorted product ranking shown as horizontal bars.
    x: product
    y: revenue
    x_label: Product
    y_label: Revenue
    sort:
      by: revenue
      order: desc
    style:
      number_format: currency_whole
      orientation: horizontal
rows:
  - ranked_products
Dataface DF-UNKNOWN-INTERNALChart Error: ranked_productsQuery execution failed: Source 'examples_db' not found. No source profiles are configured. Declare sources under `sources:` in your dataface.yml. (query: _inline_query_ranked_products)https://docs.it-dataface.com/guides/error-handling/?code=DF-UNKNOWN-INTERNAL 2026-07-17 15:04 UTC made with dataface

Layered Multi-Metric Bars

When y is a list, Dataface creates a layered bar chart. This is most useful when the metrics share a similar scale and the comparison is more important than stacking.

queries:
  product_metrics:
    columns: [product, revenue, profit]
    values:
      - ["Gadget X", 18350, 4200]
      - ["Gadget Y", 30490, 7600]
      - ["Tool Z", 34900, 9100]
      - ["Widget A", 66300, 18500]
      - ["Widget B", 85680, 24100]

charts:
  layered_product_metrics:
    query: product_metrics
    type: bar
    title: Revenue and Profit by Product
    x: product
    y: [revenue, profit]
rows:
  - layered_product_metrics
Dataface 010,00020,00030,00040,00050,00060,00070,00080,00090,0005,00015,00025,00035,00045,00055,00065,00075,00085,000revenue, profitGadget XGadget YTool ZWidget AWidget BproductrevenueprofitRevenue and Profit by Product 2026-07-17 15:04 UTC made with dataface

Style Fields

Use style for Dataface shorthand properties that affect presentational defaults such as legend visibility and grid lines.

Dataface 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.

Legend and Grid Lines

This example shows the small style surface for bar charts without changing the underlying data bindings.

source: examples_db
charts:
  category_columns_styled:
    query:
      sql: |
        SELECT category, SUM(revenue) AS revenue, SUM(units_sold) AS units_sold FROM ecommerce_orders GROUP BY category ORDER BY revenue DESC
    type: bar
    title: Revenue by Category
    x: category
    y: revenue
    color: category
    style:
      stack: zero
      legend:
        visible: false
      axis:
        grid:
          visible: false
rows:
  - category_columns_styled
Dataface DF-UNKNOWN-INTERNALChart Error: category_columns_styledQuery execution failed: Source 'examples_db' not found. No source profiles are configured. Declare sources under `sources:` in your dataface.yml. (query: _inline_query_category_columns_styled)https://docs.it-dataface.com/guides/error-handling/?code=DF-UNKNOWN-INTERNAL 2026-07-17 15:04 UTC made with dataface

Axis, Scale, and Orientation

All presentation config lives under style. This is where the family distinguishes default vertical columns from horizontal bars.

Dataface field Maps to Vega-Lite Allowed values Notes
style.orientation bar orientation transform auto (default), vertical, or horizontal auto picks horizontal for categorical x, vertical for continuous x (temporal/quantitative/date-like ordinal); vertical and horizontal lock the orientation.
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.scale config.scale ScaleStyle object Global scale config (zero, nice, domain, clamp).
style.stack encoding.y.stack "none", "zero", "normalize", "center" Stacking behavior. Omit stack when a color field is present to get the default side-by-side grouped layout. Set "none" for grouped (side-by-side), "zero" for stacked-from-baseline, "normalize" for 100% stacked, "center" for diverging stacks. (Within-group spacing of grouped bars is controlled by style.overlap, not stack.)
style.stack_order encoding.order "value" (default), "data", "alphabetical" Z-order of stacked segments. "value" puts the largest aggregate at the baseline. "data" follows SQL row order (orientation-stable not guaranteed). "alphabetical" sorts by color field name. Ignored when stacking is off or no color is set.
style.overlap bar xOffset/yOffset spacing "auto" (default), "none", "flush", "partial", "full", or a number Within-group spacing for grouped bars (a color field, not stacked). "auto" adapts to the series count — partial (25% overlap) at 2 series, none (small gap) at 3+. "none" gaps, "flush" touches, "partial" overlaps 25%, "full" coincides. A number is a fraction of bar width: >0 overlaps, 0 touches, <0 gaps. Positive overlap is only valid for 2 series — overlapping 3+ series buries the middle one, so it raises an error (use none/flush for 3+, or rely on auto). Setting any overlap with an active stack mode ("zero"/"normalize"/"center") is also an error.

Orientation and Axis Controls

This example uses style to turn a column chart into a horizontal ranking chart while also adjusting axis formatting and label space.

source: examples_db
charts:
  product_revenue_ranked:
    query:
      sql: |
        SELECT product, category, SUM(revenue) AS revenue, SUM(units_sold) AS units_sold FROM ecommerce_orders GROUP BY product, category ORDER BY revenue DESC
    type: bar
    title: Product Revenue Ranking
    x: product
    y: revenue
    sort:
      by: revenue
      order: desc
    style:
      orientation: horizontal
      axis_x:
        format: currency_whole
      axis_y:
        label:
          max_width: 140
      scale:
        nice: true
rows:
  - product_revenue_ranked
Dataface DF-UNKNOWN-INTERNALChart Error: product_revenue_rankedQuery execution failed: Source 'examples_db' not found. No source profiles are configured. Declare sources under `sources:` in your dataface.yml. (query: _inline_query_product_revenue_ranked)https://docs.it-dataface.com/guides/error-handling/?code=DF-UNKNOWN-INTERNAL 2026-07-17 15:04 UTC made with dataface

Endpoint Labels and the Top-Row Series Rail

Set style.endpoint_labels.visible: true to move the series names off the side legend and onto the chart, anchored to each segment. Where the labels go depends on the orientation:

  • Vertical stacked column charts get one label per segment in a side pane, anchored to each segment's vertical midpoint in the rightmost column. The chart pane and label pane sit side-by-side in an hconcat.
  • Horizontal stacked bar charts get a single rail of labels above the top row of the chart — one label per series, centered horizontally on its segment's midpoint within the top categorical row. The chart pane and rail sit stacked in a vconcat. The bottom row's value axis still carries the numeric measure labels.

The asymmetry follows from the reading direction: vertical stacks read top-to-bottom along the measure axis, so per-segment side labels feel natural; horizontal stacks read left-to-right inside one row, so a single label rail above the top row is the direct equivalent.

Dataface field Allowed values Notes
style.endpoint_labels.visible true or false Opt-in feature toggle. Defaults to false on every built-in theme — set per-chart when you want it.

When the label pane or rail is on, the categorical legend turns off automatically — the two would encode the same series→colour mapping twice. On the vertical layout, the y-axis also auto-flips to the left so it doesn't collide with the right-edge label pane.

When neighboring labels in the horizontal rail would overlap, the resolver lifts the right-hand label by one line-height (vertical dodge). The leftmost label always sits at the base row — that determinism is part of the contract. Dodging caps at three rows above base; if all three rows still collide, the resolver accepts overlap deterministically rather than dropping a label silently.

The endpoint-labels primitive does not fire on grouped horizontal bars (either explicit stack: none or the grouped-by-default when stack is omitted and a color field is present), since grouped bars don't form stacks to label. It also stays off for single-series charts (no color encoding) where there are no segments to name.

Vertical Stacked Columns

source: examples_db
charts:
  product_revenue_by_category_vertical:
    query:
      sql: |
        SELECT product, category, SUM(revenue) AS revenue FROM ecommerce_orders GROUP BY product, category ORDER BY product, category
    type: bar
    title: Revenue by Product (vertical stack)
    x: product
    y: revenue
    color: category
    style:
      stack: zero
      orientation: vertical
      endpoint_labels:
        visible: true

rows:
  - product_revenue_by_category_vertical
Dataface DF-UNKNOWN-INTERNALChart Error: product_revenue_by_category_verticalQuery execution failed: Source 'examples_db' not found. No source profiles are configured. Declare sources under `sources:` in your dataface.yml. (query: _inline_query_product_revenue_by_category_vertical)https://docs.it-dataface.com/guides/error-handling/?code=DF-UNKNOWN-INTERNAL 2026-07-17 15:04 UTC made with dataface

Horizontal Stacked Bars

source: examples_db
charts:
  product_revenue_by_category:
    query:
      sql: |
        SELECT product, category, SUM(revenue) AS revenue FROM ecommerce_orders GROUP BY product, category ORDER BY product, category
    type: bar
    title: Revenue by Product (stacked by Category)
    x: product
    y: revenue
    color: category
    style:
      stack: zero
      orientation: horizontal
      endpoint_labels:
        visible: true

rows:
  - product_revenue_by_category
Dataface DF-UNKNOWN-INTERNALChart Error: product_revenue_by_categoryQuery execution failed: Source 'examples_db' not found. No source profiles are configured. Declare sources under `sources:` in your dataface.yml. (query: _inline_query_product_revenue_by_category)https://docs.it-dataface.com/guides/error-handling/?code=DF-UNKNOWN-INTERNAL 2026-07-17 15:04 UTC made with dataface

Value Labels

Show the numeric value above (or inside) each bar by enabling style.bar.marks.bar.labels.visible.

<!-- dft-snippet: scaffold=bar_chart_base -->
style:
  bar:
    marks:
      bar:
        labels:
          visible: true
          position: top      # top | inside_top | middle
          format: null       # null inherits axis_quantitative.format (the measure-axis format, e.g. "~s"); or set e.g. ",.0f"
          dx: null           # pixel horizontal offset (overrides position default)
          dy: null           # pixel vertical offset (overrides position default)
          font:
            color: "#6b7280"
            size: 11

Position values:

Value Placement
top Outside, above the bar top — default
inside_top Just inside the top edge
middle Vertically centered in the bar

To enable labels for all bar charts at theme level, set marks.bar.labels.visible: true in your theme YAML.