hungerstar
hungerstar

Reputation: 21725

Changing Google Maps v3 MarkerClustererPlus Title

I am trying to dynamically set the cluster title, rollover text, of clustered icons. I want the cluster count/total to be used in the rollover text.

Through console.log I am able to see that the title has been changed to that set for var txt. It also works with alert( txt ). The default title for a cluster is "" and does not seem to be getting updated and stays at the default value.

Currently I am setting the title in google.maps.event.addListener( markerClusterer, 'mouseover', function( cluster ) {}).

I'm thinking that my code continues to execute and that might be the reason I don't see the change but I haven't been able to narrow it down.

var latlng = new google.maps.LatLng( lat, lng );

        var qs      = location.search;          
        var options = {
            zoom: 17,
            center: latlng,
            mapTypeId: google.maps.MapTypeId.ROADMAP,
            mapTypeControlOptions: { 
                style: google.maps.MapTypeControlStyle.DROPDOWN_MENU 
            }
        };

        map = new google.maps.Map( mapId[0], options );

        google.maps.event.addListener( map, 'idle', function() {

            var bounds = map.getBounds();

            downloadXML( ABSPATH + 'xml/maps/markers.php' + qs + '&bounds=' + bounds, function( data ) {

                var xml     = parseXml( data );
                var markers = xml.documentElement.getElementsByTagName( "marker" );
                var markerArray = [];

                for ( var i = 0; i < markers.length; i++ ) {

                    var attributes = getMarkerAttributes( markers[i] );
                    var marker     = createMarker( attributes );

                    // Add marker to marker array
                    markerArray.push(marker);

                }

                // Define the marker clusterer
                var clusterOptions = { 
                    zoomOnClick: false,
                    gridSize: 1
                }

                var markerClusterer = new MarkerClusterer( map, markerArray, clusterOptions );

                // Listen for a cluster to be clicked
                google.maps.event.addListener( markerClusterer, 'clusterclick', function( cluster ) {
                    combineInfoWindows( cluster );              
                });

                // Listen for a cluster to be hovered and set title
                google.maps.event.addListener( markerClusterer, 'mouseover', function( cluster ) {
                    var txt = 'There are ' + cluster.getSize() + ' properties at this location.';
                    //alert( txt );
                    console.log( cluster );
                    markerClusterer.setTitle( txt );
                });

            }); // downloadXML

        }); // google.maps.event.addListener( map, 'idle', ... )

Any help would be greatly appreciated. Thanks!

EDIT: 1

I have a solution based on the suggested solution by Rick.

I have modified the onAdd method.

/**
 * Adds the icon to the DOM.
 */
ClusterIcon.prototype.onAdd = function () {
  var cClusterIcon = this;

// MY CHANGES - START
this.cluster_.markerClusterer_.title_ = 'There are ' + this.cluster_.getSize() + ' properties at this location.';
// MY CHANGES - END

  this.div_ = document.createElement("div");
  if (this.visible_) {
    this.show();
  }

...

};

EDIT: 2 - FINAL SOLUTION

Moved changes to show method versus previous onAdd method as Rick had suggested. Change is made in a file outside of the original source file for MarkerClustererPlus.

/**
 * Positions and shows the icon.
 */
ClusterIcon.prototype.show = function () {
  if (this.div_) {
    var pos = this.getPosFromLatLng_(this.center_);
    this.div_.style.cssText = this.createCss(pos);
    if (this.cluster_.printable_) {
     // (Would like to use "width: inherit;" below, but doesn't work with MSIE)
     this.div_.innerHTML = "<img src='" + this.url_ + "'><div style='position: absolute; top: 0px; left: 0px; width: " + this.width_ + "px;'>" + this.sums_.text + "</div>";
    } else {
     this.div_.innerHTML = this.sums_.text;
    }
    //this.div_.title = this.cluster_.getMarkerClusterer().getTitle();
    // MY SOLUTION BELOW
    this.div_.title = 'There are ' + this.cluster_.getSize() + ' properties at this location.';
    this.div_.style.display = "";
  }
  this.visible_ = true;
};

Upvotes: 1

Views: 4361

Answers (3)

Clayton Leis
Clayton Leis

Reputation: 1298

I know this is an old question, but it ranked high on Google for my search. Anyway, here is what I did thanks to tips from this page:

google.maps.event.addListener(markerCluster, 'mouseover', function (c) {
    if(c.clusterIcon_.div_){
        c.clusterIcon_.div_.title =  c.getSize() + ' businesses in this area';
    }
});

I can't guarantee it will be compatible with future versions of MarkerClusterer Plus since I'm using "private" properties clusterIcon_ and div_.

Upvotes: 1

Sean Mickey
Sean Mickey

Reputation: 7716

Your problem is that you are trying to assign the mouseover event listener (where you set the title) to a MarkerClusterer, but to define a mouseover listener, you have to pass a Cluster.

There is a MarkerClusterer.getClusters() function that will return an Array of the Cluster instances. You want to loop over that Array and pass an instance of Cluster to your mouseover event listeners. If you check the reference doc and scroll down to the MarkerClusterer Events section of the doc, the row for mouseover defines the Argument to be:

c:Cluster

Which is in contrast to events like clusteringbegin and clusteringend, which define the Argument to be:

mc:MarkerClusterer

Having said all that, I'm not sure there is an easy way to set the title for each Cluster. That class does not have a setTitle function. The setTitle on the MarkerClusterer just applies the title to all of the Cluster instances. And I've double checked in JavaScript; there is no setTitle function on the Cluster class. Your best option right now seems to be to dynamically create the content you want to display within the mouseover handler for each Cluster. You could create an InfoBox and then close it on a Cluster mouseoet event. Not the simplest solution ever, but it will get you where you want to be.

Upvotes: 1

Rick
Rick

Reputation: 1573

Are you using this for clustering markers? Did you extend it to make your own setTitle function? If not, You'll have to make your own label. It's not actually a marker per se.

Edit: Didn't know this existed.

The cluster icons just pull the title from the MCOptions. I don't see where ClusterIcon or Cluster has a setTitle function, so I'd think the best bet would be overriding the ClusterIcon show prototype yourself and setting it there.

> ClusterIcon.prototype.show =
> function () {   if (this.div_) {
>     var pos = this.getPosFromLatLng_(this.center_);
>     this.div_.style.cssText = this.createCss(pos);
>     if (this.cluster_.printable_) {
>       // (Would like to use "width: inherit;" below, but doesn't work with MSIE)
>       this.div_.innerHTML = "<img src='" + this.url_ + "'><div style='position: absolute; top: 0px; left: 0px; width: " + this.width_
> + "px;'>" + this.sums_.text + "</div>";
>     } else {
>       this.div_.innerHTML = this.sums_.text;
>     }
>     this.div_.title = **** Your stuff here ***
>     this.div_.style.display = "";   }   this.visible_ = true; };

Upvotes: 2

Related Questions