use hydroxy_leptos::bar_chart::*;
use hydroxy_leptos::chart_frame::ChartFrame;
use hydroxy_leptos::segmented::{Segmented, SegmentedItem, SegmentedOption};
use leptos::prelude::*;
#[component]
pub fn Demo() -> impl IntoView {
let weeks = vec![
Datum::new("2 Sep", 6.0),
Datum::new("9 Sep", 9.0),
Datum::new("16 Sep", 7.0),
Datum::new("23 Sep", 12.0),
Datum::new("30 Sep", 10.0),
Datum::new("7 Oct", 14.0),
Datum::new("14 Oct", 11.0),
Datum::new("21 Oct", 17.0),
];
let october = vec![
Datum::new("Research", 4200.0),
Datum::new("Support", 2600.0),
Datum::new("Sales", 3100.0),
Datum::new("Product", 1800.0),
];
let september = vec![
Datum::new("Research", 3400.0),
Datum::new("Support", 2900.0),
Datum::new("Sales", 2200.0),
Datum::new("Product", 2500.0),
];
let sources = vec![
Datum::new("Customer interviews", 18.0),
Datum::new("Support tickets", 14.0),
Datum::new("Sales call notes", 11.0),
Datum::new("In-app survey comments", 8.0),
Datum::new("App store reviews", 5.0),
];
let (month, set_month) = signal(Some(String::from("oct")));
// Same categories, new values: each bar glides to its new height.
let spend =
Signal::derive(move || if month.get().as_deref() == Some("sep") { september.clone() } else { october.clone() });
view! {
<div style="display: grid; gap: var(--space-10);">
// The latest week is picked out; hover any bar, or focus the plot and use the
// arrow keys, to read it. The goal line widens the axis to fit.
<ChartFrame title="Interviews read" description="Per week, since the start of September, against a goal of 15.">
<BarChart data=weeks label="Interviews read per week" annotations=vec![Annotation::y_line(15.0, "Goal")] />
</ChartFrame>
// A chosen bar, every value shown, money formatting, and live data.
<Segmented
label="Month"
items=vec![SegmentedOption::new("sep"), SegmentedOption::new("oct")]
value=month
on_value_change=move |v| set_month.set(Some(v))
>
<SegmentedItem value="sep" label="September" />
<SegmentedItem value="oct" label="October" />
</Segmented>
<ChartFrame title="Monthly spend" description="By team, switch the month to watch the bars glide.">
<BarChart
data=spend
label="Monthly spend by team"
height=160
highlight=Highlight::Index(0)
show_values=true
format=|v: f64| {
let k = v / 1000.0;
if k.fract() == 0.0 { format!("£{k:.0}k") } else { format!("£{k:.1}k") }
}
/>
</ChartFrame>
// Horizontal suits long category names.
<ChartFrame title="Interviews by source" description="Horizontal bars keep long names readable.">
<BarChart
data=sources
label="Interviews by source"
orientation=Orientation::Horizontal
height=200
highlight=Highlight::Index(0)
show_values=true
annotations=vec![Annotation::y_line(11.2, "Average")]
/>
</ChartFrame>
</div>
}
}
use dioxus::prelude::*;
use hydroxy_dioxus::bar_chart::{Annotation, BarChart, Datum, Highlight, Orientation};
use hydroxy_dioxus::chart_frame::ChartFrame;
use hydroxy_dioxus::segmented::{Segmented, SegmentedItem, SegmentedOption};
#[component]
pub fn BarChartDemo() -> Element {
let weeks = vec![
Datum::new("2 Sep", 6.0),
Datum::new("9 Sep", 9.0),
Datum::new("16 Sep", 7.0),
Datum::new("23 Sep", 12.0),
Datum::new("30 Sep", 10.0),
Datum::new("7 Oct", 14.0),
Datum::new("14 Oct", 11.0),
Datum::new("21 Oct", 17.0),
];
let sources = vec![
Datum::new("Customer interviews", 18.0),
Datum::new("Support tickets", 14.0),
Datum::new("Sales call notes", 11.0),
Datum::new("In-app survey comments", 8.0),
Datum::new("App store reviews", 5.0),
];
let mut month = use_signal(|| Some(String::from("oct")));
let spend = if month().as_deref() == Some("sep") {
vec![
Datum::new("Research", 3400.0),
Datum::new("Support", 2900.0),
Datum::new("Sales", 2200.0),
Datum::new("Product", 2500.0),
]
} else {
vec![
Datum::new("Research", 4200.0),
Datum::new("Support", 2600.0),
Datum::new("Sales", 3100.0),
Datum::new("Product", 1800.0),
]
};
rsx! {
div { style: "display: grid; gap: var(--space-10);",
ChartFrame { title: "Interviews read", description: "Per week, since the start of September, against a goal of 15.",
BarChart { data: weeks, label: "Interviews read per week", annotations: vec![Annotation::y_line(15.0, "Goal")] }
}
Segmented {
label: "Month",
items: vec![SegmentedOption::new("sep"), SegmentedOption::new("oct")],
value: month(),
on_value_change: move |v| month.set(Some(v)),
SegmentedItem { value: "sep", label: "September" }
SegmentedItem { value: "oct", label: "October" }
}
ChartFrame { title: "Monthly spend", description: "By team, switch the month to watch the bars glide.",
BarChart {
data: spend,
label: "Monthly spend by team",
height: 160,
highlight: Highlight::Index(0),
show_values: true,
format: move |v: f64| {
let k = v / 1000.0;
if k.fract() == 0.0 { format!("£{k:.0}k") } else { format!("£{k:.1}k") }
},
}
}
ChartFrame { title: "Interviews by source", description: "Horizontal bars keep long names readable.",
BarChart {
data: sources,
label: "Interviews by source",
orientation: Orientation::Horizontal,
height: 200,
highlight: Highlight::Index(0),
show_values: true,
annotations: vec![Annotation::y_line(11.2, "Average")],
}
}
}
}
}