forked from sara-maria's block: Spinning globe with city markers
forked from anonymous's block: Spinning globe with city markers
forked from anonymous's block: Spinning globe with city markers
xxxxxxxxxx
<html>
<head>
<!-- Declare the character set of the document -->
<meta charset="UTF-8">
<!-- Support IE9-IE10 -->
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<!-- Set the viewport -->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- Javascripts -->
<script src="https://d3js.org/d3.v3.min.js"></script>
<style>
body {
overflow:visible;
background: #454545;
position: relative;
}
svg {
position: absolute;
left: 0;
top: 0;
}
.city {
fill: rgb(255, 255, 193);
stroke: rgb(142, 142, 21);
stroke-width: 0.4;
}
.highlight {
fill: rgb(205, 39, 235);
stroke: rgb(226, 47, 211);
}
</style>
<script type="text/javascript">
var margin = 0,
width = 800 - margin,
height = 500 - margin;
function draw(geo_data) {
var svg = d3.select("body").select("#content").select("svg")
.attr("width", width + margin)
.attr("height", height + margin);
/////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////
// DRAW GLOBE
// Based on: https://bl.ocks.org/PatrickStotz/1f19b3e4cb848100ffd7
/////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////
var earthcolor = d3.rgb("rgb(105, 113, 142)");
var countryfillcolor = d3.rgb("rgb(84, 139, 84)");
var countrystrokecolor = d3.rgb("rgb(25, 64, 224)");
var projection = d3.geo.orthographic()
.scale(200)
.translate([width / 2, height / 2])
.clipAngle(90)
//.precision(0.2);
var pathproj = d3.geo.path().projection(projection);
// drawing a sphere as landmass
var g = svg.append("g");
g.append("path")
.datum({type: "Sphere"})
.attr("class", "sphere")
.attr("d", pathproj)
.attr("fill", earthcolor);
// drawing the worldmap
var map = svg.append('g').selectAll('path')
.attr("class", "fill")
.data(geo_data.features)
.enter()
.append('path')
.attr('d', pathproj)
.style('fill', countryfillcolor) //country fill
.style('stroke', countrystrokecolor)
.style('stroke-width', .5)
.style('opacity',.8);
/////////////////////////////////////////////////////////////////////////////////
//draw, spin, and highlight the cities on the world
function plot_points(data) {
// Add city points to map!
// JSON object (instead of circles) for points allowed to be clipped at "backside" of earth:
svg.append('g')
.selectAll("path")
.data(data,function(d,i){ return d.id })
.enter()
.append("path")
.classed("city", true)
.datum(function(d) {
return {
type: "Point",
coordinates: [d.lon, d.lat],
class: "nohighlight" //My attempt at changing style through class..... not working....
}; })
.attr("d", pathproj);
// Control the radius of ALL circles!
pathproj.pointRadius(function(d,i) {
if (d.type =="Point") {
return d.class==="nohighlight" ? 4 : 20;
}
});
////////////////////////////////////////////////////////////////////////////////////////////////////
// Spinning the globe:
////////////////////////////////////////////////////////////////////////////////////////////////////
function spinning_globe(){
var time = Date.now();
var rotate = [0, 0];
var velocity = [.015, -0];
d3.timer(t => {
// get current time
var dt = Date.now() - time;
//Define new projection over a rotating path
projection.rotate([rotate[0] + velocity[0] * dt, rotate[1] + velocity[1] * dt]);
//Add new projection to the map
map.attr('d', pathproj)
// Spin city locations: Method with JSON path element - only requires this line:
svg.selectAll("path.city").attr("d", pathproj);
}); // end timer spinning globe
}; // end spinning globe
spinning_globe();
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
//// HIGHLIGHTING the cities one by one:
var city_idx = 0; //data.id starts at 1
//Every 300 msec: highlight a new city:
var city_play = setInterval(function() {
city_idx++;
// Control the radius of ALL circles!
pathproj.pointRadius(function(d,i) {
if (i < city_idx){
return 4
} else
return 2
});
// CHANGE CLASS?
// CHANGE RADIUS?
d3.selectAll(".city").attr("class", function(d, i){
if (i < city_idx){
return "city highlight"
} else
return "city"
}).attr("d", pathproj)
var len = d3.selectAll(".city").data().length;
console.log(city_idx, len)
//Stop when all cities are highlighted
if(city_idx>=len){
clearInterval(city_play) //terminates calls to update function within setInterval function.
};
}, 300); // end timer city play setInterval
}; // end plot_points function
////////////////////////////////////////////////////////////////////////////////////////////////////
// loading igem data
d3.csv("team_gps.csv", function(d) {
d['id'] = +d['id'];
d['lat'] = +d['lat'];
d['lon'] = +d['lon'];
return d;
}, plot_points);
}; // end of draw function
////////////////////////////////////////////////////////////////////////////////////////////////////
</script>
</head>
<body>
<div id="content">
<svg></svg>
</div>
<script type="text/javascript">
d3.json("world_countries.json", function(error, geo_data) {
draw(geo_data)
});
</script>
</body>
</html>
Modified http://d3js.org/d3.v3.min.js to a secure url
https://d3js.org/d3.v3.min.js