;(function(w, d3, undefined){ "use strict"; var width, height; function getSize(){ width = w.innerWidth/2, height = w.innerHeight/1.5; 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]); var scale0 = projection.scale(); var path = d3.geo.path() .projection(projection) .pointRadius(2); //Setup zoom behavior zoom = d3.behavior.zoom(true) .scale(projection.scale()) .scaleExtent([100, 800]) .on("zoom", move); var circle = d3.geo.circle(); var svg = viewport .call(zoom) .on("dblclick.zoom", null); //Create a list of random stars and add them to outerspace var starList = createStars(300); 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); var defs1 = svg.append("defs") var linear1 = defs1.append("linearGradient") .attr("id", "gradBlue") .attr("x1", "0%") .attr("y1", "0%") .attr("x2", "100%") .attr("y2", "0%") linear1.append("stop").attr("offset", "0%").attr("style", "stop-color:#005C99;stop-opacity:1") linear1.append("stop").attr("offset", "100%").attr("style", "stop-color:#0099FF;stop-opacity:1") //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 g = svg.append("g"), features; //Add all of the countries to the globe d3.json("world-countries.json", function(collection) { VisDock.startChrome(); features = g.selectAll(".feature").data(collection.features); var id = 0; features.enter().append("path") .attr("class", "feature") .attr("id", function(){ return "f" + id++}) .attr("d", function(d){ return path(circle.clip(d)); }); VisDock.finishChrome(); }); //Redraw all items with new projections function redraw(){ features.attr("d", function(d){ return path(circle.clip(d)); }); stars.attr("d", function(d){ spacePath.pointRadius(d.properties.radius); return spacePath(d); }); } function move() { if(d3.event){ VisDock.startChrome(); 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); 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(); AnnotatedByData.update(); VisDock.finishChrome(); } } 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(); d3.timer(function(){ VisDock.startChrome(); if (viewport.attr("pointer-events") == "visiblePainted" || viewport.attr("pointer-events") == null){ viewport.call(zoom) } else { Panel.panel.selectAll("*").on("mousedown.zoom", null) Panel.panel.selectAll("*").on("mousewheel.zoom", null) } var layers = d3.selectAll(".VisDockPathLayer")[0]; for (var i = 0; i < layers.length; i++){ var id = parseInt(layers[i].getAttributeNS(null, "id").split("_f")[1]) var d = d3.selectAll("#f" + id.toString()).attr("d") layers[i].setAttributeNS(null, "d", d) } VisDock.finishChrome(); }) }(window, d3));