Skip to content

Commit cdb2326

Browse files
authored
feat(google-maps): support options object on marker clusterer (#21861)
Adds support for an `options` input to the marker clusterer, similar to the other Google Maps directives. Fixes #21763.
1 parent deebaae commit cdb2326

File tree

5 files changed

+78
-21
lines changed

5 files changed

+78
-21
lines changed

src/google-maps/map-marker-clusterer/map-marker-clusterer.spec.ts

+40
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,44 @@ describe('MapMarkerClusterer', () => {
116116
});
117117
});
118118

119+
it('sets marker clusterer options', () => {
120+
fixture.detectChanges();
121+
const options: MarkerClustererOptions = {
122+
enableRetinaIcons: true,
123+
gridSize: 1337,
124+
ignoreHidden: true,
125+
imageExtension: 'png'
126+
};
127+
fixture.componentInstance.options = options;
128+
fixture.detectChanges();
129+
expect(markerClustererSpy.setOptions).toHaveBeenCalledWith(jasmine.objectContaining(options));
130+
});
131+
132+
it('gives precedence to specific inputs over options', () => {
133+
fixture.detectChanges();
134+
const options: MarkerClustererOptions = {
135+
enableRetinaIcons: true,
136+
gridSize: 1337,
137+
ignoreHidden: true,
138+
imageExtension: 'png'
139+
};
140+
const expectedOptions: MarkerClustererOptions = {
141+
enableRetinaIcons: false,
142+
gridSize: 42,
143+
ignoreHidden: false,
144+
imageExtension: 'jpeg'
145+
};
146+
fixture.componentInstance.enableRetinaIcons = expectedOptions.enableRetinaIcons;
147+
fixture.componentInstance.gridSize = expectedOptions.gridSize;
148+
fixture.componentInstance.ignoreHidden = expectedOptions.ignoreHidden;
149+
fixture.componentInstance.imageExtension = expectedOptions.imageExtension;
150+
fixture.componentInstance.options = options;
151+
fixture.detectChanges();
152+
153+
expect(markerClustererSpy.setOptions)
154+
.toHaveBeenCalledWith(jasmine.objectContaining(expectedOptions));
155+
});
156+
119157
it('sets Google Maps Markers in the MarkerClusterer', () => {
120158
fixture.detectChanges();
121159

@@ -246,6 +284,7 @@ describe('MapMarkerClusterer', () => {
246284
[title]="title"
247285
[zIndex]="zIndex"
248286
[zoomOnClick]="zoomOnClick"
287+
[options]="options"
249288
(clusteringbegin)="onClusteringBegin()">
250289
<map-marker *ngIf="state === 'state1'"></map-marker>
251290
<map-marker *ngIf="state === 'state1' || state === 'state2'"></map-marker>
@@ -274,6 +313,7 @@ class TestApp {
274313
title?: string;
275314
zIndex?: number;
276315
zoomOnClick?: boolean;
316+
options?: MarkerClustererOptions;
277317

278318
state = 'state1';
279319

src/google-maps/map-marker-clusterer/map-marker-clusterer.ts

+32-18
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ import {GoogleMap} from '../google-map/google-map';
3232
import {MapEventManager} from '../map-event-manager';
3333
import {MapMarker} from '../map-marker/map-marker';
3434

35+
/** Default options for a clusterer. */
36+
const DEFAULT_CLUSTERER_OPTIONS: MarkerClustererOptions = {};
37+
3538
/**
3639
* Angular component for implementing a Google Maps Marker Clusterer.
3740
*
@@ -153,6 +156,12 @@ export class MapMarkerClusterer implements OnInit, AfterContentInit, OnChanges,
153156
}
154157
private _zoomOnClick: boolean;
155158

159+
@Input()
160+
set options(options: MarkerClustererOptions) {
161+
this._options = options;
162+
}
163+
private _options: MarkerClustererOptions;
164+
156165
/**
157166
* See
158167
* googlemaps.github.io/v3-utility-library/modules/
@@ -212,6 +221,9 @@ export class MapMarkerClusterer implements OnInit, AfterContentInit, OnChanges,
212221
} = this;
213222

214223
if (clusterer) {
224+
if (changes['options']) {
225+
clusterer.setOptions(this._combineOptions());
226+
}
215227
if (changes['ariaLabelFn']) {
216228
clusterer.ariaLabelFn = ariaLabelFn;
217229
}
@@ -376,25 +388,27 @@ export class MapMarkerClusterer implements OnInit, AfterContentInit, OnChanges,
376388
}
377389

378390
private _combineOptions(): MarkerClustererOptions {
391+
const options = this._options || DEFAULT_CLUSTERER_OPTIONS;
379392
return {
380-
ariaLabelFn: this.ariaLabelFn,
381-
averageCenter: this._averageCenter,
382-
batchSize: this.batchSize,
383-
batchSizeIE: this._batchSizeIE,
384-
calculator: this._calculator,
385-
clusterClass: this._clusterClass,
386-
enableRetinaIcons: this._enableRetinaIcons,
387-
gridSize: this._gridSize,
388-
ignoreHidden: this._ignoreHidden,
389-
imageExtension: this._imageExtension,
390-
imagePath: this._imagePath,
391-
imageSizes: this._imageSizes,
392-
maxZoom: this._maxZoom,
393-
minimumClusterSize: this._minimumClusterSize,
394-
styles: this._styles,
395-
title: this._title,
396-
zIndex: this._zIndex,
397-
zoomOnClick: this._zoomOnClick,
393+
...options,
394+
ariaLabelFn: this.ariaLabelFn ?? options.ariaLabelFn,
395+
averageCenter: this._averageCenter ?? options.averageCenter,
396+
batchSize: this.batchSize ?? options.batchSize,
397+
batchSizeIE: this._batchSizeIE ?? options.batchSizeIE,
398+
calculator: this._calculator ?? options.calculator,
399+
clusterClass: this._clusterClass ?? options.clusterClass,
400+
enableRetinaIcons: this._enableRetinaIcons ?? options.enableRetinaIcons,
401+
gridSize: this._gridSize ?? options.gridSize,
402+
ignoreHidden: this._ignoreHidden ?? options.ignoreHidden,
403+
imageExtension: this._imageExtension ?? options.imageExtension,
404+
imagePath: this._imagePath ?? options.imagePath,
405+
imageSizes: this._imageSizes ?? options.imageSizes,
406+
maxZoom: this._maxZoom ?? options.maxZoom,
407+
minimumClusterSize: this._minimumClusterSize ?? options.minimumClusterSize,
408+
styles: this._styles ?? options.styles,
409+
title: this._title ?? options.title,
410+
zIndex: this._zIndex ?? options.zIndex,
411+
zoomOnClick: this._zoomOnClick ?? options.zoomOnClick,
398412
};
399413
}
400414

src/google-maps/map-marker-clusterer/marker-clusterer-types.ts

+2
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ declare class MarkerClusterer {
7777
setValues(values: any): void;
7878
setZIndex(zIndex: number): void;
7979
setZoomOnClick(zoomOnClick: boolean): void;
80+
// Note: This one doesn't appear in the docs page, but it exists at runtime.
81+
setOptions(options: MarkerClustererOptions): void;
8082
unbind(key: string): void;
8183
unbindAll(): void;
8284
static CALCULATOR(markers: google.maps.Marker[], numStyles: number): ClusterIconInfo;

src/google-maps/testing/fake-google-map-utils.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -434,9 +434,9 @@ export function createMarkerClustererSpy(): jasmine.SpyObj<MarkerClusterer> {
434434
'setCalculator', 'setClusterClass', 'setEnableRetinaIcons', 'setGridSize',
435435
'setIgnoreHidden', 'setImageExtension', 'setImagePath', 'setImageSizes', 'setMap',
436436
'setMaxZoom', 'setMinimumClusterSize', 'setStyles', 'setTitle', 'setZIndex',
437-
'setZoomOnClick',
437+
'setZoomOnClick', 'setOptions',
438438
]);
439-
markerClustererSpy.addListener.and.returnValue({ remove: () => { } });
439+
markerClustererSpy.addListener.and.returnValue({remove: () => {}});
440440
return markerClustererSpy;
441441
}
442442

tools/public_api_guard/google-maps/google-maps.d.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,7 @@ export declare class MapMarkerClusterer implements OnInit, AfterContentInit, OnC
294294
markerClusterer?: MarkerClusterer;
295295
set maxZoom(maxZoom: number);
296296
set minimumClusterSize(minimumClusterSize: number);
297+
set options(options: MarkerClustererOptions);
297298
set styles(styles: ClusterIconStyle[]);
298299
set title(title: string);
299300
set zIndex(zIndex: number);
@@ -323,7 +324,7 @@ export declare class MapMarkerClusterer implements OnInit, AfterContentInit, OnC
323324
ngOnChanges(changes: SimpleChanges): void;
324325
ngOnDestroy(): void;
325326
ngOnInit(): void;
326-
static ɵcmp: i0.ɵɵComponentDefWithMeta<MapMarkerClusterer, "map-marker-clusterer", ["mapMarkerClusterer"], { "ariaLabelFn": "ariaLabelFn"; "averageCenter": "averageCenter"; "batchSize": "batchSize"; "batchSizeIE": "batchSizeIE"; "calculator": "calculator"; "clusterClass": "clusterClass"; "enableRetinaIcons": "enableRetinaIcons"; "gridSize": "gridSize"; "ignoreHidden": "ignoreHidden"; "imageExtension": "imageExtension"; "imagePath": "imagePath"; "imageSizes": "imageSizes"; "maxZoom": "maxZoom"; "minimumClusterSize": "minimumClusterSize"; "styles": "styles"; "title": "title"; "zIndex": "zIndex"; "zoomOnClick": "zoomOnClick"; }, { "clusteringbegin": "clusteringbegin"; "clusteringend": "clusteringend"; }, ["_markers"], ["*"]>;
327+
static ɵcmp: i0.ɵɵComponentDefWithMeta<MapMarkerClusterer, "map-marker-clusterer", ["mapMarkerClusterer"], { "ariaLabelFn": "ariaLabelFn"; "averageCenter": "averageCenter"; "batchSize": "batchSize"; "batchSizeIE": "batchSizeIE"; "calculator": "calculator"; "clusterClass": "clusterClass"; "enableRetinaIcons": "enableRetinaIcons"; "gridSize": "gridSize"; "ignoreHidden": "ignoreHidden"; "imageExtension": "imageExtension"; "imagePath": "imagePath"; "imageSizes": "imageSizes"; "maxZoom": "maxZoom"; "minimumClusterSize": "minimumClusterSize"; "styles": "styles"; "title": "title"; "zIndex": "zIndex"; "zoomOnClick": "zoomOnClick"; "options": "options"; }, { "clusteringbegin": "clusteringbegin"; "clusteringend": "clusteringend"; }, ["_markers"], ["*"]>;
327328
static ɵfac: i0.ɵɵFactoryDef<MapMarkerClusterer, never>;
328329
}
329330

0 commit comments

Comments
 (0)