Skip to content

Commit 26865e3

Browse files
jqnatividadclaude
authored andcommitted
docs: add book recipe page and example for funnel and waterfall
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 3b36754 commit 26865e3

6 files changed

Lines changed: 98 additions & 3 deletions

File tree

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+
- [Funnel Charts](./recipes/basic_charts/funnel_charts.md)
2223
- [Waterfall Charts](./recipes/basic_charts/waterfall_charts.md)
2324
- [Icicle Charts](./recipes/basic_charts/icicle_charts.md)
2425
- [Indicator Charts](./recipes/basic_charts/indicator_charts.md)

docs/book/src/recipes/basic_charts.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,5 @@ 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)
17+
Funnel Charts | [![Funnel Charts](./img/funnel.png)](./basic_charts/funnel_charts.md)
18+
Waterfall Charts | [![Waterfall Charts](./img/waterfall.png)](./basic_charts/waterfall_charts.md)
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Funnel Charts
2+
3+
A funnel chart shows how a quantity narrows as it passes through a sequence of stages. It is a
4+
*containment* form: each stage is understood to be a subset of the one above it, and the band
5+
widths carry that claim — so it suits pipelines that genuinely nest, such as a conversion funnel.
6+
7+
Stages are fed **upstream-first**: plotly draws index 0 at the top, which is the opposite of a
8+
plain category axis.
9+
10+
`text_info` takes a `+`-joined flaglist, so a band can show its own value alongside its conversion
11+
from the previous stage (`"value+percent previous"`), the share of the first stage
12+
(`"percent initial"`), or the share of the total (`"percent total"`).
13+
14+
For a sequence whose steps do *not* nest — independent totals, or contributions that can be
15+
negative — see [Waterfall Charts](./waterfall_charts.md) instead.
16+
17+
The following imports have been used to produce the plots below:
18+
19+
```rust,no_run
20+
use plotly::color::NamedColor;
21+
use plotly::common::{Marker, Orientation};
22+
use plotly::funnel::Connector as FunnelConnector;
23+
use plotly::{Funnel, Plot};
24+
```
25+
26+
The `to_inline_html` method is used to produce the html plot displayed in this page.
27+
28+
## Basic Funnel
29+
```rust,no_run
30+
{{#include ../../../../../examples/basic_charts/src/main.rs:basic_funnel}}
31+
```
32+
33+
{{#include ../../../../../examples/basic_charts/output/inline_basic_funnel.html}}
20.4 KB
Loading
23.5 KB
Loading

examples/basic_charts/src/main.rs

Lines changed: 62 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use plotly::{
77
ColorScale, ColorScalePalette, DashType, Domain, Fill, Font, HoverInfo, Line, LineShape,
88
Marker, Mode, Orientation, Pattern, PatternShape,
99
},
10+
funnel::Connector as FunnelConnector,
1011
icicle::{
1112
BranchValues as IcicleBranchValues, Leaf as IcicleLeaf, Marker as IcicleMarker,
1213
PathBar as IciclePathBar, Side as IcicleSide, Tiling as IcicleTiling,
@@ -31,8 +32,8 @@ use plotly::{
3132
},
3233
treemap::{BranchValues, Marker as TreemapMarker, Packing, PathBar, Side, Tiling},
3334
waterfall::{Marker as WaterfallMarker, Measure, MeasureStyle},
34-
Bar, Icicle, Indicator, Parcats, Pie, Plot, Sankey, Scatter, ScatterPolar, Sunburst, Table,
35-
Treemap, Waterfall,
35+
Bar, Funnel, Icicle, Indicator, Parcats, Pie, Plot, Sankey, Scatter, ScatterPolar, Sunburst,
36+
Table, Treemap, Waterfall,
3637
};
3738
use plotly_utils::write_example_to_html;
3839
use rand_distr::{Distribution, Normal, Uniform};
@@ -812,6 +813,59 @@ fn bar_chart_with_pattern_fills(show: bool, file_name: &str) {
812813
}
813814
// ANCHOR_END: bar_chart_with_pattern_fills
814815

816+
// Funnel Charts
817+
// ANCHOR: basic_funnel
818+
fn basic_funnel(show: bool, file_name: &str) {
819+
let trace = Funnel::new(
820+
vec![100, 60, 40, 25],
821+
vec!["Visits", "Signups", "Trials", "Purchases"],
822+
)
823+
.text_info("value+percent previous")
824+
.connector(FunnelConnector::new().visible(true))
825+
.marker(Marker::new().color(NamedColor::SteelBlue));
826+
827+
let layout = Layout::new().title("Conversion Funnel");
828+
let mut plot = Plot::new();
829+
plot.set_layout(layout);
830+
plot.add_trace(trace);
831+
832+
let path = write_example_to_html(&plot, file_name);
833+
if show {
834+
plot.show_html(path);
835+
}
836+
}
837+
// ANCHOR_END: basic_funnel
838+
839+
// Waterfall Charts
840+
// ANCHOR: basic_waterfall
841+
fn basic_waterfall(show: bool, file_name: &str) {
842+
let trace = Waterfall::new(
843+
vec!["Start", "Revenue", "Costs", "End"],
844+
vec![100.0, 40.0, -25.0, 0.0],
845+
)
846+
.measure(vec![
847+
Measure::Absolute,
848+
Measure::Relative,
849+
Measure::Relative,
850+
Measure::Total,
851+
])
852+
.text_info("label+delta")
853+
.increasing(MeasureStyle::new().marker(WaterfallMarker::new().color(NamedColor::SeaGreen)))
854+
.decreasing(MeasureStyle::new().marker(WaterfallMarker::new().color(NamedColor::Tomato)))
855+
.totals(MeasureStyle::new().marker(WaterfallMarker::new().color(NamedColor::SteelBlue)));
856+
857+
let layout = Layout::new().title("Basic Waterfall");
858+
let mut plot = Plot::new();
859+
plot.set_layout(layout);
860+
plot.add_trace(trace);
861+
862+
let path = write_example_to_html(&plot, file_name);
863+
if show {
864+
plot.show_html(path);
865+
}
866+
}
867+
// ANCHOR_END: basic_waterfall
868+
815869
// Sankey Diagrams
816870
// ANCHOR: basic_sankey_diagram
817871
fn basic_sankey_diagram(show: bool, file_name: &str) {
@@ -1508,6 +1562,12 @@ fn main() {
15081562

15091563
bar_chart_with_pattern_fills(false, "bar_chart_with_pattern_fills");
15101564

1565+
// Funnel Charts
1566+
basic_funnel(true, "basic_funnel");
1567+
1568+
// Waterfall Charts
1569+
basic_waterfall(true, "basic_waterfall");
1570+
15111571
// Sankey Diagrams
15121572
basic_sankey_diagram(false, "basic_sankey_diagram");
15131573
custom_node_sankey_diagram(false, "custom_node_sankey_diagram");

0 commit comments

Comments
 (0)