|
<!DOCTYPE html> |
|
<html> |
|
<head> |
|
<style> |
|
body { |
|
font-family: "Helvetica Neue", sans-serif; |
|
margin: 0; |
|
background: #3a403d; |
|
} |
|
</style> |
|
</head> |
|
<body> |
|
<script src="https://d3js.org/d3.v4.min.js"></script> |
|
<script src="https://d3js.org/topojson.v1.min.js"></script> |
|
<script> |
|
var width = window.innerWidth, height = window.innerHeight; |
|
|
|
var projection = d3.geoOrthographic() |
|
.scale(width / 4.1) |
|
.translate([width / 2, height / 2]) |
|
.clipAngle(90) |
|
.precision(1); |
|
|
|
var path = d3.geoPath() |
|
.projection(projection); |
|
|
|
var svg = d3.select("body").append("svg") |
|
.attr("width", width) |
|
.attr("height", height); |
|
|
|
var g = svg.append("g"); |
|
|
|
var graticule = d3.geoGraticule() |
|
.step([10, 10]); |
|
|
|
g.append("path") |
|
.datum(graticule) |
|
.attr("class", "graticule") |
|
.attr("d", path) |
|
.style("fill", "#fff") |
|
.style("stroke", "#ccc"); |
|
|
|
svg.append("rect") |
|
.attr("x", 40) |
|
.attr("y", 40) |
|
.attr("width", 20) |
|
.attr("height", height - 80) |
|
.attr("rx", 10) |
|
.attr("ry", 10) |
|
.style("stroke", "#ccc") |
|
.style("fill", "#fff"); |
|
|
|
var cScale = d3.scaleLinear() |
|
.domain([40, height - 40]) |
|
.range([0, 360]); |
|
|
|
var rScale = d3.scaleLinear() |
|
.domain([0, 360]) |
|
.range([40, height - 40]); |
|
|
|
svg.append("text") |
|
.attr("x", 50) |
|
.attr("y", 30) |
|
.attr("text-anchor", "middle") |
|
.style("fill", "#fff") |
|
.text("Clip Angle") |
|
|
|
svg.append("circle") |
|
.attr("class", "circle") |
|
.attr("cx", 50) |
|
.attr("cy", rScale(90)) |
|
.attr("r", 20) |
|
.style("stroke", "#aaa") |
|
.style("fill", "#ccc") |
|
.style("cursor", "ns-resize") |
|
.call(d3.drag() |
|
.on("drag", dragged) |
|
); |
|
|
|
svg.append("text") |
|
.attr("class", "circle-text") |
|
.attr("x", 50) |
|
.attr("y", rScale(90)) |
|
.attr("dy", 6) |
|
.attr("text-anchor", "middle") |
|
.style("cursor", "ns-resize") |
|
.text("90") |
|
.call(d3.drag() |
|
.on("drag", dragged) |
|
); |
|
|
|
function dragged(){ |
|
var y = d3.mouse(this)[1]; |
|
y < 40 ? y = 40 : y = y; |
|
y > height - 40 ? y = height - 40 : y = y; |
|
|
|
d3.select(".circle") |
|
.attr("cy", y); |
|
|
|
projection.clipAngle(cScale(y)); |
|
|
|
d3.select(".graticule") |
|
.attr("d", path); |
|
|
|
d3.select(".circle-text") |
|
.attr("y", y) |
|
.text(Math.round(cScale(y))); |
|
|
|
} |
|
|
|
d3.timer(function(elapsed) { |
|
|
|
projection.rotate([.05 * elapsed - 120, 0, 0]); |
|
g.selectAll("path").attr("d", path); |
|
|
|
}); |
|
|
|
var c = d3.scaleOrdinal(d3.schemeCategory20); |
|
|
|
d3.json("countries.json", function(error, data){ |
|
|
|
g.selectAll(".subunit") |
|
.data(topojson.feature(data, data.objects.polygons).features) |
|
.enter().append("path") |
|
.attr("class", "subunit") |
|
.attr("d", path) |
|
.style("stroke", "#fff") |
|
.style("stroke-width", "1px") |
|
.style("fill", function(d,i){ return c(i); }) |
|
.style("opacity", ".6"); |
|
|
|
}); |
|
</script> |
|
|
|
</body> |
|
</html> |