Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 7 additions & 8 deletions apps/class-solid/src/components/Analysis.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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,
Expand All @@ -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,
};
Expand Down Expand Up @@ -146,7 +145,7 @@ export function TimeSeriesPlot({ analysis }: { analysis: TimeseriesAnalysis }) {
{/* TODO: get label for yVariable from model config */}
<ChartContainer>
<Legend entries={chartData} />
<Chart title="Vertical profile plot" formatX={formatSeconds}>
<Chart title="Timeseries plot" formatX={formatSeconds}>
<AxisBottom domain={xLim} label="Time [s]" />
<AxisLeft domain={yLim} label={analysis.yVariable} />
<For each={chartData()}>{(d) => Line(d)}</For>
Expand Down
10 changes: 10 additions & 0 deletions apps/class-solid/src/components/plots/ChartContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -162,9 +162,19 @@ export function useChartContext() {
}
return context;
}

export interface ChartData<T> {
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)}`;
}
11 changes: 7 additions & 4 deletions apps/class-solid/src/components/plots/Line.tsx
Original file line number Diff line number Diff line change
@@ -1,29 +1,32 @@
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;
y: number;
}

export function Line(d: ChartData<Point>) {
const [chart, updateChart] = useChartContext();
const [chart, _updateChart] = useChartContext();
const [hovered, setHovered] = createSignal(false);

const l = d3.line<Point>(
(d) => chart.scaleX(d.x),
(d) => chart.scaleY(d.y),
);

const stroke = () => (hovered() ? highlight(d.color) : d.color);

return (
<path
onMouseEnter={() => 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) || ""}
>
<title>{d.label}</title>
Expand Down
31 changes: 22 additions & 9 deletions apps/class-solid/src/components/plots/skewTlogP.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -108,28 +113,36 @@ function Sounding(data: ChartData<SoundingRecord>) {
.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 (
<g
onMouseEnter={() => setHovered(true)}
onMouseLeave={() => setHovered(false)}
>
<title>{data.label}</title>
<path
d={temperatureLine(data.data) || ""}
clip-path="url(#clipper)"
stroke={data.color}
stroke={stroke()}
stroke-dasharray={data.linestyle}
stroke-width={hovered() ? 5 : 3}
stroke-width={3}
fill="none"
/>
>
<title>{titleT()}</title>
</path>
<path
d={dewpointLine(data.data) || ""}
clip-path="url(#clipper)"
stroke={data.color}
stroke-dasharray={data.linestyle}
stroke-width={hovered() ? 5 : 3}
stroke={stroke()}
stroke-dasharray="5,5"
stroke-width={3}
fill="none"
/>
>
<title>{titleTd()}</title>
</path>
</g>
);
}
Expand Down
8 changes: 4 additions & 4 deletions apps/class-solid/src/lib/profiles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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];
Expand All @@ -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",
};
}