diff --git a/docs/book/src/SUMMARY.md b/docs/book/src/SUMMARY.md index a365aec3..4b0e8577 100644 --- a/docs/book/src/SUMMARY.md +++ b/docs/book/src/SUMMARY.md @@ -10,15 +10,16 @@ - [Basic Charts](./recipes/basic_charts.md) - [Scatter Plots](./recipes/basic_charts/scatter_plots.md) - [Line Charts](./recipes/basic_charts/line_charts.md) - - [Bar Charts](./recipes/basic_charts/bar_charts.md) - - [Sankey Diagrams](./recipes/basic_charts/sankey_diagrams.md) + - [Bar Charts](./recipes/basic_charts/bar_charts.md) + - [Pie Charts](./recipes/basic_charts/pie_charts.md) + - [Sankey Diagrams](./recipes/basic_charts/sankey_diagrams.md) - [Statistical Charts](./recipes/statistical_charts.md) - [Error Bars](./recipes/statistical_charts/error_bars.md) - [Box Plots](./recipes/statistical_charts/box_plots.md) - [Histograms](./recipes/statistical_charts/histograms.md) - [Scientific Charts](./recipes/scientific_charts.md) - [Contour Plots](./recipes/scientific_charts/contour_plots.md) - - [Heatmaps](./recipes/scientific_charts/heatmaps.md) + - [Heatmaps](./recipes/scientific_charts/heatmaps.md) - [Financial Charts](./recipes/financial_charts.md) - [Time Series and Date Axes](./recipes/financial_charts/time_series_and_date_axes.md) - [Candlestick Charts](./recipes/financial_charts/candlestick_charts.md) diff --git a/docs/book/src/recipes/basic_charts.md b/docs/book/src/recipes/basic_charts.md index c8e3a77f..aaf9f5a5 100644 --- a/docs/book/src/recipes/basic_charts.md +++ b/docs/book/src/recipes/basic_charts.md @@ -6,5 +6,6 @@ Kind | Link :---|:----: Scatter Plots |[![Scatter Plots](./img/line_and_scatter_plot.png)](./basic_charts/scatter_plots.md) Line Charts | [![Line Charts](./img/line_shape_options_for_interpolation.png)](./basic_charts/line_charts.md) -Bar Charts | [![Scatter Plots](./img/bar_chart_with_error_bars.png)](./basic_charts/scatter_plots.md) +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) diff --git a/docs/book/src/recipes/basic_charts/pie_charts.md b/docs/book/src/recipes/basic_charts/pie_charts.md new file mode 100644 index 00000000..bb17de49 --- /dev/null +++ b/docs/book/src/recipes/basic_charts/pie_charts.md @@ -0,0 +1,41 @@ +# Pie Charts + +The following imports have been used to produce the plots below: + +```rust,no_run +use plotly::common::{Domain, Font, HoverInfo, Orientation}; +use plotly::layout::{ + Annotation, Layout, LayoutGrid}, +use plotly::layout::Layout; +use plotly::{Pie, Plot}; +``` + +The `to_inline_html` method is used to produce the html plot displayed in this page. + + +## Basic Pie Chart +```rust,no_run +{{#include ../../../../../examples/basic_charts/src/main.rs:basic_pie_chart}} +``` + +{{#include ../../../../../examples/basic_charts/out/basic_pie_chart.html}} + +```rust,no_run +{{#include ../../../../../examples/basic_charts/src/main.rs:basic_pie_chart_labels}} +``` + +{{#include ../../../../../examples/basic_charts/out/basic_pie_chart_labels.html}} + +## Grouped Pie Chart +```rust,no_run +{{#include ../../../../../examples/basic_charts/src/main.rs:grouped_donout_pie_charts}} +``` + +{{#include ../../../../../examples/basic_charts/out/grouped_donout_pie_charts.html}} + +## Pie Chart Text Control +```rust,no_run +{{#include ../../../../../examples/basic_charts/src/main.rs:pie_chart_text_control}} +``` + +{{#include ../../../../../examples/basic_charts/out/pie_chart_text_control.html}} \ No newline at end of file diff --git a/docs/book/src/recipes/img/pie_charts.png b/docs/book/src/recipes/img/pie_charts.png new file mode 100644 index 00000000..5e114d76 Binary files /dev/null and b/docs/book/src/recipes/img/pie_charts.png differ diff --git a/examples/basic_charts/src/main.rs b/examples/basic_charts/src/main.rs index f66f5285..0de8a8ca 100644 --- a/examples/basic_charts/src/main.rs +++ b/examples/basic_charts/src/main.rs @@ -4,13 +4,16 @@ use ndarray::Array; use plotly::{ color::{NamedColor, Rgb, Rgba}, common::{ - ColorScale, ColorScalePalette, DashType, Fill, Font, Line, LineShape, Marker, Mode, - Orientation, Pattern, PatternShape, + ColorScale, ColorScalePalette, DashType, Domain, Fill, Font, HoverInfo, Line, LineShape, + Marker, Mode, Orientation, Pattern, PatternShape, + }, + layout::{ + Annotation, Axis, BarMode, CategoryOrder, Layout, LayoutGrid, Legend, TicksDirection, + TraceOrder, }, - layout::{Axis, BarMode, CategoryOrder, Layout, Legend, TicksDirection, TraceOrder}, sankey::{Line as SankeyLine, Link, Node}, traces::table::{Cells, Header}, - Bar, Plot, Sankey, Scatter, ScatterPolar, Table, + Bar, Pie, Plot, Sankey, Scatter, ScatterPolar, Table, }; use rand_distr::{Distribution, Normal, Uniform}; @@ -819,6 +822,138 @@ fn table_chart(show: bool) -> Plot { } // ANCHOR_END: table_chart +// Pie Charts +// ANCHOR: basic_pie_chart +fn basic_pie_chart(show: bool) -> Plot { + let values = vec![2, 3, 4]; + let labels = vec!["giraffes", "orangutans", "monkeys"]; + let t = Pie::new(values).labels(labels); + let mut plot = Plot::new(); + plot.add_trace(t); + + if show { + plot.show(); + } + plot +} +// ANCHOR_END: basic_pie_chart + +// ANCHOR: basic_pie_chart_labels +fn basic_pie_chart_labels(show: bool) -> Plot { + let labels = ["giraffes", "giraffes", "orangutans", "monkeys"]; + let t = Pie::::from_labels(&labels); + let mut plot = Plot::new(); + plot.add_trace(t); + + if show { + plot.show(); + } + plot +} +// ANCHOR_END: basic_pie_chart_labels + +// ANCHOR: pie_chart_text_control +fn pie_chart_text_control(show: bool) -> Plot { + let values = vec![2, 3, 4, 4]; + let labels = vec!["Wages", "Operating expenses", "Cost of sales", "Insurance"]; + let t = Pie::new(values) + .labels(labels) + .automargin(true) + .show_legend(true) + .text_position(plotly::common::Position::Outside) + .name("Costs") + .text_info("label+percent"); + let mut plot = Plot::new(); + plot.add_trace(t); + + let layout = Layout::new().height(700).width(700).show_legend(true); + plot.set_layout(layout); + + if show { + plot.show(); + } + plot +} +// ANCHOR_END: pie_chart_text_control + +// ANCHOR: grouped_donout_pie_charts +fn grouped_donout_pie_charts(show: bool) -> Plot { + let mut plot = Plot::new(); + + let values = vec![16, 15, 12, 6, 5, 4, 42]; + let labels = vec![ + "US", + "China", + "European Union", + "Russian Federation", + "Brazil", + "India", + "Rest of World", + ]; + let t = Pie::new(values) + .labels(labels) + .name("GHG Emissions") + .hover_info(HoverInfo::All) + .text("GHG") + .hole(0.4) + .domain(Domain::new().column(0)); + plot.add_trace(t); + + let values = vec![27, 11, 25, 8, 1, 3, 25]; + let labels = vec![ + "US", + "China", + "European Union", + "Russian Federation", + "Brazil", + "India", + "Rest of World", + ]; + + let t = Pie::new(values) + .labels(labels) + .name("CO2 Emissions") + .hover_info(HoverInfo::All) + .text("CO2") + .text_position(plotly::common::Position::Inside) + .hole(0.4) + .domain(Domain::new().column(1)); + plot.add_trace(t); + + let layout = Layout::new() + .title("Global Emissions 1990-2011") + .height(400) + .width(600) + .annotations(vec![ + Annotation::new() + .font(Font::new().size(20)) + .show_arrow(false) + .text("GHG") + .x(0.17) + .y(0.5), + Annotation::new() + .font(Font::new().size(20)) + .show_arrow(false) + .text("CO2") + .x(0.82) + .y(0.5), + ]) + .show_legend(false) + .grid( + LayoutGrid::new() + .columns(2) + .rows(1) + .pattern(plotly::layout::GridPattern::Independent), + ); + plot.set_layout(layout); + + if show { + plot.show(); + } + plot +} +// ANCHOR_END: grouped_donout_pie_charts + fn write_example_to_html(plot: Plot, name: &str) { std::fs::create_dir_all("./out").unwrap(); let html = plot.to_inline_html(Some(name)); @@ -869,4 +1004,13 @@ fn main() { // Sankey Diagrams write_example_to_html(basic_sankey_diagram(false), "basic_sankey_diagram"); + + // Pie Charts + write_example_to_html(basic_pie_chart(false), "basic_pie_chart"); + write_example_to_html(basic_pie_chart_labels(false), "basic_pie_chart_labels"); + write_example_to_html(pie_chart_text_control(false), "pie_chart_text_control"); + write_example_to_html( + grouped_donout_pie_charts(false), + "grouped_donout_pie_charts", + ); } diff --git a/plotly/src/common/color.rs b/plotly/src/common/color.rs index 1d7a03af..e03e0ee2 100644 --- a/plotly/src/common/color.rs +++ b/plotly/src/common/color.rs @@ -1,23 +1,22 @@ -//! This module provides several user interfaces for describing a color to be -//! used throughout the rest of the library. The easiest way of describing a -//! colour is to use a `&str` or `String`, which is simply serialized as-is and -//! passed on to the underlying `plotly.js` library. `plotly.js` supports [`CSS -//! color formats`], and will fallback to some default color if the color string -//! is malformed. -//! -//! For a more type-safe approach, the `RGB` or `RGBA` structs can be used to -//! construct a valid color, which will then get serialized to an appropriate -//! string representation. Cross-browser compatible [`predefined colors`] are -//! supported via the `NamedColor` enum. -//! -//! The `Color` trait is public, and so can be implemented for custom colour -//! types. The user can then implement a valid serialization function according -//! to their own requirements. On the whole, that should be largely unnecessary -//! given the functionality already provided within this module. -//! -//! [`CSS color formats`]: https://www.w3schools.com/cssref/css_colors_legal.asp -//! [`predefined colors`]: https://www.w3schools.com/cssref/css_colors.asp - +/// This module provides several user interfaces for describing a color to be +/// used throughout the rest of the library. The easiest way of describing a +/// colour is to use a `&str` or `String`, which is simply serialized as-is and +/// passed on to the underlying `plotly.js` library. `plotly.js` supports [`CSS +/// color formats`], and will fallback to some default color if the color string +/// is malformed. +/// +/// For a more type-safe approach, the `RGB` or `RGBA` structs can be used to +/// construct a valid color, which will then get serialized to an appropriate +/// string representation. Cross-browser compatible [`predefined colors`] are +/// supported via the `NamedColor` enum. +/// +/// The `Color` trait is public, and so can be implemented for custom colour +/// types. The user can then implement a valid serialization function according +/// to their own requirements. On the whole, that should be largely unnecessary +/// given the functionality already provided within this module. +/// +/// [`CSS color formats`]: +/// [`predefined colors`]: use dyn_clone::DynClone; use erased_serde::Serialize as ErasedSerialize; use serde::Serialize; @@ -116,7 +115,7 @@ impl Serialize for Rgba { /// Cross-browser compatible [`predefined colors`]. /// -/// [`predefined colors`]: https://www.w3schools.com/cssref/css_colors.asp +/// [`predefined colors`]: #[derive(Debug, Clone, Copy, Serialize)] #[serde(rename_all = "lowercase")] pub enum NamedColor { diff --git a/plotly/src/common/mod.rs b/plotly/src/common/mod.rs index 1723ebf7..81b5d551 100644 --- a/plotly/src/common/mod.rs +++ b/plotly/src/common/mod.rs @@ -153,10 +153,16 @@ pub enum ConstrainText { #[derive(Serialize, Clone, Debug)] pub enum Orientation { + #[serde(rename = "a")] + Auto, #[serde(rename = "v")] Vertical, #[serde(rename = "h")] Horizontal, + #[serde(rename = "r")] + Radial, + #[serde(rename = "t")] + Tangential, } #[derive(Serialize, Clone, Debug)] @@ -225,6 +231,7 @@ pub enum PlotType { Surface, DensityMapbox, Table, + Pie, } #[derive(Serialize, Clone, Debug)] @@ -273,6 +280,10 @@ pub enum Position { BottomCenter, #[serde(rename = "bottom right")] BottomRight, + #[serde(rename = "inside")] + Inside, + #[serde(rename = "outside")] + Outside, } #[derive(Serialize, Clone, Debug)] diff --git a/plotly/src/configuration.rs b/plotly/src/configuration.rs index 95043caf..36c9c8ce 100644 --- a/plotly/src/configuration.rs +++ b/plotly/src/configuration.rs @@ -212,7 +212,7 @@ impl Configuration { /// When set it determines base URL for the "Edit in Chart Studio" /// `show_edit_in_chart_studio`/`show_send_to_cloud` mode bar button and /// the show_link/send_data on-graph link. To enable sending your data to - /// Chart Studio Cloud, you need to set both `plotly_server_url` to "https://chart-studio.plotly.com" and + /// Chart Studio Cloud, you need to set both `plotly_server_url` to and /// also set `showSendToCloud` to `true`. pub fn plotly_server_url(mut self, plotly_server_url: &str) -> Self { self.plotly_server_url = Some(plotly_server_url.to_string()); diff --git a/plotly/src/layout/mod.rs b/plotly/src/layout/mod.rs index c4c3c87a..af3eabf6 100644 --- a/plotly/src/layout/mod.rs +++ b/plotly/src/layout/mod.rs @@ -929,7 +929,7 @@ pub struct Shape { #[serde(rename = "fillcolor")] fill_color: Option>, /// Determines which regions of complex paths constitute the interior. For - /// more info please visit https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/fill-rule + /// more info please visit #[serde(rename = "fillrule")] fill_rule: Option, /// Determines whether the shape could be activated for edit or not. Has no @@ -994,7 +994,7 @@ pub struct NewShape { #[serde(rename = "fillcolor")] fill_color: Option>, /// Determines the path's interior. For more info please - /// visit https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/fill-rule + /// visit #[serde(rename = "fillrule")] fill_rule: Option, /// Sets the opacity of new shapes. Number between or equal to 0 and 1. @@ -1071,8 +1071,8 @@ pub struct Annotation { visible: Option, /// Sets the text associated with this annotation. Plotly uses a subset of /// HTML tags to do things like newline (
), bold (), italics - /// (), hyperlinks (). Tags , , - /// are also supported. + /// (), hyperlinks (). Tags , , + /// are also supported. text: Option, /// Sets the angle at which the `text` is drawn with respect to the /// horizontal. diff --git a/plotly/src/lib.rs b/plotly/src/lib.rs index dbd18add..c9d89c40 100644 --- a/plotly/src/lib.rs +++ b/plotly/src/lib.rs @@ -36,7 +36,7 @@ pub use traces::{ // Bring the different trace types into the top-level scope pub use traces::{ Bar, BoxPlot, Candlestick, Contour, DensityMapbox, HeatMap, Histogram, Image, Mesh3D, Ohlc, - Sankey, Scatter, Scatter3D, ScatterMapbox, ScatterPolar, Surface, Table, + Pie, Sankey, Scatter, Scatter3D, ScatterMapbox, ScatterPolar, Surface, Table, }; pub trait Restyle: serde::Serialize {} diff --git a/plotly/src/plot.rs b/plotly/src/plot.rs index 717cee02..f6213dd2 100644 --- a/plotly/src/plot.rs +++ b/plotly/src/plot.rs @@ -585,6 +585,7 @@ impl PartialEq for Plot { mod tests { use std::path::PathBuf; + #[cfg(feature = "kaleido")] use base64::{engine::general_purpose, Engine as _}; use serde_json::{json, to_value}; diff --git a/plotly/src/traces/image.rs b/plotly/src/traces/image.rs index d081f9b4..6c056f19 100644 --- a/plotly/src/traces/image.rs +++ b/plotly/src/traces/image.rs @@ -217,7 +217,7 @@ pub struct Image { dy: Option, /// Specifies the data URI of the image to be visualized. The URI consists - /// of "data:image/[][;base64],". + /// of "data:image/[\]\[;base64\],\". source: Option, /// Sets text elements associated with each (x,y) pair. If a single string, @@ -245,12 +245,12 @@ pub struct Image { /// inserted using %{variable}, for example "y: %{y}". Numbers are /// formatted using d3-format's syntax %{variable:d3-format}, for example /// "Price: %{y:$.2f}". - /// https://github.com/d3/d3-3.x-api-reference/blob/master/Formatting.md#d3_format for details + /// for details /// on the formatting syntax. Dates are formatted using d3-time-format's /// syntax %{variable|d3-time-format}, for example "Day: - /// %{2019-01-01|%A}". https://github.com/d3/d3-3.x-api-reference/blob/master/Time-Formatting.md#format for details + /// %{2019-01-01|%A}". for details /// on the date formatting syntax. The variables available in - /// `hovertemplate` are the ones emitted as event data described at this link https://plotly.com/javascript/plotlyjs-events/#event-data. + /// `hovertemplate` are the ones emitted as event data described at this link . /// Additionally, every attributes that can be specified per-point (the ones /// that are `arrayOk: true`) are available. Anything contained in tag /// `` is displayed in the secondary box, for example diff --git a/plotly/src/traces/mesh3d.rs b/plotly/src/traces/mesh3d.rs index 223c4a45..c289e58f 100644 --- a/plotly/src/traces/mesh3d.rs +++ b/plotly/src/traces/mesh3d.rs @@ -190,12 +190,12 @@ where /// inserted using %{variable}, for example "y: %{y}". Numbers are /// formatted using d3-format's syntax %{variable:d3-format}, for example /// "Price: %{y:$.2f}". - /// https://github.com/d3/d3-3.x-api-reference/blob/master/Formatting.md#d3_format for details + /// for details /// on the formatting syntax. Dates are formatted using d3-time-format's /// syntax %{variable|d3-time-format}, for example "Day: - /// %{2019-01-01|%A}". https://github.com/d3/d3-3.x-api-reference/blob/master/Time-Formatting.md#format for details + /// %{2019-01-01|%A}". for details /// on the date formatting syntax. The variables available in - /// `hovertemplate` are the ones emitted as event data described at this link https://plotly.com/javascript/plotlyjs-events/#event-data. + /// `hovertemplate` are the ones emitted as event data described at this link . /// Additionally, every attributes that can be specified per-point (the ones /// that are `arrayOk: true`) are available. Anything contained in tag /// `` is displayed in the secondary box, for example @@ -204,8 +204,8 @@ where #[serde(rename = "hovertemplate")] hover_template: Option>, /// Sets the hover text formatting rulefor `x` using d3 formatting - /// mini-languages which are very similar to those in Python. For numbers, see: https://github.com/d3/d3-format/tree/v1.4.5#d3-format. And for dates - /// see: https://github.com/d3/d3-time-format/tree/v2.2.3#locale_format. We add two items to d3's date + /// mini-languages which are very similar to those in Python. For numbers, see: . And for dates + /// see: . We add two items to d3's date /// formatter: "%h" for half of the year as a decimal number as well as /// "%{n}f" for fractional seconds with n digits. For example, /// "2016-10-13 09:15:23.456" with tickformat "%H~%M~%S.%2f" would display @@ -214,8 +214,8 @@ where #[serde(rename = "xhoverformat")] x_hover_format: Option, /// Sets the hover text formatting rulefor `y` using d3 formatting - /// mini-languages which are very similar to those in Python. For numbers, see: https://github.com/d3/d3-format/tree/v1.4.5#d3-format. And for dates - /// see: https://github.com/d3/d3-time-format/tree/v2.2.3#locale_format. We add two items to d3's date + /// mini-languages which are very similar to those in Python. For numbers, see: . And for dates + /// see: . We add two items to d3's date /// formatter: "%h" for half of the year as a decimal number as well as /// "%{n}f" for fractional seconds with n digits. For example, /// "2016-10-13 09:15:23.456" with tickformat "%H~%M~%S.%2f" would display @@ -286,8 +286,8 @@ where reverse_scale: Option, /// Sets the hover text formatting rulefor `z` using d3 formatting - /// mini-languages which are very similar to those in Python. For numbers, see: https://github.com/d3/d3-format/tree/v1.4.5#d3-format. And for dates - /// see: https://github.com/d3/d3-time-format/tree/v2.2.3#locale_format. We add two items to d3's date + /// mini-languages which are very similar to those in Python. For numbers, see: . And for dates + /// see: . We add two items to d3's date /// formatter: "%h" for half of the year as a decimal number as well as /// "%{n}f" for fractional seconds with n digits. For example, /// "2016-10-13 09:15:23.456" with tickformat "%H~%M~%S.%2f" would display diff --git a/plotly/src/traces/mod.rs b/plotly/src/traces/mod.rs index f12305c3..515072b2 100644 --- a/plotly/src/traces/mod.rs +++ b/plotly/src/traces/mod.rs @@ -10,6 +10,7 @@ pub mod histogram; pub mod image; pub mod mesh3d; mod ohlc; +pub mod pie; pub mod sankey; mod scatter; mod scatter3d; @@ -27,6 +28,7 @@ pub use heat_map::HeatMap; pub use histogram::Histogram; pub use mesh3d::Mesh3D; pub use ohlc::Ohlc; +pub use pie::Pie; pub use sankey::Sankey; pub use scatter::Scatter; pub use scatter3d::Scatter3D; diff --git a/plotly/src/traces/pie.rs b/plotly/src/traces/pie.rs new file mode 100644 index 00000000..d3e951f4 --- /dev/null +++ b/plotly/src/traces/pie.rs @@ -0,0 +1,456 @@ +//! Pie chart plot + +use plotly_derive::FieldSetter; +use serde::Serialize; + +use crate::private::{NumOrString, NumOrStringCollection}; +use crate::{ + common::{ + Dim, Domain, Font, HoverInfo, Label, LegendGroupTitle, Marker, Orientation, PlotType, + Position, Visible, + }, + Trace, +}; + +#[derive(Debug, Clone, Serialize)] +pub enum PieDirection { + Clockwise, + CounterClockwise, +} + +/// Construct a Pie Chart trace. +/// +/// # Examples +/// +/// ``` +/// use plotly::Pie; +/// +/// let trace = Pie::new( +/// vec![2, 3, 5]); +/// +/// let expected = serde_json::json!({ +/// "type": "pie", +/// "values": [2, 3, 5], +/// }); +/// +/// assert_eq!(serde_json::to_value(trace).unwrap(), expected); +/// ``` +/// # Using only labels +/// +/// Build a new Pie Chart by only assigning the labels field. The Pie chart +/// will be generated by counting the number of unique labels, see [Pie::labels] +/// field description. Note that to create a Pie chart by using this +/// function, the type parameter `P` needs to be specialized, this can be +/// done by doing +/// +/// ``` +/// use plotly::Pie; +/// +/// let labels = ["giraffes", "giraffes", "orangutans", "monkeys"]; +/// +/// let trace = Pie::::from_labels(&labels); +/// +/// let expected = serde_json::json!({ +/// "type": "pie", +/// "labels": ["giraffes", "giraffes", "orangutans", "monkeys"], +/// }); +/// +/// assert_eq!(serde_json::to_value(trace).unwrap(), expected); +/// ``` +#[serde_with::skip_serializing_none] +#[derive(Serialize, Clone, Debug, FieldSetter)] +#[field_setter(box_self, kind = "trace")] +pub struct Pie

+where + P: Serialize + Clone, +{ + #[field_setter(default = "PlotType::Pie")] + r#type: PlotType, + domain: Option, + /// Determines whether outside text labels can push the margins. + automargin: Option, + /// Assigns extra data each datum. This may be useful when listening to + /// hover, click and selection events. Note that, “scatter” traces also + /// appends customdata items in the markers DOM elements + #[serde(rename = "customdata")] + custom_data: Option, + /// Specifies the direction at which succeeding sectors follow one another. + /// The 'direction' property is an enumeration that may be specified as + /// One of the following enumeration values: ['clockwise', + /// 'counterclockwise'] + direction: Option, + /// Sets the label step. See label0 for more info. + dlabel: Option, + /// Sets the fraction of the radius to cut out of the pie. Use this to make + /// a donut chart. The 'hole' property is a number and may be specified + /// as a value in the interval [0, 1] + hole: Option, + /// Determines which trace information appear on hover. If none or skip are + /// set, no information is displayed upon hovering. But, if none is set, + /// click and hover events are still fired. + #[serde(rename = "hoverinfo")] + hover_info: Option, + #[serde(rename = "hoverlabel")] + hover_label: Option

Pie

+where + P: Serialize + Clone + 'static, +{ + /// Build a new Pie Chart by only assigning the values field + pub fn new(values: Vec

) -> Box { + Box::new(Self { + values: Some(values), + ..Default::default() + }) + } + + /// Same as [Pie::new()] + pub fn from_values(values: Vec

) -> Box { + Box::new(Self { + values: Some(values), + ..Default::default() + }) + } + + /// Build a new Pie Chart by only assigning the labels field. The Pie chart + /// will be generated by counting the number of unique labels, see + /// [Pie::labels] field description. Note that to create a Pie chart by + /// using this function, the type parameter `P` needs to be specialized, + /// this can be done by doing + /// ``` + /// use plotly::Pie; + /// + /// let labels = ["giraffes", "giraffes", "orangutans", "monkeys"]; + /// let trace = Pie::::from_labels(&labels); + /// ``` + pub fn from_labels + ToString>(labels: &[T]) -> Box { + let l = labels.iter().map(|s| s.to_string()).collect(); + Box::new(Self { + labels: Some(l), + ..Default::default() + }) + } +} + +impl

Trace for Pie

+where + P: Serialize + Clone, +{ + fn to_json(&self) -> String { + serde_json::to_string(self).unwrap() + } +} + +#[cfg(test)] +mod tests { + use serde_json::{json, to_value}; + + use super::*; + + #[test] + fn serialize_pie() { + let pie_trace = Pie::new(vec![45, 55]) + .name("pie") + .automargin(true) + .direction(PieDirection::Clockwise) + .hole(0.2) + .inside_text_font(Font::new().color("#ff7f0e")) + .inside_text_orientation(Orientation::Tangential) + .labels(vec!["a", "b"]) + .sort(true) + .visible(Visible::True) + .show_legend(true) + .legend_rank(1000) + .legend_group("legend group") + .legend_group_title("Legend Group Title") + .opacity(0.5) + .ids(vec!["one"]) + .text("text") + .text_info("label+percent") + .text_array(vec!["text"]) + .text_template("text_template") + .text_template_array(vec!["text_template"]) + .text_font(Font::new()) + .text_position(Position::TopCenter) + .text_position_array(vec![Position::MiddleLeft]) + .hover_text("hover_text") + .hover_text_array(vec!["hover_text"]) + .hover_info(HoverInfo::XAndYAndZ) + .hover_template("hover_template") + .hover_template_array(vec!["hover_template"]) + .meta("meta") + .custom_data(vec!["custom_data"]) + .marker(Marker::new()) + .hover_label(Label::new()) + .ui_revision(6); + let expected = json!({ + "values": [45, 55], + "type": "pie", + "name": "pie", + "automargin": true, + "direction" : "Clockwise", + "hole": 0.2, + "insidetextfont": {"color": "#ff7f0e"}, + "insidetextorientation": "t", + "labels": ["a", "b"], + "sort": true, + "visible": true, + "showlegend": true, + "legendrank": 1000, + "legendgroup": "legend group", + "legendgrouptitle": {"text": "Legend Group Title"}, + "opacity": 0.5, + "ids": ["one"], + "text": ["text"], + "textinfo": "label+percent", + "textfont": {}, + "texttemplate": ["text_template"], + "textposition": ["middle left"], + "hovertext": ["hover_text"], + "hoverinfo": "x+y+z", + "hovertemplate": ["hover_template"], + "meta": "meta", + "customdata": ["custom_data"], + "marker": {}, + "hoverlabel": {}, + "uirevision": 6, + }); + + assert_eq!(to_value(pie_trace).unwrap(), expected); + } + + #[test] + fn new_from_values() { + let values = vec![2.2, 3.3, 4.4]; + let trace = Pie::from_values(values); + + let expected = serde_json::json!({ + "type": "pie", + "values": [2.2, 3.3, 4.4], + }); + + assert_eq!(to_value(trace).unwrap(), expected); + } + + #[test] + fn new_from_labels() { + let labels = ["giraffes", "giraffes", "orangutans", "monkeys"]; + + let trace = Pie::::from_labels(&labels); + + let expected = serde_json::json!({ + "type": "pie", + "labels": ["giraffes", "giraffes", "orangutans", "monkeys"], + }); + + assert_eq!(to_value(trace).unwrap(), expected); + } +} diff --git a/plotly/src/traces/sankey.rs b/plotly/src/traces/sankey.rs index be96afa2..1809b10e 100644 --- a/plotly/src/traces/sankey.rs +++ b/plotly/src/traces/sankey.rs @@ -332,7 +332,7 @@ where #[serde(rename = "textfont")] text_font: Option, /// Sets the value formatting rule using d3 formatting mini-languages which - /// are very similar to those in Python. For numbers, see: https://github.com/d3/d3-format/tree/v1.4.5#d3-format. + /// are very similar to those in Python. For numbers, see: . #[serde(rename = "valueformat")] value_format: Option, /// Adds a unit to follow the value in the hover tooltip. Add a space if a diff --git a/plotly/src/traces/scatter.rs b/plotly/src/traces/scatter.rs index 57d5e8a5..da81526e 100644 --- a/plotly/src/traces/scatter.rs +++ b/plotly/src/traces/scatter.rs @@ -146,12 +146,12 @@ where /// inserted using %{variable}, for example "y: %{y}". Numbers are /// formatted using d3-format's syntax %{variable:d3-format}, for example /// "Price: %{y:$.2f}". - /// https://github.com/d3/d3-3.x-api-reference/blob/master/Formatting.md#d3_format for details + /// for details /// on the formatting syntax. Dates are formatted using d3-time-format's - /// syntax %{variable|d3-time-format}, for example "Day: - /// %{2019-01-01|%A}". https://github.com/d3/d3-3.x-api-reference/blob/master/Time-Formatting.md#format for details + /// syntax %{variable|d3-time-format}, for example "Day: %{2019-01-01|%A}". + /// for details /// on the date formatting syntax. The variables available in - /// `hovertemplate` are the ones emitted as event data described at this link https://plotly.com/javascript/plotlyjs-events/#event-data. + /// `hovertemplate` are the ones emitted as event data described at this link . /// Additionally, every attributes that can be specified per-point (the ones /// that are `arrayOk: true`) are available. Anything contained in tag /// `` is displayed in the secondary box, for example diff --git a/plotly/src/traces/scatter3d.rs b/plotly/src/traces/scatter3d.rs index 412ba1f8..e8a0e3b9 100644 --- a/plotly/src/traces/scatter3d.rs +++ b/plotly/src/traces/scatter3d.rs @@ -169,13 +169,12 @@ where /// box. Note that this will override `HoverInfo`. Variables are /// inserted using %{variable}, for example "y: %{y}". Numbers are /// formatted using d3-format's syntax %{variable:d3-format}, for example - /// "Price: %{y:$.2f}". - /// https://github.com/d3/d3-3.x-api-reference/blob/master/Formatting.md#d3_format for details + /// "Price: %{y:$.2f}". for details /// on the formatting syntax. Dates are formatted using d3-time-format's /// syntax %{variable|d3-time-format}, for example "Day: - /// %{2019-01-01|%A}". https://github.com/d3/d3-3.x-api-reference/blob/master/Time-Formatting.md#format for details + /// %{2019-01-01|%A}". for details /// on the date formatting syntax. The variables available in - /// `hovertemplate` are the ones emitted as event data described at this link https://plotly.com/javascript/plotlyjs-events/#event-data. + /// `hovertemplate` are the ones emitted as event data described at this link . /// Additionally, every attributes that can be specified per-point (the ones /// that are `arrayOk: true`) are available. Anything contained in tag /// `` is displayed in the secondary box, for example @@ -184,8 +183,8 @@ where #[serde(rename = "hovertemplate")] hover_template: Option>, /// Sets the hover text formatting rulefor `x` using d3 formatting - /// mini-languages which are very similar to those in Python. For numbers, see: https://github.com/d3/d3-format/tree/v1.4.5#d3-format. And for - /// dates see: https://github.com/d3/d3-time-format/tree/v2.2.3#locale_format. We add two items to d3's + /// mini-languages which are very similar to those in Python. For numbers, see: . And for + /// dates see: . We add two items to d3's /// date formatter: "%h" for half of the year as a decimal number as well as /// "%{n}f" for fractional seconds with n digits. For example, /// "2016-10-13 09:15:23.456" with tickformat "%H~%M~%S.%2f" would display @@ -194,8 +193,8 @@ where #[serde(rename = "xhoverformat")] x_hover_format: Option, /// Sets the hover text formatting rulefor `y` using d3 formatting - /// mini-languages which are very similar to those in Python. For numbers, see: https://github.com/d3/d3-format/tree/v1.4.5#d3-format. And for - /// dates see: https://github.com/d3/d3-time-format/tree/v2.2.3#locale_format. We add two items to d3's + /// mini-languages which are very similar to those in Python. For numbers, see: . And for + /// dates see: . We add two items to d3's /// date formatter: "%h" for half of the year as a decimal number as well as /// "%{n}f" for fractional seconds with n digits. For example, /// "2016-10-13 09:15:23.456" with tickformat "%H~%M~%S.%2f" would display @@ -204,8 +203,8 @@ where #[serde(rename = "yhoverformat")] y_hover_format: Option, /// Sets the hover text formatting rulefor `z` using d3 formatting - /// mini-languages which are very similar to those in Python. For numbers, see: https://github.com/d3/d3-format/tree/v1.4.5#d3-format. And for - /// dates see: https://github.com/d3/d3-time-format/tree/v2.2.3#locale_format. We add two items to d3's + /// mini-languages which are very similar to those in Python. For numbers, see: . And for + /// dates see: . We add two items to d3's /// date formatter: "%h" for half of the year as a decimal number as well as /// "%{n}f" for fractional seconds with n digits. For example, /// "2016-10-13 09:15:23.456" with tickformat "%H~%M~%S.%2f" would display diff --git a/plotly/src/traces/scatter_mapbox.rs b/plotly/src/traces/scatter_mapbox.rs index 76348e6a..035632b4 100644 --- a/plotly/src/traces/scatter_mapbox.rs +++ b/plotly/src/traces/scatter_mapbox.rs @@ -148,12 +148,12 @@ where /// inserted using %{variable}, for example "y: %{y}". Numbers are /// formatted using d3-format's syntax %{variable:d3-format}, for example /// "Price: %{y:$.2f}". - /// https://github.com/d3/d3-3.x-api-reference/blob/master/Formatting.md#d3_format for details + /// for details /// on the formatting syntax. Dates are formatted using d3-time-format's /// syntax %{variable|d3-time-format}, for example "Day: - /// %{2019-01-01|%A}". https://github.com/d3/d3-3.x-api-reference/blob/master/Time-Formatting.md#format for details + /// %{2019-01-01|%A}". for details /// on the date formatting syntax. The variables available in - /// `hovertemplate` are the ones emitted as event data described at this link https://plotly.com/javascript/plotlyjs-events/#event-data. + /// `hovertemplate` are the ones emitted as event data described at this link . /// Additionally, every attributes that can be specified per-point (the ones /// that are `arrayOk: true`) are available. Anything contained in tag /// `` is displayed in the secondary box, for example diff --git a/plotly/src/traces/scatter_polar.rs b/plotly/src/traces/scatter_polar.rs index 7bb51073..4f9b4f1f 100644 --- a/plotly/src/traces/scatter_polar.rs +++ b/plotly/src/traces/scatter_polar.rs @@ -133,12 +133,12 @@ where /// inserted using %{variable}, for example "y: %{y}". Numbers are /// formatted using d3-format's syntax %{variable:d3-format}, for example /// "Price: %{y:$.2f}". - /// https://github.com/d3/d3-3.x-api-reference/blob/master/Formatting.md#d3_format for details + /// for details /// on the formatting syntax. Dates are formatted using d3-time-format's /// syntax %{variable|d3-time-format}, for example "Day: - /// %{2019-01-01|%A}". https://github.com/d3/d3-3.x-api-reference/blob/master/Time-Formatting.md#format for details + /// %{2019-01-01|%A}". for details /// on the date formatting syntax. The variables available in - /// `hovertemplate` are the ones emitted as event data described at this link https://plotly.com/javascript/plotlyjs-events/#event-data. + /// `hovertemplate` are the ones emitted as event data described at this link . /// Additionally, every attributes that can be specified per-point (the ones /// that are `arrayOk: true`) are available. Anything contained in tag /// `` is displayed in the secondary box, for example