javascriptruby-on-railsgoogle-mapscoffeescriptgmaps4rails

How do I add cluster markers to Gmaps4rails?


I was able to add the marker cluster in this format inside of the index.html.erb file. When I decided to add infowindows that is when my map started to break.

<script type = "text/javascript">
    handler = Gmaps.build('Google',
    {markers:
      {clusterer: {
        gridSize: 60,
        maxZoom: 20,
        styles: [ {
          textSize: 10,
          textColor: '#ff0000',
          url: 'assets/creative/m1.png',
          height: 60,
          width: 60 }
        , {
          textSize: 14, 
          textColor: '#ffff00',
          url:'assets/creative/m2.png',
          height: 60,
          width: 60 }
        , {
         textSize: 18, 
         textColor: '#0000ff',
         url: 'assets/creative/m3.png',
         width: 60,
         height: 60}
        ]}}}
    );
        handler.buildMap({ provider: {}, internal: {id: 'map'}}, function(){
             markers = handler.addMarkers(<%=raw @hash.to_json %>);
            handler.bounds.extendWith(markers);
            handler.fitMapToBounds();

        });

When I add infowindows to my web app under my custom.js.coffee file as

class InfoBoxBuilder extends Gmaps.Google.Builders.Marker 

create_infowindow: ->
return null unless _.isString @args.infowindow

boxText = document.createElement("div")
boxText.setAttribute('class', 'panel panel-green') 
boxText.innerHTML = @args.infowindow
@infowindow = new InfoBox(@infobox(boxText))


infobox: (boxText)->
content: boxText
pixelOffset: new google.maps.Size(-140, 0)
boxStyle:
  width: "280px"

@buildMap = (markers)->
handler = Gmaps.build 'Google', { builders: { Marker: InfoBoxBuilder} 
} 
handler = Gmaps.build 'Google', { builders: { markers:
      {clusterer: {
        gridSize: 60,
        maxZoom: 20,
        styles: [ {
          textSize: 10,
          textColor: '#ff0000',
          url: 'assets/creative/m1.png',
          height: 60,
          width: 60 }
        , {
          textSize: 14, 
          textColor: '#ffff00',
          url:'assets/creative/m2.png',
          height: 60,
          width: 60 }
        , {
         textSize: 18, 
         textColor: '#0000ff',
         url: 'assets/creative/m3.png',
         width: 60,
         height: 60}
        ]}}} }  #dependency injection

  handler.buildMap { provider: {}, internal: {id: 'map'} }, ->
  markers = handler.addMarkers(markers)
  handler.bounds.extendWith(markers)
  handler.fitMapToBounds()

I get the marker cluster working but I lose the infowindow formatting. How do I inject the infowwindow and the marker cluster code into the custom.coffee.js file.


Solution

  • I finally figured it out. I first converted the infobox builder from coffeescript to plain old vanilla javascript and then after the first dependency injection I added the marker cluster dependency. I added the following code to the view.

        var InfoBoxBuilder, handler,
          extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
          hasProp = {}.hasOwnProperty;
    
        InfoBoxBuilder = (function(superClass) {
          extend(InfoBoxBuilder, superClass);
    
          function InfoBoxBuilder() {
            return InfoBoxBuilder.__super__.constructor.apply(this, arguments);
          }
    
          InfoBoxBuilder.prototype.create_infowindow = function() {
            var boxText;
            if (!_.isString(this.args.infowindow)) {
              return null;
            }
            boxText = document.createElement("div");
            boxText.setAttribute('class', 'panel panel-green');
            boxText.innerHTML = this.args.infowindow;
            return this.infowindow = new InfoBox(this.infobox(boxText));
          };
    
          InfoBoxBuilder.prototype.infobox = function(boxText) {
            return {
              content: boxText,
              pixelOffset: new google.maps.Size(-140, 0),
              boxStyle: {
                width: "280px"
              }
            };
          };
    
          return InfoBoxBuilder;
    
        })(Gmaps.Google.Builders.Marker);
    
            handler = Gmaps.build('Google', {
              builders: {
                Marker: InfoBoxBuilder
              },
               markers:
                      {clusterer: {
                        gridSize: 60,
                        maxZoom: 20,
                        styles: [ {
                          textSize: 10,
                          textColor: '#ff0000',
                          url: 'assets/creative/m1.png',
                          height: 60,
                          width: 60 }
                        , {
                          textSize: 14, 
                          textColor: '#ffff00',
                          url:'assets/creative/m2.png',
                          height: 60,
                          width: 60 }
                        , {
                         textSize: 18, 
                         textColor: '#0000ff',
                         url: 'assets/creative/m3.png',
                         width: 60,
                         height: 60}
                        ]}}
            });
            handler.buildMap({ provider: {}, internal: {id: 'map'}}, function(){
                             markers = handler.addMarkers(<%=raw @hash.to_json %>);
                            handler.bounds.extendWith(markers);
                            handler.fitMapToBounds();
    
                        });
    

    Now I can have both marker clusters and a custom infowindow for each of my locations.