import {
Directive,
EventEmitter,
Input,
NgZone,
OnChanges,
OnDestroy,
OnInit,
Output,
SimpleChanges,
} from '@angular/core';
import { InfoWindowManager, MarkerManager } from '@agm/core';
import { Marker } from '@agm/core/services/google-maps-types';
import { SpiderManager } from '../services/managers/spider-manager';
import { FormatEvent, LegColorOptions, SpiderfyEvent, SpiderOptions } from '../services/google-spider-types';
/**
* AgmMarkerSpider spiderfies 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-spider',
providers: [
SpiderManager,
{ provide: MarkerManager, useExisting: SpiderManager },
InfoWindowManager,
],
})
export class AgmMarkerSpider implements OnDestroy, OnChanges, OnInit, SpiderOptions {
/**
* The colors of the legs
*/
@Input() legColors: LegColorOptions;
/**
* Disable listening for marker move events (in case markers won't be dragged/moved)
*/
@Input() markersWontMove: boolean;
/**
* Disable listening for visibility events (in case markers won't be hidden)
*/
@Input() markersWontHide: boolean;
/**
* Disable the OverlappingMarkerSpiderfier.markerStatus.SPIDERFIABLE event
*/
@Input() basicFormatEvents: boolean;
/**
* Do not unspiderify the markers when one of them is clicked
*/
@Input() keepSpiderfied: boolean;
/**
* Do not unspiderify when the map is clicked
*/
@Input() ignoreMapClick: boolean;
/**
* The pixel radius within which a marker is considered overlapping
*/
@Input() nearbyDistance: number;
/**
* The amount of markers before the spiderfier switches to spiral mode
*/
@Input() circleSpiralSwitchover: number;
/**
* The distance for the spiderfied markers from the center (circle mode)
*/
@Input() circleFootSeparation: number;
/**
* The starting angle for the spiderfied markers (circle mode)
*/
@Input() circleStartAngle: number;
/**
* The distance for the spiderfied markers from the center (spiral mode)
*/
@Input() spiralFootSeparation: number;
/**
* The distance between the spiderfied markers from the first to the second (spiral mode)
*/
@Input() spiralLengthStart: number;
/**
* The increment to the distance for each consecutive marker (spiral mode)
*/
@Input() spiralLengthFactor: number;
/**
* The thickness of the marker lines
*/
@Input() legWeight: number;
/**
* Triggers when a marker is formatted, can be used to style the icon
*/
@Output() format: EventEmitter = new EventEmitter();
/**
* Triggers when markers are spiderfied (expanded)
*/
@Output() spiderfy: EventEmitter = new EventEmitter();
/**
* Triggers when markers are unspiderfied (collapsed)
*/
@Output() unspiderfy: EventEmitter = new EventEmitter();
constructor(private _spiderManager: SpiderManager, private _ngZone: NgZone) {
}
/** @internal */
ngOnDestroy() {
this._spiderManager.clearMarkers();
}
/** @internal */
ngOnChanges(changes: SimpleChanges) {
if (changes['legColors']) {
this._spiderManager.setLegColors(this);
}
if (changes['markersWontMove']) {
this._spiderManager.setMarkersWontMove(this);
}
if (changes['markersWontHide']) {
this._spiderManager.setMarkersWontHide(this);
}
if (changes['basicFormatEvents']) {
this._spiderManager.setBasicFormatEvents(this);
}
if (changes['keepSpiderfied']) {
this._spiderManager.setKeepSpiderfied(this);
}
if (changes['ignoreMapClick']) {
this._spiderManager.setIgnoreMapClick(this);
}
if (changes['nearbyDistance']) {
this._spiderManager.setNearbyDistance(this);
}
if (changes['circleSpiralSwitchover']) {
this._spiderManager.setCircleSpiralSwitchover(this);
}
if (changes['circleFootSeparation']) {
this._spiderManager.setCircleFootSeparation(this);
}
if (changes['circleStartAngle']) {
this._spiderManager.setCircleStartAngle(this);
}
if (changes['spiralFootSeparation']) {
this._spiderManager.setSpiralFootSeparation(this);
}
if (changes['spiralLengthStart']) {
this._spiderManager.setSpiralLengthStart(this);
}
if (changes['spiralLengthFactor']) {
this._spiderManager.setSpiralLengthFactor(this);
}
if (changes['legWeight']) {
this._spiderManager.setLegWeight(this);
}
}
/** @internal */
ngOnInit() {
this._spiderManager.init({
markersWontMove: this.markersWontMove,
markersWontHide: this.markersWontHide,
basicFormatEvents: this.basicFormatEvents,
keepSpiderfied: this.keepSpiderfied,
ignoreMapClick: this.ignoreMapClick,
nearbyDistance: this.nearbyDistance,
circleSpiralSwitchover: this.circleSpiralSwitchover,
circleFootSeparation: this.circleFootSeparation,
circleStartAngle: this.circleStartAngle,
spiralFootSeparation: this.spiralFootSeparation,
spiralLengthStart: this.spiralLengthStart,
spiralLengthFactor: this.spiralLengthFactor,
legWeight: this.legWeight,
});
this._spiderManager.instance.then(spiderfier => {
spiderfier.addListener('format', (marker: Marker, status: string) => this._ngZone.run(() => this.format.emit({
marker,
status,
spiderfier,
})));
spiderfier.addListener('spiderfy', (changedMarkers: Marker[], unchangedMarkers: Marker[]) => this._ngZone.run(() => this.spiderfy.emit({
changedMarkers,
unchangedMarkers,
spiderfier,
})));
spiderfier.addListener('unspiderfy', (changedMarkers: Marker[], unchangedMarkers: Marker[]) => this._ngZone.run(() => this.unspiderfy.emit({
changedMarkers,
unchangedMarkers,
spiderfier,
})));
});
}
}