diff --git a/apps/class-solid/src/components/Analysis.tsx b/apps/class-solid/src/components/Analysis.tsx index 62a3d27..0f3cdbc 100644 --- a/apps/class-solid/src/components/Analysis.tsx +++ b/apps/class-solid/src/components/Analysis.tsx @@ -8,11 +8,13 @@ import { For, Match, type Setter, + Show, Switch, createEffect, createMemo, createUniqueId, } from "solid-js"; +import { createStore } from "solid-js/store"; import type { Observation } from "~/lib/experiment_config"; import { getThermodynamicProfiles, @@ -142,15 +144,34 @@ export function TimeSeriesPlot({ analysis }: { analysis: TimeseriesAnalysis }) { }; }); + const [toggles, setToggles] = createStore>({}); + + // Initialize all lines as visible + createEffect(() => { + for (const d of chartData()) { + setToggles(d.label, true); + } + }); + + function toggleLine(label: string, value: boolean) { + setToggles(label, value); + } + return ( <> {/* TODO: get label for yVariable from model config */} - + - {(d) => Line(d)} + + {(d) => ( + + + + )} +
@@ -223,16 +244,49 @@ export function VerticalProfilePlot({ }; }); + function chartData() { + return [...profileData(), ...observations()]; + } + + const [toggles, setToggles] = createStore>({}); + + // Initialize all lines as visible + createEffect(() => { + for (const d of chartData()) { + setToggles(d.label, true); + } + }); + + function toggleLine(label: string, value: boolean) { + setToggles(label, value); + } + return ( <>
- [...profileData(), ...observations()]} /> + [...profileData(), ...observations()]} + toggles={toggles} + onChange={toggleLine} + /> - {(d) => Line(d)} - {(d) => Line(d)} + + {(d) => ( + + + + )} + + + {(d) => ( + + + + )} + { entries: () => ChartData[]; + toggles: Record; + onChange: (key: string, value: boolean) => void; } export function Legend(props: LegendProps) { @@ -12,34 +14,29 @@ export function Legend(props: LegendProps) { return (
- {(d) => ( - <> - - - legend - - -

{d.label}

-
- - )} + {(d) => { + const id = createUniqueId(); + return ( +
+ + props.onChange(d.label, v.currentTarget.checked) + } + id={id} + /> + +
+ ); + }}
); diff --git a/apps/class-solid/src/components/plots/skewTlogP.tsx b/apps/class-solid/src/components/plots/skewTlogP.tsx index 66b6586..26bb985 100644 --- a/apps/class-solid/src/components/plots/skewTlogP.tsx +++ b/apps/class-solid/src/components/plots/skewTlogP.tsx @@ -1,6 +1,7 @@ // Code modified from https://github.com/rsobash/d3-skewt/ (MIT license) import * as d3 from "d3"; -import { For, createSignal } from "solid-js"; +import { For, Show, createEffect, createSignal } from "solid-js"; +import { createStore } from "solid-js/store"; import { AxisBottom, AxisLeft } from "./Axes"; import type { ChartData, SupportedScaleTypes } from "./ChartContainer"; import { @@ -149,9 +150,7 @@ function Sounding(data: ChartData) { // Note: using temperatures in Kelvin as that's easiest to get from CLASS, but // perhaps not the most interoperable with other sounding data sources. -export function SkewTPlot({ - data, -}: { data: () => ChartData[] }) { +export function SkewTPlot(props: { data: () => ChartData[] }) { const pressureLines = [1000, 850, 700, 500, 300, 200, 100]; const temperatureLines = d3.range(-100, 45, 10); @@ -161,9 +160,30 @@ export function SkewTPlot({ pressureGrid.map((pressure) => [pressure, temperature]), ); + const [toggles, setToggles] = createStore>({}); + + // Initialize all lines as visible + createEffect(() => { + for (const d of props.data()) { + setToggles(d.label, true); + } + }); + + function toggleLine(label: string, value: boolean) { + setToggles(label, value); + } + + function showSounding(i: number) { + const cd = props.data()[i]; + if (!toggles || !cd) { + return true; + } + return toggles[cd.label]; + } + return ( - + {(t) => SkewTGridLine(t)} {(p) => LogPGridLine(p)} - {(d) => DryAdiabat(d)} - {(d) => Sounding(d)} + {(d) => } + + {(d, i) => ( + + + + )} + ); diff --git a/apps/class-solid/src/components/ui/checkbox.tsx b/apps/class-solid/src/components/ui/checkbox.tsx new file mode 100644 index 0000000..783011a --- /dev/null +++ b/apps/class-solid/src/components/ui/checkbox.tsx @@ -0,0 +1,62 @@ +import type { ValidComponent } from "solid-js"; +import { Match, Switch, splitProps } from "solid-js"; + +import * as CheckboxPrimitive from "@kobalte/core/checkbox"; +import type { PolymorphicProps } from "@kobalte/core/polymorphic"; + +import { cn } from "~/lib/utils"; + +type CheckboxRootProps = + CheckboxPrimitive.CheckboxRootProps & { class?: string | undefined }; + +const Checkbox = ( + props: PolymorphicProps>, +) => { + const [local, others] = splitProps(props as CheckboxRootProps, ["class"]); + return ( + + + + + + + {/* biome-ignore lint/a11y/noSvgWithoutTitle: want to use tooltip for something else */} + + + + + + {/* biome-ignore lint/a11y/noSvgWithoutTitle: want to use tooltip for something else */} + + + + + + + + + ); +}; + +export { Checkbox };