Skip to content

Commit 6fff5de

Browse files
author
David Peter
committed
Add 'plotly_noembed' cargo feature
This adds a new `plotly_noembed` feature that can be used to reduce the sizes of binaries by not embedding `plotly.min.js`. Since askama can not handle compile-time flags, we had to duplicate the `plot.html` and `static_plot.html` templates, where the new `*_noembed.html` version only contains the CDN-variant. The `use_local_plotly` option has been feature-gated such that it is not available when using the new feature. I verified that this works by building an application that depends on plotly.rs (including optimization and LTO in all cases): no plotly: 4.96 MiB (5,201,920 bytes) master: 8.96 MiB (9,400,320 bytes) this branch: 5.44 MiB (5,701,632 bytes) The difference between this branch and master is 3,698,688 bytes, which is very close to the size of `plotly.min.js` (3,686,400 bytes). Just as expected.
1 parent 32717e0 commit 6fff5de

File tree

6 files changed

+89
-0
lines changed

6 files changed

+89
-0
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ All notable changes to this project will be documented in this file.
33

44
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).
55

6+
## [0.10.0] - 2024-xx-xx
7+
### Added
8+
- [[#231](https://github.com/plotly/plotly.rs/pull/231)] Added new `plotly_noembed` feature to reduce binary sizes by not embedding `plotly.min.js`.
9+
610
## [0.9.0] - 2024-06-29
711
### Added
812
- [[#153](https://github.com/plotly/plotly.rs/pull/153)] Added `LayoutScene`.

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,11 @@ Adds trait implementations so that `image::RgbImage` and `image::RgbaImage` can
201201

202202
Adds support for creating plots directly using [ndarray](https://github.com/rust-ndarray/ndarray) types.
203203

204+
### `plotly_noembed`
205+
206+
This feature can be used to reduce the binary size by not embedding `plotly.min.js`. This requires the use of the CDN version,
207+
and disables the `use_local_plotly` method.
208+
204209
### `wasm`
205210

206211
Enables compilation for the `wasm32-unknown-unknown` target and provides access to a `bindings` module containing wrappers around functions exported by the plotly.js library.

plotly/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ exclude = ["target/*"]
1717
kaleido = ["plotly_kaleido"]
1818
plotly_ndarray = ["ndarray"]
1919
plotly_image = ["image"]
20+
plotly_noembed = []
2021
wasm = ["getrandom", "js-sys", "wasm-bindgen", "wasm-bindgen-futures"]
2122
with-axum = ["rinja/with-axum", "rinja_axum"]
2223

plotly/src/plot.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,22 @@ use serde::Serialize;
1111

1212
use crate::{Configuration, Layout};
1313

14+
#[cfg(not(feature = "plotly_noembed"))]
1415
#[derive(Template)]
1516
#[template(path = "plot.html", escape = "none")]
1617
struct PlotTemplate<'a> {
1718
plot: &'a Plot,
1819
remote_plotly_js: bool,
1920
}
2021

22+
#[cfg(feature = "plotly_noembed")]
23+
#[derive(Template)]
24+
#[template(path = "plot_noembed.html", escape = "none")]
25+
struct PlotTemplate<'a> {
26+
plot: &'a Plot,
27+
}
28+
29+
#[cfg(not(feature = "plotly_noembed"))]
2130
#[derive(Template)]
2231
#[template(path = "static_plot.html", escape = "none")]
2332
#[cfg(not(target_family = "wasm"))]
@@ -29,6 +38,17 @@ struct StaticPlotTemplate<'a> {
2938
height: usize,
3039
}
3140

41+
#[cfg(feature = "plotly_noembed")]
42+
#[derive(Template)]
43+
#[template(path = "static_plot_noembed.html", escape = "none")]
44+
#[cfg(not(target_family = "wasm"))]
45+
struct StaticPlotTemplate<'a> {
46+
plot: &'a Plot,
47+
format: ImageFormat,
48+
width: usize,
49+
height: usize,
50+
}
51+
3252
#[derive(Template)]
3353
#[template(path = "inline_plot.html", escape = "none")]
3454
struct InlinePlotTemplate<'a> {
@@ -182,6 +202,7 @@ pub struct Plot {
182202
#[serde(rename = "config")]
183203
configuration: Configuration,
184204
#[serde(skip)]
205+
#[cfg(not(feature = "plotly_noembed"))]
185206
remote_plotly_js: bool,
186207
}
187208

@@ -190,6 +211,7 @@ impl Plot {
190211
pub fn new() -> Plot {
191212
Plot {
192213
traces: Traces::new(),
214+
#[cfg(not(feature = "plotly_noembed"))]
193215
remote_plotly_js: true,
194216
..Default::default()
195217
}
@@ -203,6 +225,7 @@ impl Plot {
203225
/// Note that when using `Plot::to_inline_html()`, it is assumed that the
204226
/// `plotly.js` library is already in scope, so setting this attribute
205227
/// will have no effect.
228+
#[cfg(not(feature = "plotly_noembed"))]
206229
pub fn use_local_plotly(&mut self) {
207230
self.remote_plotly_js = false;
208231
}
@@ -422,6 +445,7 @@ impl Plot {
422445
fn render(&self) -> String {
423446
let tmpl = PlotTemplate {
424447
plot: self,
448+
#[cfg(not(feature = "plotly_noembed"))]
425449
remote_plotly_js: self.remote_plotly_js,
426450
};
427451
tmpl.render().unwrap()
@@ -432,6 +456,7 @@ impl Plot {
432456
let tmpl = StaticPlotTemplate {
433457
plot: self,
434458
format,
459+
#[cfg(not(feature = "plotly_noembed"))]
435460
remote_plotly_js: self.remote_plotly_js,
436461
width,
437462
height,

plotly/templates/plot_noembed.html

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<!doctype html>
2+
<html lang="en">
3+
4+
<head>
5+
<meta charset="utf-8" />
6+
</head>
7+
8+
<body>
9+
<div>
10+
<script src="https://cdn.jsdelivr.net/npm/[email protected]/es5/tex-svg.js"></script>
11+
<script src="https://cdn.plot.ly/plotly-2.12.1.min.js"></script>
12+
13+
<div id="plotly-html-element" class="plotly-graph-div" style="height:100%; width:100%;"></div>
14+
15+
<script type="module">
16+
const graph_div = document.getElementById("plotly-html-element");
17+
await Plotly.newPlot(graph_div, {{ plot| tojson | safe }});
18+
</script>
19+
</div>
20+
</body>
21+
22+
</html>
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8" />
5+
</head>
6+
<body>
7+
<div>
8+
<script src="https://cdn.jsdelivr.net/npm/[email protected]/es5/tex-mml-chtml.js"></script>
9+
<script src="https://cdn.plot.ly/plotly-2.12.1.min.js"></script>
10+
11+
<div id="plotly-html-element" hidden></div>
12+
<img id="plotly-img-element"></img>
13+
14+
<script type="module">
15+
const graph_div = document.getElementById("plotly-html-element");
16+
await Plotly.newPlot(graph_div, {{ plot|tojson|safe }});
17+
18+
const img_element = document.getElementById("plotly-img-element");
19+
const data_url = await Plotly.toImage(
20+
graph_div,
21+
{
22+
format: "{{ format }}",
23+
width: {{ width }},
24+
height: {{ height }},
25+
}
26+
);
27+
28+
img_element.setAttribute("src", data_url);
29+
</script>
30+
</div>
31+
</body>
32+
</html>

0 commit comments

Comments
 (0)