xscale/yscale at draw time.Fires before grid pushes the panel viewport. We can therefore
measure labels against the live cell, run eunoia's placement, and
compute a viewport bbox that fits both the diagram and the labels.
On window resize grid invalidates the gTree and makeContext
re-runs, so the panel grows or shrinks to track the current device
and exterior labels never extend past the viewport edge.
# S3 method for EulerPanel
makeContext(x)Aspect preservation: the new bbox keeps xrng / yrng equal to the
geometry's natural aspect (set by setup_geometry()) so that
circles render as circles. The smaller dimension is padded if the
label-driven canvas bbox is asymmetric.