Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add OverlappingMarkerSpiderfier package #1329

Closed
wants to merge 3 commits into from

Conversation

chancezeus
Copy link

As mentioned in #1146 it would be nice to have support for the OverlappingMarkerSpiderfier. Since a lot of (if not most) people would also like to be able to combine the spiderfier with the cluster library I made some changes to the way the MarkerManager works. The change basically makes it possible for MarkerManagers to be nested which enables the spider and cluster plugins to be active at the same time (ordering should not matter) and forwarding the actual creation of markers onto the "parent" MarkerManager (this will be the MarkerManager instance associated with the AgmMap instance). I did not want to modify too much in the core packages, but I did extend the base MarkerManager constructor with an @Optional() @SkipSelf() _markerManager: MarkerManager. If interested I can add extra functionality to also have the "core" MarkerManager forward it's calls up the tree (until the "parent" is not defined anymore) and thus add the option to create for example an AgmMarkerGroup directive that clusters similar markers which can be disabled at once and/or other (more advanced) features...

Copy link
Owner

@sebholstein sebholstein left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work!

I added some comments. We should also change the naming a bit:

Package name: @agm/marker-spiderfier
Folder name: marker-spiderfier

/**
* Triggers when a marker is formatted, can be used to style the icon
*/
@Output() format: EventEmitter<{ marker: Marker, status: string }> = new EventEmitter<{ marker: Marker, status: string }>();
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we extract this as a type? So others can use this in their code.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated

/**
* Triggers when markers are spiderfied (expanded)
*/
@Output() spiderfy: EventEmitter<{ changedMarkers: Marker[], unchangedMarkers: Marker[] }> = new EventEmitter<{ changedMarkers: Marker[], unchangedMarkers: Marker[] }>();
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here for the type

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated


-----

this package levereges the [npm-overlapping-marker-spiderfier][npm-overlapping-marker-spiderfier] to add spiderfy
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this -> This

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated

*/
@Directive({
selector: 'agm-marker-spider',
providers: [
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as want to start implementing ChangeDetectionStrategy.OnPush for all component: can you add it here and test that it runs with OnPush?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changeDetection attribute is only available for components, not directives. Please update the @agm/core package and I'll test if this gives any problems in my package

/**
* Triggers when markers are unspiderfied (collapsed)
*/
@Output() unspiderfy: EventEmitter<{ changedMarkers: Marker[], unchangedMarkers: Marker[] }> = new EventEmitter<{ changedMarkers: Marker[], unchangedMarkers: Marker[] }>();
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here for the type

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated

@agm/js-marker-spider has a peer depedency on [npm-overlapping-marker-spiderfier][npm-overlapping-marker-spiderfier]

```shell
npm install npm-overlapping-marker-spiderfier @agm/js-marker-spider --save
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should use a version range here for npm-overlapping-marker-spiderfier that works with our package.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I actually made a full ts rewrite of the package that is 100% compatible but forgot to update the readme, I will update and include version info

```shell
npm install npm-overlapping-marker-spiderfier @agm/js-marker-spider --save
# or
yarn add npm-overlapping-marker-spiderfier @agm/js-marker-spider
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here also

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See previous comment


const markerPromise = this._markerManager.getNativeMarker(marker);

this._markers.set(marker, markerPromise);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This happens in the _makerManager.addMarker already

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True, but the _markerManager is a reference to the parent (notice the @SkipSelf) which means that the local _markers is not updated. By setting the _markers here too, it allows for the manager to keep a local reference to it's own markers which is used in removal/clear to only delete markers owned by the spiderfier, not by any parent (cluster/agm-map) managers)...

The update(s) to core (as explained in the intro) are to allow cascading of marker creation from "nested" marker managers up the chain (until the "core" marker manager belonging to the "agm-map" directive, that way it is possible to have a clustered-spiderfier (or any other nested (grouping) marker layer)...

if (this._markers.has(marker)) {
spider.removeMarker(nativeMarker as any);

this._markers.delete(marker);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This happens in the _makerManager.addMarker already

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See previous comment

}

createEventObservable<T>(eventName: string, marker: AgmMarker): Observable<T> {
// Override the default "click" event with "spider_click"
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could it be a valid use case that the user want's a click event instead of a spider_click event?

Copy link
Author

@chancezeus chancezeus Mar 3, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The click event in the spiderfier is not very functional since it will also trigger when the "root" marker is clicked. Long story short: the click event might be usefull for only very few people and to (properly) support the info window, I have to replace the click event (otherwise the infowindow will also trigger when clicking the still collapsed markers)...

If you (or anyone) has a suggestion I'm all ears...

@chancezeus
Copy link
Author

I pushed a commit with most of the changes, please comment on the few ones remaining with questions and I'll modify and commit accordingly...

@chancezeus
Copy link
Author

@SebastianM the requested replacements of (?:../)+core to @agm/core result in the failing travis checks since travis does not know about the @agm/* packages when it runs. Unfortunately my experience with travis is limited but I guess some additional config (mapping @agm/* to the correct paths) is needed to make the test(s) run correctly again...

@chancezeus
Copy link
Author

Example of nested cluster and spiderfier (this comes from my own (working) test component):

<agm-map [latitude]="51.673858" [longitude]="7.815982" [maxZoom]="16">
  <agm-marker-cluster [maxZoom]="14"
                      imagePath="https://raw.githubusercontent.com/googlemaps/v3-utility-library/master/markerclustererplus/images/m">
    <agm-marker-spider [keepSpiderfied]="true" (format)="testEvent('format', $event)"
                       (spiderfy)="testEvent('spiderfy', $event)" (unspiderfy)="testEvent('unspiderfy', $event)">
      <agm-marker [latitude]="51.673858" [longitude]="7.815982"
                  (markerClick)="testEvent('markerClick', $event)"></agm-marker>
      <agm-marker [latitude]="51.673858" [longitude]="7.815982"
                  (markerClick)="testEvent('markerClick', $event)"></agm-marker>
      <agm-marker [latitude]="51.673858" [longitude]="7.815982"
                  (markerClick)="testEvent('markerClick', $event)"></agm-marker>
      <agm-marker [latitude]="51.673858" [longitude]="7.815982"
                  (markerClick)="testEvent('markerClick', $event)"></agm-marker>
      <agm-marker [latitude]="51.67" [longitude]="7.8"
                  (markerClick)="testEvent('markerClick', $event)"></agm-marker>
    </agm-marker-spider>
  </agm-marker-cluster>
</agm-map>

- Replace google.maps types with corresponding @agm types
@ChrisDevinePimss
Copy link

@SebastianM any update on this?

@felberto
Copy link

@SebastianM are there any updates on this?

@Murali1689
Copy link

@SebastianM Any updates on this?

@Satheesh28
Copy link

<agm-marker-cluster [maxZoom]="14"
imagePath="https://raw.githubusercontent.com/googlemaps/v3-utility-library/master/markerclustererplus/images/m">
<agm-marker-spider [keepSpiderfied]="true" (format)="testEvent('format', $event)"

this not working for me please help me @chancezeus

@lam3rr
Copy link

lam3rr commented Jul 27, 2018

@SebastianM are there any updates on this?

@WheelyWonka
Copy link

Hola ! Any update on this ? Thanks !

@amorimdev
Copy link

@SebastianM Any updates on this?

@amorimdev
Copy link

@chancezeus I have had to use this feature so I took the liberty to publish a package.

If anyone feel interested to, follow link of the package.
https://www.npmjs.com/package/agm-oms

@ChrisDevinePimss
Copy link

ChrisDevinePimss commented Oct 3, 2018

@chancezeus I have had to use this feature so I took the liberty to publish a package.

If anyone feel interested to, follow link of the package.
https://www.npmjs.com/package/agm-oms

You sir are my hero 4 the day!

@drjaat
Copy link

drjaat commented Oct 4, 2018

@chancezeus I have had to use this feature so I took the liberty to publish a package.

If anyone feel interested to, follow link of the package.
https://www.npmjs.com/package/agm-oms

error agm-marker-spider is not known element
and i have added this to app.module.ts in import also but no working

@btimeteam
Copy link

@drjaat you import agm-oms in same location where you imports @agm/core? And you export AgmMarkerSpiderModule? If you do not try export this module.

@Smiter15
Copy link

Smiter15 commented Oct 8, 2018

@chancezeus I have had to use this feature so I took the liberty to publish a package.

If anyone feel interested to, follow link of the package.
https://www.npmjs.com/package/agm-oms

Does this play well with marker clusterer ? If so can you update the README with the syntax please

@ChrisDevinePimss
Copy link

@chancezeus I have had to use this feature so I took the liberty to publish a package.
If anyone feel interested to, follow link of the package.
https://www.npmjs.com/package/agm-oms

Does this play well with marker clusterer ? If so can you update the README with the syntax please

I tested it and found that it does

@Smiter15
Copy link

Smiter15 commented Oct 8, 2018

@chancezeus I have had to use this feature so I took the liberty to publish a package.
If anyone feel interested to, follow link of the package.
https://www.npmjs.com/package/agm-oms

Does this play well with marker clusterer ? If so can you update the README with the syntax please

I tested it and found that it does

Thanks for the reply. When using it in my setup I have a clustered marker of 2 and when I click on it, it just flashes and doesn't separate. Here is my mark up:

<agm-map (mapReady)="mapReady($event)">
    <agm-marker-cluster imagePath="https://raw.githubusercontent.com/googlemaps/v3-utility-library/master/markerclustererplus/images/m">
        <agm-marker-spider>
            <agm-marker *ngFor="let marker of markers" [latitude]="marker.lat" [longitude]="marker.lang">
                <agm-snazzy-info-window [closeWhenOthersOpen]="true">
                    <ng-template>
                        <div class="row pop-over-content">
                            ...
                        </div>
                    </ng-template>
                </agm-snazzy-info-window>
            </agm-marker>
        </agm-marker-spider>
    </agm-marker-cluster>
</agm-map>

Is this correct ? I don't get any errors.
When I remove the agm-clusterer tag it works and spiderfies the 2 markers :/

@ChrisDevinePimss
Copy link

ChrisDevinePimss commented Oct 8, 2018

turn clustering off at a certain zoom point using [maxZoom]="10"

I changed your code to as below code below

<agm-map (mapReady)="mapReady($event)">
    <agm-marker-cluster [maxZoom]="10" imagePath="https://raw.githubusercontent.com/googlemaps/v3-utility-library/master/markerclustererplus/images/m">
        <agm-marker-spider>
            <agm-marker *ngFor="let marker of markers" [latitude]="marker.lat" [longitude]="marker.lang">
                <agm-snazzy-info-window [closeWhenOthersOpen]="true">
                    <ng-template>
                        <div class="row pop-over-content">
                            ...
                        </div>
                    </ng-template>
                </agm-snazzy-info-window>
            </agm-marker>
        </agm-marker-spider>
    </agm-marker-cluster>
</agm-map>

@Smiter15
Copy link

Smiter15 commented Oct 8, 2018

turn clustering off at a certain zoom point using [maxZoom]="10"

I changed your code to as below code below

<agm-map (mapReady)="mapReady($event)">
    <agm-marker-cluster [maxZoom]="10" imagePath="https://raw.githubusercontent.com/googlemaps/v3-utility-library/master/markerclustererplus/images/m">
        <agm-marker-spider>
            <agm-marker *ngFor="let marker of markers" [latitude]="marker.lat" [longitude]="marker.lang">
                <agm-snazzy-info-window [closeWhenOthersOpen]="true">
                    <ng-template>
                        <div class="row pop-over-content">
                            ...
                        </div>
                    </ng-template>
                </agm-snazzy-info-window>
            </agm-marker>
        </agm-marker-spider>
    </agm-marker-cluster>
</agm-map>

Works a treat ! Thank you

@AScheidt
Copy link

This extension works great! Just one question: How do I use the [legColors] in <agm-marker-spider> correctly? I want to set the usual and highlighted properties of the legColors: LegColorOptions property to a certain color, but don't know how to achieve this.

@AScheidt
Copy link

AScheidt commented Oct 29, 2018

@chancezeus I have had to use this feature so I took the liberty to publish a package.

If anyone feel interested to, follow link of the package.
https://www.npmjs.com/package/agm-oms

I'm getting the error:
Error: Uncaught (in promise): TypeError: _this._markerManager.deleteMarkers is not a function TypeError: _this._markerManager.deleteMarkers is not a function at spider-manager.js:72

I think it's a typo isn't it? Because spider-manager.js tries to call _this._markerManager.deleteMarkerS when there is only a Method calles deleteMarker()

@rgails
Copy link

rgails commented Jan 25, 2019

@chancezeus I have had to use this feature so I took the liberty to publish a package.
If anyone feel interested to, follow link of the package.
https://www.npmjs.com/package/agm-oms

I'm getting the error:
Error: Uncaught (in promise): TypeError: _this._markerManager.deleteMarkers is not a function TypeError: _this._markerManager.deleteMarkers is not a function at spider-manager.js:72

I think it's a typo isn't it? Because spider-manager.js tries to call _this._markerManager.deleteMarkerS when there is only a Method calles deleteMarker()

Someone fixed it in a different version of the package: https://www.npmjs.com/package/agm-spiderfeir

@azurenote
Copy link

This extension saved my days. Thank you for your great work. Hope this fully merged to main branch.

@stale
Copy link

stale bot commented May 9, 2019

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the stale label May 9, 2019
@stale stale bot closed this May 16, 2019
@ghost ghost reopened this Aug 9, 2019
@stale stale bot removed the stale label Aug 9, 2019
@henryyue2010
Copy link

I met problems when trying to use agm-oms with js-marker-clusterer. Hopfully, the package of marker spiderfier can be fully supported in agm asap. Thank you very much.

@stale
Copy link

stale bot commented Nov 8, 2019

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the stale label Nov 8, 2019
@ghost ghost added needs: adopter a PR that was abandoned, and needs to be cleaned up before merge and removed stale labels Nov 12, 2019
@CrackerakiUA
Copy link

when this will be completed? :)

@ghost
Copy link

ghost commented Nov 19, 2019

Whenever someone adopts this PR and makes the necessary changes. I won't be doing it anytime soon, since there are more pressing issues.

@anotherboz
Copy link

I resolved conflicts, rebuild the angular-spiderfier plugin and published the new package under https://www.npmjs.com/package/agm-spiderfier

Now, I don't know if it's better to keep this package distinct or merge it in agm.

@CrackerakiUA
Copy link

404 Not Found: @agm/js-marker-spider@1.0.5 @anotherboz latest also not working. And if I install agm/js-marker-spider I see error from code: ERROR in src/app/common/Map/map/map.module.ts(10,39): error TS2307: Cannot find module 'agm/js-marker-spider'.

@albuquerquefabio
Copy link

I resolved conflicts, rebuild the angular-spiderfier plugin and published the new package under https://www.npmjs.com/package/agm-spiderfier

Now, I don't know if it's better to keep this package distinct or merge it in agm.

It work perfect!
But, your new version 1.0.6 is the correct one.

@CrackerakiUA
Copy link

CrackerakiUA commented May 7, 2020

I resolved conflicts, rebuild the angular-spiderfier plugin and published the new package under https://www.npmjs.com/package/agm-spiderfier
Now, I don't know if it's better to keep this package distinct or merge it in agm.

It work perfect!
But, your new version 1.0.6 is the correct one.

well, good point, it works under https://www.npmjs.com/package/agm-spiderfier1 with latest agm/core

@shahabas-cp-14
Copy link

I resolved conflicts, rebuild the angular-spiderfier plugin and published the new package under https://www.npmjs.com/package/agm-spiderfier
Now, I don't know if it's better to keep this package distinct or merge it in agm.

It work perfect!
But, your new version 1.0.6 is the correct one.

well, good point, it works under https://www.npmjs.com/package/agm-spiderfier1 with latest agm/core

but when I try to take the production build, I am getting the error : Module not found: Error: Can't resolve 'agm-spiderfier'

@albuquerquefabio
Copy link

albuquerquefabio commented May 20, 2020

I resolved conflicts, rebuild the angular-spiderfier plugin and published the new package under https://www.npmjs.com/package/agm-spiderfier
Now, I don't know if it's better to keep this package distinct or merge it in agm.

It work perfect!
But, your new version 1.0.6 is the correct one.

well, good point, it works under https://www.npmjs.com/package/agm-spiderfier1 with latest agm/core

but when I try to take the production build, I am getting the error : Module not found: Error: Can't resolve 'agm-spiderfier'

I had the same problem and to solve it follow this:

Install as dev Dependencies

npm i -D @type/jest@25.2.1

Install as Dependencies

npm i --save @agm/core@1.1.0 agm-spiderfier@1.0.0 agm-spiderfier1@1.0.6
npm i --save ts-overlapping-marker-spiderfier@1.0.2 agm-oms

At your tsconfig.app.json

{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "outDir": "./out-tsc/app",
    // Add  types jest
    "types": ["jest"]
  },
  "include": [
    "src/**/*.ts",
    // Add agm-spiderfier to be compiled
    "./node_modules/agm-spiderfier/**/*.ts"
  ],
  "exclude": ["src/test.ts", "src/**/*.spec.ts"]
}

@ghost
Copy link

ghost commented Jul 3, 2020

replaced by #1771

@ghost ghost closed this Jul 3, 2020
@crac7
Copy link

crac7 commented Apr 28, 2021

not work !

I resolved conflicts, rebuild the angular-spiderfier plugin and published the new package under https://www.npmjs.com/package/agm-spiderfier
Now, I don't know if it's better to keep this package distinct or merge it in agm.

It work perfect!
But, your new version 1.0.6 is the correct one.

well, good point, it works under https://www.npmjs.com/package/agm-spiderfier1 with latest agm/core

but when I try to take the production build, I am getting the error : Module not found: Error: Can't resolve 'agm-spiderfier'

I had the same problem and to solve it follow this:

Install as dev Dependencies

npm i -D @type/jest@25.2.1

Install as Dependencies

npm i --save @agm/core@1.1.0 agm-spiderfier@1.0.0 agm-spiderfier1@1.0.6
npm i --save ts-overlapping-marker-spiderfier@1.0.2 agm-oms

At your tsconfig.app.json

{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "outDir": "./out-tsc/app",
    // Add  types jest
    "types": ["jest"]
  },
  "include": [
    "src/**/*.ts",
    // Add agm-spiderfier to be compiled
    "./node_modules/agm-spiderfier/**/*.ts"
  ],
  "exclude": ["src/test.ts", "src/**/*.spec.ts"]
}

@ffuf-ralphnival
Copy link

turn clustering off at a certain zoom point using [maxZoom]="10"
I changed your code to as below code below

<agm-map (mapReady)="mapReady($event)">
    <agm-marker-cluster [maxZoom]="10" imagePath="https://raw.githubusercontent.com/googlemaps/v3-utility-library/master/markerclustererplus/images/m">
        <agm-marker-spider>
            <agm-marker *ngFor="let marker of markers" [latitude]="marker.lat" [longitude]="marker.lang">
                <agm-snazzy-info-window [closeWhenOthersOpen]="true">
                    <ng-template>
                        <div class="row pop-over-content">
                            ...
                        </div>
                    </ng-template>
                </agm-snazzy-info-window>
            </agm-marker>
        </agm-marker-spider>
    </agm-marker-cluster>
</agm-map>

Works a treat ! Thank you

With this nested approach of cluster > spider, is there a way that when cluster has clicked, then it will spiderfy after? Thanks

This pull request was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs: adopter a PR that was abandoned, and needs to be cleaned up before merge
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet