misaligned d3 zoom

I wrote the question and context in this issue Panning and zooming · Issue #1590 · observablehq/plot · GitHub

In 2 words: I have a d3 zoom working fine a in notebook, and partially fine in a web page (on on y axis, but misaligned on x axis) and it is the same code, and there is not interfering css, I think.

Any idea why ??

1 Like

In case someone want to compare:

To be clear, here is the problem on the standalone page:
misaligned-zoom

But all works as expected in the notebook:
misaligned-zoom-ok

I cannot spot the difference in code…

The issue, as you seem to have figured out, is with the legend. If you remove the legend, it should work fine. I think the easiest solution is to remove the legend and then recreate it separately in another DIV.

The reason the legend causes these problems is because it creates a misalignment between the pointer position in the containing DIV (where the zoom is called from) and the chart (where the zoom is applied). That’s the standard way to do things but it’s important to have that alignment. Removing the legend solves the problem, since that’s what causing the misalignment in the first place.

It’s not completely clear to me why moving the legend below the chart doesn’t solve the problem in your webpage but it seems to be related to how the container is contained. In your webpage, your container is

<div id="plot-3"></div>

which spans the whole page. In the notebook, the container is an Observable output cell, which has all kinds of styles applied to it. For example, it’s constrained to lie within a DIV of class "relative notebook" whose width is further constrained. I noticed that if I set your plot-3 to have a width that agrees with the width as specified by your Plot command, then things seem to work much better in the horizontal direction. They’re still a bit off in the vertical direction, though. Perhaps, you could fiddle with that a bit further, if you don’t like the idea of creating the legend separately.

@mcmcclur thx a lot for taking the time to look into it. This has helped me narrow down the issue further. Much appreciated.

Indeed it is the legend which disaligns the zoom, more precisely the wrapper figure element generated by plot() if there is a title, subtitle, legend, caption option (Cf. Plots | Observable Plot). d3.zoom in general (for lack a better understanding) does always not behave as expected in cases where there is more than a single child element to the div on which it is called.

I followed your advice and manage the legend separately, and updated the notebook and standalone page.

Now all works fine. It is still puzzling to me that stacking elements vertically ends up misaligning the zoom horizontally (!) but never mind.

EDIT:
A disciplined way to make sure only the chart is rendered is to use option figure=false. It will overrides title, subtitle, caption, legend.