Skip to content

Commit 1405731

Browse files
authored
add examples on building responsive plots and custom HTML pages (#257)
Fixes #175 Closes #228 Signed-off-by: Andrei Gherghescu <8067229+andrei-ng@users.noreply.github.com>
1 parent 86e12ae commit 1405731

File tree

4 files changed

+173
-1
lines changed

4 files changed

+173
-1
lines changed

examples/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22

33
This folder contains a multitude of usage examples covering as many features of the library as possible. Instructions on how to run each example can be found in each example's subdirectory.
44

5-
Pull requests with more examples of different behaviour are always welcome.
5+
Pull requests with more examples of different behaviour are always welcome.

examples/customization/Cargo.toml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
[package]
2+
name = "customization"
3+
version = "0.1.0"
4+
authors = ["Andrei Gherghescu andrei-ng@protonmail.com"]
5+
edition = "2021"
6+
7+
[dependencies]
8+
build_html = "2.5.0"
9+
rand = "0.8"
10+
ndarray = "0.16"
11+
plotly = { path = "../../plotly" }

examples/customization/README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# HTML Customization
2+
3+
We often get issues/questions regarding customization of the HTML output. In most situations, these are not related to Plotly functionality but rather custom behavior related to HTML rendering.
4+
5+
The directory [./customization](./customization) contains examples of the most frequent raised questions by users of `plotly-rs`, such as
6+
- making the resulting HTML plot responsive on browser window size change
7+
- making the resulting HTML fill the entire browser page
8+
- placing multiple plots in the same HTML page using the [`build_html`](https://crates.io/crates/build_html) crate

examples/customization/src/main.rs

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
#![allow(dead_code)]
2+
3+
use build_html::*;
4+
use ndarray::Array;
5+
use plotly::{
6+
color::NamedColor,
7+
common::{Marker, Mode, Title},
8+
layout::{Center, DragMode, Mapbox, MapboxStyle, Margin},
9+
Configuration, DensityMapbox, Layout, Plot, Scatter, Scatter3D,
10+
};
11+
const DEFAULT_HTML_APP_NOT_FOUND: &str = "Could not find default application for HTML files.";
12+
13+
fn density_mapbox_responsive_autofill() {
14+
let trace = DensityMapbox::new(vec![45.5017], vec![-73.5673], vec![0.75]).zauto(true);
15+
16+
let layout = Layout::new()
17+
.drag_mode(DragMode::Zoom)
18+
.margin(Margin::new().top(0).left(0).bottom(0).right(0))
19+
.mapbox(
20+
Mapbox::new()
21+
.style(MapboxStyle::OpenStreetMap)
22+
.center(Center::new(45.5017, -73.5673))
23+
.zoom(5),
24+
);
25+
26+
let mut plot = Plot::new();
27+
plot.add_trace(trace);
28+
plot.set_layout(layout);
29+
plot.set_configuration(Configuration::default().responsive(true).fill_frame(true));
30+
31+
plot.show();
32+
}
33+
34+
fn multiple_plots_on_same_html_page() {
35+
let html: String = HtmlPage::new()
36+
.with_title("Plotly-rs Multiple Plots")
37+
.with_script_link("https://cdn.plot.ly/plotly-latest.min.js")
38+
.with_header(1, "Multiple Plotly plots on the same HTML page")
39+
.with_raw(first_plot())
40+
.with_raw(second_plot())
41+
.with_raw(third_plot())
42+
.to_html_string();
43+
44+
let file = write_html(&html);
45+
show_with_default_app(&file);
46+
}
47+
48+
fn first_plot() -> String {
49+
let n: usize = 100;
50+
let t: Vec<f64> = Array::linspace(0., 10., n).into_raw_vec_and_offset().0;
51+
let y: Vec<f64> = t.iter().map(|x| x.sin()).collect();
52+
53+
let trace = Scatter::new(t, y).mode(Mode::Markers);
54+
let mut plot = Plot::new();
55+
plot.add_trace(trace);
56+
plot.to_inline_html(Some("scattter_1"))
57+
}
58+
59+
fn second_plot() -> String {
60+
let trace = Scatter::new(vec![1, 2, 3, 4], vec![10, 11, 12, 13])
61+
.mode(Mode::Markers)
62+
.marker(
63+
Marker::new()
64+
.size_array(vec![40, 60, 80, 100])
65+
.color_array(vec![
66+
NamedColor::Red,
67+
NamedColor::Blue,
68+
NamedColor::Cyan,
69+
NamedColor::OrangeRed,
70+
]),
71+
);
72+
let mut plot = Plot::new();
73+
plot.add_trace(trace);
74+
plot.to_inline_html(Some("scatter_2"))
75+
}
76+
77+
fn third_plot() -> String {
78+
let n: usize = 100;
79+
let t: Vec<f64> = Array::linspace(0., 10., n).into_raw_vec_and_offset().0;
80+
let y: Vec<f64> = t.iter().map(|x| x.sin()).collect();
81+
let z: Vec<f64> = t.iter().map(|x| x.cos()).collect();
82+
83+
let trace = Scatter3D::new(t, y, z).mode(Mode::Markers);
84+
let mut plot = Plot::new();
85+
plot.add_trace(trace);
86+
let l = Layout::new()
87+
.title(Title::with_text("Scatter3d"))
88+
.height(800);
89+
plot.set_layout(l);
90+
plot.to_inline_html(Some("scatter_3_3d"))
91+
}
92+
93+
#[cfg(all(unix, not(target_os = "android"), not(target_os = "macos")))]
94+
fn show_with_default_app(temp_path: &str) {
95+
use std::process::Command;
96+
Command::new("xdg-open")
97+
.args([temp_path])
98+
.output()
99+
.expect(DEFAULT_HTML_APP_NOT_FOUND);
100+
}
101+
102+
#[cfg(target_os = "macos")]
103+
fn show_with_default_app(temp_path: &str) {
104+
use std::process::Command;
105+
Command::new("open")
106+
.args([temp_path])
107+
.output()
108+
.expect(DEFAULT_HTML_APP_NOT_FOUND);
109+
}
110+
111+
#[cfg(target_os = "windows")]
112+
fn show_with_default_app(temp_path: &str) {
113+
use std::process::Command;
114+
Command::new("cmd")
115+
.args(&["/C", "start", &format!(r#"{}"#, temp_path)])
116+
.spawn()
117+
.expect(DEFAULT_HTML_APP_NOT_FOUND);
118+
}
119+
120+
fn write_html(html_data: &str) -> String {
121+
use std::env;
122+
use std::{fs::File, io::Write};
123+
124+
use rand::{
125+
distributions::{Alphanumeric, DistString},
126+
thread_rng,
127+
};
128+
129+
// Set up the temp file with a unique filename.
130+
let mut temp = env::temp_dir();
131+
let mut plot_name = Alphanumeric.sample_string(&mut thread_rng(), 22);
132+
plot_name.push_str(".html");
133+
plot_name = format!("plotly_{}", plot_name);
134+
temp.push(plot_name);
135+
136+
// Save the rendered plot to the temp file.
137+
let temp_path = temp.to_str().unwrap();
138+
139+
{
140+
let mut file = File::create(temp_path).unwrap();
141+
file.write_all(html_data.as_bytes())
142+
.expect("failed to write html output");
143+
file.flush().unwrap();
144+
}
145+
temp_path.to_string()
146+
}
147+
148+
fn main() {
149+
// Uncomment any of these lines to display the example.
150+
151+
// density_mapbox_responsive_autofill();
152+
// multiple_plots_on_same_html_page();
153+
}

0 commit comments

Comments
 (0)