Skip to content

Conversation

@tsibley
Copy link
Contributor

@tsibley tsibley commented Nov 6, 2025

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: #1252

Checklist

… 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: <#1252>
@nextstrain-bot nextstrain-bot temporarily deployed to nextstrain-s-trs-fix-pr-nwo4pg November 6, 2025 05:44 Inactive
@tsibley tsibley requested a review from jameshadfield November 7, 2025 21:24
Comment on lines +102 to +113
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;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This fixes the bug, but the radius seems off:

Image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Listing previous versions fails for some datasets

4 participants