use crate::{edge::Edge, state::State, Anchor, Legend, Tick};
use leptos::prelude::*;
#[derive(Clone, Debug, PartialEq)]
#[non_exhaustive]
pub struct InsetLegend {
pub edge: RwSignal<Edge>,
pub legend: Legend,
}
impl InsetLegend {
fn new(edge: Edge, anchor: Anchor) -> Self {
Self {
edge: RwSignal::new(edge),
legend: Legend::new(anchor),
}
}
pub fn top_left() -> Self {
Self::new(Edge::Top, Anchor::Start)
}
pub fn top() -> Self {
Self::new(Edge::Top, Anchor::Middle)
}
pub fn top_right() -> Self {
Self::new(Edge::Top, Anchor::End)
}
pub fn bottom_left() -> Self {
Self::new(Edge::Bottom, Anchor::Start)
}
pub fn bottom() -> Self {
Self::new(Edge::Bottom, Anchor::Middle)
}
pub fn bottom_right() -> Self {
Self::new(Edge::Bottom, Anchor::End)
}
pub fn left() -> Self {
Self::new(Edge::Left, Anchor::Middle)
}
pub fn right() -> Self {
Self::new(Edge::Right, Anchor::Middle)
}
}
#[component]
pub(super) fn InsetLegend<X: Tick, Y: Tick>(
legend: InsetLegend,
state: State<X, Y>,
) -> impl IntoView {
let InsetLegend { edge, legend } = legend;
let inner = state.layout.inner;
let width = Legend::width(&state.pre);
let height = legend.fixed_height(&state.pre);
let bounds = Memo::new(move |_| {
let inner = inner.get();
let height = height.get();
let width = width.get();
let (top, right, bottom, left) = match edge.get() {
Edge::Top => (0.0, 0.0, inner.height() - height, 0.0),
Edge::Bottom => (inner.height() - height, 0.0, 0.0, 0.0),
Edge::Left => (0.0, inner.width() - width, 0.0, 0.0),
Edge::Right => (0.0, 0.0, 0.0, inner.width() - width),
};
inner.shrink(top, right, bottom, left)
});
view! {
<g class="_chartistry_legend_inset">
<Legend legend=legend edge=edge bounds=bounds state=state />
</g>
}
.into_any()
}