-
Notifications
You must be signed in to change notification settings - Fork 99
Description
SuperClusterAlgorithm Properties Not Accessible in Renderer
Issue Description
When using SuperClusterAlgorithm with custom map and reduce functions in @googlemaps/markerclusterer, the aggregated properties computed by the algorithm are not accessible in the renderer function. The cluster object passed to the renderer does not contain the properties that were calculated and returned by the algorithm's map/reduce functions.
Expected Behavior
The aggregated properties computed by SuperCluster's map/reduce functions should be accessible in the renderer, either:
- Through
cluster.markers[0].properties - Through the
statsparameter - Through some other documented mechanism
Actual Behavior
cluster.markers[0].propertiesisundefinedstatsparameter doesn't contain the aggregated properties- No way to access the computed aggregation data in the renderer
Reproduction Code
import { SuperClusterAlgorithm, MarkerClusterer } from '@googlemaps/markerclusterer';
// Define aggregated properties interface
interface AggregatedProps {
total_assets: number;
asset_type_counts: Record<string, number>;
selected_count: number;
status_counts: Record<string, number>;
most_severe_status: string;
}
// Create SuperCluster algorithm with map/reduce functions
const algorithm = new SuperClusterAlgorithm({
maxZoom: 22,
radius: 80,
// MAP: Process individual markers
map: (props) => {
const aggregated: AggregatedProps = {
total_assets: 1,
asset_type_counts: { [props.assetType]: 1 },
selected_count: props.isSelected ? 1 : 0,
status_counts: { [props.status]: 1 },
most_severe_status: props.status,
};
console.log('MAP function returning:', aggregated);
return aggregated;
},
// REDUCE: Merge properties of clusters
reduce: (accumulated, props) => {
accumulated.total_assets += props.total_assets;
// Merge asset type counts
for (const type in props.asset_type_counts) {
accumulated.asset_type_counts[type] =
(accumulated.asset_type_counts[type] || 0) + props.asset_type_counts[type];
}
// Merge other properties...
accumulated.selected_count += props.selected_count;
console.log('REDUCE function result:', accumulated);
},
});
// Custom renderer that should access aggregated properties
const renderer = {
render: (cluster, stats, map) => {
console.log('Renderer cluster:', cluster);
console.log('Renderer stats:', stats);
console.log('Cluster markers:', cluster.markers);
console.log('First marker properties:', cluster.markers[0]?.properties);
// ❌ These are all undefined:
// - cluster.markers[0].properties
// - stats.properties
// - stats (doesn't contain our aggregated data)
// Expected: Access to AggregatedProps computed by map/reduce
// Actual: No access to computed aggregation data
// Create marker without access to aggregated data
return new google.maps.Marker({
position: cluster.position,
label: String(cluster.count), // Can only use basic cluster.count
});
}
};
// Initialize clusterer
const clusterer = new MarkerClusterer({
map: googleMap,
algorithm: algorithm,
renderer: renderer,
});Console Output
MAP function returning: { total_assets: 1, asset_type_counts: {...}, ... }
REDUCE function result: { total_assets: 5, asset_type_counts: {...}, ... }
Renderer cluster: { count: 5, position: {...}, markers: [...] }
Renderer stats: { ... } // Basic stats, no custom properties
Cluster markers: [Marker, Marker, Marker, Marker, Marker]
First marker properties: undefined
Environment
@googlemaps/markerclusterer:^2.5.3- TypeScript:
^5.0.0 - Browser: Chrome 118+
Workaround
Currently having to manually re-aggregate data in the renderer by processing cluster.markers, which defeats the purpose of using SuperCluster's efficient map/reduce aggregation:
const renderer = {
render: (cluster, stats, map) => {
// Manual re-aggregation (inefficient)
const clusterAssets = cluster.markers.map(getAssetFromMarker);
const manuallyAggregated = {
total_assets: clusterAssets.length,
selected_count: clusterAssets.filter(a => a.isSelected).length,
// ... re-compute everything the algorithm already computed
};
// Use manually aggregated data for rendering
return createMarkerWithAggregatedData(manuallyAggregated);
}
};Suggested Fix
The renderer should have access to the aggregated properties, ideally through one of these approaches:
- Option 1:
cluster.propertiescontaining the aggregated data - Option 2:
cluster.markers[0].propertiescontaining the aggregated data - Option 3:
statsparameter containing the aggregated data - Option 4: Additional parameter with aggregated data
Related Documentation
Could not find documentation on how to access custom properties computed by SuperCluster's map/reduce functions in the MarkerClusterer renderer.