From 9e87b7c60c0bf286dbc98a6eec02a6474da17ee3 Mon Sep 17 00:00:00 2001 From: Thomas Sibley Date: Wed, 5 Nov 2025 21:20:02 -0800 Subject: [PATCH] static-site[list-resources]: Fix crash in modal_draw() when bottoming out during radius calculations Fixes the algorithm which calculates an ideal radius for the points on the beeswarm plot by ensuring that beeswarmData, beeswarmHeight, and radius are all set to their last computed values when bottoming out as well as when topping out. Simplifies state tracking instead of doubling variables unnecessarily. Previously when bottoming out on downward iterations, the algorithm would leave beeswarmData unset, which caused errors like this from inside d3: TypeError: can't access property Symbol.iterator, items is undefined This was triggered when many data points were close together causing beeswarm heights to soar. Bottoming out will mean that some points in the plot are cut off, i.e. above the top of the chart. This seems preferable to a crash (or unclickably tiny points). Future improvements could dynamically scale the chart height in such cases, or alternatively the chart width to spread out points horizontally and make the longer timeline scrollable. Resolves: --- .../components/list-resources/modal_draw.js | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/static-site/components/list-resources/modal_draw.js b/static-site/components/list-resources/modal_draw.js index 24c7502ee..f0699490d 100644 --- a/static-site/components/list-resources/modal_draw.js +++ b/static-site/components/list-resources/modal_draw.js @@ -92,7 +92,6 @@ export default function modal_draw(ref, resource, lightGrey) { heights.marginBelowAxis; let radius = 12; const padding = 1; - let nextRadius = radius; let iterCount = 0; let beeswarmData; let beeswarmHeight = 0; @@ -100,21 +99,18 @@ export default function modal_draw(ref, resource, lightGrey) { const maxIter = 5; const radiusJump = 2; while (iterCount++ < maxIter && spareHeight > 50) { - const nextBeeswarmData = dodge(flatData, { - radius: nextRadius * 2 + padding, + beeswarmData = dodge(flatData, { + radius: radius * 2 + padding, x: (d) => x(d["date"]), }); - const nextBeeswarmHeight = d3.max(nextBeeswarmData.map((d) => d.y)); + beeswarmHeight = d3.max(beeswarmData.map((d) => d.y)); const nextSpareHeight = - availBeeswarmHeight - nextBeeswarmHeight - nextRadius; + availBeeswarmHeight - beeswarmHeight - radius; if (nextSpareHeight <= spareHeight && nextSpareHeight > 0) { - beeswarmData = nextBeeswarmData; - beeswarmHeight = nextBeeswarmHeight; spareHeight = nextSpareHeight; - radius = nextRadius; - nextRadius += radiusJump; + radius += radiusJump; } else { - nextRadius -= radiusJump; + radius -= radiusJump; } }