# 📊 Custom Charts - Waterfall Chart Example

**URL:** <https://community.holistics.io/t/custom-charts-waterfall-chart-example/2402>\
**Category:** Tips and Showcases\
**Created:** [February 24, 2025, 8:15am UTC](https://community.holistics.io/t/custom-charts-waterfall-chart-example/2402 "2025-02-24T08:15:13Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![Theodore](https://community.holistics.io/user_avatar/community.holistics.io/theodore/32/832_2.png) [@Theodore](https://community.holistics.io/u/Theodore)\
**Post date:** [February 24, 2025, 8:15am UTC](https://community.holistics.io/t/custom-charts-waterfall-chart-example/2402/1 "2025-02-24T08:15:13Z")

</div>

# 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**
>
> ```auto
> 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)](https://docs.holistics.io/docs/charts/understand-custom-chart)
- Custom Charts Library: [Custom Chart Library | Holistics Docs (4.0)](https://docs.holistics.io/docs/charts/custom-charts/library/intro)
