Vipul Sharma
Vipul Sharma

Reputation: 441

Google Map marker tooltip on all markers, TypeError: projection is undefined

cTooltip.prototype = new google.maps.OverlayView;

cTooltip.prototype.draw1 = function(pos, content, margin){
  var div = this.div_;
  div.style.cssText = 'z-index:9999;cursor:pointer;visibility:hidden;position:absolute;text-align:center;margin:'+margin;
  if(content){
    div.innerHTML = content;
  }
  if(pos){

    $(markers_sets).each(function () {
       if (this.id == per.markers_set) {
            m_settings = this.settings;
       }
    });

    var markersOffset = (typeof m_settings.markers_offset !== 'undefined' ? parseInt(m_settings.markers_offset) : 7);

    var width = $('.vipul_'+tooltipCount).outerWidth() / 2;
    pin_center = 56 - width;
    var projection = this.getProjection();
    var position = projection.fromLatLngToDivPixel(pos);
    div.style.left = (position.x - 64 + pin_center + markersOffset) + 'px';
    div.style.top = (position.y - 40) + 'px';
    div.style.visibility = 'visible';
  }

tooltipCount++;
}

When I call cTooltip on mousehover event, its working but when I call it directly inside loop, first tooltip can be seen but after second loop error is coming

div.onmouseover = function() {
      if (tool_tip_timeout != null) {
        clearTimeout(tool_tip_timeout);
        tool_tip_timeout = null;
      }
      if (display_tip && !this.hasClass('hideTooltip')) {
        var tool_tip_html ='';
        tool_tip_html += '<div class="maptive-bubble-blue vipul_'+tooltipCount+'">';
        tool_tip_html += '<div class="maptive-bubble-pin-container">';
        tool_tip_html += '<div class="maptive-bubble-text">' + getTooltip(pos) + '</div>';
        tool_tip_html += '<div class="maptive-bubble-pin"></div>';
        tool_tip_html += '</div>';
        tool_tip_html += '<div class="maptive-bubble-shadow"><img src="/ver4/images/bubble-shadow.png"></div>';
        tool_tip_html += '</div>';
        tool_tip_timeout = setTimeout(function() {
          //tooltip.draw1(new google.maps.LatLng(parseFloat(l[marker_lat_i]), parseFloat(l[marker_lng_i])), tool_tip_html, '-' + (parseInt(md.groups_top)) + 'px 0px 0px ' + Math.abs(parseInt(md.groups_left) - parseInt(md.groups_width) - 3) + 'px');
          tooltip.draw1(new google.maps.LatLng(parseFloat(l[marker_lat_i]), parseFloat(l[marker_lng_i])), tool_tip_html, '-' + (parseInt(md.groups_top) + 6) + 'px 0px 0px 0px');
        }, 500);
      }
      display_tip = false;
    };

Error is shown below, above written code inside mousehover event is working but I want to show all the tooltips on all marker after loading map instead of using mousehover event.

TypeError: projection is undefined

var position = projection.fromLatLngToDivPixel(pos);

Rest of the code

function cMarker(opt_options) {
  this.setValues(opt_options);
  var group = this.get('group');
  var unique_groups = this.get('unique_groups');
  var l = this.get('data');
  var descr = this.get('description');
  var pos = this.get('pos');
  var tooltip = this.tooltip = this.get('tooltip');
  this.r = pos;
  var div = this.div_ = document.createElement('div');
  var mb = parseInt(md.markers_top) + 40;




   div.onmouseover = function() {
      if (tip_content != "") {
        if (tool_tip_timeout != null) {
          clearTimeout(tool_tip_timeout);
          tool_tip_timeout = null;
        }
        if (display_tip && !this.hasClass('hideTooltip')) {
        var tool_tip_html ='';
        tool_tip_html += '<div class="maptive-bubble-blue vipul_'+tooltipCount+'">';
        tool_tip_html += '<div class="maptive-bubble-pin-container">';
        tool_tip_html += '<div class="maptive-bubble-text">' + tip_content + '</div>';
        tool_tip_html += '<div class="maptive-bubble-pin"></div>';
        tool_tip_html += '</div>';
        tool_tip_html += '<div class="maptive-bubble-shadow"><img src="/ver4/images/bubble-shadow.png"></div>';
        tool_tip_html += '</div>';
          tool_tip_timeout = setTimeout(function() {
            tooltip.draw(new google.maps.LatLng(parseFloat(l[marker_lat_i]), parseFloat(l[marker_lng_i])), tool_tip_html, '-' + (parseInt(md.markers_top) + 6) + 'px 0px 0px 0px');
          }, 500);
        }
        display_tip=false;
      }
    };
}

I want to draw tooltip on all markers, that why instead of mousehover I need to call it on load event or by simply by placing it outside that mousehover event but error is projection is undefined after displaying one tooltip.

Upvotes: 0

Views: 343

Answers (1)

Dr.Molle
Dr.Molle

Reputation: 117334

Don't call the draw-method on your own, it will be called automatically when:

  1. you add the overlay to the map
  2. the viewport of the map changes

The workflow when working with OverlayView is the following:

  1. call the constructor (cMarker in this case), in the constructor set the properties of the overlay(will be done via this.setValues(opt_options); in your code)
  2. when you set the map-property of the overlay(should be done inside the constructor, because you want to draw the overlays initially) , the API will automatically call the onAdd-method
  3. In the onAdd- method create the node (with the desired content and additionally added event-listeners) and add it to a MapPane
  4. the draw-method is called automatically(as I said initially after onAdd() or when the viewport changes). Use this method only to update the CSS-position(or additionally the CSS-size, when you want the size to be dependant on the map-zoom)

This workflow ensures that: 1. the mapPanes are ready when onAdd() will be called 2. the projection is available when draw() will be called

When you want to break out of this predefined execution-order listen to the panes_changed-event of the overlay, when it fires the panes and projection are available, you may add the overlay to the map

  google.maps.event.addListenerOnce(yourOverlayInstance,'panes_changed',
   function(){/*create node with content and events , 
                add it to a pane ,
                set position and optinally the size*/});

But this kind of custom implementation makes no sense, because the draw-method will be called automatically when the projection is available.

Upvotes: 1

Related Questions