$.getJSON(
"https://spreadsheets.google.com/feeds/list/1p0NKYGkH2MHcqzd7olnTbmLEexZ8-Uz7pTaK--1mPvI/1/public/values?alt=json",
function(data) {
// process google sheet into geojson
var devGeojson = {
type: 'FeatureCollection',
features: []
};
var devs = data.feed.entry;
for (var i in devs) {
if (devs[i].gsx$latitude.$t) {
var feature = {
type: 'Feature',
properties: {
title: '
' + devs[i].gsx$name.$t + '
',
'marker-color': '#227FBB',
'marker-size': 'large',
'marker-symbol': 'rocket',
url: 'https://gisdevs.slack.com/team/' + devs[i].gsx$name.$t
},
geometry: {
type: 'Point',
coordinates: [devs[i].gsx$longitude.$t, devs[i].gsx$latitude.$t]
}
};
devGeojson.features.push(feature);
}
}
(function(w, d3, undefined) {
"use strict";
var width, height;
function getSize() {
width = w.innerWidth,
height = w.innerHeight;
if (width === 0 || height === 0) {
setTimeout(function() {
getSize();
}, 100);
} else {
init();
}
}
function init() {
//Setup path for outerspace
var space = d3.geo.azimuthal()
.mode("equidistant")
.translate([width/2, height/2]);
space
.scale(space.scale() * 3);
var spacePath = d3.geo.path()
.projection(space)
.pointRadius(1);
//Setup path for globe
var projection = d3.geo.azimuthal()
.mode("orthographic")
.translate([width/2, height/2])
.scale(300)
.origin([-30,40])
var scale0 = projection.scale();
var path = d3.geo.path()
.projection(projection)
.pointRadius(2);
//Setup path for devs
var devPath = d3.geo.path()
.projection(projection)
.pointRadius(6);
//Setup zoom behavior
var zoom = d3.behavior
.zoom(true)
.translate(projection.origin())
.scale(projection.scale())
.scaleExtent([200, 800])
.on("zoom", move);
var circle = d3.geo.greatCircle()
.origin([-30,40]);
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.call(zoom)
.on("dblclick.zoom", null);
//Create a list of random stars and add them to outerspace
var starList = createStars(1000);
var stars = svg.append("g")
.selectAll("g")
.data(starList)
.enter()
.append("path")
.attr("class", "star")
.attr("d", function(d) {
spacePath.pointRadius(d.properties.radius);
return spacePath(d);
});
svg.append("rect")
.attr("class", "frame")
.attr("width", width)
.attr("height", height);
//Create the base globe
var backgroundCircle = svg.append("circle")
.attr('cx', width / 2)
.attr('cy', height / 2)
.attr('r', projection.scale())
.attr('class', 'globe')
.attr("filter", "url(#glow)")
.attr("fill", "url(#gradBlue)");
var countryG = svg.append("g"),
devG = svg.append("g"),
globeFeatures,
devFeatures;
//Add all of the countries to the globe
d3.json("world-countries.json", function(collection) {
globeFeatures = countryG.selectAll(".feature")
.data(collection.features);
globeFeatures.enter().append("path")
.attr("class", "feature")
.attr("d", function(d) {
return path(circle.clip(d));
});
});
// add dev points to the globe
//console.log(devGeojson.features);
devFeatures = devG.selectAll(".dev")
.data(devGeojson.features);
devFeatures.enter()
.append("path")
.attr("class", "dev")
.attr("d", function(d) {
return devPath(circle.clip(d));
});
//Redraw all items with new projections
function redraw() {
globeFeatures.attr("d", function(d) {
return path(circle.clip(d));
});
devFeatures.attr("d", function(d) {
return devPath(circle.clip(d));
});
stars.attr("d", function(d) {
spacePath.pointRadius(d.properties.radius);
return spacePath(d);
});
}
function move() {
if (d3.event) {
var scale = d3.event.scale;
var origin = [d3.event.translate[0] * -1, d3.event.translate[1]];
projection.scale(scale);
space.scale(scale * 3);
backgroundCircle.attr('r', scale);
path.pointRadius(2 * scale / scale0);
devPath.pointRadius(6 * scale / scale0);
projection.origin(origin);
circle.origin(origin);
//globe and stars spin in the opposite direction because of the projection mode
var spaceOrigin = [origin[0] * -1, origin[1] * -1];
space.origin(spaceOrigin);
redraw();
}
}
function createStars(number) {
var data = [];
for (var i = 0; i < number; i++) {
data.push({
geometry: {
type: 'Point',
coordinates: randomLonLat()
},
type: 'Feature',
properties: {
radius: Math.random() * 1.5
}
});
}
return data;
}
function randomLonLat() {
return [Math.random() * 360 - 180, Math.random() * 180 - 90];
}
}
getSize();
}(window, d3));
});