From c8dee9f882cdf0ddfd86d83dff142b35d762247d Mon Sep 17 00:00:00 2001 From: Akash Mohan Chaudhary <30294175+hadt0786@users.noreply.github.com> Date: Fri, 28 Aug 2026 22:11:35 +0530 Subject: [PATCH] feat: expose SuperCluster properties on clusters --- src/algorithms/supercluster.test.ts | 29 +++++++++++++++++++++++++++++ src/algorithms/supercluster.ts | 1 + src/algorithms/superviewport.ts | 1 + src/cluster.ts | 8 +++++++- 4 files changed, 38 insertions(+), 1 deletion(-) diff --git a/src/algorithms/supercluster.test.ts b/src/algorithms/supercluster.test.ts index 4ee91a97..881b990b 100644 --- a/src/algorithms/supercluster.test.ts +++ b/src/algorithms/supercluster.test.ts @@ -99,6 +99,35 @@ describe.each(testMarkerTypes)( expect(cluster.markers[0]).toBe(marker); }); + test("should expose aggregated properties on Cluster", () => { + const superCluster = new SuperClusterAlgorithm({}); + const marker: Marker = new markerClass(); + const clusterFeature = { + type: "Feature", + geometry: { coordinates: [0, 0], type: "Point" }, + properties: { + marker, + cluster: true, + cluster_id: 100, + point_count: 2, + point_count_abbreviated: 2, + highRiskCount: 1, + totalRisk: 3, + }, + } as unknown as ClusterFeature<{ marker: Marker }>; + + jest + .spyOn(superCluster["superCluster"], "getLeaves") + .mockImplementation(() => [clusterFeature]); + + const cluster = superCluster["transformCluster"](clusterFeature); + + expect(cluster.properties).toMatchObject({ + highRiskCount: 1, + totalRisk: 3, + }); + }); + test("should not cluster if zoom didn't change", () => { const mapCanvasProjection = jest.fn() as unknown as google.maps.MapCanvasProjection; diff --git a/src/algorithms/supercluster.ts b/src/algorithms/supercluster.ts index 3a912b63..845a5b91 100644 --- a/src/algorithms/supercluster.ts +++ b/src/algorithms/supercluster.ts @@ -127,6 +127,7 @@ export class SuperClusterAlgorithm extends AbstractAlgorithm { .getLeaves(properties.cluster_id, Infinity) .map((leaf) => leaf.properties.marker), position: { lat, lng }, + properties, }); } diff --git a/src/algorithms/superviewport.ts b/src/algorithms/superviewport.ts index 00670c57..58476980 100644 --- a/src/algorithms/superviewport.ts +++ b/src/algorithms/superviewport.ts @@ -132,6 +132,7 @@ export class SuperClusterViewportAlgorithm extends AbstractViewportAlgorithm { .getLeaves(properties.cluster_id, Infinity) .map((leaf) => leaf.properties.marker), position: { lat, lng }, + properties, }); } diff --git a/src/cluster.ts b/src/cluster.ts index 3ea066a0..6f391427 100644 --- a/src/cluster.ts +++ b/src/cluster.ts @@ -16,18 +16,24 @@ import { MarkerUtils, Marker } from "./marker-utils"; +export type ClusterProperties = Record; + export interface ClusterOptions { position?: google.maps.LatLng | google.maps.LatLngLiteral; markers?: Marker[]; + /** Algorithm-specific properties associated with this cluster. */ + properties?: ClusterProperties; } export class Cluster { public marker?: Marker; public readonly markers: Marker[] = []; + public readonly properties?: ClusterProperties; protected _position?: google.maps.LatLng; - constructor({ markers, position }: ClusterOptions) { + constructor({ markers, position, properties }: ClusterOptions) { if (markers) this.markers = markers; + this.properties = properties; if (position) { if (position instanceof google.maps.LatLng) { this._position = position;