Skip to content

Commit bf47b18

Browse files
jqnatividadclaude
authored andcommitted
feat(traces): add Waterfall trace type
plotly.js has shipped the `waterfall` trace since well before the bundled 3.7.0 build — only the Rust wrapper was missing. It registers with the same categories as `funnel` (bar-like, cartesian, svg, oriented), so it composes with subplot grids and static image export. The layout-level `waterfallmode`/`waterfallgap`/`waterfallgroupgap` attributes and the `WaterfallMode` enum already existed; this fills in the trace. Field set is exactly the attributes plotly.js declares in `waterfall`'s own block, plus the base-trace attributes `Bar` already carries, minus the date-axis period family — `xperiodalignment` needs a `PeriodAlignment` enum that does not exist yet, and waterfall's position axis is categorical in practice. Consequently `base` is scalar (`arrayOk: false` here, unlike `Bar`), there is no top-level `marker`, and error bars, calendars and point selection are absent. `measure` is a typed enum but `textinfo` stays a plain `String`, and the difference is the schema's: `textinfo` is a `flaglist`, an open-ended `+`-joined set, so it follows the existing `pie.rs`/`funnel.rs` precedent. `measure` is a `data_array` whose entries plotly.js validates against a closed set, silently treating anything it does not recognise as `relative` — a typo there renders a different chart rather than raising an error, which is what earns it a type. Bar colours come from `increasing`/`decreasing`/`totals` rather than a per-point array, because plotly.js declares every attribute in those blocks `arrayOk: false`; all three share one `MeasureStyle`/`Marker` pair since the schema generates them from a single helper. `Connector` is waterfall's own — it has no `fillcolor` and gains a `ConnectorMode`, so `funnel::Connector` is not reusable. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Signed-off-by: Andrei Gherghescu <8067229+andrei-ng@users.noreply.github.com>
1 parent 3c5a1ab commit bf47b18

9 files changed

Lines changed: 596 additions & 3 deletions

File tree

‎CHANGELOG.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a
1414
- [[#414](https://github.com/plotly/plotly.rs/issues/414)] Add `DensityMap` (MapLibre `map` subplot) trace type — density heatmaps with full color-scale and hover support
1515
- [[#417](https://github.com/plotly/plotly.rs/issues/417)] Add `ScatterMap` (MapLibre `map` subplot) trace type — the modern counterpart to `ScatterMapbox`
1616
- Add `Funnel` trace type (bar-like, cartesian) with `Connector` and `FunnelHoverInfo` options, plus the layout-level `funnelmode`/`funnelgap`/`funnelgroupgap` attributes and a `FunnelMode` enum
17+
- Add `Waterfall` trace type (bar-like, cartesian) with a typed `Measure` enum (`absolute`/`relative`/`total`), per-class `increasing`/`decreasing`/`totals` styling via `MeasureStyle`, a `Connector` with `ConnectorMode`, and a `WaterfallHoverInfo` enum. The layout-level `waterfallmode`/`waterfallgap`/`waterfallgroupgap` attributes and the `WaterfallMode` enum already existed
1718
- [[#418](https://github.com/plotly/plotly.rs/issues/418)] Add native point clustering to `ScatterMap` via a `Cluster` option
1819
- [[#421](https://github.com/plotly/plotly.rs/pull/421)] Backfill trace attributes for trace types to bring them to parity with plotly.js 3.7
1920
- [[#422](https://github.com/plotly/plotly.rs/issues/422)] Add `Indicator`, `Histogram2d`, `Icicle` trace types

‎docs/book/src/SUMMARY.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
- [Parallel Categories](./recipes/basic_charts/parcats_charts.md)
2020
- [Treemap Charts](./recipes/basic_charts/treemap_charts.md)
2121
- [Sunburst Charts](./recipes/basic_charts/sunburst_charts.md)
22+
- [Waterfall Charts](./recipes/basic_charts/waterfall_charts.md)
2223
- [Icicle Charts](./recipes/basic_charts/icicle_charts.md)
2324
- [Indicator Charts](./recipes/basic_charts/indicator_charts.md)
2425
- [Statistical Charts](./recipes/statistical_charts.md)

‎docs/book/src/recipes/basic_charts.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,4 @@ Treemap Charts | [![Treemap Charts](./img/treemap.png)](./basic_charts/treemap_c
1414
Sunburst Charts | [![Sunburst Charts](./img/sunburst.png)](./basic_charts/sunburst_charts.md)
1515
Icicle Charts | [![Icicle Charts](./img/icicle.png)](./basic_charts/icicle_charts.md)
1616
Indicator Charts | [![Indicator Charts](./img/indicator.png)](./basic_charts/indicator_charts.md)
17+
Waterfall Charts | [Waterfall Charts](./basic_charts/waterfall_charts.md)
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Waterfall Charts
2+
3+
A waterfall chart shows how a running total is built up from a starting value and a
4+
sequence of signed contributions. Each bar's role is set by its `Measure`:
5+
6+
- `Measure::Absolute` resets the running total and draws a bar from zero to it,
7+
- `Measure::Relative` adds a signed delta, drawn as a floating bar,
8+
- `Measure::Total` draws the running total accumulated so far.
9+
10+
The value supplied for a `Total` bar is ignored — plotly.js re-derives it — but the slot
11+
must still be present, because the label, value and `measure` arrays are read positionally.
12+
13+
The following imports have been used to produce the plots below:
14+
15+
```rust,no_run
16+
use plotly::color::NamedColor;
17+
use plotly::waterfall::{Marker as WaterfallMarker, Measure, MeasureStyle};
18+
use plotly::{Plot, Waterfall};
19+
```
20+
21+
The `to_inline_html` method is used to produce the html plot displayed in this page.
22+
23+
## Basic Waterfall
24+
```rust,no_run
25+
{{#include ../../../../../examples/basic_charts/src/main.rs:basic_waterfall}}
26+
```
27+
28+
{{#include ../../../../../examples/basic_charts/output/inline_basic_waterfall.html}}

‎examples/basic_charts/src/main.rs‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,9 @@ use plotly::{
3030
Align as TableAlign, Cells, Fill as TableFill, Font as TableFont, Header, Line as TableLine,
3131
},
3232
treemap::{BranchValues, Marker as TreemapMarker, Packing, PathBar, Side, Tiling},
33+
waterfall::{Marker as WaterfallMarker, Measure, MeasureStyle},
3334
Bar, Icicle, Indicator, Parcats, Pie, Plot, Sankey, Scatter, ScatterPolar, Sunburst, Table,
34-
Treemap,
35+
Treemap, Waterfall,
3536
};
3637
use plotly_utils::write_example_to_html;
3738
use rand_distr::{Distribution, Normal, Uniform};

‎plotly/src/common/mod.rs‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,7 @@ pub enum PlotType {
243243
Treemap,
244244
Sunburst,
245245
Violin,
246+
Waterfall,
246247
}
247248

248249
#[derive(Serialize, Clone, Debug)]

‎plotly/src/lib.rs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,14 +62,14 @@ pub use plot::{Plot, Trace, Traces};
6262
pub use traces::{
6363
box_plot, choropleth, choropleth_map, contour, density_map, funnel, heat_map, histogram, histogram2d,
6464
icicle, image, indicator, mesh3d, parcats, sankey, scatter, scatter3d, scatter_map,
65-
scatter_mapbox, splom, sunburst, surface, treemap, violin,
65+
scatter_mapbox, splom, sunburst, surface, treemap, violin, waterfall,
6666
};
6767
// Bring the different trace types into the top-level scope
6868
pub use traces::{
6969
Bar, BoxPlot, Candlestick, Choropleth, ChoroplethMap, Contour, DensityMap, DensityMapbox,
7070
Funnel, HeatMap, Histogram, Histogram2d, Icicle, Image, Indicator, Mesh3D, Ohlc, Parcats, Pie, Sankey,
7171
Scatter, Scatter3D, ScatterGeo, ScatterMap, ScatterMapbox, ScatterPolar, Splom, Sunburst,
72-
Surface, Table, Treemap, Violin,
72+
Surface, Table, Treemap, Violin, Waterfall,
7373
};
7474

7575
pub trait Restyle: serde::Serialize {}

‎plotly/src/traces/mod.rs‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ pub mod surface;
3232
pub mod table;
3333
pub mod treemap;
3434
pub mod violin;
35+
pub mod waterfall;
3536

3637
pub use bar::Bar;
3738
pub use box_plot::BoxPlot;
@@ -64,5 +65,6 @@ pub use surface::Surface;
6465
pub use table::Table;
6566
pub use treemap::Treemap;
6667
pub use violin::Violin;
68+
pub use waterfall::Waterfall;
6769

6870
pub use self::image::Image;

0 commit comments

Comments
 (0)