Skip to content

Commit fc70391

Browse files
authored
Refactor Color trait and apply throughout codebase (#87)
1 parent b55efe6 commit fc70391

18 files changed

+414
-501
lines changed

plotly/examples/basic_charts.rs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@ use plotly::common::{
55
};
66
use plotly::layout::{Axis, BarMode, Layout, Legend, TicksDirection, TraceOrder};
77
use plotly::sankey::{Line as SankeyLine, Link, Node};
8-
use plotly::{Bar, NamedColor, Plot, Rgb, Rgba, Sankey, Scatter, ScatterPolar};
8+
use plotly::{
9+
color::{NamedColor, Rgb, Rgba},
10+
Bar, Plot, Sankey, Scatter, ScatterPolar,
11+
};
912
use rand_distr::{Distribution, Normal, Uniform};
1013

1114
// Scatter Plots
@@ -254,11 +257,6 @@ fn large_data_sets(show: bool) {
254257
.sample_iter(&mut rng)
255258
.take(n)
256259
.collect();
257-
let colors: Vec<f64> = Normal::new(0., 1.)
258-
.unwrap()
259-
.sample_iter(&mut rng)
260-
.take(n)
261-
.collect();
262260

263261
let x: Vec<f64> = r
264262
.iter()
@@ -276,7 +274,6 @@ fn large_data_sets(show: bool) {
276274
.marker(
277275
Marker::new()
278276
.color_scale(ColorScale::Palette(ColorScalePalette::Viridis))
279-
.color_array(colors)
280277
.line(Line::new().width(1.)),
281278
);
282279
let mut plot = Plot::new();
@@ -406,7 +403,6 @@ fn line_shape_options_for_interpolation(show: bool) {
406403
plot.add_trace(trace4);
407404
plot.add_trace(trace5);
408405
plot.add_trace(trace6);
409-
plot.show_png(1024, 680);
410406
if show {
411407
plot.show();
412408
}

plotly/examples/fundamentals.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use plotly::common::{DashType, Fill, Font, Mode};
33
use plotly::layout::{
44
Axis, GridPattern, Layout, LayoutGrid, Margin, Shape, ShapeLayer, ShapeLine, ShapeType,
55
};
6-
use plotly::{Bar, NamedColor, Plot, Scatter};
6+
use plotly::{color::NamedColor, Bar, Plot, Scatter};
77
use rand::thread_rng;
88
use rand_distr::{Distribution, Normal};
99

plotly/examples/statistical_charts.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@ use plotly::box_plot::{BoxMean, BoxPoints};
33
use plotly::common::{ErrorData, ErrorType, Line, Marker, Mode, Orientation, Title};
44
use plotly::histogram::{Bins, Cumulative, HistFunc, HistNorm};
55
use plotly::layout::{Axis, BarMode, BoxMode, Layout, Margin};
6-
use plotly::{Bar, BoxPlot, Histogram, NamedColor, Plot, Rgb, Rgba, Scatter};
6+
use plotly::{
7+
color::{NamedColor, Rgb, Rgba},
8+
Bar, BoxPlot, Histogram, Plot, Scatter,
9+
};
710
use rand_distr::{Distribution, Normal, Uniform};
811

912
// Error Bars

plotly/examples/subplots.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use plotly::common::{AxisSide, Font, Title};
22
use plotly::layout::{Axis, GridPattern, Layout, LayoutGrid, Legend, RowOrder, TraceOrder};
3-
use plotly::{Plot, Rgb, Scatter};
3+
use plotly::{color::Rgb, Plot, Scatter};
44

55
// Subplots
66
fn simple_subplot(show: bool) {

plotly/src/common/color.rs

Lines changed: 225 additions & 313 deletions
Large diffs are not rendered by default.

plotly/src/common/mod.rs

Lines changed: 64 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,8 @@ pub mod color;
22

33
use serde::{Serialize, Serializer};
44

5-
use crate::common::color::ColorWrapper;
5+
use crate::color::{Color, ColorArray};
66
use crate::private;
7-
use color::Color;
87

98
#[derive(Serialize, Clone, Debug)]
109
#[serde(untagged)]
@@ -504,7 +503,7 @@ pub struct Line {
504503
#[serde(skip_serializing_if = "Option::is_none")]
505504
simplify: Option<bool>,
506505
#[serde(skip_serializing_if = "Option::is_none")]
507-
color: Option<ColorWrapper>,
506+
color: Option<Box<dyn Color>>,
508507
#[serde(skip_serializing_if = "Option::is_none")]
509508
cauto: Option<bool>,
510509
#[serde(skip_serializing_if = "Option::is_none")]
@@ -520,7 +519,7 @@ pub struct Line {
520519
#[serde(skip_serializing_if = "Option::is_none", rename = "reversescale")]
521520
reverse_scale: Option<bool>,
522521
#[serde(skip_serializing_if = "Option::is_none", rename = "outliercolor")]
523-
outlier_color: Option<ColorWrapper>,
522+
outlier_color: Option<Box<dyn Color>>,
524523
#[serde(skip_serializing_if = "Option::is_none", rename = "outlierwidth")]
525524
outlier_width: Option<usize>,
526525
}
@@ -556,7 +555,7 @@ impl Line {
556555
}
557556

558557
pub fn color<C: Color>(mut self, color: C) -> Self {
559-
self.color = Some(color.to_color());
558+
self.color = Some(Box::new(color));
560559
self
561560
}
562561

@@ -596,7 +595,7 @@ impl Line {
596595
}
597596

598597
pub fn outlier_color<C: Color>(mut self, outlier_color: C) -> Self {
599-
self.outlier_color = Some(outlier_color.to_color());
598+
self.outlier_color = Some(Box::new(outlier_color));
600599
self
601600
}
602601

@@ -667,18 +666,21 @@ pub enum ExponentFormat {
667666
#[derive(Serialize, Clone, Debug)]
668667
pub struct Gradient {
669668
r#type: GradientType,
670-
color: Dim<ColorWrapper>,
669+
color: Dim<Box<dyn Color>>,
671670
}
672671

673672
impl Gradient {
674-
pub fn new<C: Color + Serialize>(gradient_type: GradientType, color: Dim<C>) -> Self {
675-
let color = match color {
676-
Dim::Scalar(c) => Dim::Scalar(c.to_color()),
677-
Dim::Vector(c) => Dim::Vector(private::to_color_array(c)),
678-
};
673+
pub fn new<C: Color>(gradient_type: GradientType, color: C) -> Self {
679674
Gradient {
680675
r#type: gradient_type,
681-
color,
676+
color: Dim::Scalar(Box::new(color)),
677+
}
678+
}
679+
680+
pub fn new_array<C: Color>(gradient_type: GradientType, colors: Vec<C>) -> Self {
681+
Gradient {
682+
r#type: gradient_type,
683+
color: Dim::Vector(ColorArray(colors).into()),
682684
}
683685
}
684686
}
@@ -749,15 +751,15 @@ pub struct ColorBar {
749751
#[serde(rename = "ypad")]
750752
y_pad: f64,
751753
#[serde(skip_serializing_if = "Option::is_none", rename = "outlinecolor")]
752-
outline_color: Option<ColorWrapper>,
754+
outline_color: Option<Box<dyn Color>>,
753755
#[serde(rename = "outlinewidth")]
754756
outline_width: usize,
755757
#[serde(skip_serializing_if = "Option::is_none", rename = "bordercolor")]
756-
border_color: Option<ColorWrapper>,
758+
border_color: Option<Box<dyn Color>>,
757759
#[serde(rename = "borderwidth")]
758760
border_width: usize,
759761
#[serde(skip_serializing_if = "Option::is_none", rename = "bgcolor")]
760-
background_color: Option<ColorWrapper>,
762+
background_color: Option<Box<dyn Color>>,
761763
#[serde(skip_serializing_if = "Option::is_none", rename = "tickmode")]
762764
tick_mode: Option<TickMode>,
763765
#[serde(rename = "nticks")]
@@ -777,7 +779,7 @@ pub struct ColorBar {
777779
#[serde(rename = "tickwidth")]
778780
tick_width: usize,
779781
#[serde(skip_serializing_if = "Option::is_none", rename = "tickcolor")]
780-
tick_color: Option<ColorWrapper>,
782+
tick_color: Option<Box<dyn Color>>,
781783
#[serde(rename = "showticklabels")]
782784
show_tick_labels: bool,
783785
#[serde(skip_serializing_if = "Option::is_none", rename = "tickfont")]
@@ -906,7 +908,7 @@ impl ColorBar {
906908
}
907909

908910
pub fn outline_color<C: Color>(mut self, outline_color: C) -> ColorBar {
909-
self.outline_color = Some(outline_color.to_color());
911+
self.outline_color = Some(Box::new(outline_color));
910912
self
911913
}
912914

@@ -916,7 +918,7 @@ impl ColorBar {
916918
}
917919

918920
pub fn border_color<C: Color>(mut self, border_color: C) -> ColorBar {
919-
self.border_color = Some(border_color.to_color());
921+
self.border_color = Some(Box::new(border_color));
920922
self
921923
}
922924

@@ -926,7 +928,7 @@ impl ColorBar {
926928
}
927929

928930
pub fn background_color<C: Color>(mut self, background_color: C) -> ColorBar {
929-
self.background_color = Some(background_color.to_color());
931+
self.background_color = Some(Box::new(background_color));
930932
self
931933
}
932934

@@ -976,7 +978,7 @@ impl ColorBar {
976978
}
977979

978980
pub fn tick_color<C: Color>(mut self, tick_color: C) -> ColorBar {
979-
self.tick_color = Some(tick_color.to_color());
981+
self.tick_color = Some(Box::new(tick_color));
980982
self
981983
}
982984

@@ -1076,7 +1078,7 @@ pub struct Marker {
10761078
#[serde(skip_serializing_if = "Option::is_none")]
10771079
gradient: Option<Gradient>,
10781080
#[serde(skip_serializing_if = "Option::is_none")]
1079-
color: Option<Dim<ColorWrapper>>,
1081+
color: Option<Dim<Box<dyn Color>>>,
10801082
#[serde(skip_serializing_if = "Option::is_none")]
10811083
cauto: Option<bool>,
10821084
#[serde(skip_serializing_if = "Option::is_none")]
@@ -1096,7 +1098,7 @@ pub struct Marker {
10961098
#[serde(skip_serializing_if = "Option::is_none", rename = "colorbar")]
10971099
color_bar: Option<ColorBar>,
10981100
#[serde(skip_serializing_if = "Option::is_none", rename = "outliercolor")]
1099-
outlier_color: Option<ColorWrapper>,
1101+
outlier_color: Option<Box<dyn Color>>,
11001102
}
11011103

11021104
impl Marker {
@@ -1155,13 +1157,12 @@ impl Marker {
11551157
}
11561158

11571159
pub fn color<C: Color>(mut self, color: C) -> Self {
1158-
self.color = Some(Dim::Scalar(color.to_color()));
1160+
self.color = Some(Dim::Scalar(Box::new(color)));
11591161
self
11601162
}
11611163

1162-
pub fn color_array<C: Color>(mut self, color: Vec<C>) -> Self {
1163-
let color = private::to_color_array(color);
1164-
self.color = Some(Dim::Vector(color));
1164+
pub fn color_array<C: Color>(mut self, colors: Vec<C>) -> Self {
1165+
self.color = Some(Dim::Vector(ColorArray(colors).into()));
11651166
self
11661167
}
11671168

@@ -1211,7 +1212,7 @@ impl Marker {
12111212
}
12121213

12131214
pub fn outlier_color<C: Color>(mut self, outlier_color: C) -> Self {
1214-
self.outlier_color = Some(outlier_color.to_color());
1215+
self.outlier_color = Some(Box::new(outlier_color));
12151216
self
12161217
}
12171218
}
@@ -1223,7 +1224,7 @@ pub struct Font {
12231224
#[serde(skip_serializing_if = "Option::is_none")]
12241225
size: Option<usize>,
12251226
#[serde(skip_serializing_if = "Option::is_none")]
1226-
color: Option<ColorWrapper>,
1227+
color: Option<Box<dyn Color>>,
12271228
}
12281229

12291230
impl Font {
@@ -1242,7 +1243,7 @@ impl Font {
12421243
}
12431244

12441245
pub fn color<C: Color>(mut self, color: C) -> Self {
1245-
self.color = Some(color.to_color());
1246+
self.color = Some(Box::new(color));
12461247
self
12471248
}
12481249
}
@@ -1364,9 +1365,9 @@ impl Title {
13641365
#[derive(Serialize, Clone, Debug, Default)]
13651366
pub struct Label {
13661367
#[serde(skip_serializing_if = "Option::is_none", rename = "bgcolor")]
1367-
background_color: Option<ColorWrapper>,
1368+
background_color: Option<Box<dyn Color>>,
13681369
#[serde(skip_serializing_if = "Option::is_none", rename = "bordercolor")]
1369-
border_color: Option<ColorWrapper>,
1370+
border_color: Option<Box<dyn Color>>,
13701371
#[serde(skip_serializing_if = "Option::is_none")]
13711372
font: Option<Font>,
13721373
#[serde(skip_serializing_if = "Option::is_none")]
@@ -1381,12 +1382,12 @@ impl Label {
13811382
}
13821383

13831384
pub fn background_color<C: Color>(mut self, background_color: C) -> Self {
1384-
self.background_color = Some(background_color.to_color());
1385+
self.background_color = Some(Box::new(background_color));
13851386
self
13861387
}
13871388

13881389
pub fn border_color<C: Color>(mut self, border_color: C) -> Self {
1389-
self.border_color = Some(border_color.to_color());
1390+
self.border_color = Some(Box::new(border_color));
13901391
self
13911392
}
13921393

@@ -1449,7 +1450,7 @@ pub struct ErrorData {
14491450
#[serde(skip_serializing_if = "Option::is_none")]
14501451
copy_ystyle: Option<bool>,
14511452
#[serde(skip_serializing_if = "Option::is_none")]
1452-
color: Option<ColorWrapper>,
1453+
color: Option<Box<dyn Color>>,
14531454
#[serde(skip_serializing_if = "Option::is_none")]
14541455
thickness: Option<f64>,
14551456
#[serde(skip_serializing_if = "Option::is_none")]
@@ -1510,7 +1511,7 @@ impl ErrorData {
15101511
}
15111512

15121513
pub fn color<C: Color>(mut self, color: C) -> Self {
1513-
self.color = Some(color.to_color());
1514+
self.color = Some(Box::new(color));
15141515
self
15151516
}
15161517

@@ -1530,7 +1531,7 @@ mod tests {
15301531
use serde_json::{json, to_value};
15311532

15321533
use super::*;
1533-
use crate::NamedColor;
1534+
use crate::color::NamedColor;
15341535

15351536
#[test]
15361537
fn test_serialize_domain() {
@@ -1951,7 +1952,7 @@ mod tests {
19511952
"smoothing": 1.0,
19521953
"dash": "dash",
19531954
"simplify": true,
1954-
"color": "#FFFFFF",
1955+
"color": "#ffffff",
19551956
"cauto": true,
19561957
"cmin": 0.0,
19571958
"cmax": 1.0,
@@ -2019,8 +2020,12 @@ mod tests {
20192020
#[test]
20202021
#[rustfmt::skip]
20212022
fn test_serialize_gradient() {
2022-
let gradient = Gradient::new(GradientType::Horizontal, Dim::Scalar("#ffffff"));
2023-
let expected = json!({"color": "#FFFFFF", "type": "horizontal"});
2023+
let gradient = Gradient::new(GradientType::Horizontal, "#ffffff");
2024+
let expected = json!({"color": "#ffffff", "type": "horizontal"});
2025+
assert_eq!(to_value(gradient).unwrap(), expected);
2026+
2027+
let gradient = Gradient::new_array(GradientType::Horizontal, vec!["#ffffff"]);
2028+
let expected = json!({"color": ["#ffffff"], "type": "horizontal"});
20242029
assert_eq!(to_value(gradient).unwrap(), expected);
20252030
}
20262031

@@ -2060,7 +2065,7 @@ mod tests {
20602065
.size_min(1)
20612066
.size_mode(SizeMode::Area)
20622067
.line(Line::new())
2063-
.gradient(Gradient::new(GradientType::Radial, Dim::Scalar("#FFFFFF")))
2068+
.gradient(Gradient::new(GradientType::Radial, "#FFFFFF"))
20642069
.color(NamedColor::Blue)
20652070
.color_array(vec![NamedColor::Black, NamedColor::Blue])
20662071
.cauto(true)
@@ -2071,7 +2076,7 @@ mod tests {
20712076
.auto_color_scale(true)
20722077
.reverse_scale(true)
20732078
.show_scale(true)
2074-
// .color_bar(ColorBar::new()) awaiting fix in other branch
2079+
.color_bar(ColorBar::new())
20752080
.outlier_color("#FFFFFF");
20762081

20772082
let expected = json!({
@@ -2085,6 +2090,23 @@ mod tests {
20852090
"line": {},
20862091
"gradient": {"type": "radial", "color": "#FFFFFF"},
20872092
"color": ["black", "blue"],
2093+
"colorbar": {
2094+
"borderwidth": 0,
2095+
"len": 1,
2096+
"nticks": 0,
2097+
"outlinewidth": 1,
2098+
"separate_thousands": true,
2099+
"showticklabels": true,
2100+
"thickness": 30,
2101+
"ticklen": 5,
2102+
"tickwidth": 1,
2103+
"x": 1.02,
2104+
"xanchor": "left",
2105+
"xpad": 10.0,
2106+
"y": 0.5,
2107+
"yanchor": "middle",
2108+
"ypad": 10.0,
2109+
},
20882110
"cauto": true,
20892111
"cmin": 0.0,
20902112
"cmax": 1.0,

0 commit comments

Comments
 (0)