diff --git a/apps/class-solid/src/components/Analysis.tsx b/apps/class-solid/src/components/Analysis.tsx index f140eb0..96dddab 100644 --- a/apps/class-solid/src/components/Analysis.tsx +++ b/apps/class-solid/src/components/Analysis.tsx @@ -59,8 +59,6 @@ const colors = [ "#b0ab0b", ]; -const linestyles = ["none", "5,5", "10,10", "15,5,5,5", "20,10,5,5,5,10"]; - interface FlatExperiment { label: string; color: string; @@ -71,12 +69,13 @@ interface FlatExperiment { // Create a derived store for looping over all outputs: const flatExperiments: () => FlatExperiment[] = createMemo(() => { + let nextColor = 0; return experiments .filter((e) => e.output.running === false) // skip running experiments - .flatMap((e, i) => { + .flatMap((e) => { const reference: FlatExperiment = { - color: colors[0], - linestyle: linestyles[i % 5], + color: colors[nextColor++ % 10], + linestyle: "none", label: e.config.reference.name, config: e.config.reference, output: e.output.reference, @@ -86,8 +85,8 @@ const flatExperiments: () => FlatExperiment[] = createMemo(() => { const output = e.output.permutations[j]; return { label: `${e.config.reference.name}/${config.name}`, - color: colors[(j + 1) % 10], - linestyle: linestyles[i % 5], + color: colors[nextColor++ % 10], + linestyle: "none", config, output, }; @@ -146,7 +145,7 @@ export function TimeSeriesPlot({ analysis }: { analysis: TimeseriesAnalysis }) { {/* TODO: get label for yVariable from model config */} - + {(d) => Line(d)} diff --git a/apps/class-solid/src/components/plots/ChartContainer.tsx b/apps/class-solid/src/components/plots/ChartContainer.tsx index 57cafa1..f8a3cf3 100644 --- a/apps/class-solid/src/components/plots/ChartContainer.tsx +++ b/apps/class-solid/src/components/plots/ChartContainer.tsx @@ -162,9 +162,19 @@ export function useChartContext() { } return context; } + export interface ChartData { label: string; color: string; linestyle: string; data: T[]; } + +export function highlight(hex: string) { + const g = 246; // gray level + const b = (h: string, i: number) => + Math.round(Number.parseInt(h.slice(i, i + 2), 16) * 0.5 + g * 0.5) + .toString(16) + .padStart(2, "0"); + return `#${b(hex, 1)}${b(hex, 3)}${b(hex, 5)}`; +} diff --git a/apps/class-solid/src/components/plots/Line.tsx b/apps/class-solid/src/components/plots/Line.tsx index 5a5c6b2..0320a2d 100644 --- a/apps/class-solid/src/components/plots/Line.tsx +++ b/apps/class-solid/src/components/plots/Line.tsx @@ -1,7 +1,7 @@ import * as d3 from "d3"; import { createSignal } from "solid-js"; import type { ChartData } from "./ChartContainer"; -import { useChartContext } from "./ChartContainer"; +import { highlight, useChartContext } from "./ChartContainer"; export interface Point { x: number; @@ -9,21 +9,24 @@ export interface Point { } export function Line(d: ChartData) { - const [chart, updateChart] = useChartContext(); + const [chart, _updateChart] = useChartContext(); const [hovered, setHovered] = createSignal(false); const l = d3.line( (d) => chart.scaleX(d.x), (d) => chart.scaleY(d.y), ); + + const stroke = () => (hovered() ? highlight(d.color) : d.color); + return ( setHovered(true)} onMouseLeave={() => setHovered(false)} fill="none" - stroke={d.color} + stroke={stroke()} stroke-dasharray={d.linestyle} - stroke-width={hovered() ? 5 : 3} + stroke-width="3" d={l(d.data) || ""} > {d.label} diff --git a/apps/class-solid/src/components/plots/skewTlogP.tsx b/apps/class-solid/src/components/plots/skewTlogP.tsx index d3f1de0..66b6586 100644 --- a/apps/class-solid/src/components/plots/skewTlogP.tsx +++ b/apps/class-solid/src/components/plots/skewTlogP.tsx @@ -3,7 +3,12 @@ import * as d3 from "d3"; import { For, createSignal } from "solid-js"; import { AxisBottom, AxisLeft } from "./Axes"; import type { ChartData, SupportedScaleTypes } from "./ChartContainer"; -import { Chart, ChartContainer, useChartContext } from "./ChartContainer"; +import { + Chart, + ChartContainer, + highlight, + useChartContext, +} from "./ChartContainer"; import { Legend } from "./Legend"; interface SoundingRecord { p: number; @@ -108,28 +113,36 @@ function Sounding(data: ChartData) { .x((d) => x(d.Td - 273.15) + (y(basep) - y(d.p)) / tan) .y((d) => y(d.p)); + const titleT = () => `${data.label} T`; + const titleTd = () => `${data.label} Td`; + + const stroke = () => (hovered() ? highlight(data.color) : data.color); + return ( setHovered(true)} onMouseLeave={() => setHovered(false)} > - {data.label} + > + {titleT()} + + > + {titleTd()} + ); } diff --git a/apps/class-solid/src/lib/profiles.ts b/apps/class-solid/src/lib/profiles.ts index d7f669b..4d82375 100644 --- a/apps/class-solid/src/lib/profiles.ts +++ b/apps/class-solid/src/lib/profiles.ts @@ -186,8 +186,8 @@ export function getThermodynamicProfiles( export function observationsForProfile(obs: Observation, variable = "theta") { return { label: obs.name, - color: "red", - linestyle: "3,10", + color: "#000000", + linestyle: "none", data: obs.height.map((h, i) => { const T = obs.temperature[i] + 273.15; const rh = obs.relativeHumidity[i]; @@ -213,7 +213,7 @@ export function observationsForSounding(obs: Observation) { return { p, T, Td }; }), label: obs.name, - color: "red", - linestyle: "3,10", + color: "#000000", + linestyle: "none", }; }