window.onload = function () { console.log("hello") init() } function init () { var radiusOfEarth = 6371 var w = 500 var h = 500 var islands = []; var regions; var expLayer; var tooltip = document.getElementById("tooltip") var projection = d3.geo.orthographic() .center([-4, 55.7]) .translate([w/2,h/5]) .clipAngle(90) .rotate([-110,0]) .scale([w/2.5]); var path = d3.geo.path() .projection(projection); var svg = d3.select("#vis") .append("svg") .attr("width", w) .attr("height", h); var t = textures.paths() .d("caps") .lighter() .thicker() .stroke("hsla(64, 77%, 30%, 1)") .background("hsla(64, 77%, 30%, 0.3)"); svg.call(t); svg.append("defs").append("path") .datum({type: "Sphere"}) .attr("id", "sphere") .attr("d", path); svg.append("use") .attr("class", "stroke") .attr("fill", "#eeeeee") .attr("xlink:href", "#sphere"); d3.json("countries-topo.json", function(json) { console.log(json) var countries = topojson.mesh(json, json.objects.countries, function (a, b) { return a !== b }) console.log(countries) regions = svg.append("path") //.datum(countries) .datum(topojson.feature(json, json.objects.countries)) .attr("class", "regions") .attr("d", path) .attr("stroke", "#eee") .attr("fill", function (d) { return "#ccc" }) /*regions = svg.selectAll(".regions") .datum(countries) .enter() .append("path") .attr("class", "regions") .attr("d", path) .attr("stroke", "#eee") .attr("fill", function (d) { return "#ccc" })*/ d3.csv("biomedata.csv", function(data) { for (var i = 0; i < data.length; i++) { var island = new Object(); island.type = "Feature" island.properties = new Object() island.properties.biome = data[i].biome island.properties.radius = data[i].radius island.properties.type = data[i].type island.properties.kmsq = data[i].kmsq island.geometry = new Object() island.geometry.type = "Polygon" island.geometry.coordinates = [] var circle = createCircleCoords(30, +data[i].radius, radiusOfEarth, [data[i].lat, data[i].lon]) island.geometry.coordinates.push(circle) islands.push(island) } islands.sort(function(a, b){return d3.descending(+a.properties.radius, +b.properties.radius);}) expLayer = svg.selectAll(".islands") .data(islands) .enter() .append("path") .attr("class", "islands") .attr("d", path) .attr("stroke", function (d) { if (d.properties.type === "absence") { return "hsla(0, 100%, 50%, 1)" } else { return "hsla(64, 77%, 30%, 1)" } }) .attr("stroke-dasharray", function (d) { if (d.properties.type === "absence") { return (3,3) } else { return (0) } }) .attr("stroke-width", function (d) { if (d.properties.type === "absence") { return 2 } else { return 2 } }) .attr("fill", function (d) { if (d.properties.type === "absence") { return "hsla(0, 100%, 50%, 0.3)" } else { return t.url() } }) .on("mouseover", function(d) { var p1 = "
"+d.properties.biome+"
" var p2 = ""+addCommas(d.properties.kmsq)+" km2
" tooltip.innerHTML = p1+p2; }) .on("mouseout", function(d) { tooltip.innerHTML = "" }); }) }) var dragData = { start: { x: 0, y: 0 }, move: { x: 0, y: 0 }, rotate: { x: -110, y: 0 } } var vis = document.getElementById("vis") vis.addEventListener("mousedown", function (e) { dragData.start.x = e.clientX dragData.start.y = e.clientY vis.addEventListener("mousemove", mousemoveHandler) }) vis.addEventListener("mouseup", function (e) { vis.removeEventListener("mousemove", mousemoveHandler) dragData.move.x = 0; dragData.rotate.x = projection.rotate()[0] dragData.move.y = 0; dragData.rotate.y = projection.rotate()[1] }) function mousemoveHandler (e) { dragData.move.x = e.clientX-dragData.start.x dragData.move.y = e.clientY-dragData.start.y projection.rotate([dragData.rotate.x+dragData.move.x/2, dragData.rotate.y-dragData.move.y/2, 0]) path.projection(projection) regions .transition() .duration(0) .attr("d", path) expLayer .transition() .duration(0) .attr("d", path) } /*var interval = setInterval(function () { projection.rotate([projection.rotate()[0]+1, 0, 0]) path.projection(projection) regions .transition() .duration(0) .attr("d", path) expLayer .transition() .duration(0) .attr("d", path) }, 100) */ } function createCircleCoords (numOfPoints, radiusOfCircle, radiusOfSphere, centreLatLon) { var degrees = 0 var degreesIncrement = 360/(numOfPoints-1) var coordinates = [] for (var i = 0; i < numOfPoints; i++){ var coordinate = createCoordinate(degToRad(centreLatLon[0]), degToRad(centreLatLon[1]), degToRad(degrees), radiusOfCircle, radiusOfSphere) coordinates.push(coordinate) degrees += degreesIncrement degrees = degrees%360 } return coordinates; function createCoordinate (lat1, lon1, bearing, d, R) { var lat2 = Math.asin(Math.sin(lat1)*Math.cos(d/R) + Math.cos(lat1)* Math.sin(d/R)*Math.cos(bearing)) var lon2 = lon1 + Math.atan2(Math.sin(bearing)*Math.sin(d/R)*Math.cos(lat1), Math.cos(d/R)-Math.sin(lat1)*Math.sin(lat2)) //console.log(radToDeg(lat2), radToDeg(lon2)) return [radToDeg(lon2), radToDeg(lat2)] } } function degToRad (deg) { var rad = (deg*Math.PI)/180 return rad } function radToDeg (rad) { var deg = (rad*180)/Math.PI return deg } function addCommas (nStr) { nStr += ''; var x = nStr.split('.'); var x1 = x[0]; var x2 = x.length > 1 ? '.' + x[1] : ''; var rgx = /(\d+)(\d{3})/; while (rgx.test(x1)) { x1 = x1.replace(rgx, '$1' + ',' + '$2'); } return x1 + x2; }