Skip welcome & menu and move to editor
Welcome to JS Bin
Load cached copy from
 
<!DOCTYPE html>
<meta charset="utf-8">
<body>
  <script src="http://d3js.org/d3.v3.min.js"></script>
  <script src="http://d3js.org/topojson.v1.min.js"></script>
  <!-- I recommend you host this file on your own, since this will change without warning -->
  <script src="http://datamaps.github.io/scripts/datamaps.world.min.js?v=1"></script>
  <h2>Datamaps Playground, Custom Markers Plugins</h2>
  <p><a href="http://datamaps.github.io/">DataMaps Project Homepage</a></p>
  <p> <button id="set">Set Markers</button> <button id="clear">Clear Markers</button> </p>
  <div id="container1" style="position: relative; width: 80%; max-height: 450px;"></div>
 
     
     <script>
       //basic map config with custom fills, mercator projection
      var map = new Datamap({
        scope: 'world',
        element: document.getElementById('container1'),
        projection: 'mercator',
        height: 500
      })
      
      
      /*******
      
      Marker Custom Plugin Code
      
      ********/
       
  function handleMarkers (layer, data, options ) {
    var self = this,
        fillData = this.options.fills,
        svg = this.svg;
    if ( !data || (data && !data.slice) ) {
      throw "Datamaps Error - markers must be an array";
    }
    var markers = layer.selectAll('image.datamaps-marker').data( data, JSON.stringify );
    markers
      .enter()
        .append('image')
        .attr('class', 'datamaps-marker')
        .attr('xlink:href', function( datum ) {
          return datum.iconUrl || options.defaultIcon;
        })
        .attr('height', 20)
        .attr('width', 20)
        .attr('x', function ( datum ) {
          var latLng;
          if ( datumHasCoords(datum) ) {
            latLng = self.latLngToXY(datum.latitude, datum.longitude);
          }
          else if ( datum.centered ) {
            latLng = self.path.centroid(svg.select('path.' + datum.centered).data()[0]);
          }
          if ( latLng ) return latLng[0] - 10;
        })
        .attr('y', function ( datum ) {
          var latLng;
          if ( datumHasCoords(datum) ) {
            latLng = self.latLngToXY(datum.latitude, datum.longitude);
          }
          else if ( datum.centered ) {
            latLng = self.path.centroid(svg.select('path.' + datum.centered).data()[0]);
          }
          if ( latLng ) return latLng[1] - 20;
        })
   
    markers.exit()
      .transition()
        .attr("height", 0)
        .remove();
    function datumHasCoords (datum) {
      return typeof datum !== 'undefined' && typeof datum.latitude !== 'undefined' && typeof datum.longitude !== 'undefined';
    }
}
       
      /*******
      End Marker Custom Plugin Code
      ********/
       
       
     /********
     Add & Register Plugin
     *********/
       
     map.addPlugin('markers', handleMarkers)
     /*******
     Zoom behavior
     ********/
     // Keep a reference to the d3 zoom behavior
     var zoom = d3.behavior.zoom();
     var currentZoom = null;
     
     // Reset d3.event.translate and d3.event.scale
     function resetZoom() {
       zoom.scale(1);
       zoom.translate([0, 0]);
     }
     var zoomInOpts = {
       scaleFactor: 2,
       center: {
         lat: 45,
         lng: -90
       },
       transition: {
         duration: 1000
       },
       onZoomComplete: function(zoomData) {
         currentZoom = zoomData;
         resetZoom();
       }
     };
     var zoomOutOpts = {
       scaleFactor: 0.5,
       center: {
         lat: 40,
         lng: -90
       },
       transition: {
         duration: 1000
       },
       onZoomComplete: function(zoomData) {
         currentZoom = zoomData;
         resetZoom();
       }
     };
     
     function transformStr(x, y, scale) {
       //var translateX = d3.event.translate[0];
       //var translateY = d3.event.translate[1];
       //var scale = d3.event.scale;
       return "translate(" + [x, y] + ")scale(" + scale + ")";
     }
     function redraw() {
       var translateX = d3.event.translate[0];
       var translateY = d3.event.translate[1];
       var scale = d3.event.scale;
       console.log("Scale: "+ d3.event.scale);
       
       if (currentZoom) {
        console.log("CurrentZoom.scale: "+ currentZoom.scale);  
         scale *= currentZoom.scale;
         translateX += currentZoom.translate.x
         translateY += currentZoom.translate.y;
       }
       
       map.svg.selectAll("g")
         .attr("transform", transformStr(translateX, translateY, scale))
       ;
       // fix the pin scale when zooming.
       map.svg.selectAll("image")
         // Various options I've tried
         //.attr("transform", transformStr(translateX+8-(8*scale), translateY+14-(14*scale), scale))
        //.attr("transform", transformStr(translateX+(scale), translateY+(scale*scale), scale))
         //.attr("transform", transformStr(translateX-(.5*scale), translateY-(scale), scale))
         //.attr("transform", transformStr(translateX, translateY, scale))
         //.attr("transform", transformStr(0, 0, scale))
        .attr("height", 20*(1/scale))
        .attr("width", 20*(1/scale))
       ;
     }
     
     // on mousewhel
     map.svg.call(zoom.on("zoom", redraw)); 
     
     /*******
     Call Plugin and setup some button handlers
     ********/
             
     function setMarkers() {
       map.markers([
         {name: 'Austin, TX', iconUrl: 'http://simpleicon.com/wp-content/uploads/map-marker-1.svg', latitude: 30.2, longitude: -97.7, fillKey: 'gt50'},
         {name: 'Iceland', iconUrl: 'http://simpleicon.com/wp-content/uploads/map-marker-1.svg', latitude: 64.1333932, longitude: -21.92, fillKey: 'lt50'},
         {name: 'Brazil', centered: 'BRA', fillKey: 'gt50'},
         {name: 'Hot again', latitude: 10, longitude: 0, fillKey: 'gt50'}
         ], 
         {defaultIcon: 'https://cdn0.iconfinder.com/data/icons/small-n-flat/24/678111-map-marker-128.png'},
         {
           popupTemplate: function(geo, data){
             return "<div class='hoverinfo'>Popup for " + data.name + "</div>";
           }
         }           
       );
     }
       
       
       d3.select('#clear').on('click', function() {
         map.markers([]);
       })
       
       d3.select('#set').on('click', setMarkers);
        
       setMarkers();
     </script>
</body>
Output

You can jump to the latest bin by adding /latest to your URL

Dismiss x
public
Bin info
nrpieperpro
0viewers