leptos_chartistry/layout/
mod.rs1mod compose;
2pub mod legend;
3pub mod rotated_label;
4pub mod tick_labels;
5
6pub use compose::Layout;
7
8use crate::{
9 bounds::Bounds,
10 edge::Edge,
11 state::{PreState, State},
12 Tick,
13};
14use leptos::prelude::*;
15
16#[derive(Clone)]
18#[non_exhaustive]
19pub enum EdgeLayout<XY: Tick> {
20 Legend(legend::Legend),
22 RotatedLabel(rotated_label::RotatedLabel),
24 TickLabels(tick_labels::TickLabels<XY>),
26}
27
28struct UseVerticalLayout {
29 width: Signal<f64>,
30 layout: UseLayout,
31}
32
33#[derive(Clone)]
34enum UseLayout {
35 Legend(legend::Legend),
36 RotatedLabel(rotated_label::RotatedLabel),
37 TickLabels(tick_labels::UseTickLabels),
38}
39
40impl UseLayout {
41 fn render<X: Tick, Y: Tick>(
42 self,
43 edge: Edge,
44 bounds: Memo<Bounds>,
45 state: State<X, Y>,
46 ) -> impl IntoView {
47 match self {
48 Self::Legend(inner) => view! {<legend::Legend legend=inner edge=edge bounds=bounds state=state />}.into_any(),
49 Self::RotatedLabel(inner) => view! {<rotated_label::RotatedLabel label=inner edge=edge bounds=bounds state=state />}.into_any(),
50 Self::TickLabels(inner) => view! {<tick_labels::TickLabels ticks=inner edge=edge bounds=bounds state=state />}.into_any(),
51 }
52 }
53}
54
55impl<X: Tick> EdgeLayout<X> {
56 fn fixed_height<Y: Tick>(&self, state: &PreState<X, Y>) -> Signal<f64> {
57 match self {
58 Self::Legend(inner) => inner.fixed_height(state),
59 Self::RotatedLabel(inner) => inner.fixed_height(state),
60 Self::TickLabels(inner) => inner.fixed_height(state),
61 }
62 }
63
64 fn to_horizontal_use<Y: Tick>(
65 &self,
66 state: &PreState<X, Y>,
67 avail_width: Memo<f64>,
68 ) -> UseLayout {
69 match self {
70 Self::Legend(inner) => inner.to_horizontal_use(),
71 Self::RotatedLabel(inner) => inner.to_horizontal_use(),
72 Self::TickLabels(inner) => inner.to_horizontal_use(state, avail_width),
73 }
74 }
75}
76
77impl<Y: Tick> EdgeLayout<Y> {
78 fn to_vertical_use<X: Tick>(
79 &self,
80 state: &PreState<X, Y>,
81 avail_height: Memo<f64>,
82 ) -> UseVerticalLayout {
83 match self {
84 Self::Legend(inner) => inner.to_vertical_use(state),
85 Self::RotatedLabel(inner) => inner.to_vertical_use(state),
86 Self::TickLabels(inner) => inner.to_vertical_use(state, avail_height),
87 }
88 }
89}
90
91pub trait IntoEdge<XY: Tick> {
93 fn into_edge(self) -> EdgeLayout<XY>;
95}
96
97macro_rules! impl_into_edge {
98 ($ty:ty, $enum:ident) => {
99 impl<XY: Tick> IntoEdge<XY> for $ty {
100 fn into_edge(self) -> EdgeLayout<XY> {
101 EdgeLayout::$enum(self)
102 }
103 }
104
105 impl<XY: Tick> From<$ty> for EdgeLayout<XY> {
106 fn from(inner: $ty) -> Self {
107 inner.into_edge()
108 }
109 }
110
111 impl<XY: Tick> From<$ty> for Vec<EdgeLayout<XY>> {
112 fn from(inner: $ty) -> Self {
113 vec![inner.into_edge()]
114 }
115 }
116 };
117}
118impl_into_edge!(legend::Legend, Legend);
119impl_into_edge!(rotated_label::RotatedLabel, RotatedLabel);
120impl_into_edge!(tick_labels::TickLabels<XY>, TickLabels);