Skip to main content

Bar Chart with Running Average Line

A bar chart with a running average line overlays a moving-average line on a time-based bar chart, so you can read each period's value against a smoothed trend in one view.

  • Good for: smoothing noisy time series, spotting trend direction under volatile bars, comparing each period to its recent neighbors.
  • Not great for: non-time categories, comparing against a single flat benchmark (use Bar Chart with Average Line), or part-to-whole composition.
Bar chart with a running average line tracking the trend across bars

Syntax

Use the following AML definition to add the Bar Chart with Running Average Line to your custom chart library.

Legacy syntax
CustomChart {
fields {
field dimension {
type: "dimension"
label: "Dimension"
}

field measure {
type: "measure"
label: "Value"
}
}

options {
option tooltip {
type: 'toggle'
label: 'Show tooltip'
default_value: true
}
option bar_color {
type: 'color-picker'
label: 'Bar color'
default_value: '#00FFFF'
}
option line_color {
type: 'color-picker'
label: 'Line color'
default_value: '#00FFFF'
}
option points_before {
type: 'number-input'
label: 'Points before'
default_value: -3
}
option points_after {
type: 'number-input'
label: 'Points after'
default_value: 0
}
}

template: @vgl {
"data": {
"values": @{values}
},
"transform": [
{
"sort": [{"field": @{fields.dimension.name}}],
"window": [{"op": "average", "field": @{fields.measure.name}, "as": "avg"}],
"frame": [@{options.points_before.value}, @{options.points_after.value}]
}
],
"layer": [
{"mark": {
"type": "bar",
"tooltip": @{options.tooltip.value},
"color": @{options.bar_color.value}
},
"encoding": {
"x": {
"field": @{fields.dimension.name},
"type": "temporal",
"axis": {
"labelAngle": -45,
"format": @{fields.dimension.format},
"formatType": "holisticsFormat"
}
},
"y": {
"field": @{fields.measure.name},
"type": "quantitative",
"axis": {
"format": @{fields.measure.format},
"formatType": "holisticsFormat"
}
}
}
},
{"mark": {
"type": "line",
"tooltip": @{options.tooltip.value},
"color": @{options.line_color.value}
},
"encoding": {
"x": {"field": @{fields.dimension.name}, "type": "nominal"},
"y": {"field": "avg", "type": "quantitative"}
}

}
]};;
}

Required fields

A Bar Chart with Running Average Line expects exactly two fields. Each row is one bar, ordered along a time axis.

FieldLabelTypeRole
dimensionDimensiondimensionTime axis (plotted as temporal); sets bar order and the running-average window. Sorted ascending (apply_order: 1).
valueValuemeasureBar height and the input to the running average. Sorted descending (apply_order: 2).

Data requirements: dimension must be a date or datetime, since the x-axis is temporal. Pre-aggregate to one row per time period; the template sorts by dimension and computes the running average over a sliding window but does not combine duplicate periods.

Sample data:

dimensionvalue
2024-01-014200
2024-02-013800
2024-03-015100
2024-04-014600
2024-05-015300
2024-06-014900

Options

Set these options to adjust the chart without editing the Vega template. The CustomChartDef block above declares each option's type and allowed values.

OptionDefaultEffect
tooltiptrueToggles hover tooltips on both the bars and the average line.
bar_color#255DD4Fill color of the bars.
line_color#E5484DColor of the running average line and its points.
points_before-3Window start, in rows before the current point, for the running average. -3 averages the current period and the three before it.
points_after0Window end, in rows after the current point. 0 stops the window at the current period.

Known limitations

  • Time axis only. The x-axis is temporal, so dimension must be a date or datetime. Non-time categories will not plot correctly.

  • Window is row-based, not calendar-based. points_before and points_after count rows, so gaps in the time series (missing periods) skew the average. Fill missing periods first for an even smoothing window.

  • Early bars have a partial window. The first few points average fewer rows than the full window, so the start of the line is less smoothed than the rest.


Open Markdown
Let us know what you think about this document :)