Skip to content

Resolve #184 #218

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 20 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
8696877
Defining axis serializer function
yasuomaidana Aug 2, 2024
d45f901
Defining axes as vector instead of filed items values
yasuomaidana Aug 2, 2024
b39bd4e
Updating layout test to use the new vector axis instead of filed acce…
yasuomaidana Aug 2, 2024
1fc5ab2
Updating themes layout usage signature
yasuomaidana Aug 2, 2024
badc5ad
Merge branch 'main' of https://github.com/plotly/plotly.rs into multi…
yasuomaidana Aug 2, 2024
d3e3ef2
Updating test to new axis definition
yasuomaidana Aug 2, 2024
df4759b
Updating statistical charts example
yasuomaidana Aug 6, 2024
3e910b2
Creating axis builders
yasuomaidana Aug 11, 2024
52e687b
Adding x,y,z add axis to api
yasuomaidana Aug 22, 2024
e53cead
Defining axis serializer function
yasuomaidana Aug 2, 2024
14721ac
Defining axes as vector instead of filed items values
yasuomaidana Aug 2, 2024
8f39f9b
Updating layout test to use the new vector axis instead of filed acce…
yasuomaidana Aug 2, 2024
da083f2
Updating themes layout usage signature
yasuomaidana Aug 2, 2024
b93a5d4
Updating test to new axis definition
yasuomaidana Aug 2, 2024
92fc89c
Updating statistical charts example
yasuomaidana Aug 6, 2024
73657bd
Creating axis builders
yasuomaidana Aug 11, 2024
bb2dfb1
Reducing code complexity
yasuomaidana Oct 23, 2024
99db7dc
Implementing axis and axes setters
yasuomaidana Oct 23, 2024
c0d81e7
Formatting code
yasuomaidana Oct 23, 2024
324111c
Merge remote-tracking branch 'origin/multiples-axis' into multiples-axis
yasuomaidana Oct 23, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 17 additions & 10 deletions examples/statistical_charts/src/main.rs
Original file line number Diff line number Diff line change
@@ -202,8 +202,9 @@ fn grouped_box_plot() {
plot.add_trace(trace2);
plot.add_trace(trace3);

let y_axis = Vec::from([Some(Box::new(Axis::new().title("normalized moisture").zero_line(false)))]);
let layout = Layout::new()
.y_axis(Axis::new().title("normalized moisture").zero_line(false))
.y_axis(y_axis)
.box_mode(BoxMode::Group);

plot.set_layout(layout);
@@ -316,9 +317,10 @@ fn grouped_horizontal_box_plot() {
plot.add_trace(trace2);
plot.add_trace(trace3);

let x_axis = Vec::from([Some(Box::new(Axis::new().title("normalized moisture").zero_line(false)))]);
let layout = Layout::new()
.title("Grouped Horizontal Box Plot")
.x_axis(Axis::new().title("normalized moisture").zero_line(false))
.x_axis(x_axis)
.box_mode(BoxMode::Group);

plot.set_layout(layout);
@@ -361,19 +363,21 @@ fn fully_styled_box_plot() {
];

let mut plot = Plot::new();
let layout = Layout::new()
.title("Points Scored by the Top 9 Scoring NBA Players in 2012")
.y_axis(
Axis::new()

let y_axis = Vec::from([Some(
Box::new(Axis::new()
.auto_range(true)
.show_grid(true)
.zero_line(true)
.dtick(5.0)
.grid_color(Rgb::new(255, 255, 255))
.grid_width(1)
.zero_line_color(Rgb::new(255, 255, 255))
.zero_line_width(2),
)
.zero_line_width(2)
))]);
let layout = Layout::new()
.title("Points Scored by the Top 9 Scoring NBA Players in 2012")
.y_axis(y_axis )
.margin(Margin::new().left(40).right(30).bottom(80).top(100))
.paper_background_color(Rgb::new(243, 243, 243))
.plot_background_color(Rgb::new(243, 243, 243))
@@ -511,10 +515,13 @@ fn colored_and_styled_histograms() {
.opacity(0.75)
.auto_bin_x(false)
.x_bins(Bins::new(-3.2, 4.0, 0.06));

let x_axis = Vec::from([Some(Box::new(Axis::new().title("Value")))]);
let y_axis = Vec::from([Some(Box::new(Axis::new().title("Count")))]);
let layout = Layout::new()
.title("Colored and Styled Histograms")
.x_axis(Axis::new().title("Value"))
.y_axis(Axis::new().title("Count"))
.x_axis(x_axis)
.y_axis(y_axis)
.bar_mode(BarMode::Overlay)
.bar_gap(0.05)
.bar_group_gap(0.2);
106 changes: 59 additions & 47 deletions examples/subplots/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#![allow(dead_code)]

use std::vec;
use plotly::common::{Anchor, AxisSide, Font, Title};
use plotly::layout::{
Annotation, Axis, GridPattern, Layout, LayoutGrid, Legend, RowOrder, TraceOrder,
@@ -40,7 +41,7 @@ fn simple_subplot_matches_x_axis() {
plot.add_trace(trace1);
plot.add_trace(trace2);

let layout = Layout::new().x_axis(Axis::new().matches("x2")).grid(
let layout = Layout::new().x_axis(Vec::from([Some(Box::new(Axis::new().matches("x2")))])).grid(
LayoutGrid::new()
.rows(1)
.columns(2)
@@ -50,7 +51,7 @@ fn simple_subplot_matches_x_axis() {

plot.show();
}

//
fn simple_subplot_matches_y_axis() {
let trace1 = Scatter::new(vec![1, 2, 3], vec![4, 5, 6]).name("trace1");
let trace2 = Scatter::new(vec![20, 30, 40], vec![50, 60, 70])
@@ -62,7 +63,7 @@ fn simple_subplot_matches_y_axis() {
plot.add_trace(trace1);
plot.add_trace(trace2);

let layout = Layout::new().y_axis(Axis::new().matches("y2")).grid(
let layout = Layout::new().y_axis(Vec::from([Some(Box::new(Axis::new().matches("x2")))])).grid(
LayoutGrid::new()
.rows(1)
.columns(2)
@@ -72,7 +73,7 @@ fn simple_subplot_matches_y_axis() {

plot.show();
}

//
fn custom_sized_subplot() {
let trace1 = Scatter::new(vec![1, 2, 3], vec![4, 5, 6]).name("trace1");
let trace2 = Scatter::new(vec![20, 30, 40], vec![50, 60, 70])
@@ -84,10 +85,14 @@ fn custom_sized_subplot() {
plot.add_trace(trace1);
plot.add_trace(trace2);

let mut x_axis = Vec::new();
x_axis.push(Some(Box::new(Axis::new().domain(&[0., 0.7]))));
x_axis.push(Some(Box::new(Axis::new().domain(&[0.8, 1.]))));
let y_axis = Vec::from([Some(Box::new(Axis::new().anchor("x2")))]);

let layout = Layout::new()
.x_axis(Axis::new().domain(&[0., 0.7]))
.y_axis2(Axis::new().anchor("x2"))
.x_axis2(Axis::new().domain(&[0.8, 1.]));
.x_axis(x_axis)
.y_axis(y_axis);
plot.set_layout(layout);

plot.show();
@@ -162,11 +167,13 @@ fn stacked_subplots_with_shared_x_axis() {
plot.add_trace(trace2);
plot.add_trace(trace3);

let mut y_axis = Vec::new();
y_axis.push(Some(Box::new(Axis::new().domain(&[0., 0.33]))));
y_axis.push(Some(Box::new(Axis::new().domain(&[0.33, 0.66]))));
y_axis.push(Some(Box::new(Axis::new().domain(&[0.66, 1.]))));
let layout = Layout::new()
.y_axis(Axis::new().domain(&[0., 0.33]))
.legend(Legend::new().trace_order(TraceOrder::Reversed))
.y_axis2(Axis::new().domain(&[0.33, 0.66]))
.y_axis3(Axis::new().domain(&[0.66, 1.]));
.y_axis(y_axis);
plot.set_layout(layout);

plot.show();
@@ -193,22 +200,29 @@ fn multiple_custom_sized_subplots() {
plot.add_trace(trace3);
plot.add_trace(trace4);

let mut x_axis = Vec::new();
x_axis.push(Some(Box::new(Axis::new().domain(&[0., 0.45]).anchor("y1"))));
x_axis.push(Some(Box::new(Axis::new().domain(&[0.55, 1.]).anchor("y2"))));
x_axis.push(Some(Box::new(Axis::new().domain(&[0.55, 1.]).anchor("y3"))));
x_axis.push(Some(Box::new(Axis::new().domain(&[0., 1.]).anchor("y4"))));

let mut y_axis = Vec::new();
y_axis.push(Some(Box::new(Axis::new().domain(&[0.5, 1.]).anchor("x1"))));
y_axis.push(Some(Box::new(Axis::new().domain(&[0.8, 1.]).anchor("x2"))));
y_axis.push(Some(Box::new(Axis::new().domain(&[0.5, 0.75]).anchor("x3"))));
y_axis.push(Some(Box::new(Axis::new().domain(&[0., 0.45]).anchor("x4"))));

let layout = Layout::new()
.title("Multiple Custom Sized Subplots")
.x_axis(Axis::new().domain(&[0., 0.45]).anchor("y1"))
.y_axis(Axis::new().domain(&[0.5, 1.]).anchor("x1"))
.x_axis2(Axis::new().domain(&[0.55, 1.]).anchor("y2"))
.y_axis2(Axis::new().domain(&[0.8, 1.]).anchor("x2"))
.x_axis3(Axis::new().domain(&[0.55, 1.]).anchor("y3"))
.y_axis3(Axis::new().domain(&[0.5, 0.75]).anchor("x3"))
.x_axis4(Axis::new().domain(&[0., 1.]).anchor("y4"))
.y_axis4(Axis::new().domain(&[0., 0.45]).anchor("x4"));
.x_axis(x_axis)
.y_axis(y_axis);

plot.set_layout(layout);

plot.show();
}

// Multiple Axes
// // Multiple Axes
fn two_y_axes() {
let trace1 = Scatter::new(vec![1, 2, 3], vec![40, 50, 60]).name("trace1");
let trace2 = Scatter::new(vec![2, 3, 4], vec![4, 5, 6])
@@ -219,16 +233,17 @@ fn two_y_axes() {
plot.add_trace(trace1);
plot.add_trace(trace2);

let mut y_axis = Vec::new();
y_axis.push(Some(Box::new(Axis::new().title("yaxis title"))));
y_axis.push(Some(Box::new(Axis::new().title(Title::from("yaxis2 title").font(Font::new().color(Rgb::new(148, 103, 189))))
.tick_font(Font::new().color(Rgb::new(148, 103, 189)))
.overlaying("y")
.side(AxisSide::Right))));

let layout = Layout::new()
.title("Double Y Axis Example")
.y_axis(Axis::new().title("yaxis title"))
.y_axis2(
Axis::new()
.title(Title::from("yaxis2 title").font(Font::new().color(Rgb::new(148, 103, 189))))
.tick_font(Font::new().color(Rgb::new(148, 103, 189)))
.overlaying("y")
.side(AxisSide::Right),
);
.y_axis(y_axis);

plot.set_layout(layout);

plot.show();
@@ -248,41 +263,38 @@ fn multiple_axes() {
plot.add_trace(trace3);
plot.add_trace(trace4);

let layout = Layout::new()
.title("multiple y-axes example")
.width(800)
.x_axis(Axis::new().domain(&[0.3, 0.7]))
.y_axis(
Axis::new()
let mut y_axis = Vec::new();

y_axis.push(Some(Box::new(Axis::new()
.title(Title::from("yaxis title").font(Font::new().color("#1f77b4")))
.tick_font(Font::new().color("#1f77b4")),
)
.y_axis2(
Axis::new()
.tick_font(Font::new().color("#1f77b4")))));
y_axis.push(Some(Box::new(Axis::new()
.title(Title::from("yaxis2 title").font(Font::new().color("#ff7f0e")))
.tick_font(Font::new().color("#ff7f0e"))
.anchor("free")
.overlaying("y")
.side(AxisSide::Left)
.position(0.15),
)
.y_axis3(
Axis::new()
.position(0.15))));
y_axis.push(Some(Box::new(Axis::new()
.title(Title::from("yaxis3 title").font(Font::new().color("#d62728")))
.tick_font(Font::new().color("#d62728"))
.anchor("x")
.overlaying("y")
.side(AxisSide::Right),
)
.y_axis4(
Axis::new()
.side(AxisSide::Right))));
y_axis.push(Some(Box::new(Axis::new()
.title(Title::from("yaxis4 title").font(Font::new().color("#9467bd")))
.tick_font(Font::new().color("#9467bd"))
.anchor("free")
.overlaying("y")
.side(AxisSide::Right)
.position(0.85),
);
.position(0.85))));


let layout = Layout::new()
.title("multiple y-axes example")
.width(800)
.x_axis(Vec::from([Some(Box::new(Axis::new().domain(&[0.3, 0.7])))]))
.y_axis(y_axis);
plot.set_layout(layout);

plot.show();
190 changes: 74 additions & 116 deletions plotly/src/layout/mod.rs
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@ pub mod themes;
pub mod update_menu;

use std::borrow::Cow;

use std::collections::HashMap;
use plotly_derive::FieldSetter;
use serde::{Serialize, Serializer};
use update_menu::UpdateMenu;
@@ -17,6 +17,49 @@ use crate::{
private::{NumOrString, NumOrStringCollection},
};


fn serialize_axes<S>(axes: &Option<Vec<Option<Box<Axis>>>>, serializer: S, axis_prefix: &str) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut map = HashMap::new();
let axes = axes.as_ref().unwrap();

for (i, axis) in axes.iter().enumerate() {
let axe = axis.as_ref().unwrap();
let key = if i == 0 {
axis_prefix.to_string()
} else {
format!("{}{}", axis_prefix, i + 1)
};
map.insert(key, axe);
}

map.serialize(serializer)
}

fn serialize_x_axes<S>(axes: &Option<Vec<Option<Box<Axis>>>>, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serialize_axes(axes, serializer, "xaxis")
}

fn serialize_y_axes<S>(axes: &Option<Vec<Option<Box<Axis>>>>, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serialize_axes(axes, serializer, "yaxis")
}


fn serialize_z_axes<S>(axes: &Option<Vec<Option<Box<Axis>>>>, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serialize_axes(axes, serializer, "zaxis")
}

#[derive(Serialize, Debug, Clone)]
#[serde(rename_all = "lowercase")]
pub enum AxisType {
@@ -1298,7 +1341,7 @@ pub enum DragMode3D {
impl Serialize for DragMode3D {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
S: Serializer,
{
match *self {
Self::Zoom => serializer.serialize_str("zoom"),
@@ -1706,38 +1749,10 @@ pub struct LayoutTemplate {
grid: Option<LayoutGrid>,
calendar: Option<Calendar>,

#[serde(rename = "xaxis")]
x_axis: Option<Box<Axis>>,
#[serde(rename = "yaxis")]
y_axis: Option<Box<Axis>>,
#[serde(rename = "xaxis2")]
x_axis2: Option<Box<Axis>>,
#[serde(rename = "yaxis2")]
y_axis2: Option<Box<Axis>>,
#[serde(rename = "xaxis3")]
x_axis3: Option<Box<Axis>>,
#[serde(rename = "yaxis3")]
y_axis3: Option<Box<Axis>>,
#[serde(rename = "xaxis4")]
x_axis4: Option<Box<Axis>>,
#[serde(rename = "yaxis4")]
y_axis4: Option<Box<Axis>>,
#[serde(rename = "xaxis5")]
x_axis5: Option<Box<Axis>>,
#[serde(rename = "yaxis5")]
y_axis5: Option<Box<Axis>>,
#[serde(rename = "xaxis6")]
x_axis6: Option<Box<Axis>>,
#[serde(rename = "yaxis6")]
y_axis6: Option<Box<Axis>>,
#[serde(rename = "xaxis7")]
x_axis7: Option<Box<Axis>>,
#[serde(rename = "yaxis7")]
y_axis7: Option<Box<Axis>>,
#[serde(rename = "xaxis8")]
x_axis8: Option<Box<Axis>>,
#[serde(rename = "yaxis8")]
y_axis8: Option<Box<Axis>>,
#[serde(flatten, serialize_with = "serialize_x_axes")]
x_axis: Option<Vec<Option<Box<Axis>>>>,
#[serde(flatten, serialize_with = "serialize_y_axes")]
y_axis: Option<Vec<Option<Box<Axis>>>>,

// ternary: Option<LayoutTernary>,
scene: Option<LayoutScene>,
@@ -1873,55 +1888,12 @@ pub struct Layout {
grid: Option<LayoutGrid>,
calendar: Option<Calendar>,

#[serde(rename = "xaxis")]
x_axis: Option<Box<Axis>>,
#[serde(rename = "yaxis")]
y_axis: Option<Box<Axis>>,
#[serde(rename = "zaxis")]
z_axis: Option<Box<Axis>>,

#[serde(rename = "xaxis2")]
x_axis2: Option<Box<Axis>>,
#[serde(rename = "yaxis2")]
y_axis2: Option<Box<Axis>>,
#[serde(rename = "zaxis2")]
z_axis2: Option<Box<Axis>>,
#[serde(rename = "xaxis3")]
x_axis3: Option<Box<Axis>>,
#[serde(rename = "yaxis3")]
y_axis3: Option<Box<Axis>>,
#[serde(rename = "zaxis3")]
z_axis3: Option<Box<Axis>>,
#[serde(rename = "xaxis4")]
x_axis4: Option<Box<Axis>>,
#[serde(rename = "yaxis4")]
y_axis4: Option<Box<Axis>>,
#[serde(rename = "zaxis4")]
z_axis4: Option<Box<Axis>>,
#[serde(rename = "xaxis5")]
x_axis5: Option<Box<Axis>>,
#[serde(rename = "yaxis5")]
y_axis5: Option<Box<Axis>>,
#[serde(rename = "zaxis5")]
z_axis5: Option<Box<Axis>>,
#[serde(rename = "xaxis6")]
x_axis6: Option<Box<Axis>>,
#[serde(rename = "yaxis6")]
y_axis6: Option<Box<Axis>>,
#[serde(rename = "zaxis6")]
z_axis6: Option<Box<Axis>>,
#[serde(rename = "xaxis7")]
x_axis7: Option<Box<Axis>>,
#[serde(rename = "yaxis7")]
y_axis7: Option<Box<Axis>>,
#[serde(rename = "zaxis7")]
z_axis7: Option<Box<Axis>>,
#[serde(rename = "xaxis8")]
x_axis8: Option<Box<Axis>>,
#[serde(rename = "yaxis8")]
y_axis8: Option<Box<Axis>>,
#[serde(rename = "zaxis8")]
z_axis8: Option<Box<Axis>>,
#[serde(flatten, serialize_with = "serialize_x_axes")]
x_axis: Option<Vec<Option<Box<Axis>>>>,
#[serde(flatten, serialize_with = "serialize_y_axes")]
y_axis: Option<Vec<Option<Box<Axis>>>>,
#[serde(flatten, serialize_with = "serialize_z_axes")]
z_axis: Option<Vec<Option<Box<Axis>>>>,

// ternary: Option<LayoutTernary>,
scene: Option<LayoutScene>,
@@ -2961,6 +2933,13 @@ mod tests {

#[test]
fn test_serialize_layout_template() {
let mut xaxis: Vec<Option<Box<Axis>>> = Vec::new();
let mut yaxis: Vec<Option<Box<Axis>>> = Vec::new();
for _ in 0..8 {
xaxis.push(Some(Box::new(Axis::new())));
yaxis.push(Some(Box::new(Axis::new())));
}

let layout_template = LayoutTemplate::new()
.title("Title")
.show_legend(false)
@@ -2987,22 +2966,8 @@ mod tests {
.hover_label(Label::new())
.grid(LayoutGrid::new())
.calendar(Calendar::Jalali)
.x_axis(Axis::new())
.x_axis2(Axis::new())
.x_axis3(Axis::new())
.x_axis4(Axis::new())
.x_axis5(Axis::new())
.x_axis6(Axis::new())
.x_axis7(Axis::new())
.x_axis8(Axis::new())
.y_axis(Axis::new())
.y_axis2(Axis::new())
.y_axis3(Axis::new())
.y_axis4(Axis::new())
.y_axis5(Axis::new())
.y_axis6(Axis::new())
.y_axis7(Axis::new())
.y_axis8(Axis::new())
.x_axis(xaxis)
.y_axis(yaxis)
.annotations(vec![Annotation::new()])
.shapes(vec![Shape::new()])
.new_shape(NewShape::new())
@@ -3103,6 +3068,13 @@ mod tests {

#[test]
fn test_serialize_layout() {
let mut xaxis: Vec<Option<Box<Axis>>> = Vec::new();
let mut yaxis: Vec<Option<Box<Axis>>> = Vec::new();
for _ in 0..8 {
xaxis.push(Some(Box::new(Axis::new())));
yaxis.push(Some(Box::new(Axis::new())));
}

let layout = Layout::new()
.title("Title")
.title(String::from("Title"))
@@ -3132,22 +3104,8 @@ mod tests {
.template(Template::new())
.grid(LayoutGrid::new())
.calendar(Calendar::Jalali)
.x_axis(Axis::new())
.x_axis2(Axis::new())
.x_axis3(Axis::new())
.x_axis4(Axis::new())
.x_axis5(Axis::new())
.x_axis6(Axis::new())
.x_axis7(Axis::new())
.x_axis8(Axis::new())
.y_axis(Axis::new())
.y_axis2(Axis::new())
.y_axis3(Axis::new())
.y_axis4(Axis::new())
.y_axis5(Axis::new())
.y_axis6(Axis::new())
.y_axis7(Axis::new())
.y_axis8(Axis::new())
.x_axis(xaxis)
.y_axis(yaxis)
.annotations(vec![Annotation::new()])
.shapes(vec![Shape::new()])
.new_shape(NewShape::new())
@@ -3169,7 +3127,7 @@ mod tests {
.extend_pie_colors(true)
.sunburst_colorway(vec!["#654654"])
.extend_sunburst_colors(false)
.z_axis(Axis::new())
.z_axis(Vec::from([Some(Box::new(Axis::new()))]))
.scene(LayoutScene::new());

let expected = json!({
40 changes: 22 additions & 18 deletions plotly/src/layout/themes.rs
Original file line number Diff line number Diff line change
@@ -64,22 +64,22 @@ pub static PLOTLY_WHITE: Lazy<Template> = Lazy::new(|| {
.plot_background_color("#ffffff")
.title(Title::new().x(0.05))
.x_axis(
Axis::new()
Vec::from([Some(Box::new(Axis::new()
.auto_margin(true)
.grid_color("#EBF0F8")
.line_color("#EBF0F8")
// missing title.standoff = 15
.zero_line_color("#EBF0F8")
.zero_line_width(2),
.zero_line_width(2)))])
)
.y_axis(
Axis::new()
Vec::from([Some(Box::new(Axis::new()
.auto_margin(true)
.grid_color("#EBF0F8")
.line_color("#EBF0F8")
// missing title.standoff = 15
.zero_line_color("#EBF0F8")
.zero_line_width(2),
.zero_line_width(2)))])
);
Template::new().layout(layout_template)
});
@@ -140,22 +140,26 @@ pub static PLOTLY_DARK: Lazy<Template> = Lazy::new(|| {
.plot_background_color("#111111")
.title(Title::new().x(0.05))
.x_axis(
Axis::new()
.auto_margin(true)
.grid_color("#283442")
.line_color("#506784")
// missing title.standoff = 15
.zero_line_color("#283442")
.zero_line_width(2),
Vec::from(
[Some(Box::new(Axis::new()
.auto_margin(true)
.grid_color("#283442")
.line_color("#506784")
// missing title.standoff = 15
.zero_line_color("#283442")
.zero_line_width(2)))]
)
)
.y_axis(
Axis::new()
.auto_margin(true)
.grid_color("#283442")
.line_color("#506784")
// missing title.standoff = 15
.zero_line_color("#283442")
.zero_line_width(2),
Vec::from(
[Some(Box::new(Axis::new()
.auto_margin(true)
.grid_color("#283442")
.line_color("#506784")
// missing title.standoff = 15
.zero_line_color("#283442")
.zero_line_width(2)))]
)
);
Template::new().layout(layout_template)
});