This is the code for Chapter 11, Figure 6 from D3.js in Action showing mixed mode rendering where the country polygons are rendered in canvas and the triangles are rendered in SVG.
forked from emeeks bl.ock Ch. 11, Fig. 6 - D3.js in Action
license: CC0-1.0 |
This is the code for Chapter 11, Figure 6 from D3.js in Action showing mixed mode rendering where the country polygons are rendered in canvas and the triangles are rendered in SVG.
forked from emeeks bl.ock Ch. 11, Fig. 6 - D3.js in Action
<html> | |
<head> | |
<title>D3 in Action Chapter 11 - Example 4</title> | |
<meta charset="utf-8" /> | |
<script src="https://d3js.org/d3.v3.min.js" type="text/JavaScript"></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(95).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) | |
.on("zoomstart", zoomInitialized) | |
.on("zoomend", zoomFinished); | |
d3.select("svg").call(mapZoom); | |
var g = d3.select("svg").append("g") | |
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")}); | |
zoomFinished(); | |
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 = "pink"; | |
context.lineWidth = "1px"; | |
for (var x in countries.features) { | |
context.beginPath(); | |
canvasPath.context(context)(countries.features[x]); | |
context.stroke() | |
context.fill(); | |
} | |
context.strokeStyle = "black"; | |
context.fillStyle = "rgba(255,0,0,.5)"; | |
context.lineWidth = 1; | |
for (var x in sampleData) { | |
context.beginPath(); | |
canvasPath.context(context)(sampleData[x]); | |
context.stroke() | |
context.fill(); | |
} | |
} | |
function zoomInitialized() { | |
d3.selectAll("path.sample").style("display", "none"); | |
zoomed(); | |
} | |
function zoomFinished() { | |
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").style("display", "block").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> |