Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve markers clustering experience #8478

Open
livthomas opened this issue Jul 15, 2019 · 8 comments
Open

Improve markers clustering experience #8478

livthomas opened this issue Jul 15, 2019 · 8 comments
Labels
needs investigation 🔍 Issues that require further research (e.g. it's not clear whether it's GL JS or something else)

Comments

@livthomas
Copy link

Motivation

I am trying to add clustering of HTML markers to my application. And since Mapbox does not directly support it, we need to implement it on our own. One of the solutions is using built-in clustering but not showing individual "markers" (just cluster circles) and re-rendering HTML markers on every moveend event.

This works, however, sometimes there is a situation when there is a longer transition (e.g. after clicking on a cluster circle) and the cluster is not recalculated before moveend event is emitted. To work around this, I am calling the following line in moveend event callback:

this.mapboxMap.once('idle', () => this.redrawMarkers());

But the idle event is emitted only after all transition animations have completed and all tiles have loaded. The problem is it usually takes a while to load the tiles and so marker clusters are not re-rendered immediately after the transition ended but after another 1-2 seconds.

Design Alternatives

I can see many possible solutions of this problem:

  1. Add support for HTML markers clustering.
  2. Add support for drawing arbitrary marker shapes (not only dots or circles) using WebGL.
  3. Emit moveend event only after clusters are re-calculated.
  4. Add some new event which will be emitted after clusters are re-calculated.
  5. Add some new event which will be emitted after transition animation have completed. (But I am not sure if this one will help.)

Design

I think the best solution of this problem would be to implement one of the first two options. But I can see that it will not be that easy so one of 3-5 is probably a better solution for now.

@mourner
Copy link
Member

mourner commented Jul 15, 2019

Are you seeing this problem in the official HTML marker example? If so, can you describe the exact steps to trigger the issue?

@livthomas
Copy link
Author

@mourner No, it is in my custom implementation which is based on some of the ideas from HTML clustering issue comments. In fact, it is exactly the opposite of what you linked here. In my application, the markers themselves are HTML elements and cluster circles are simply a circle layer.

I am trying to put simplified code to JS Bin. But our application is quite complex (written in Angular) and it is quite hard to extract all the code from it to vanilla JavaScript while keeping all the functionality responsible for rendering and clustering of markers.

@mourner
Copy link
Member

mourner commented Jul 15, 2019

Can you set up a minimal test case (e.g. on JSFiddle) to demonstrate the issue here? No need to extract the whole code, the simplest example that can show the problem you're having would suffice.

@livthomas
Copy link
Author

@mourner I have finally managed to put together a reproducer. It uses some data structures from our application so I hope it is not too complicated.

https://jsbin.com/yukumuyoha/edit?html,output

Try clicking on a marker cluster and see that the markers will not show up immediately but only after you move the map.

Then try to uncomment the following line in the code (it is there twice):

map.once('idle', () => redrawMarkers());

After that the markers will always show up after clicking on a marker cluster, however, they will show up only after all map tiles have been loaded.

I would need a callback that would be called immediately after marker clusters are recalculated so I do not need to wait for all tiles to be loaded. That would be much better user experience.

@livthomas
Copy link
Author

@mourner Sorry, I have shared the old JS Bin. You can find the new one here:

https://jsbin.com/vigoweduro/edit?html,output

@asheemmamoowala asheemmamoowala added needs investigation 🔍 Issues that require further research (e.g. it's not clear whether it's GL JS or something else) and removed needs information 🙏 labels Aug 7, 2019
@luchux
Copy link

luchux commented Oct 5, 2019

I am facing the same issue that @livthomas

@mourner basically this happens when you need to use builtin functionality of clustering with custom html markers. You end up removing and adding markers from the map, based in their (in-cluster status).

IMHO implementing this functionality is trivial from the builtin cluster. Take into account that makers are added like new mapboxgl.Marker(el).setLngLat(marker.geometry.coordinates).addTo(map);
to be able to add html to the marker. Then builtin clustering should hide-show them accordance to clustering status.

@cetooley
Copy link

cetooley commented Feb 13, 2020

I am encountering this issue using a similar marker clustering setup as here: https://blog.mapbox.com/clustering-properties-with-mapbox-and-html-markers-bb353c8662ba

Basically it works pretty well when I do zoomend or moveend and updates reasonably within time using "idle" or "render" events but those two spam the heck out of things. It seems to me like the "moveend" event happens before any clustering or unclustering of features, which happen well before idle or render events. If there was a set of "cluster" events which fired whenever there was a change to clusters I think this could be solved easily.

@cetooley
Copy link

I can get the issue to show on the official documentation sometimes too, using Firefox 73.0. It's possibly related to the number of clusters on the screen - our implementation has a large number of clusters.

To attempt to reproduce:
Zoom using the mouse scroller by small increments until you get something like this:
image

Drag the map a bit and some clusters will disappear to give you this:
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs investigation 🔍 Issues that require further research (e.g. it's not clear whether it's GL JS or something else)
Projects
None yet
Development

No branches or pull requests

5 participants