From dea661e9481711bdabccf3f9922267666a39c445 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Tue, 8 Apr 2025 16:40:26 +0200 Subject: [PATCH 1/5] In legend replace line with inert checkbox --- .../src/components/plots/Legend.tsx | 25 ++------ .../src/components/ui/checkbox.tsx | 62 +++++++++++++++++++ 2 files changed, 67 insertions(+), 20 deletions(-) create mode 100644 apps/class-solid/src/components/ui/checkbox.tsx diff --git a/apps/class-solid/src/components/plots/Legend.tsx b/apps/class-solid/src/components/plots/Legend.tsx index ec29bc79..f1452b24 100644 --- a/apps/class-solid/src/components/plots/Legend.tsx +++ b/apps/class-solid/src/components/plots/Legend.tsx @@ -1,5 +1,6 @@ import { For } from "solid-js"; import { cn } from "~/lib/utils"; +import { Checkbox } from "../ui/checkbox"; import type { ChartData } from "./ChartContainer"; import { useChartContext } from "./ChartContainer"; @@ -19,26 +20,10 @@ export function Legend(props: LegendProps) { > {(d) => ( - <> - - - legend - - -

{d.label}

-
- +
+ +

{d.label}

+
)}
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 00000000..783011a8 --- /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 }; From 956ca798c89bca12003cd5378ecfb8e1c62072d5 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Tue, 8 Apr 2025 17:17:26 +0200 Subject: [PATCH 2/5] Add checkboxes to legends, remove line in legend --- apps/class-solid/src/components/Analysis.tsx | 48 +++++++++++++++++-- .../src/components/plots/Legend.tsx | 7 ++- .../src/components/plots/skewTlogP.tsx | 40 +++++++++++++--- 3 files changed, 84 insertions(+), 11 deletions(-) diff --git a/apps/class-solid/src/components/Analysis.tsx b/apps/class-solid/src/components/Analysis.tsx index 96dddabd..4c6c9d98 100644 --- a/apps/class-solid/src/components/Analysis.tsx +++ b/apps/class-solid/src/components/Analysis.tsx @@ -6,11 +6,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, @@ -140,15 +142,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) => ( + + + + )} +
@@ -220,11 +241,32 @@ 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} + /> diff --git a/apps/class-solid/src/components/plots/Legend.tsx b/apps/class-solid/src/components/plots/Legend.tsx index f1452b24..b43dc689 100644 --- a/apps/class-solid/src/components/plots/Legend.tsx +++ b/apps/class-solid/src/components/plots/Legend.tsx @@ -6,6 +6,8 @@ import { useChartContext } from "./ChartContainer"; export interface LegendProps { entries: () => ChartData[]; + toggles: Record; + onChange: (key: string, value: boolean) => void; } export function Legend(props: LegendProps) { @@ -21,7 +23,10 @@ export function Legend(props: LegendProps) { {(d) => (
- + props.onChange(d.label, v)} + />

{d.label}

)} diff --git a/apps/class-solid/src/components/plots/skewTlogP.tsx b/apps/class-solid/src/components/plots/skewTlogP.tsx index 66b6586c..8999e677 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 whendryAdiabat(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) => ( + + + + )} + ); From 477874b11633e5c2c4cb902f59ac03336069af49 Mon Sep 17 00:00:00 2001 From: Stefan Verhoeven Date: Tue, 8 Apr 2025 17:23:48 +0200 Subject: [PATCH 3/5] Hide lines in vertical profiles plot when unchecked --- apps/class-solid/src/components/Analysis.tsx | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/apps/class-solid/src/components/Analysis.tsx b/apps/class-solid/src/components/Analysis.tsx index 4c6c9d98..d2147bc6 100644 --- a/apps/class-solid/src/components/Analysis.tsx +++ b/apps/class-solid/src/components/Analysis.tsx @@ -270,8 +270,20 @@ export function VerticalProfilePlot({ - {(d) => Line(d)} - {(d) => Line(d)} + + {(d) => ( + + + + )} + + + {(d) => ( + + + + )} +
Date: Tue, 8 Apr 2025 18:44:54 +0200 Subject: [PATCH 4/5] Correct name --- apps/class-solid/src/components/plots/skewTlogP.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/class-solid/src/components/plots/skewTlogP.tsx b/apps/class-solid/src/components/plots/skewTlogP.tsx index 8999e677..26bb9852 100644 --- a/apps/class-solid/src/components/plots/skewTlogP.tsx +++ b/apps/class-solid/src/components/plots/skewTlogP.tsx @@ -173,7 +173,7 @@ export function SkewTPlot(props: { data: () => ChartData[] }) { setToggles(label, value); } - function whendryAdiabat(i: number) { + function showSounding(i: number) { const cd = props.data()[i]; if (!toggles || !cd) { return true; @@ -207,7 +207,7 @@ export function SkewTPlot(props: { data: () => ChartData[] }) { {(d) => } {(d, i) => ( - + )} From 66cf6199ec367bfc478690da73b0185439b14dc7 Mon Sep 17 00:00:00 2001 From: Peter Kalverla Date: Thu, 10 Apr 2025 14:58:51 +0200 Subject: [PATCH 5/5] Legend formatting --- .../src/components/plots/Legend.tsx | 37 +++++++++++-------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/apps/class-solid/src/components/plots/Legend.tsx b/apps/class-solid/src/components/plots/Legend.tsx index b43dc689..db78173c 100644 --- a/apps/class-solid/src/components/plots/Legend.tsx +++ b/apps/class-solid/src/components/plots/Legend.tsx @@ -1,6 +1,5 @@ import { For } from "solid-js"; -import { cn } from "~/lib/utils"; -import { Checkbox } from "../ui/checkbox"; +import { createUniqueId } from "solid-js"; import type { ChartData } from "./ChartContainer"; import { useChartContext } from "./ChartContainer"; @@ -15,21 +14,29 @@ export function Legend(props: LegendProps) { return (
- {(d) => ( -
- props.onChange(d.label, v)} - /> -

{d.label}

-
- )} + {(d) => { + const id = createUniqueId(); + return ( +
+ + props.onChange(d.label, v.currentTarget.checked) + } + id={id} + /> + +
+ ); + }}
);