Skip to content

Commit 732b02b

Browse files
committed
Merge remote-tracking branch 'origin/main' into sebdotv/mapbox-domain
Signed-off-by: Andrei Gherghescu <[email protected]>
2 parents 6c9deed + ba867e0 commit 732b02b

File tree

17 files changed

+231
-37
lines changed

17 files changed

+231
-37
lines changed

Diff for: .github/dependabot.yml

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
version: 2
2+
3+
updates:
4+
- package-ecosystem: cargo
5+
directory: /
6+
schedule:
7+
interval: daily

Diff for: .github/workflows/ci.yml

+8-6
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ name: CI
33
on:
44
workflow_dispatch:
55
pull_request:
6-
branches: [ master ]
6+
branches: [ main ]
77
push:
8-
branches: [ master ]
8+
branches: [ main ]
99

1010
# Cancel any in-flight jobs for the same PR/branch so there's only one active
1111
# at a time
@@ -27,7 +27,7 @@ jobs:
2727
components: rustfmt
2828
- run: cargo fmt --all -- --check
2929
- run: cd ${{ github.workspace }}/examples && cargo fmt --all -- --check
30-
30+
3131
clippy:
3232
name: Clippy
3333
runs-on: ubuntu-latest
@@ -57,7 +57,9 @@ jobs:
5757
- uses: actions/checkout@v3
5858
- uses: dtolnay/rust-toolchain@stable
5959
- run: cargo test --features plotly_ndarray,plotly_image,kaleido
60-
60+
- if: ${{ matrix.os == 'windows-latest' }}
61+
run: gci -recurse -filter "*example*"
62+
6163
code-coverage:
6264
name: Code Coverage
6365
runs-on: ubuntu-latest
@@ -70,7 +72,7 @@ jobs:
7072
# we are skipping anything to do with wasm here
7173
- run: cargo llvm-cov --workspace --features plotly_ndarray,plotly_image,kaleido --lcov --output-path lcov.info
7274
- uses: codecov/codecov-action@v3
73-
75+
7476
build_examples:
7577
name: Build Examples
7678
strategy:
@@ -94,7 +96,7 @@ jobs:
9496
- uses: actions/checkout@v3
9597
- uses: dtolnay/rust-toolchain@stable
9698
- run: cd ${{ github.workspace }}/examples/${{ matrix.example }} && cargo build
97-
99+
98100
build_wasm_examples:
99101
name: Build Wasm Examples
100102
strategy:

Diff for: CHANGELOG.md

+5-4
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@ 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.8.5] - 2023-xx-xx
6+
## [0.8.5] - 2024-xx-xx
77
### Added
8-
- [[#153](https://github.com/igiagkiozis/plotly/pull/153)] Added `LayoutScene`
8+
- [[#181](https://github.com/igiagkiozis/plotly/pull/181)] Fix compilation error when mixing the crate with `askama/with-axum` by adding `with-axum` feature.
9+
- [[#163](https://github.com/plotly/plotly.rs/pull/163)] Added `DensityMapbox`.
10+
- [[#153](https://github.com/igiagkiozis/plotly/pull/153)] Added `LayoutScene`.
911

1012
## [0.8.4] - 2023-07-09
1113
### Added
@@ -46,8 +48,7 @@ Version 0.8.0 represents a significant release which refactors a lot of the code
4648
- Support for `Sankey` diagrams
4749
- Support for `Plot3D` - 3D plots for scatter, line and surface data
4850
### Changed
49-
- Improve implementation of `private::NumOrString` to support more primitive types ([Issue
50-
#47](https://github.com/igiagkiozis/plotly/issues/47))
51+
- Improve implementation of `private::NumOrString` to support more primitive types ([Issue #47](https://github.com/igiagkiozis/plotly/issues/47))
5152
- Remove `private::TruthyEnum` in favour of a more robust way of serializing to `String` or `bool`
5253
- Refactor `Color` module
5354
- Refactored HTML templates with cleaner Javascript code

Diff for: examples/maps/src/main.rs

+22-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
use plotly::{
44
common::Marker,
55
layout::{Center, DragMode, Mapbox, MapboxStyle, Margin},
6-
Layout, Plot, ScatterMapbox,
6+
DensityMapbox, Layout, Plot, ScatterMapbox,
77
};
88

99
fn scatter_mapbox() {
@@ -27,8 +27,29 @@ fn scatter_mapbox() {
2727
plot.show();
2828
}
2929

30+
fn density_mapbox() {
31+
let trace = DensityMapbox::new(vec![45.5017], vec![-73.5673], vec![0.75]).zauto(true);
32+
33+
let layout = Layout::new()
34+
.drag_mode(DragMode::Zoom)
35+
.margin(Margin::new().top(0).left(0).bottom(0).right(0))
36+
.mapbox(
37+
Mapbox::new()
38+
.style(MapboxStyle::OpenStreetMap)
39+
.center(Center::new(45.5017, -73.5673))
40+
.zoom(5),
41+
);
42+
43+
let mut plot = Plot::new();
44+
plot.add_trace(trace);
45+
plot.set_layout(layout);
46+
47+
plot.show();
48+
}
49+
3050
fn main() {
3151
// Uncomment any of these lines to display the example.
3252

3353
// scatter_mapbox();
54+
// density_mapbox();
3455
}

Diff for: examples/statistical_charts/src/main.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -345,7 +345,7 @@ fn fully_styled_box_plot() {
345345
v
346346
};
347347

348-
let x_data = vec![
348+
let x_data = [
349349
"Carmelo<br>Anthony",
350350
"Dwyane<br>Wade",
351351
"Deron<br>Williams",

Diff for: plotly/Cargo.toml

+7-5
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,15 @@ kaleido = ["plotly_kaleido"]
1818
plotly_ndarray = ["ndarray"]
1919
plotly_image = ["image"]
2020
wasm = ["getrandom", "js-sys", "wasm-bindgen", "wasm-bindgen-futures"]
21+
with-axum = ["askama/with-axum", "askama_axum"]
2122

2223
[dependencies]
2324
askama = { version = ">=0.11.0, <0.13.0", features = ["serde-json"] }
25+
askama_axum = { version = "0.4.0", optional = true }
2426
dyn-clone = "1"
25-
erased-serde = "0.3"
27+
erased-serde = "0.4"
2628
getrandom = { version = "0.2", features = ["js"], optional = true }
27-
image = { version = "0.24.2", optional = true }
29+
image = { version = "0.24", optional = true }
2830
js-sys = { version = "0.3", optional = true }
2931
plotly_derive = { version = "0.8.4", path = "../plotly_derive" }
3032
plotly_kaleido = { version = "0.8.4", path = "../plotly_kaleido", optional = true }
@@ -33,15 +35,15 @@ once_cell = "1"
3335
serde = { version = "1.0.132", features = ["derive"] }
3436
serde_json = "1.0.73"
3537
serde_repr = "0.1"
36-
serde_with = "2"
38+
serde_with = ">=2, <4"
3739
rand = "0.8"
3840
wasm-bindgen = { version = "0.2", optional = true }
3941
wasm-bindgen-futures = { version = "0.4", optional = true }
4042

4143
[dev-dependencies]
4244
csv = "1.1.6"
43-
image = "0.24.4"
44-
itertools = "0.10.3"
45+
image = "0.24"
46+
itertools = ">=0.10, <0.13"
4547
itertools-num = "0.1.3"
4648
ndarray = "0.15.4"
4749
plotly_kaleido = { version = "0.8.4", path = "../plotly_kaleido" }

Diff for: plotly/src/common/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,7 @@ pub enum PlotType {
201201
Ohlc,
202202
Sankey,
203203
Surface,
204+
DensityMapbox,
204205
}
205206

206207
#[derive(Serialize, Clone, Debug)]

Diff for: plotly/src/layout/update_menu.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ impl ButtonBuilder {
100100
pub fn new() -> Self {
101101
Default::default()
102102
}
103-
pub fn push_restyle(mut self, restyle: impl Restyle + Serialize) -> Self {
103+
pub fn push_restyle(mut self, restyle: impl Restyle) -> Self {
104104
let restyle = serde_json::to_value(&restyle).unwrap();
105105
for (k, v) in restyle.as_object().unwrap() {
106106
self.restyles.insert(k.clone(), v.clone());

Diff for: plotly/src/lib.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ pub use plot::{ImageFormat, Plot, Trace};
3333
pub use traces::{box_plot, contour, histogram, image, mesh3d, sankey, scatter_mapbox, surface};
3434
// Bring the different trace types into the top-level scope
3535
pub use traces::{
36-
Bar, BoxPlot, Candlestick, Contour, HeatMap, Histogram, Image, Mesh3D, Ohlc, Sankey, Scatter,
37-
Scatter3D, ScatterMapbox, ScatterPolar, Surface,
36+
Bar, BoxPlot, Candlestick, Contour, DensityMapbox, HeatMap, Histogram, Image, Mesh3D, Ohlc,
37+
Sankey, Scatter, Scatter3D, ScatterMapbox, ScatterPolar, Surface,
3838
};
3939

4040
pub trait Restyle: serde::Serialize {}

Diff for: plotly/src/plot.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ struct PlotTemplate<'a> {
2020

2121
#[derive(Template)]
2222
#[template(path = "static_plot.html", escape = "none")]
23+
#[cfg(not(target_family = "wasm"))]
2324
struct StaticPlotTemplate<'a> {
2425
plot: &'a Plot,
2526
format: ImageFormat,
@@ -162,7 +163,7 @@ impl Traces {
162163
///
163164
/// let layout = Layout::new().title("<b>Line and Scatter Plot</b>".into());
164165
/// plot.set_layout(layout);
165-
///
166+
///
166167
/// # if false { // We don't actually want to try and display the plot in a browser when running a doctest.
167168
/// plot.show();
168169
/// # }
@@ -650,6 +651,7 @@ mod tests {
650651
assert!(!dst.exists());
651652
}
652653

654+
#[cfg(not(target_os = "windows"))]
653655
#[test]
654656
#[cfg(feature = "kaleido")]
655657
fn test_save_to_png() {
@@ -661,6 +663,7 @@ mod tests {
661663
assert!(!dst.exists());
662664
}
663665

666+
#[cfg(not(target_os = "windows"))]
664667
#[test]
665668
#[cfg(feature = "kaleido")]
666669
fn test_save_to_jpeg() {
@@ -672,6 +675,7 @@ mod tests {
672675
assert!(!dst.exists());
673676
}
674677

678+
#[cfg(not(target_os = "windows"))]
675679
#[test]
676680
#[cfg(feature = "kaleido")]
677681
fn test_save_to_svg() {
@@ -695,6 +699,7 @@ mod tests {
695699
assert!(!dst.exists());
696700
}
697701

702+
#[cfg(not(target_os = "windows"))]
698703
#[test]
699704
#[cfg(feature = "kaleido")]
700705
fn test_save_to_pdf() {
@@ -706,6 +711,7 @@ mod tests {
706711
assert!(!dst.exists());
707712
}
708713

714+
#[cfg(not(target_os = "windows"))]
709715
#[test]
710716
#[cfg(feature = "kaleido")]
711717
fn test_save_to_webp() {

Diff for: plotly/src/traces/density_mapbox.rs

+146
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
//! Density mapbox scatter plot
2+
3+
use plotly_derive::FieldSetter;
4+
use serde::Serialize;
5+
6+
use crate::common::{LegendGroupTitle, Line, PlotType, Visible};
7+
use crate::Trace;
8+
9+
#[serde_with::skip_serializing_none]
10+
#[derive(Serialize, Clone, Debug, FieldSetter)]
11+
#[field_setter(box_self, kind = "trace")]
12+
pub struct DensityMapbox<Lat, Lon, Z>
13+
where
14+
Lat: Serialize + Clone,
15+
Lon: Serialize + Clone,
16+
Z: Serialize + Clone,
17+
{
18+
#[field_setter(default = "PlotType::DensityMapbox")]
19+
r#type: PlotType,
20+
/// Sets the trace name. The trace name appear as the legend item and on
21+
/// hover.
22+
name: Option<String>,
23+
/// Determines whether or not this trace is visible. If
24+
/// `Visible::LegendOnly`, the trace is not drawn, but can appear as a
25+
/// legend item (provided that the legend itself is visible).
26+
visible: Option<Visible>,
27+
28+
/// Determines whether or not an item corresponding to this trace is shown
29+
/// in the legend.
30+
#[serde(rename = "showlegend")]
31+
show_legend: Option<bool>,
32+
33+
/// Sets the legend rank for this trace. Items and groups with smaller ranks
34+
/// are presented on top/left side while with `"reversed"
35+
/// `legend.trace_order` they are on bottom/right side. The default
36+
/// legendrank is 1000, so that you can use ranks less than 1000 to
37+
/// place certain items before all unranked items, and ranks greater
38+
/// than 1000 to go after all unranked items.
39+
#[serde(rename = "legendrank")]
40+
legend_rank: Option<usize>,
41+
/// Sets the legend group for this trace. Traces part of the same legend
42+
/// group show/hide at the same time when toggling legend items.
43+
#[serde(rename = "legendgroup")]
44+
legend_group: Option<String>,
45+
/// Set and style the title to appear for the legend group.
46+
#[serde(rename = "legendgrouptitle")]
47+
legend_group_title: Option<LegendGroupTitle>,
48+
49+
/// Line display properties.
50+
line: Option<Line>,
51+
52+
lat: Option<Vec<Lat>>,
53+
lon: Option<Vec<Lon>>,
54+
z: Option<Vec<Z>>,
55+
56+
/// Sets the opacity of the trace.
57+
opacity: Option<f64>,
58+
59+
/// Sets a reference between this trace's data coordinates and a mapbox
60+
/// subplot. If "mapbox" (the default value), the data refer to
61+
/// `layout.mapbox`. If "mapbox2", the data refer to `layout.mapbox2`, and
62+
/// so on.
63+
subplot: Option<String>,
64+
65+
/// Determines whether or not the color domain is computed
66+
/// with respect to the input data (here in `z`) or the bounds set
67+
/// in `zmin` and `zmax`. Defaults to false when `zmin` and `zmax` are
68+
/// set by the user.
69+
zauto: Option<bool>,
70+
71+
/// Sets the upper bound of the color domain. Value should have the
72+
/// same units as in `z` and if set, `zmin` must be set as well.
73+
zmax: Option<Z>,
74+
75+
zmid: Option<Z>,
76+
77+
zmin: Option<Z>,
78+
79+
zoom: Option<u8>,
80+
81+
radius: Option<u8>,
82+
//color_continuous_scale: Option<HashMap<Z, NamedColor>>,
83+
//color_continuous_midpoint: Option<ContinuousColorScale>,
84+
}
85+
86+
impl<Lat, Lon, Z> DensityMapbox<Lat, Lon, Z>
87+
where
88+
Lat: Serialize + Clone + std::default::Default, // TODO why is "+ Default" necessary?
89+
Lon: Serialize + Clone + std::default::Default,
90+
Z: Serialize + Clone + std::default::Default,
91+
{
92+
pub fn new(lat: Vec<Lat>, lon: Vec<Lon>, z: Vec<Z>) -> Box<Self> {
93+
Box::new(Self {
94+
lat: Some(lat),
95+
lon: Some(lon),
96+
z: Some(z),
97+
..Default::default()
98+
})
99+
}
100+
}
101+
102+
impl<Lat, Lon, Z> Trace for DensityMapbox<Lat, Lon, Z>
103+
where
104+
Lat: Serialize + Clone,
105+
Lon: Serialize + Clone,
106+
Z: Serialize + Clone,
107+
{
108+
fn to_json(&self) -> String {
109+
serde_json::to_string(&self).unwrap()
110+
}
111+
}
112+
113+
#[cfg(test)]
114+
mod tests {
115+
use serde_json::{json, to_value};
116+
117+
use super::*;
118+
119+
#[test]
120+
fn test_serialize_density_mapbox() {
121+
let density_mapbox = DensityMapbox::new(vec![45.5017], vec![-73.5673], vec![1.0])
122+
.name("name")
123+
.visible(Visible::True)
124+
.show_legend(true)
125+
.legend_rank(1000)
126+
.legend_group("legend group")
127+
.zoom(5)
128+
.radius(20)
129+
.opacity(0.5);
130+
let expected = json!({
131+
"type": "densitymapbox",
132+
"lat": [45.5017],
133+
"lon": [-73.5673],
134+
"z": [1.0],
135+
"name": "name",
136+
"visible": true,
137+
"showlegend": true,
138+
"legendrank": 1000,
139+
"legendgroup": "legend group",
140+
"opacity": 0.5,
141+
"zoom": 5,
142+
"radius": 20,
143+
});
144+
assert_eq!(to_value(density_mapbox.clone()).unwrap(), expected);
145+
}
146+
}

0 commit comments

Comments
 (0)