Show full Gaussian probability tooltip
This commit is contained in:
@@ -77,8 +77,8 @@ export function TemperatureTooltipContent({
|
||||
</div>
|
||||
)}
|
||||
{probabilityRows.length > 0 && (
|
||||
<div className={rows.length > 0 ? "mt-1.5 grid gap-1 border-t border-slate-100 pt-1.5" : "grid gap-1"}>
|
||||
{probabilityRows.slice(0, 8).map((item) => (
|
||||
<div className={rows.length > 0 ? "mt-1.5 grid max-h-[260px] gap-1 overflow-y-auto border-t border-slate-100 pt-1.5 pr-1" : "grid max-h-[260px] gap-1 overflow-y-auto pr-1"}>
|
||||
{probabilityRows.map((item) => (
|
||||
<div key={item.key} className="flex min-w-[160px] items-center justify-between gap-4">
|
||||
<span className="inline-flex items-center gap-1.5 text-violet-700">
|
||||
<span className="h-2 w-2 rounded-full" style={{ backgroundColor: item.color }} />
|
||||
@@ -118,6 +118,18 @@ function buildTooltipRows(
|
||||
.filter((item): item is TooltipRow => item !== null);
|
||||
}
|
||||
|
||||
function formatProbabilityRangeValue(value: number) {
|
||||
return Number(value.toFixed(1)).toString();
|
||||
}
|
||||
|
||||
function formatProbabilityRangeLabel(
|
||||
lower: number,
|
||||
upper: number,
|
||||
tempSymbol: string,
|
||||
) {
|
||||
return `${formatProbabilityRangeValue(lower)}-${formatProbabilityRangeValue(upper)}${tempSymbol}`;
|
||||
}
|
||||
|
||||
function buildTooltipProbabilityRows(
|
||||
probabilityOverlay: ProbabilityOverlay | null | undefined,
|
||||
tempSymbol: string,
|
||||
@@ -135,18 +147,20 @@ function buildTooltipProbabilityRows(
|
||||
});
|
||||
}
|
||||
|
||||
const topBand = [...probabilityOverlay.bands]
|
||||
.filter((band) => validNumber(band.probability) !== null)
|
||||
.sort((a, b) => b.probability - a.probability)[0];
|
||||
if (topBand) {
|
||||
const probabilityPct = Math.round(topBand.probability * 100);
|
||||
rows.push({
|
||||
key: topBand.key,
|
||||
label: topBand.label,
|
||||
value: `${probabilityPct}%`,
|
||||
color: "#a78bfa",
|
||||
});
|
||||
}
|
||||
rows.push(
|
||||
...[...probabilityOverlay.bands]
|
||||
.filter((band) => validNumber(band.probability) !== null && band.probability > 0)
|
||||
.sort((a, b) => a.lower - b.lower)
|
||||
.map((band) => {
|
||||
const probabilityPct = Math.round(band.probability * 100);
|
||||
return {
|
||||
key: band.key,
|
||||
label: formatProbabilityRangeLabel(band.lower, band.upper, tempSymbol),
|
||||
value: `${probabilityPct}%`,
|
||||
color: "#a78bfa",
|
||||
};
|
||||
}),
|
||||
);
|
||||
return rows;
|
||||
}
|
||||
|
||||
|
||||
+24
-4
@@ -61,6 +61,15 @@ export function runTests() {
|
||||
engine: "legacy",
|
||||
muLine: { value: 27.4, label: "Gaussian μ 27.4°C" },
|
||||
bands: [
|
||||
{
|
||||
key: "legacy_probability_26_0",
|
||||
value: 26,
|
||||
lower: 25.5,
|
||||
upper: 26.5,
|
||||
probability: 0.18,
|
||||
label: "26°C 18%",
|
||||
opacity: 0.08,
|
||||
},
|
||||
{
|
||||
key: "legacy_probability_27_0",
|
||||
value: 27,
|
||||
@@ -70,6 +79,15 @@ export function runTests() {
|
||||
label: "27°C 42%",
|
||||
opacity: 0.13,
|
||||
},
|
||||
{
|
||||
key: "legacy_probability_28_0",
|
||||
value: 28,
|
||||
lower: 27.5,
|
||||
upper: 28.5,
|
||||
probability: 0.31,
|
||||
label: "28°C 31%",
|
||||
opacity: 0.11,
|
||||
},
|
||||
],
|
||||
},
|
||||
"°C",
|
||||
@@ -77,13 +95,15 @@ export function runTests() {
|
||||
);
|
||||
|
||||
assert(
|
||||
probabilityRows.length === 2,
|
||||
"temperature tooltip should show Gaussian μ and the leading probability bucket as compact context",
|
||||
probabilityRows.length === 4,
|
||||
"temperature tooltip should show Gaussian μ and every available probability bucket as compact context",
|
||||
);
|
||||
assert(
|
||||
probabilityRows.some((row) => row.key === "legacy_probability_mu" && row.value === "27.4°C") &&
|
||||
probabilityRows.some((row) => row.key === "legacy_probability_27_0" && row.value === "42%"),
|
||||
"temperature tooltip should format Gaussian μ and probability values without drawing a full probability band on the main chart",
|
||||
probabilityRows.some((row) => row.key === "legacy_probability_26_0" && row.label === "25.5-26.5°C" && row.value === "18%") &&
|
||||
probabilityRows.some((row) => row.key === "legacy_probability_27_0" && row.label === "26.5-27.5°C" && row.value === "42%") &&
|
||||
probabilityRows.some((row) => row.key === "legacy_probability_28_0" && row.label === "27.5-28.5°C" && row.value === "31%"),
|
||||
"temperature tooltip should format the full Gaussian probability distribution by temperature range without drawing it on the main chart",
|
||||
);
|
||||
|
||||
const projectRoot = process.cwd();
|
||||
|
||||
Reference in New Issue
Block a user