Scale wet and dry calendar bars independently (#57)
In the calendar category strip, precip (Dry + rain intensity) and dry-streak (Rain day + dry buckets) mix wet and dry categories. Heights scaled to the single tallest bucket across both, so a dominant dry-day count flattened the rain-intensity bars to ~2px and vice versa, hiding the opposing distribution. Give each bucket a scale group (wet/dry) and size bars to the tallest bucket within their own group. Temperature tiers share one group, so they scale together as before.
This commit is contained in:
parent
29302624a7
commit
79d755c16e
1 changed files with 19 additions and 9 deletions
|
|
@ -534,20 +534,26 @@ function renderTotals(visible) {
|
|||
["14+ dry", drynessColor(14), (d) => d >= 14],
|
||||
];
|
||||
const vals = days.map((r) => r.dsr).filter((d) => d != null);
|
||||
buckets = B.map(([label, color, fn]) => [label, color, vals.filter(fn).length]);
|
||||
// Group (index 3) sets which categories share a height scale: the lone "Rain day"
|
||||
// (wet) is scaled apart from the dry-streak buckets so it can't flatten them.
|
||||
buckets = B.map(([label, color, fn], i) =>
|
||||
[label, color, vals.filter(fn).length, i === 0 ? "wet" : "dry"]);
|
||||
title = "dry streak";
|
||||
} else if (metric === "precip") {
|
||||
const classes = days.map((r) => r.precip && r.precip.c).filter(Boolean);
|
||||
buckets = [["Dry", drynessColor(7), classes.filter((c) => c === "dry").length]]
|
||||
// Dry days scale independently of the rain-intensity buckets (wet) so a big dry
|
||||
// count doesn't crush the rain bars — and vice versa.
|
||||
buckets = [["Dry", drynessColor(7), classes.filter((c) => c === "dry").length, "dry"]]
|
||||
.concat(SCALE_RAIN.map((t) =>
|
||||
[t.label, PRECIP_COLORS[t.c], classes.filter((c) => c === t.c).length]));
|
||||
[t.label, PRECIP_COLORS[t.c], classes.filter((c) => c === t.c).length, "wet"]));
|
||||
title = "rain intensity";
|
||||
} else {
|
||||
const classes = days
|
||||
.map((r) => { const g = r[metric]; return g && g.c; })
|
||||
.filter(Boolean);
|
||||
// Temperature tiers all share one scale group, so they scale together as before.
|
||||
buckets = SCALE_TEMP.map((t) =>
|
||||
[t.label, TIER_COLORS[t.c], classes.filter((c) => c === t.c).length, t.c === "normal"]);
|
||||
[t.label, TIER_COLORS[t.c], classes.filter((c) => c === t.c).length, "temp"]);
|
||||
title = (TEMP_METRIC_INFO[metric] || {}).label || "value";
|
||||
}
|
||||
|
||||
|
|
@ -573,11 +579,15 @@ function renderTotals(visible) {
|
|||
// own color. Every category — including the neutral "Normal" center of the diverging
|
||||
// temperature scale — draws a line, so the strip reads as a full distribution.
|
||||
// Category names live in the color key below the grid too, so this stays terse.
|
||||
// Line heights scale to the tallest category.
|
||||
const maxLine = Math.max(1, ...buckets.map((b) => b[2]));
|
||||
const LINE_MAX = 30; // px — height of the most common category
|
||||
const cols = buckets.map(([label, color, n]) => {
|
||||
const h = !n ? 0 : Math.max(2, Math.round(LINE_MAX * n / maxLine));
|
||||
// Line heights scale to the tallest category *within each scale group* (index 3):
|
||||
// for precip/dry-streak, wet and dry days scale independently, so a lopsided count
|
||||
// on one side doesn't shrink the opposing side's bars into invisibility. Temperature
|
||||
// tiers all sit in one group, so they still scale against each other as before.
|
||||
const maxByGroup = {};
|
||||
for (const b of buckets) maxByGroup[b[3]] = Math.max(maxByGroup[b[3]] || 1, b[2]);
|
||||
const LINE_MAX = 30; // px — height of the tallest category in its group
|
||||
const cols = buckets.map(([label, color, n, group]) => {
|
||||
const h = !n ? 0 : Math.max(2, Math.round(LINE_MAX * n / maxByGroup[group]));
|
||||
const line = h ? `<span class="ct-line" style="height:${h}px"></span>` : "";
|
||||
// Caption stacks the category name over its value; the name reserves two lines
|
||||
// so the value figures stay aligned across columns whether a name wraps or not.
|
||||
|
|
|
|||
Loading…
Reference in a new issue