Improve your interactive maps in Vue.js and Leaflet with custom Clusters

Kevin Cluzel
4 min readMar 15, 2021

Hello everyone, this story is the second part of a tutorial serie. The first one can be found following this link: https://kevincluzel.medium.com/create-your-interactive-maps-with-vue-js-and-leaflet-32e833da8e51

In the previous article, we learned how to setup our map and display personalized markers on it. But problems occur when too many of our markers are displayed at the same place: Let’s imagine an area with many restaurants close to each other (like in a mall). How can we cope with that? By using clusters.

As we can see, a problem occurs when we zoom out

A cluster is a group of elements positioned or occuring closely together. In our program, we will represent it with a specific icon which, in case of clicking on it, will open to reveal the elements contained in it.

How do we proceed? Well, a library for vue2-leaflet allow us to easily make clusters. Its problem is the lack of documentation, meaning you can get a bit confused at first: vue2-leaflet-markercluster.

npm install --save vue2-leaflet-markercluster

Once the install donee, we will import the library in our map.vue, register it in our components, et import the style (mandatory).

import Vue2LeafletMarkerCluster from 'vue2-leaflet-markercluster';

Integration is very simple: The v-marker-cluster element will simply encompass our markers component, in our example, the <restaurant> element:

And here it is, our clustering system is functional. Functional, but with a very poor design. We can fortunately modify it to match the overall design of our program, here’s how:

We will first add a “options” property to our v-marker-cluster component:

clusterOptions is located in data (), here’s its content:

spiderfyDistanceMultiplier is a parameter used to manage the distance necessary to put the icons into a cluster.

Disclaimer: The next part can seem complex and difficult. I will try to explain the process as simple as I can, but no need to panic if some things are still blurry: The customization will happen later, I’m just trying to explain the whole process.

iconCreateFunction is the main thing: This function will allow us import a Vue component and transform it in a cluster icon. If you pay attention to the cod, you will notice this: We put the markers id from the cluster into a clusterUsers variable.

We then create a variable named clusterIconEl from an EnhancedClusterIcon that is mounted, to which we pass the clusterUsers property. clusterIconEl will then be used for creating thee Icon used by the cluster.

But what is EnhancedClusterIcon? It’s simply the extension to Vue of a specific component, which contains the icon’s cluster code. We integrate it this way:

We acknowledge the necessity to delete the the basic icon manually in our code, like we showed previously.

The hard and boring explanation is now over, we can now see the file Vue cluster-icon which contains our icon’s code.

Quite simple, no? The image of our choice, a function which calculates the number of markers passing in parameters to show it below the cluster, a bit of CSS and we’re done! Our cluster will therefore give us the following result if case of zooming out too much.

If we click on the icon, there will be a zoom, the cluster will open and the icons will be visible, and if necessary it stays in place while updating its elements number. Voilà, we’ve made it!

Bonus tip: Why not add small explicative bubbles when we click on an icon of the restaurant? Come on, it’s pretty simple and quite practical, I will put the code below.

For the file restaurant.vue, it’s sufficient to import LPopup of vue2-leflet and to use it for displaying the restaurant’s name and also a review:

Obviously, don’t forget to update in the data of map.vue the markers with the new grade:

I will let you discover the result by yourself…

We finished the cartography on Vue.js, thank you for following this tutorial and I hope this will make you want to use this tech for all your projects!

You can find the whole code of this project at the following link:

--

--

Kevin Cluzel

French Developper, passionate about learning all kind of stuff, and sharing the few knowledge I have.