Waterfall Chart
Waterfall chart is useful for visualizing how intermediate values contribute to a total, particularly when showing the cumulative effect of sequential positive or negative changes. Common applications include financial statements, P&L analysis, budget variances, and sales funnels.
Template Code
CustomChart {
fields {
field amount {
type: 'measure'
}
field label {
type: 'dimension'
}
field label_sorter {
type: 'dimension'
}
}
options {
option begin_label {
label: 'Begin Label'
type: 'input'
default_value: ''
}
option end_label {
label: 'End Label'
type: 'input'
default_value: 'Total'
}
option bar_size {
label: 'Bar Size'
type: 'number-input'
default_value: 50
}
option begin_end_color {
label: 'Begin - End Color'
type: 'color-picker'
default_value: '#BDBDBD'
}
option begin_end_text {
label: 'Begin - End Label Color'
type: 'color-picker'
default_value: 'black'
}
option positive {
label: 'Positive Color'
type: 'color-picker'
default_value: '#58A65C'
}
option negative {
label: 'Negative Color'
type: 'color-picker'
default_value: '#D85140'
}
option value_format {
label: 'Format'
type: 'input'
default_value: '$,.0f'
}
}
template: @vgl {
"$schema": "https://vega.github.io/schema/vega-lite/v5.json",
"data": {
"values": @{values}
},
"transform": [
{"calculate": "datum['@{fields.amount.name}']", "as": "amount"},
{"calculate": "datum['@{fields.label.name}']", "as": "label"},
{"calculate": "datum['@{fields.label_sorter.name}']", "as": "label_sorter"},
{
"window": [{"op": "sum", "field": "amount", "as": "sum"}],
"sort": [{"field": "label_sorter", "order": "ascending"}]
},
{
"window": [{"op": "lead", "field": "label", "as": "lead"}],
"sort": [{"field": "label_sorter", "order": "ascending"}]
},
{"calculate": "datum.lead === null ? '@{options.end_label.value}' : datum.lead", "as": "lead"},
{"calculate": "datum.label === '@{options.end_label.value}' ? 0 : datum.sum - datum.amount", "as": "previous_sum"},
{"calculate": "datum.label === '@{options.end_label.value}' ? datum.sum : datum.amount", "as": "amount"},
{
"calculate": "(datum.label !== '@{options.begin_label.value}' && datum.label !== '@{options.end_label.value}' && datum.amount > 0 ? '+' + format(datum.amount, '@{options.value_format.value}') : format(datum.amount, '@{options.value_format.value}'))",
"as": "text_amount"
},
{"calculate": "(datum.sum + datum.previous_sum) / 2", "as": "center"},
{"calculate": "datum.sum < datum.previous_sum ? datum.sum : ''", "as": "sum_dec"},
{"calculate": "datum.sum > datum.previous_sum ? datum.sum : ''", "as": "sum_inc"}
],
"params": [
{"name": "barSize", "value": @{options.bar_size.value}},
{"name": "ruleOffset", "expr": "barSize/2"}
],
"encoding": {
"x": {
"field": "label",
"type": "ordinal",
"sort": {"field": "label_sorter", "order": "ascending"},
"axis": {
"format": @{fields.label.format},
"formatType": "holisticsFormat"
}
}
},
"layer": [
{
"mark": {"type": "bar", "size": @{options.bar_size.value}},
"params": [
{
"name": "normalPointSelection",
"select": {
"type": "point",
"toggle": "true",
"clear": "mouseup"
}
}
],
"encoding": {
"y": {"field": "previous_sum", "type": "quantitative", "format": @{fields.amount.format}, "formatType": "holisticsFormat"},
"y2": {"field": "sum"},
"color": {
"condition": [
{
"test": "datum.label === '@{options.begin_label.value}'",
"value": @{options.begin_end_color.value}
},
{"test": "datum.sum < datum.previous_sum", "value": @{options.negative.value}}
],
"value": @{options.positive.value}
},
"fillOpacity": {
"condition": {"param": "normalPointSelection", "value": 1},
"value": 0.3
},
"tooltip": [
{"field": "label", "title": @{fields.label.name}, "format": @{fields.label.format}, "formatType": "holisticsFormat"},
{"field": "amount", "title": @{fields.amount.name}, "format": @{options.value_format.value}},
{"field": "sum", "title": "Total", "format": @{options.value_format.value}}
]
}
},
{
"transform": [
{"filter": "datum.lead === '@{options.end_label.value}'"},
{"calculate": "datum.sum / 2", "as": "center_end"}
],
"encoding": {
"x": {
"field": "lead",
"sort": null,
"axis": {
"format": @{fields.label.format},
"formatType": "holisticsFormat"
}
},
"tooltip": [
{"field": "sum", "title": "Total", "format": @{options.value_format.value}}
]
},
"layer": [
{
"mark": {"type": "bar", "size": @{options.bar_size.value}},
"encoding": {
"y": {"field": "sum", "type": "quantitative"},
"color": {"value": @{options.begin_end_color.value}}
}
},
{
"mark": {"type": "text", "fontWeight": "bold", "baseline": "middle"},
"encoding": {
"y": {"field": "center_end", "type": "quantitative"},
"text": {"field": "sum", "format": @{options.value_format.value}},
"color": {"value": @{options.begin_end_text.value}}
}
}
]
},
{
"mark": {
"type": "rule",
"color": @{options.begin_end_color.value},
"opacity": 1,
"strokeWidth": 1,
"xOffset": {"expr": "ruleOffset"},
"x2Offset": {"expr": "-ruleOffset"}
},
"encoding": {
"x2": {"field": "lead"},
"y": {"field": "sum", "type": "quantitative"}
}
},
{
"mark": {"type": "text", "fontWeight": "bold", "baseline": "middle"},
"encoding": {
"y": {"field": "center", "type": "quantitative"},
"text": {"field": "text_amount", "type": "nominal"},
"color": {
"condition": [
{
"test": "datum.label === '@{options.begin_label.value}' || datum.label === '@{options.end_label.value}'",
"value": @{options.begin_end_text.value}
}
],
"value": "white"
}
}
}
],
"holisticsConfig": {
"crossFilterSignals": ["normalPointSelection"],
},
"config": {
"axis": {
"title": null,
"ticks": false,
"labelPadding": 10,
"labelFontSize": 11,
"labelColor": "#858B9E",
"labelAngle": 0,
"labelOverlap": "parity",
"labelLimit": 70,
"gridDash": [8, 3],
"gridColor": "#F4F6F8",
"domainColor": "#bec1cb"
},
"axisY": {
"domain": false
},
"view": {
"opacity": 0
},
"font": "Inter"
}
};;
}
Required fields
Field type | Description | |
---|---|---|
Amount | Measure | The numeric value for each step. Can be positive or negative to show increases or decreases |
Label | Dimension | The name or description of each step in your sequence |
Label Sorter | Dimension | Control the order of steps in your waterfall chart |
Chart options
- Begin / End Column Label: Customize labels for the starting and ending columns (default: empty for start, βTotalβ for end)
- Begin / End Column Color: Set colors for the first and last columns to distinguish them from intermediate steps
- Column width: Adjust the thickness of the bars for better visual balance
- Positive Value Color: Color for columns showing increases
- Negative Value color: Color for columns showing decreases
- Value format: Customize how numbers are displayed (e.g., β$,.0fβ for currency)
Interactive features
- Hover tooltips show detailed information for each step
- Click to highlight specific columns
- Cross-filtering support to connect with other charts
- Auto-calculated running totals and intermediate values
Getting started with Custom Charts
Prerequisites: Custom Charts is available to customers from Standard Plan and above
- Understand Custom Charts: Understand Custom Chart | Holistics Docs (4.0)
- Custom Charts Library: Custom Chart Library | Holistics Docs (4.0)