Disclaimer: In my example the expanded features are not arranged in a circle though, they are simply shown at their normal "unclustered" place on the map. Might be possible to additionally arrange them in a circle.
So, I got the expansion working with an additional layer that contains the features that are not clustered. This is what I did:
I added a click event on the clustered layer that fires when the user clicks on a cluster:
const select = new olInteraction.Select({
layers: [clusterLayer],
style: null
});
map.addInteraction(select);
const selectableFeatures = select.getFeatures();
selectableFeatures.on('add', (feature) => {
const features = feature.element.get('features') || [];
//is it a cluster with > 1 items?
if (features.length > 1) {
features.forEach((feature) => feature.set('cluster', false));
}
});
Then I ensured the cluster does not show the features that have been clicked on by setting the geometryFunction on the cluster:
const clusterSource = new olSource.Cluster({
distance: 80,
geometryFunction: (feature) => {
if (feature.get('cluster') === false) return null;
return feature.getGeometry();
},
source,
});
Then I created an additional vector layer that shows only the features where the property cluster === false
:
const vectorLayer = new olLayer.Vector({
id,
selectable: true,
title: 'Layer that is not Clustered',
source,
style: (feature, resolution) => {
if (feature.get('cluster') === false) {
//styling of the expanded features goes here
return [
new olStyle.Style({
image: new olStyle.Circle({
radius: 30,
scale: getScale(resolution) * 1.5,
fill: new olStyle.Fill({
color: (hover || selected) ? '#1F54A0' : 'rgba(51, 51, 51, 0.8)',
})
})
})
];
}
//hide the clustered features on this layer
return new olStyle.Style({});
},
zIndex:2,
maxResolution: 10,
});