use leptos::callback::Callback;
use leptos::prelude::*;
use orbital_data::{ChartFieldBinding, Dataset};
use orbital_macros::component_doc;
use crate::shared::{ChartContainer, LinePlot};
use crate::{
AxisClickData, AxisDef, AxisHighlightConfig, ChartFeatures, ChartItemId, ChartMotion,
GridConfig, HighlightScope, LegendConfig, OrbitalChartPalette, OrbitalChartsTheme, PlotInset,
SeriesDef, TooltipConfig, ZoomWindow, CHART_FEATURES_DEFAULT,
};
#[component_doc(
category = "Charts",
preview_slug = "line-chart",
preview_label = "Line Chart",
preview_icon = icondata::AiLineChartOutlined,
)]
#[component]
pub fn LineChart(
#[prop(optional)]
dataset: Option<Dataset>,
#[prop(optional, into)]
x_field: Option<String>,
#[prop(optional)]
y_fields: Option<Vec<String>>,
#[prop(optional)]
binding: Option<ChartFieldBinding>,
#[prop(optional)]
series: Option<Vec<SeriesDef>>,
#[prop(optional)]
x_axis: Option<Vec<AxisDef>>,
#[prop(optional)]
y_axis: Option<Vec<AxisDef>>,
#[prop(optional)]
width: Option<f64>,
#[prop(optional)]
height: Option<f64>,
#[prop(optional)]
margin: Option<PlotInset>,
#[prop(optional)]
grid: Option<GridConfig>,
#[prop(optional)]
loading: Option<bool>,
#[prop(optional)]
skip_animation: Option<bool>,
#[prop(optional)]
motion: Option<ChartMotion>,
#[prop(optional)]
highlight_scope: Option<HighlightScope>,
#[prop(optional)]
axis_highlight: Option<AxisHighlightConfig>,
#[prop(optional)]
legend: Option<LegendConfig>,
#[prop(optional)]
tooltip: Option<TooltipConfig>,
#[prop(optional)]
charts_theme: Option<OrbitalChartsTheme>,
#[prop(optional)]
palette: Option<OrbitalChartPalette>,
#[prop(optional)]
on_item_click: Option<Callback<(ChartItemId,), ()>>,
#[prop(optional)]
on_axis_click: Option<Callback<(AxisClickData,), ()>>,
#[prop(optional)]
on_legend_click: Option<Callback<(String,), ()>>,
#[prop(default = CHART_FEATURES_DEFAULT)]
features: ChartFeatures,
#[prop(default = true)]
keyboard_navigation: bool,
#[prop(optional)]
zoom: Option<Vec<ZoomWindow>>,
#[prop(optional)]
on_zoom_change: Option<Callback<(Vec<ZoomWindow>,), ()>>,
#[prop(optional, into)]
class: MaybeProp<String>,
#[prop(optional)]
children: Option<Children>,
) -> impl IntoView {
let binding = binding.or_else(|| {
x_field
.zip(y_fields.clone())
.map(|(x, y)| ChartFieldBinding::new(x, y))
});
let w = width.unwrap_or(520.0);
let h = height.unwrap_or(320.0);
let grid = grid.or({
Some(GridConfig {
horizontal: true,
vertical: true,
})
});
view! {
<ChartContainer
class=class
dataset=dataset
binding=binding
series=series
x_axis=x_axis
y_axis=y_axis
width=Some(w)
height=Some(h)
margin=margin
grid=grid
loading=loading
skip_animation=skip_animation
motion=motion
highlight_scope=highlight_scope
axis_highlight=axis_highlight
legend=legend
tooltip=tooltip
charts_theme=charts_theme
palette=palette
on_item_click=on_item_click
on_axis_click=on_axis_click
on_legend_click=on_legend_click
features=features
keyboard_navigation=keyboard_navigation
prefer_line_x_strict=true
zoom=zoom
on_zoom_change=on_zoom_change
>
{match children {
Some(c) => c().into_any(),
None => view! { <LinePlot /> }.into_any(),
}}
</ChartContainer>
}
}