Clusters ghost after updating tileLayer in Leaflet map

When I update the main map tiling layer, and then zoom in and out of the map, the clusters layer seems to ghost whereas it should clear and re-render different clusters on each zoom level.

It’s easy to repro here, just change the default styling and then zoom and and out of the map:

Try caching your layers on the map object rather than the global object so that you automatically discard them when the map is re-initialized.

Here’s a diff* using our new compare view:

*The fork won’t render correctly because of the CORS restrictions on your data, but the code at least is still readable.

@mbostock Thanks. I forked your example (nice diff view, by the way!) and the issue seems to persist.

I’ll to try to fix the CORS issue, for some reason it seemed like I need to Header always set Access-Control-Allow-Credentials "true" so that I could enable force-cache in my d3.csv calls. And that then prevents a wildcard for Access-Control-Allow-Origin. Perhaps there is a free server I could use instead to serve the csv – it was too big for gist.

@mbostock I’ve fixed the CORS problem by uploading to gist (It just barely worked this time due to some improvements I made to the filesize). And I made the changes you suggested.

https://beta.observablehq.com/@john-clarke/montreal-311-incidents-in-2016-2018 – so you should be able to fork again and reproduce.

Just for reference this is what happens – if you zoom in and out a few times:

I’m not seeing the suggested changes applied—the published notebook still uses global?

Weird. It is as if the publish isn’t working. I’ve forked and shared to
https://beta.observablehq.com/d/7f921a18818167d0 (with the changes you suggested)

Here’s how I’d approach this problem. (Compare.)

To summarize:

  • In the map cell, create the three layers (osm, marker, heatmap) for the map immediately, but leave the marker and heatmap layers empty. Register zoomstart and zoomend listeners to toggle the presence of the heatmap layer as desired based on zoom level.

  • In a separate “side-effect” cell that references both map and filtered_incidents, populate the contents of the marker and heatmap layers, replacing whatever was there before, and then fly to the desired bounds.

Or in other words, try to minimize side-effects across cells. We want to use side-effects here so that we can replace the map layers without re-initializing the map completely, but everything else can be safely moved to the map cell to simplify the logic and avoid bugs.

Wow, that looks so much cleaner – and seems to have fixed the original issue. Thanks for looking into it.

What would you recommend to be best way to publish this? I could just copy it over to the original notebook, or publish the fork and hide the original notebook?

BTW, I really like the diff – views – so nice.

I ended up forking, then publishing again – that works well (with a version number 2)

@mbostock – thanks again.

1 Like