js-markerclusterer
js-markerclusterer copied to clipboard
Updating styles to new version.
HI,
I've switched to the new version of this and it does work, but I'm having difficulty styling the clusters whereas I managed easily with the old version.
In the old version I had it set up like:
let markerCluster = new MarkerClusterer({map, markers}, {
maxZoom: 14,
clusterClass: 'custom-clustericon',
styles: [
{
width: 30,
height: 30,
className: 'custom-clustericon-1'
},
{
width: 40,
height: 40,
className: 'custom-clustericon-2'
},
{
width: 50,
height: 50,
className: 'custom-clustericon-3'
}
]
});
and styled as so:
.custom-clustericon {
background: var(--cluster-color);
color: #fff;
border-radius: 100%;
font-weight: bold;
font-size: 15px;
display: flex;
align-items: center;
}
.custom-clustericon:before,
.custom-clustericon:after {
content: "";
display: block;
position: absolute;
width: 100%;
height: 100%;
transform: translate(-50%, -50%);
top: 50%;
left: 50%;
background: var(--cluster-color);
border-radius: 100%;
}
.custom-clustericon:before {
width: calc(100% + 10px);
height: calc(100% + 10px);
opacity: 0.6;
}
.custom-clustericon:after {
width: calc(100% + 20px);
height: calc(100% + 20px);
opacity: 0.3;
}
// The bigger the number, the more markers/groups are contained within.
.custom-clustericon-1 {
--cluster-color: hsl(var(--color-highlight));
}
.custom-clustericon-2 {
--cluster-color: hsl(var(--color-secondary));
}
.custom-clustericon-3 {
--cluster-color: hsl(var(--color-primary));
}
How can I replicate the older styles using the new version? I;ve tried to inspect the new cluster markers, but all I see is a div with a single transparent pixel image within. Nothing to actually help me style. I just want to replicate the styles I have above. Custom cluster icon colours and three cluster sizes. I'm not sure what those sizes were specifically as I just used the ones that came as default with the old version.
Thanks, Neil
@rctneil Thank you for opening this issue. 🙏 Please check out these other resources that might be applicable:
- Support Console - If you have a support contract.
- Discord - chat with other developers
-
StackOverflow - use the
google-maps
tag - Google Maps Platform issue trackers
This is an automated message, feel free to ignore.
@rctneil Please take a moment to fill out this short survey. Thank you!
This is an automated message, feel free to ignore.
@jpoehnelt Sorry, I couldn't find anything to help me out at those links. Any suggestions to getting this sorted?
I vote for this change too
I don't believe this is possible anymore since you can't add classes to clusters (which are google.maps.Marker instances), only the label (text) of a cluster has a className parameter which isn't very helpful. Now the default clusters are base64 encoded SVG data images used as the URL parameter when you create a cluster (Marker instance). The SVG images are created on the fly since they're relatively easy to make (depending on the shape) but they still do not compare to just having a div/span and manipulating it with CSS, which is quite a shame.
You can see how cluster images are created in the renderer.ts file:
https://github.com/googlemaps/js-markerclusterer/blob/main/src/renderer.ts#L116
That's a big shame. I'd love the option to customise the cluster markers to match my sites theme.
There isn't a direct way to do this like before, but you can create your own instance of Renderer and have the render function return a Marker
instance with the icon and styling of your choice. Then provide that Renderer
instance in the options when you create your MarkerClusterer
instance.
I'll keep this issue open as an FR to add better styling support.
@amuramoto I think this can be closed with the introduction of advanced marker which can contain arbitrary markup
@vicb i think the issue here is that they want to style the cluster marker. In the old version of the lib, you could provide your own arbitrary icons and style them with css but currently we now hardcode the cluster icons.
Do you have any plan to restore this ability?
If not then I think this can be closed as the solution would be to implement a custom renderer generating advanced markers.
I reposted this originally and still would love to be able to style the cluster marker fully.
It's such a shame to see it not be customisable like it was.
The Grid Clusterer library found at:
https://github.com/bdcoder2/grid_clusterer
... has hooks for creating custom cluster markers, see the reference at: https://bdcoder2.github.io/grid_clusterer/v161/reference.html#i5_prop_cluster_marker_create_handler
Just another option as it does support both "Classic" and "Advanced" markers. :)
@rctneil Not sure if you have already figured this out but this is how I got it. Very difficult to find clear documentation.
const renderer = {
render({ count, position }: { count: number, position: any }, stats: any) {
const color = "#d11100";
const svg = window.btoa(`
<svg fill="${color}" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 240 240">
<circle cx="120" cy="120" opacity=".8" r="70" />
</svg>`);
// create marker using svg icon
console.log(count);
if (count > 1) {
return new google.maps.Marker({
position,
icon: {
url: `data:image/svg+xml;base64,${svg}`,
scaledSize: new google.maps.Size(75, 75),
},
label: {
text: String(count),
color: "rgba(255,255,255,0.9)",
fontSize: "12px",
},
// adjust zIndex to be above other markers
zIndex: Number(google.maps.Marker.MAX_ZINDEX) + count,
});
}
return new google.maps.Marker({
icon: {
url: `${window.location.origin}/location-pin.svg`,
scaledSize: new google.maps.Size(30, 30),
},
})
}
}
const markerClusterer = new MarkerClusterer({
markers: clusters, map: mapRef.current, algorithm, renderer: renderer
});