From cd7df6b83cc7db556cc83eaf22589215d7051a6d Mon Sep 17 00:00:00 2001 From: Ioannis Giagkiozis Date: Thu, 26 Mar 2020 08:11:22 +0000 Subject: [PATCH] bug fix - default html application not found --- CHANGELOG.md | 3 + README.md | 4 +- plotly/Cargo.toml | 2 +- plotly/README.md | 5 +- plotly/src/layout.rs | 184 +++++++++++++++++++++++++++++++++++++++++-- plotly/src/plot.rs | 17 +++- 6 files changed, 200 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9797307..9e9859e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,9 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.4.1] - 2020-03-26 +### Fixed +- Added error message to capture the scenario when there is no default browser (or no browser at all) on a machine. The message suggests a few alternatives. ## [0.4.0] - 2020-02-27 ### Added diff --git a/README.md b/README.md index e094420..75b2d59 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ Add this to your `Cargo.toml`: ```toml [dependencies] -plotly = "0.4.0" +plotly = "0.4.1" ``` For changes since the last version please consult the [change log](CHANGELOG.md). @@ -25,7 +25,7 @@ Saving to png, jpeg, webp, svg, pdf and eps formats can be made available by ena ```toml [dependencies] -plotly = { version = "0.4.0", features = ["orca"] } +plotly = { version = "0.4.1", features = ["orca"] } ``` This feature requires some manual configuration to function. For details and installation instructions please see the [plotly_orca](plotly_orca). diff --git a/plotly/Cargo.toml b/plotly/Cargo.toml index c47359f..0746dbc 100644 --- a/plotly/Cargo.toml +++ b/plotly/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "plotly" -version = "0.4.0" +version = "0.4.1" description = "A plotting library powered by Plotly.js" authors = ["Ioannis Giagkiozis "] license = "MIT" diff --git a/plotly/README.md b/plotly/README.md index 004194b..a47b2ac 100644 --- a/plotly/README.md +++ b/plotly/README.md @@ -9,12 +9,9 @@ Add this to your `Cargo.toml`: ```toml [dependencies] -plotly = "0.4.0" +plotly = "0.4.1" ``` -This feature requires some manual configuration to function. For details and installation instructions - please see the `plotly_orca` [README](plotly_orca/README.md). - ## Plotly in action ```rust extern crate plotly; diff --git a/plotly/src/layout.rs b/plotly/src/layout.rs index 25123dd..550f25a 100644 --- a/plotly/src/layout.rs +++ b/plotly/src/layout.rs @@ -934,6 +934,176 @@ impl Axis { } } +#[derive(Serialize, Debug)] +pub enum RowOrder { + #[serde(rename="top to bottom")] + TopToBottom, + #[serde(rename="bottom to top")] + BottomToTop, +} + +#[derive(Serialize, Debug)] +pub enum GridPattern { + #[serde(rename="independent")] + Independent, + #[serde(rename="independent")] + Coupled, +} + +#[derive(Serialize, Debug)] +pub enum GridXSide { + #[serde(rename="bottom")] + Bottom, + #[serde(rename="bottom plot")] + BottomPlot, + #[serde(rename="top plot")] + TopPlot, + #[serde(rename="top")] + Top, +} + +#[derive(Serialize, Debug)] +pub enum GridYSide { + #[serde(rename="left")] + Left, + #[serde(rename="left plot")] + LeftPlot, + #[serde(rename="right plot")] + RightPlot, + #[serde(rename="right")] + Right, +} + +#[derive(Serialize, Debug)] +pub struct GridDomain { + #[serde(skip_serializing_if = "Option::is_none")] + x: Option>, + #[serde(skip_serializing_if = "Option::is_none")] + y: Option>, +} + +impl GridDomain { + pub fn new() -> GridDomain { + GridDomain {x: None, y: None} + } + + pub fn x(mut self, x: Vec) -> GridDomain { + self.x = Some(x); + self + } + + pub fn y(mut self, y: Vec) -> GridDomain { + self.y = Some(y); + self + } +} + +#[derive(Serialize, Debug)] +pub struct LayoutGrid { + #[serde(skip_serializing_if = "Option::is_none")] + rows: Option, + #[serde(skip_serializing_if = "Option::is_none", rename="roworder")] + row_order: Option, + #[serde(skip_serializing_if = "Option::is_none")] + columns: Option, + #[serde(skip_serializing_if = "Option::is_none", rename="subplots")] + sub_plots: Option>, + #[serde(skip_serializing_if = "Option::is_none", rename="xaxes")] + x_axes: Option>, + #[serde(skip_serializing_if = "Option::is_none", rename="yaxes")] + y_axes: Option>, + #[serde(skip_serializing_if = "Option::is_none")] + pattern: Option, + #[serde(skip_serializing_if = "Option::is_none", rename="xgap")] + x_gap: Option, + #[serde(skip_serializing_if = "Option::is_none", rename="ygap")] + y_gap: Option, + #[serde(skip_serializing_if = "Option::is_none")] + domain: Option, + #[serde(skip_serializing_if = "Option::is_none", rename="xside")] + x_side: Option, + #[serde(skip_serializing_if = "Option::is_none", rename="yside")] + y_side: Option, +} + +impl LayoutGrid { + pub fn new() -> LayoutGrid { + LayoutGrid { + rows: None, + row_order: None, + columns: None, + sub_plots: None, + x_axes: None, + y_axes: None, + pattern: None, + x_gap: None, + y_gap: None, + domain: None, + x_side: None, + y_side: None, + } + } + + pub fn rows(mut self, rows: usize) -> LayoutGrid { + self.rows = Some(rows); + self + } + + pub fn row_order(mut self, row_order: RowOrder) -> LayoutGrid { + self.row_order = Some(row_order); + self + } + + pub fn columns(mut self, columns: usize) -> LayoutGrid { + self.columns = Some(columns); + self + } + + pub fn sub_plots(mut self, sub_plots: Vec) -> LayoutGrid { + self.sub_plots = Some(sub_plots); + self + } + + pub fn x_axes(mut self, x_axes: Vec) -> LayoutGrid { + self.x_axes = Some(x_axes); + self + } + + pub fn y_axes(mut self, y_axes: Vec) -> LayoutGrid { + self.y_axes = Some(y_axes); + self + } + + pub fn pattern(mut self, pattern: GridPattern) -> LayoutGrid { + self.pattern = Some(pattern); + self + } + + pub fn x_gap(mut self, x_gap: f64) -> LayoutGrid { + self.x_gap = Some(x_gap); + self + } + + pub fn y_gap(mut self, y_gap: f64) -> LayoutGrid { + self.y_gap = Some(y_gap); + self + } + + pub fn domain(mut self, domain: GridDomain) -> LayoutGrid { + self.domain = Some(domain); + self + } + + pub fn x_side(mut self, x_side: GridXSide) -> LayoutGrid { + self.x_side = Some(x_side); + self + } + pub fn y_side(mut self, y_side: GridYSide) -> LayoutGrid { + self.y_side = Some(y_side); + self + } +} + #[derive(Serialize, Debug)] pub struct Layout { #[serde(skip_serializing_if = "Option::is_none")] @@ -985,7 +1155,8 @@ pub struct Layout { #[serde(skip_serializing_if = "Option::is_none")] template: Option, - // grid: Option, + #[serde(skip_serializing_if = "Option::is_none")] + grid: Option, #[serde(skip_serializing_if = "Option::is_none")] calendar: Option, #[serde(skip_serializing_if = "Option::is_none")] @@ -1036,10 +1207,7 @@ pub struct Layout { #[serde(skip_serializing_if = "Option::is_none", rename = "sunburstcolorway")] sunburst_colorway: Option>, - #[serde( - skip_serializing_if = "Option::is_none", - rename = "extendsuburstcolors" - )] + #[serde(skip_serializing_if = "Option::is_none", rename = "extendsuburstcolors")] extend_sunburst_colors: Option, } @@ -1067,6 +1235,7 @@ impl Layout { hover_distance: None, spike_distance: None, hover_label: None, + grid: None, calendar: None, xaxis: None, yaxis: None, @@ -1201,6 +1370,11 @@ impl Layout { self } + pub fn grid(mut self, grid: LayoutGrid) -> Layout { + self.grid = Some(grid); + self + } + pub fn calendar(mut self, calendar: Calendar) -> Layout { self.calendar = Some(calendar); self diff --git a/plotly/src/plot.rs b/plotly/src/plot.rs index 82cbbe0..2484282 100644 --- a/plotly/src/plot.rs +++ b/plotly/src/plot.rs @@ -70,6 +70,17 @@ pub struct Plot { layout: Option, } +const DEFAULT_HTML_APP_NOT_FOUND: &str = r#"Could not find default application for HTML files. +Consider using the `to_html` method to save the plot instead. If using the `orca` feature the following +additional formats are available accessed by following methods: +- to_png +- to_jpeg +- to_webp +- to_svg +- to_pdf +- to_eps +"#; + impl Plot { /// Create a new `Plot`. pub fn new() -> Plot { @@ -314,12 +325,12 @@ impl Plot { Command::new("xdg-open") .args(&[temp_path]) .output() - .unwrap(); + .expect(DEFAULT_HTML_APP_NOT_FOUND); } #[cfg(target_os = "macos")] fn show_with_default_app(temp_path: &str) { - Command::new("open").args(&[temp_path]).output().unwrap(); + Command::new("open").args(&[temp_path]).output().expect(DEFAULT_HTML_APP_NOT_FOUND); } #[cfg(target_os = "windows")] @@ -328,7 +339,7 @@ impl Plot { .arg("/C") .arg(format!(r#"start {}"#, temp_path)) .output() - .unwrap(); + .expect(DEFAULT_HTML_APP_NOT_FOUND); } }