import {Directive, Input, OnDestroy, OnChanges, OnInit, SimpleChange, Output, EventEmitter} from '@angular/core'; import {ClusterManager} from '../services/managers/cluster-manager'; import {MarkerManager, InfoWindowManager} from '@agm/core'; import {ClusterOptions, ClusterStyle} from '../services/google-clusterer-types'; /** * AgmMarkerCluster clusters map marker if they are near together * * ### Example * ```typescript * import { Component } from '@angular/core'; * * @Component({ * selector: 'my-map-cmp', * styles: [` * agm-map { * height: 300px; * } * `], * template: ` * * * * * * * * * ` * }) * ``` */ @Directive({ selector: 'agm-marker-cluster', providers: [ ClusterManager, {provide: MarkerManager, useExisting: ClusterManager}, InfoWindowManager, ] }) export class AgmMarkerCluster implements OnDestroy, OnChanges, OnInit, ClusterOptions { /** * The grid size of a cluster in pixels */ @Input() gridSize: number; /** * The maximum zoom level that a marker can be part of a cluster. */ @Input() maxZoom: number; /** * Whether the default behaviour of clicking on a cluster is to zoom into it. */ @Input() zoomOnClick: boolean; /** * Whether the center of each cluster should be the average of all markers in the cluster. */ @Input() averageCenter: boolean; /** * The minimum number of markers to be in a cluster before the markers are hidden and a count is shown. */ @Input() minimumClusterSize: number; /** * An object that has style properties. */ @Input() styles: ClusterStyle; @Input() imagePath: string; @Input() imageExtension: string; @Output() clusterClick: EventEmitter = new EventEmitter(); constructor(private _clusterManager: ClusterManager) {} /** @internal */ ngOnDestroy() { this._clusterManager.clearMarkers(); } /** @internal */ ngOnChanges(changes: {[key: string]: SimpleChange }) { if (changes['gridSize']) { this._clusterManager.setGridSize(this); } if (changes['maxZoom']) { this._clusterManager.setMaxZoom(this); } if (changes['styles']) { this._clusterManager.setStyles(this); } if (changes['zoomOnClick']) { this._clusterManager.setZoomOnClick(this); } if (changes['averageCenter']) { this._clusterManager.setAverageCenter(this); } if (changes['minimumClusterSize']) { this._clusterManager.setMinimumClusterSize(this); } if (changes['styles']) { this._clusterManager.setStyles(this); } if (changes['imagePath']) { this._clusterManager.setImagePath(this); } if (changes['imageExtension']) { this._clusterManager.setImageExtension(this); } } /** @internal */ ngOnInit() { this._clusterManager.init({ gridSize: this.gridSize, maxZoom: this.maxZoom, zoomOnClick: this.zoomOnClick, averageCenter: this.averageCenter, minimumClusterSize: this.minimumClusterSize, styles: this.styles, imagePath: this.imagePath, imageExtension: this.imageExtension, }); this._addEventListeners(); } private _addEventListeners() { const handlers = [ {name: 'clusterclick', handler: (ev: mapTypes.MouseEvent) => this.clusterClick.emit(ev)}, ]; handlers.forEach((obj) => { const os = this._clusterManager.createClusterEventObservable(obj.name, this).subscribe(obj.handler); this._subscriptions.push(os); }); } }