Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,26 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a

https://github.com/plotly/plotly.rs/pull/350

## [Unreleased]

### Added

- [[#NNN](https://github.com/plotly/plotly.rs/pull/NNN)] Add `Treemap` trace type, with `Tiling`/`PathBar` helpers, a dedicated `treemap::Marker` (`pad`/`corner_radius`/`depth_fade`), and `treemapcolorway`/`extendtreemapcolors` layout options
- [[#NNN](https://github.com/plotly/plotly.rs/pull/NNN)] Add `Sunburst` trace type
- [[#407](https://github.com/plotly/plotly.rs/issues/407)] Expose plotly.js 3.1–3.6 attributes:
- `Layout`: `hoversort`, `hoveranywhere`, `clickanywhere`
- `Axis`: `zerolinelayer` (`ZeroLineLayer`), `minorloglabels`, `modebardisable` (`ModeBarDisable`), `ticklabelposition` (`TickLabelPosition`), `unifiedhovertitle` (`UnifiedHoverTitle`), and `ExponentFormat::SIExtended`
- `Legend`: `maxheight`
- `Configuration`: `displayNotifier`
- `common::Label` (hover labels): `showarrow`
- `common::Pattern`: `path` (arbitrary SVG path fill)
- `Candlestick`/`Ohlc`: `hovertemplate`
- `hovertemplatefallback`/`texttemplatefallback` across applicable traces

### Changed

- [[#407](https://github.com/plotly/plotly.rs/issues/407)] Upgrade bundled plotly.js from 3.0.1 to 3.6.0

## [0.14.1] - 2026-02-15

### Fixed
Expand Down
469 changes: 236 additions & 233 deletions docs/book/plotly.min.js

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions docs/book/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
- [Bar Charts](./recipes/basic_charts/bar_charts.md)
- [Pie Charts](./recipes/basic_charts/pie_charts.md)
- [Sankey Diagrams](./recipes/basic_charts/sankey_diagrams.md)
- [Treemap Charts](./recipes/basic_charts/treemap_charts.md)
- [Sunburst Charts](./recipes/basic_charts/sunburst_charts.md)
- [Statistical Charts](./recipes/statistical_charts.md)
- [Error Bars](./recipes/statistical_charts/error_bars.md)
- [Box Plots](./recipes/statistical_charts/box_plots.md)
Expand Down
2 changes: 2 additions & 0 deletions docs/book/src/recipes/basic_charts.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,5 @@ Line Charts | [![Line Charts](./img/line_shape_options_for_interpolation.png)](.
Bar Charts | [![Bar Charts](./img/bar_chart_with_error_bars.png)](./basic_charts/scatter_plots.md)
Pie Charts | [![Pie Charts](./img/pie_charts.png)](./basic_charts/pie_charts.md)
Sankey Diagrams | [![Sankey Diagrams](./img/basic_sankey.png)](./basic_charts/sankey_diagrams.md)
Treemap Charts | [Treemap Charts](./basic_charts/treemap_charts.md)
Sunburst Charts | [Sunburst Charts](./basic_charts/sunburst_charts.md)
27 changes: 27 additions & 0 deletions docs/book/src/recipes/basic_charts/sunburst_charts.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Sunburst Charts

The following imports have been used to produce the plots below:

```rust,no_run
use plotly::common::Orientation;
use plotly::sunburst::Leaf;
use plotly::treemap::BranchValues;
use plotly::{Plot, Sunburst};
```

The `to_inline_html` method is used to produce the html plot displayed in this page.

## Basic Sunburst
```rust,no_run
{{#include ../../../../../examples/basic_charts/src/main.rs:basic_sunburst}}
```

{{#include ../../../../../examples/basic_charts/output/inline_basic_sunburst.html}}


## Styled Sunburst with Branch Values and Leaf Opacity
```rust,no_run
{{#include ../../../../../examples/basic_charts/src/main.rs:styled_sunburst}}
```

{{#include ../../../../../examples/basic_charts/output/inline_styled_sunburst.html}}
25 changes: 25 additions & 0 deletions docs/book/src/recipes/basic_charts/treemap_charts.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Treemap Charts

The following imports have been used to produce the plots below:

```rust,no_run
use plotly::treemap::{BranchValues, Packing, PathBar, Side, Tiling};
use plotly::{Plot, Treemap};
```

The `to_inline_html` method is used to produce the html plot displayed in this page.

## Basic Treemap
```rust,no_run
{{#include ../../../../../examples/basic_charts/src/main.rs:basic_treemap}}
```

{{#include ../../../../../examples/basic_charts/output/inline_basic_treemap.html}}


## Styled Treemap with Tiling and Path Bar
```rust,no_run
{{#include ../../../../../examples/basic_charts/src/main.rs:styled_treemap}}
```

{{#include ../../../../../examples/basic_charts/output/inline_styled_treemap.html}}
2 changes: 1 addition & 1 deletion docs/book/theme/header.hbs
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<script src="https://cdn.plot.ly/plotly-3.0.1.min.js"></script>
<script src="https://cdn.plot.ly/plotly-3.6.0.min.js"></script>
114 changes: 113 additions & 1 deletion examples/basic_charts/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@ use plotly::{
TicksDirection, TraceOrder,
},
sankey::{Line as SankeyLine, Link, Node},
sunburst::{InsideTextOrientation, Leaf},
traces::table::{
Align as TableAlign, Cells, Fill as TableFill, Font as TableFont, Header, Line as TableLine,
},
Bar, Pie, Plot, Sankey, Scatter, ScatterPolar, Table,
treemap::{BranchValues, Marker as TreemapMarker, Packing, PathBar, Side, Tiling},
Bar, Pie, Plot, Sankey, Scatter, ScatterPolar, Sunburst, Table, Treemap,
};
use plotly_utils::write_example_to_html;
use rand_distr::{Distribution, Normal, Uniform};
Expand Down Expand Up @@ -1043,6 +1045,108 @@ fn grouped_donout_pie_charts(show: bool, file_name: &str) {
}
// ANCHOR_END: grouped_donout_pie_charts

// ANCHOR: basic_treemap
fn basic_treemap(show: bool, file_name: &str) {
let labels = vec![
"Eve", "Cain", "Seth", "Enos", "Noam", "Abel", "Awan", "Enoch", "Azura",
];
let parents = vec![
"", "Eve", "Eve", "Seth", "Seth", "Eve", "Eve", "Awan", "Eve",
];
let trace = Treemap::new(labels, parents)
.values(vec![10.0, 14.0, 12.0, 10.0, 2.0, 6.0, 6.0, 4.0, 4.0])
.text_info("label+value");

let mut plot = Plot::new();
plot.add_trace(trace);

let path = write_example_to_html(&plot, file_name);
if show {
plot.show_html(path);
}
}
// ANCHOR_END: basic_treemap

// ANCHOR: styled_treemap
fn styled_treemap(show: bool, file_name: &str) {
let labels = vec![
"Total",
"Tech",
"Health",
"Finance",
"Software",
"Hardware",
"Pharma",
"Devices",
"Banking",
"Insurance",
];
let parents = vec![
"", "Total", "Total", "Total", "Tech", "Tech", "Health", "Health", "Finance", "Finance",
];
let trace = Treemap::new(labels, parents)
.values(vec![0.0, 0.0, 0.0, 0.0, 40.0, 30.0, 25.0, 15.0, 20.0, 18.0])
.branch_values(BranchValues::Remainder)
.marker(
TreemapMarker::new()
.corner_radius(5.0)
.line(Line::new().width(1.0).color(NamedColor::White)),
)
.tiling(Tiling::new().packing(Packing::Binary).pad(2.0))
.path_bar(PathBar::new().visible(true).side(Side::Top))
.text_info("label+value+percent parent");

let mut plot = Plot::new();
plot.add_trace(trace);

let path = write_example_to_html(&plot, file_name);
if show {
plot.show_html(path);
}
}
// ANCHOR_END: styled_treemap

// ANCHOR: basic_sunburst
fn basic_sunburst(show: bool, file_name: &str) {
let labels = vec![
"Eve", "Cain", "Seth", "Enos", "Noam", "Abel", "Awan", "Enoch", "Azura",
];
let parents = vec![
"", "Eve", "Eve", "Seth", "Seth", "Eve", "Eve", "Awan", "Eve",
];
let trace = Sunburst::new(labels, parents)
.values(vec![10.0, 14.0, 12.0, 10.0, 2.0, 6.0, 6.0, 4.0, 4.0]);

let mut plot = Plot::new();
plot.add_trace(trace);

let path = write_example_to_html(&plot, file_name);
if show {
plot.show_html(path);
}
}
// ANCHOR_END: basic_sunburst

// ANCHOR: styled_sunburst
fn styled_sunburst(show: bool, file_name: &str) {
let labels = vec!["Root", "Branch A", "Branch B", "Leaf A1", "Leaf B1"];
let parents = vec!["", "Root", "Root", "Branch A", "Branch B"];
let trace = Sunburst::new(labels, parents)
.values(vec![8.0, 3.0, 5.0, 3.0, 5.0])
.branch_values(BranchValues::Total)
.leaf(Leaf::new().opacity(0.7))
.inside_text_orientation(InsideTextOrientation::Radial);

let mut plot = Plot::new();
plot.add_trace(trace);

let path = write_example_to_html(&plot, file_name);
if show {
plot.show_html(path);
}
}
// ANCHOR_END: styled_sunburst

// ANCHOR: set_lower_or_upper_bound_on_axis
fn set_lower_or_upper_bound_on_axis(show: bool, file_name: &str) {
use std::fs::File;
Expand Down Expand Up @@ -1200,6 +1304,14 @@ fn main() {

grouped_donout_pie_charts(false, "grouped_donout_pie_charts");

// Treemap Charts
basic_treemap(false, "basic_treemap");
styled_treemap(false, "styled_treemap");

// Sunburst Charts
basic_sunburst(false, "basic_sunburst");
styled_sunburst(false, "styled_sunburst");

// Set Lower or Upper Bound on Axis
set_lower_or_upper_bound_on_axis(false, "set_lower_or_upper_bound_on_axis");
}
469 changes: 236 additions & 233 deletions plotly/resource/plotly.min.js

Large diffs are not rendered by default.

35 changes: 33 additions & 2 deletions plotly/src/common/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,8 @@ pub enum PlotType {
DensityMapbox,
Table,
Pie,
Treemap,
Sunburst,
}

#[derive(Serialize, Clone, Debug)]
Expand Down Expand Up @@ -612,6 +614,8 @@ pub enum ExponentFormat {
SI,
#[serde(rename = "B")]
B,
#[serde(rename = "SI extended")]
SIExtended,
}

#[derive(Serialize, Clone, Debug)]
Expand Down Expand Up @@ -792,6 +796,9 @@ pub enum PatternFillMode {
#[derive(Serialize, Clone, Debug, FieldSetter)]
pub struct Pattern {
shape: Option<Dim<PatternShape>>,
/// An arbitrary SVG path string to use as the pattern fill, as an
/// alternative to one of the preset `shape` values.
path: Option<Dim<String>>,
#[serde(rename = "fillmode")]
fill_mode: Option<PatternFillMode>,
#[serde(rename = "bgcolor")]
Expand Down Expand Up @@ -977,6 +984,10 @@ pub struct Label {
align: Option<String>,
#[serde(rename = "namelength")]
name_length: Option<Dim<i32>>,
/// Determines whether or not the triangular caret pointing to the data
/// point is shown on the hover label box.
#[serde(rename = "showarrow")]
show_arrow: Option<bool>,
}

impl Label {
Expand Down Expand Up @@ -1622,6 +1633,10 @@ mod tests {
assert_eq!(to_value(ExponentFormat::Power).unwrap(), json!("power"));
assert_eq!(to_value(ExponentFormat::SI).unwrap(), json!("SI"));
assert_eq!(to_value(ExponentFormat::B).unwrap(), json!("B"));
assert_eq!(
to_value(ExponentFormat::SIExtended).unwrap(),
json!("SI extended")
);
}

#[test]
Expand Down Expand Up @@ -1703,10 +1718,12 @@ mod tests {
.foreground_color_array(vec![NamedColor::Red, NamedColor::Green])
.foreground_opacity(0.9)
.size_array(vec![10.0, 20.0])
.solidity_array(vec![0.1, 0.2]);
.solidity_array(vec![0.1, 0.2])
.path_array(vec!["M0,0 L10,10", "M5,5 L15,15"]);

let expected = json!({
"shape": ["-", "|"],
"path": ["M0,0 L10,10", "M5,5 L15,15"],
"fillmode": "overlay",
"bgcolor": ["black", "blue"],
"fgcolor": ["red", "green"],
Expand All @@ -1718,6 +1735,18 @@ mod tests {
assert_eq!(to_value(pattern).unwrap(), expected);
}

#[test]
fn serialize_pattern_path() {
let pattern = Pattern::new().path("M0,0 L10,10");
assert_eq!(to_value(pattern).unwrap(), json!({"path": "M0,0 L10,10"}));

let pattern = Pattern::new().path_array(vec!["M0,0 L10,10", "M5,5 L15,15"]);
assert_eq!(
to_value(pattern).unwrap(),
json!({"path": ["M0,0 L10,10", "M5,5 L15,15"]})
);
}

#[test]
fn serialize_marker() {
let marker = Marker::new()
Expand Down Expand Up @@ -1887,13 +1916,15 @@ mod tests {
.font(Font::new())
.align("something")
.name_length_array(vec![5, 10])
.name_length(6);
.name_length(6)
.show_arrow(false);
let expected = json!({
"bgcolor": "#FFFFFF",
"bordercolor": "#000000",
"font": {},
"align": "something",
"namelength": 6,
"showarrow": false,
});

assert_eq!(to_value(label).unwrap(), expected);
Expand Down
10 changes: 10 additions & 0 deletions plotly/src/configuration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ pub struct Configuration {
plot_gl_pixel_ratio: Option<PlotGLPixelRatio>,
show_send_to_cloud: Option<bool>,
queue_length: Option<usize>,
display_notifier: Option<bool>,
}

impl Configuration {
Expand Down Expand Up @@ -420,6 +421,13 @@ impl Configuration {
self
}

/// Determines whether the notifier is displayed in the top right area of
/// the viewport.
pub fn display_notifier(mut self, display_notifier: bool) -> Self {
self.display_notifier = Some(display_notifier);
self
}

/// Sets which localization to use. When using this setting, make sure that
/// the appropriate locale is present in the HTML file. For example, to
/// use the "fr" locale, <script src="https://cdn.plot.ly/plotly-locale-fr-latest.js"></script> must be present.
Expand Down Expand Up @@ -552,6 +560,7 @@ mod tests {
.topojson_url("topojson_url")
.mapbox_access_token("123")
.queue_length(100)
.display_notifier(true)
.locale("en");

let expected = json!({
Expand Down Expand Up @@ -583,6 +592,7 @@ mod tests {
"topojsonURL": "topojson_url",
"mapboxAccessToken": "123",
"queueLength": 100,
"displayNotifier": true,
"locale": "en"
});

Expand Down
Loading