block by mhkeller 5963329

D3 + Leaflet.js making div markers from GeoJSON

Full Screen

This is a work in progress. Based off of the polygon svg example here: http://bost.ocks.org/mike/leaflet/

Built to find a way around the difficulty in manipulating markers in leaflet / adding arbitrary html / classes / ids etc. to better time them to some time of user-driven narrative (buttons, scrolling etc.)

index.html

<!DOCTYPE html>
<html>
<head>
  <title>Leaflet + D3 Example</title>
	 <link rel="stylesheet" href="//cdn.leafletjs.com/leaflet-0.5/leaflet.css" />
	 <!--[if lte IE 8]>
	     <link rel="stylesheet" href="//cdn.leafletjs.com/leaflet-0.5/leaflet.ie.css" />
	 <![endif]-->
	  <script src="//cdn.leafletjs.com/leaflet-0.5/leaflet.js"></script>
	  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
	  <script src="//d3js.org/d3.v3.min.js" charset="utf-8"></script>
	  <style>
	  	#map{
	  		position:absolute;
	  		top: 0;
	  		right: 0;
	  		bottom: 0;
	  		left: 0;
	  	}

			path {
			  fill: #fc0;
			  fill-opacity: 1;
			  stroke: #fff;
			  stroke-width: 1.5px;
			}

			path:hover {
			  fill: #0cf;
			  fill-opacity: .7;
			  cursor:pointer;
			  cursor:hand;
			}
			#canvas-container{
				position: relative;
			}
			.canvas-leaflet-zoom-hide{
				position:relative;
			}
			.canvas-point-item{
				position:absolute;
				width:10px;
				height:10px;
				margin-left:-5px;
				margin-top:-5px;
				border-radius: 50%;
				background-color: #0cf;
				border:1px solid #008fb3;
				opacity:.5;
			}
			.canvas-point-item:hover{
				background-color: #fc0;
				z-index:999999;
				cursor:pointer;
				cursor:hand;
				opacity:1;
			}	  

			</style>
</head>
<body>

	<div id="map"></div>

	<script>
	(function(){
		var map = new L.Map("map", {
      center: [37.8, -96.9],
      zoom: 4
    })
    .addLayer(new L.TileLayer("//{s}.tile.cloudmade.com/8a7a90ea33a44b48b13f84411e0b2190/90873/256/{z}/{x}/{y}.png"));


		var canvas_container = d3.select(map.getPanes().overlayPane).append("div").attr("id","canvas-container"),
		    leaflet_zoom_hide = canvas_container.append("div").attr("class", "canvas-leaflet-zoom-hide");

		d3.json("us_hospitals.json", function(collection) {
		  var bounds = d3.geo.bounds(collection),
		      path = d3.geo.path().projection(project);


		  var feature = leaflet_zoom_hide.selectAll("div")
		      .data(collection.features)
		    .enter()
		    	.append("div")
		    	.attr("class","canvas-point-item");

		  map.on("zoomstart", hideOverlay);
		  map.on("zoomend", setOverlayContainerPosition);

		  setOverlayContainerPosition();

		  function hideOverlay(){
		    leaflet_zoom_hide
		    	.style('visibility','hidden');
		  }
		  function showOverlay(){
		    leaflet_zoom_hide
		    	.style('visibility','visible');
		    	// .style("transform", "translate(-" + bottomLeft[0] + "px,-" + topRight[1] + "px)");
		  }
		  // Reposition the container to cover the features.
		  function setOverlayContainerPosition() {
		    var bottomLeft = project(bounds[0]),
		        topRight = project(bounds[1]);

		    canvas_container
		    	.style("width", topRight[0] - bottomLeft[0] + 'px')
		    	.style("height", bottomLeft[1] - topRight[1] + 'px');
					// .style("left", bottomLeft[0] + "px")
					// .style("top", topRight[1] + "px");

				showOverlay()

		    feature
		    	.style("top", function(d){ return (project(d.geometry.coordinates)[1] +'px') })
		    	.style("left", function(d){ return (project(d.geometry.coordinates)[0] +'px') })

		  }

		  // Use Leaflet to implement a D3 geographic projection.
		  function project(x) {
		    var point = map.latLngToLayerPoint(new L.LatLng(x[1], x[0]));
		    return [point.x, point.y];
		  }
		})
	}).call(this);
	</script>
</body>
</html>