block by emeeks 7a3c75a8cbb961341e0d

Ch. 11, Fig. 5 - D3.js in Action

Full Screen

This is the code for Chapter 11, Figure 5 from D3.js in Action showing mixed mode rendering where the country polygons are rendered in canvas and the triangles are rendered in SVG.

index.html

<html>
<head>
  <title>D3 in Action Chapter 11 - Example 3</title>
  <meta charset="utf-8" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
</head>
<style>
body, html {
    margin: 0;
  }
canvas {
  position: absolute;
  width: 500px;
  height: 500px;
}
svg {
  position: absolute;
  width:500px;
  height:500px;
}
path.country {
    fill: gray;
    stroke-width: 1;
    stroke: black;
    opacity: .5;
}
path.sample {
    stroke: black;
    stroke-width: 1px;
    fill: red;
    fill-opacity: .5;
}
line.link {
      stroke-width: 1px;
      stroke: black;
      stroke-opacity: .5;
}
circle.node {
  fill: red;
  stroke: white;
  stroke-width: 1px;
}
circle.xy {
  fill: pink;
  stroke: black;
  stroke-width: 1px;
}
</style>
<body>
<canvas height="500" width="500"></canvas>
<div id="viz">
  <svg></svg>
</div>
</body>
  <footer>
    
<script>
    sampleData = d3.range(2000).map(function(d) {
    var datapoint = {};
    datapoint.id = "Sample Feature " + d;
    datapoint.type = "Feature";
    datapoint.properties = {};
    datapoint.geometry = {};
    datapoint.geometry.type = "Polygon";
    datapoint.geometry.coordinates = randomCoords();
    return datapoint;
  })
  
  d3.json("world.geojson", function(data) {createMap(data)});

  function createMap(countries) {
    projection = d3.geo.mercator().scale(100).translate([250,250]);
    geoPath = d3.geo.path().projection(projection);
    canvasPath = d3.geo.path().projection(projection);

    mapZoom = d3.behavior.zoom().translate(projection.translate()).scale(projection.scale()).on("zoom", zoomed);
    d3.select("svg").call(mapZoom);

        var g = d3.select("svg")

    g.selectAll("path.sample").data(sampleData)
    .enter()
    .append("path")
    .attr("class", "sample")
    .style("stroke", "black")
    .style("stroke-width", "1px")
    .style("fill", "red")
    .style("fill-opacity", .5)
    .on("mouseover", function() {d3.select(this).style("fill", "pink")});


    zoomed();
    
    function zoomed() {
        projection.translate(mapZoom.translate()).scale(mapZoom.scale());

      	var context = d3.select("canvas").node().getContext("2d");
        context.clearRect(0,0,500,500);

	    context.strokeStyle = "black";
	    context.fillStyle = "gray";
	    context.lineWidth = "1px";
    	for (var x in countries.features) {
	    context.beginPath();
            canvasPath.context(context)(countries.features[x]);
		context.stroke()
		context.fill();
	}

      d3.selectAll("path.sample").attr("d", geoPath);


    }

  }
  
  function randomCoords() {
    var randX = (Math.random() * 350) - 175;
    var randY = (Math.random() * 170) - 85;
    return [[[randX - 5,randY],[randX,randY - 5],[randX - 10,randY - 5],[randX - 5,randY]]];
  }
</script>
  </footer>

</html>