Add earthquake example
This commit is contained in:
parent
48c93f4853
commit
b06c3779dc
@ -64,7 +64,7 @@ a.ui.icon.header {
|
||||
}
|
||||
}
|
||||
|
||||
canvas {
|
||||
canvas#homepage-globe-canvas {
|
||||
width: 350px;
|
||||
height: 350px;
|
||||
}
|
||||
@ -153,3 +153,9 @@ pre {
|
||||
font-size: 14px;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.ui.items.examples {
|
||||
a.item {
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
19
site/public/examples/_layout.ejs
Normal file
19
site/public/examples/_layout.ejs
Normal file
@ -0,0 +1,19 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<%- partial("../_header") %>
|
||||
<link href="/css/prism.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<%- partial("../_menu") %>
|
||||
|
||||
<div class='content container'>
|
||||
<div class='page ui slim stackable grid'>
|
||||
<div class='sixteen wide column'>
|
||||
<%- yield %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type='text/javascript' src='/js/prism.js'></script>
|
||||
</body>
|
||||
</html>
|
||||
41
site/public/examples/index.ejs
Normal file
41
site/public/examples/index.ejs
Normal file
@ -0,0 +1,41 @@
|
||||
<h1>Examples</h1>
|
||||
|
||||
<p>Sometimes you just need to see some code to get an idea started; here are a few examples of what you can build with Planetary.js.</p>
|
||||
|
||||
<div class='ui four connected items examples'>
|
||||
<div class='row'>
|
||||
<a class='item' href='/examples/basic.html'>
|
||||
<div class='content'>
|
||||
<div class='name'>Basic Globe</div>
|
||||
<p class='description'>It doesn't get any simpler than this:
|
||||
just a static globe.</p>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<a class='item' href='/examples/rotating.html'>
|
||||
<div class='content'>
|
||||
<div class='name'>Rotating Globe</div>
|
||||
<p class='description'>If there's one thing that's better than
|
||||
a globe, it's a globe that rotates. This is the demo from the
|
||||
homepage of Planetaryjs.com.</p>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<!-- <a class='item' href='/examples/mouse.html'> -->
|
||||
<!-- <div class='content'> -->
|
||||
<!-- <div class='name'>Mouse Interaction</div> -->
|
||||
<!-- <p class='description'>See how to use the mouse to rotate -->
|
||||
<!-- and zoom the globe.</p> -->
|
||||
<!-- </div> -->
|
||||
<!-- </a> -->
|
||||
|
||||
<a class='item' href='/examples/quake.html'>
|
||||
<div class='content'>
|
||||
<div class='name'>Earthquake Data</div>
|
||||
<p class='description'>A visualization of 2013 seismic activity.
|
||||
This demo shows the use of multiple custom plugins, D3
|
||||
scales, fetching third party data, and DOM updates via D3.</p>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
290
site/public/examples/quake.ejs
Normal file
290
site/public/examples/quake.ejs
Normal file
@ -0,0 +1,290 @@
|
||||
<h1>2013 Earthquake Data</h1>
|
||||
|
||||
<p>This is a more advanced example of what can be built with Planetary.js. The demo sets up a globe with some custom plugins (defined at the bottom of the JavaScript), and also demonstrates some non-Planetary.js specific techniques, like D3 scales, DOM manipulation, and loading external data.</p>
|
||||
|
||||
<p><a href="/examples/quake/index.html">View the demo</a></p>
|
||||
|
||||
<div class='ui raise segment'>
|
||||
<div class='ui blue ribbon label'>HTML</div>
|
||||
<pre><code class='language-html'><canvas id='quakeCanvas'></canvas>
|
||||
<h1>Earthquakes: 2013</h1>
|
||||
<ul id='magnitues'></ul>
|
||||
|
||||
<div id='controls'>
|
||||
<div>
|
||||
<input id='slider' type='range' min='0' max='100' value='0'>
|
||||
</div>
|
||||
<div>
|
||||
<span id='date'></span>&nbsp;
|
||||
</div>
|
||||
</div></code></pre>
|
||||
|
||||
<div class='ui red ribbon label'>JavaScript</div>
|
||||
|
||||
<pre><code class='language-javascript'>(function() {
|
||||
var canvas = document.getElementById('quakeCanvas');
|
||||
|
||||
// Create our Planetary.js planet and set some initial values;
|
||||
// we use several custom plugins, defined at the bottom of the file
|
||||
var planet = planetaryjs.planet();
|
||||
planet.loadPlugin(autocenter({extraHeight: -120}));
|
||||
planet.loadPlugin(autoscale({extraHeight: -120}));
|
||||
planet.loadPlugin(planetaryjs.plugins.earth({
|
||||
topojson: { file: '/world-110m.json' },
|
||||
oceans: { fill: '#001320' },
|
||||
land: { fill: '#06304e' },
|
||||
borders: { stroke: '#001320' }
|
||||
}));
|
||||
planet.loadPlugin(planetaryjs.plugins.pings({}));
|
||||
planet.loadPlugin(zoom());
|
||||
planet.loadPlugin(drag({
|
||||
onDragStart: function() {
|
||||
planet.plugins.autorotate.pause();
|
||||
},
|
||||
onDragEnd: function() {
|
||||
planet.plugins.autorotate.resume();
|
||||
}
|
||||
}));
|
||||
planet.loadPlugin(autorotate(5));
|
||||
planet.projection.rotate([100, -10, 0]);
|
||||
planet.draw(canvas);
|
||||
|
||||
|
||||
// Create a color scale for the various earthquake magnitudes; the
|
||||
// mininum magnitude in our data set is 2.5.
|
||||
var colors = d3.scale.pow()
|
||||
.exponent(2)
|
||||
.domain([2, 6,10])
|
||||
.range(['rgb(255,255,204)', 'rgb(253,141,60)','rgb(128,0,38)'])
|
||||
.clamp(true);
|
||||
// Also create a scale for mapping magnitues to ping angle sizes
|
||||
var angles = d3.scale.pow()
|
||||
.exponent(2)
|
||||
.domain([2.5, 10])
|
||||
.range([0.5, 15])
|
||||
.clamp(true);
|
||||
|
||||
// Create a key to show the magnitues and their colors
|
||||
d3.select('#magnitues').selectAll('li')
|
||||
.data(colors.ticks(9))
|
||||
.enter()
|
||||
.append('li')
|
||||
.style('color', colors)
|
||||
.text(function(d) {
|
||||
return "Magnitude " + d;
|
||||
});
|
||||
|
||||
|
||||
// Load our earthquake data and set up the controls.
|
||||
// The data consists of an array of objects in the following format:
|
||||
// {
|
||||
// mag: magnitude_of_quake
|
||||
// lng: longitude_coordinates
|
||||
// lat: latitude_coordinates
|
||||
// time: timestamp_of_quake
|
||||
// }
|
||||
// The data is ordered, with the earliest data being the first in the file.
|
||||
d3.json('/examples/quake/year_quakes_small.json', function(err, data) {
|
||||
if (err) {
|
||||
alert("Problem loading the quake data.");
|
||||
return;
|
||||
}
|
||||
|
||||
var start = parseInt(data[0].time, 10);
|
||||
var end = parseInt(data[data.length - 1].time, 10);
|
||||
var currentTime = start;
|
||||
var lastTick = new Date().getTime();
|
||||
|
||||
// A scale that maps a percentage of playback to a time
|
||||
// from the data; for example, `50` would map to the halfway
|
||||
// mark between the first and last items in our data array.
|
||||
var percentToDate = d3.scale.linear()
|
||||
.domain([0, 100])
|
||||
.range([start, end]);
|
||||
|
||||
// A scale that maps real time passage to data playback time.
|
||||
// 12 minutes of real time maps to the entirety of the
|
||||
// timespan covered by the data.
|
||||
var realToData = d3.scale.linear()
|
||||
.domain([0, 1000 * 60 * 12])
|
||||
.range([0, end - start]);
|
||||
|
||||
var paused = false;
|
||||
|
||||
// Pause playback and update the time display
|
||||
// while scrubbing using the range input.
|
||||
d3.select('#slider')
|
||||
.on('change', function(d) {
|
||||
currentTime = percentToDate(d3.event.target.value);
|
||||
d3.select('#date').text(new Date(currentTime));
|
||||
})
|
||||
.call(d3.behavior.drag()
|
||||
.on('dragstart', function() {
|
||||
paused = true;
|
||||
})
|
||||
.on('dragend', function() {
|
||||
paused = false;
|
||||
})
|
||||
);
|
||||
|
||||
|
||||
// The main playback loop; for each tick, we'll see how much
|
||||
// time passed in our accelerated playback reel and find all
|
||||
// the earthquakes that happened in that timespan, adding
|
||||
// them to the globe with a color and angle relative to their magnitudes.
|
||||
d3.timer(function() {
|
||||
var now = new Date().getTime();
|
||||
|
||||
if (paused) {
|
||||
lastTick = now;
|
||||
return;
|
||||
}
|
||||
|
||||
var realDelta = now - lastTick;
|
||||
// Avoid switching back to the window only to see thousands of pings;
|
||||
// if it's been more than 500 milliseconds since we've updated playback,
|
||||
// we'll just set the value to 500 milliseconds.
|
||||
if (realDelta > 500) realDelta = 500;
|
||||
var dataDelta = realToData(realDelta);
|
||||
|
||||
var toPing = data.filter(function(d) {
|
||||
return d.time > currentTime && d.time <= currentTime + dataDelta;
|
||||
});
|
||||
|
||||
for (var i = 0; i < toPing.length; i++) {
|
||||
var ping = toPing[i];
|
||||
planet.plugins.pings.add(ping.lat, ping.lng, {
|
||||
// Here we use the `angles` and `colors` scales we built earlier
|
||||
// to convert magnitudes to appropriate angles and colors.
|
||||
angle: angles(ping.mag),
|
||||
color: colors(ping.mag)
|
||||
});
|
||||
}
|
||||
|
||||
currentTime += dataDelta;
|
||||
if (currentTime > end) currentTime = start;
|
||||
d3.select('#date').text(new Date(currentTime));
|
||||
d3.select('#slider').property('value', percentToDate.invert(currentTime));
|
||||
lastTick = now;
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
||||
// Plugin to resize the canvas to fill the window and to
|
||||
// automatically center the planet when the window size changes
|
||||
function autocenter(options) {
|
||||
var needsCentering = false;
|
||||
var resize = function() {
|
||||
var width = window.innerWidth + (options.extraWidth || 0);
|
||||
var height = window.innerHeight + (options.extraHeight || 0);
|
||||
planet.canvas.width = width;
|
||||
planet.canvas.height = height;
|
||||
planet.projection.translate([width / 2, height / 2]);
|
||||
};
|
||||
|
||||
return function(planet) {
|
||||
planet.onInit(function() {
|
||||
needsCentering = true;
|
||||
d3.select(window).on('resize', function() {
|
||||
needsCentering = true;
|
||||
});
|
||||
});
|
||||
|
||||
planet.onDraw(function() {
|
||||
if (needsCentering) { resize(); needsCentering = false; }
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
// Plugin to automatically scale the planet's projection based
|
||||
// on the window size when the planet is initialized
|
||||
function autoscale(options) {
|
||||
return function(planet) {
|
||||
planet.onInit(function() {
|
||||
var width = window.innerWidth + (options.extraWidth || 0);
|
||||
var height = window.innerHeight + (options.extraHeight || 0);
|
||||
planet.projection.scale(Math.min(width, height) / 2);
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
// Plugin to automatically rotate the globe around its vertical
|
||||
// axis a configured number of degrees every second.
|
||||
function autorotate(degPerSec) {
|
||||
return function(planet) {
|
||||
var lastTick = null;
|
||||
var paused = false;
|
||||
planet.plugins.autorotate = {
|
||||
pause: function() { paused = true; },
|
||||
resume: function() { paused = false; }
|
||||
};
|
||||
planet.onDraw(function() {
|
||||
if (paused || !lastTick) {
|
||||
lastTick = new Date();
|
||||
} else {
|
||||
var now = new Date();
|
||||
var delta = now - lastTick;
|
||||
var rotation = planet.projection.rotate();
|
||||
rotation[0] += degPerSec * delta / 1000;
|
||||
if (rotation[0] >= 180) rotation[0] -= 360;
|
||||
planet.projection.rotate(rotation);
|
||||
lastTick = now;
|
||||
}
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
// Plugin to allow zooming with the mouse wheel
|
||||
function zoom(options) {
|
||||
return function(planet) {
|
||||
planet.onInit(function() {
|
||||
var zoom = d3.behavior.zoom()
|
||||
.scale(planet.projection.scale())
|
||||
.scaleExtent([50, 5000])
|
||||
.on('zoom', function() {
|
||||
planet.projection.scale(d3.event.scale);
|
||||
});
|
||||
d3.select(planet.canvas).call(zoom);
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
// Plugin to allow rotating the globe by dragging with the mouse
|
||||
function drag(options) {
|
||||
var options = options || {};
|
||||
var noop = function() {};
|
||||
var onDragStart = options.onDragStart || noop;
|
||||
var onDragEnd = options.onDragEnd || noop;
|
||||
var onDrag = options.onDrag || noop;
|
||||
return function(planet) {
|
||||
planet.onInit(function() {
|
||||
var drag = d3.behavior.drag()
|
||||
.on('dragstart', onDragStart)
|
||||
.on('dragend', onDragEnd)
|
||||
.on('drag', function() {
|
||||
onDrag();
|
||||
var dx = d3.event.dx;
|
||||
var dy = d3.event.dy;
|
||||
var rotation = planet.projection.rotate();
|
||||
var radius = planet.projection.scale();
|
||||
// Dragging from the center of the planet to the edge
|
||||
// of the planet should rotate it 90 degrees
|
||||
var scale = d3.scale.linear()
|
||||
.domain([-1 * radius, radius])
|
||||
.range([-90, 90]);
|
||||
var degX = scale(dx);
|
||||
var degY = scale(dy);
|
||||
rotation[0] += degX;
|
||||
rotation[1] -= degY;
|
||||
if (rotation[1] > 90) rotation[1] = 90;
|
||||
if (rotation[1] < -90) rotation[1] = -90;
|
||||
if (rotation[0] >= 180) rotation[0] -= 360;
|
||||
planet.projection.rotate(rotation);
|
||||
});
|
||||
d3.select(planet.canvas).call(drag);
|
||||
});
|
||||
};
|
||||
};
|
||||
})();</code></pre>
|
||||
</div>
|
||||
58
site/public/examples/quake/_layout.ejs
Normal file
58
site/public/examples/quake/_layout.ejs
Normal file
@ -0,0 +1,58 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<%- partial("../../_header") %>
|
||||
<link href="/css/prism.css" rel="stylesheet">
|
||||
<style>
|
||||
body {
|
||||
background-color: rgb(0, 26, 34);
|
||||
background: url('sky.jpg');
|
||||
color: white;
|
||||
}
|
||||
|
||||
ul#magnitues {
|
||||
position: absolute;
|
||||
top: 100px;
|
||||
left: 30px;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
h1 {
|
||||
position: absolute;
|
||||
top: 50px;
|
||||
left: 5px;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
canvas {
|
||||
position: absolute;
|
||||
top: 60px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
cursor: move;
|
||||
}
|
||||
|
||||
#controls {
|
||||
position: absolute;
|
||||
width: 400px;
|
||||
bottom: 5px;
|
||||
left: 50%;
|
||||
margin-left: -200px;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<%- partial("../../_menu") %>
|
||||
|
||||
<%- yield %>
|
||||
|
||||
<%- partial("../../_scripts") %>
|
||||
<script type='text/javascript' src='/examples/quake/quake.js'></script>
|
||||
<script type='text/javascript' src='/js/prism.js'></script>
|
||||
</body>
|
||||
</html>
|
||||
12
site/public/examples/quake/index.ejs
Normal file
12
site/public/examples/quake/index.ejs
Normal file
@ -0,0 +1,12 @@
|
||||
<canvas id='quakeCanvas'></canvas>
|
||||
<h1>Earthquakes: 2013</h1>
|
||||
<ul id='magnitues'></ul>
|
||||
|
||||
<div id='controls'>
|
||||
<div>
|
||||
<input id='slider' type='range' min='0' max='100' value='0'>
|
||||
</div>
|
||||
<div>
|
||||
<span id='date'></span>
|
||||
</div>
|
||||
</div>
|
||||
266
site/public/examples/quake/quake.js
Normal file
266
site/public/examples/quake/quake.js
Normal file
@ -0,0 +1,266 @@
|
||||
(function() {
|
||||
var canvas = document.getElementById('quakeCanvas');
|
||||
|
||||
// Create our Planetary.js planet and set some initial values;
|
||||
// we use several custom plugins, defined at the bottom of the file
|
||||
var planet = planetaryjs.planet();
|
||||
planet.loadPlugin(autocenter({extraHeight: -120}));
|
||||
planet.loadPlugin(autoscale({extraHeight: -120}));
|
||||
planet.loadPlugin(planetaryjs.plugins.earth({
|
||||
topojson: { file: '/world-110m.json' },
|
||||
oceans: { fill: '#001320' },
|
||||
land: { fill: '#06304e' },
|
||||
borders: { stroke: '#001320' }
|
||||
}));
|
||||
planet.loadPlugin(planetaryjs.plugins.pings({}));
|
||||
planet.loadPlugin(zoom());
|
||||
planet.loadPlugin(drag({
|
||||
onDragStart: function() {
|
||||
planet.plugins.autorotate.pause();
|
||||
},
|
||||
onDragEnd: function() {
|
||||
planet.plugins.autorotate.resume();
|
||||
}
|
||||
}));
|
||||
planet.loadPlugin(autorotate(5));
|
||||
planet.projection.rotate([100, -10, 0]);
|
||||
planet.draw(canvas);
|
||||
|
||||
|
||||
// Create a color scale for the various earthquake magnitudes; the
|
||||
// mininum magnitude in our data set is 2.5.
|
||||
var colors = d3.scale.pow()
|
||||
.exponent(2)
|
||||
.domain([2, 6,10])
|
||||
.range(['rgb(255,255,204)', 'rgb(253,141,60)','rgb(128,0,38)'])
|
||||
.clamp(true);
|
||||
// Also create a scale for mapping magnitues to ping angle sizes
|
||||
var angles = d3.scale.pow()
|
||||
.exponent(2)
|
||||
.domain([2.5, 10])
|
||||
.range([0.5, 15])
|
||||
.clamp(true);
|
||||
|
||||
// Create a key to show the magnitues and their colors
|
||||
d3.select('#magnitues').selectAll('li')
|
||||
.data(colors.ticks(9))
|
||||
.enter()
|
||||
.append('li')
|
||||
.style('color', colors)
|
||||
.text(function(d) {
|
||||
return "Magnitude " + d;
|
||||
});
|
||||
|
||||
|
||||
// Load our earthquake data and set up the controls.
|
||||
// The data consists of an array of objects in the following format:
|
||||
// {
|
||||
// mag: magnitude_of_quake
|
||||
// lng: longitude_coordinates
|
||||
// lat: latitude_coordinates
|
||||
// time: timestamp_of_quake
|
||||
// }
|
||||
// The data is ordered, with the earliest data being the first in the file.
|
||||
d3.json('/examples/quake/year_quakes_small.json', function(err, data) {
|
||||
if (err) {
|
||||
alert("Problem loading the quake data.");
|
||||
return;
|
||||
}
|
||||
|
||||
var start = parseInt(data[0].time, 10);
|
||||
var end = parseInt(data[data.length - 1].time, 10);
|
||||
var currentTime = start;
|
||||
var lastTick = new Date().getTime();
|
||||
|
||||
// A scale that maps a percentage of playback to a time
|
||||
// from the data; for example, `50` would map to the halfway
|
||||
// mark between the first and last items in our data array.
|
||||
var percentToDate = d3.scale.linear()
|
||||
.domain([0, 100])
|
||||
.range([start, end]);
|
||||
|
||||
// A scale that maps real time passage to data playback time.
|
||||
// 12 minutes of real time maps to the entirety of the
|
||||
// timespan covered by the data.
|
||||
var realToData = d3.scale.linear()
|
||||
.domain([0, 1000 * 60 * 12])
|
||||
.range([0, end - start]);
|
||||
|
||||
var paused = false;
|
||||
|
||||
// Pause playback and update the time display
|
||||
// while scrubbing using the range input.
|
||||
d3.select('#slider')
|
||||
.on('change', function(d) {
|
||||
currentTime = percentToDate(d3.event.target.value);
|
||||
d3.select('#date').text(new Date(currentTime));
|
||||
})
|
||||
.call(d3.behavior.drag()
|
||||
.on('dragstart', function() {
|
||||
paused = true;
|
||||
})
|
||||
.on('dragend', function() {
|
||||
paused = false;
|
||||
})
|
||||
);
|
||||
|
||||
|
||||
// The main playback loop; for each tick, we'll see how much
|
||||
// time passed in our accelerated playback reel and find all
|
||||
// the earthquakes that happened in that timespan, adding
|
||||
// them to the globe with a color and angle relative to their magnitudes.
|
||||
d3.timer(function() {
|
||||
var now = new Date().getTime();
|
||||
|
||||
if (paused) {
|
||||
lastTick = now;
|
||||
return;
|
||||
}
|
||||
|
||||
var realDelta = now - lastTick;
|
||||
// Avoid switching back to the window only to see thousands of pings;
|
||||
// if it's been more than 500 milliseconds since we've updated playback,
|
||||
// we'll just set the value to 500 milliseconds.
|
||||
if (realDelta > 500) realDelta = 500;
|
||||
var dataDelta = realToData(realDelta);
|
||||
|
||||
var toPing = data.filter(function(d) {
|
||||
return d.time > currentTime && d.time <= currentTime + dataDelta;
|
||||
});
|
||||
|
||||
for (var i = 0; i < toPing.length; i++) {
|
||||
var ping = toPing[i];
|
||||
planet.plugins.pings.add(ping.lat, ping.lng, {
|
||||
// Here we use the `angles` and `colors` scales we built earlier
|
||||
// to convert magnitudes to appropriate angles and colors.
|
||||
angle: angles(ping.mag),
|
||||
color: colors(ping.mag)
|
||||
});
|
||||
}
|
||||
|
||||
currentTime += dataDelta;
|
||||
if (currentTime > end) currentTime = start;
|
||||
d3.select('#date').text(new Date(currentTime));
|
||||
d3.select('#slider').property('value', percentToDate.invert(currentTime));
|
||||
lastTick = now;
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
||||
// Plugin to resize the canvas to fill the window and to
|
||||
// automatically center the planet when the window size changes
|
||||
function autocenter(options) {
|
||||
var needsCentering = false;
|
||||
var resize = function() {
|
||||
var width = window.innerWidth + (options.extraWidth || 0);
|
||||
var height = window.innerHeight + (options.extraHeight || 0);
|
||||
planet.canvas.width = width;
|
||||
planet.canvas.height = height;
|
||||
planet.projection.translate([width / 2, height / 2]);
|
||||
};
|
||||
|
||||
return function(planet) {
|
||||
planet.onInit(function() {
|
||||
needsCentering = true;
|
||||
d3.select(window).on('resize', function() {
|
||||
needsCentering = true;
|
||||
});
|
||||
});
|
||||
|
||||
planet.onDraw(function() {
|
||||
if (needsCentering) { resize(); needsCentering = false; }
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
// Plugin to automatically scale the planet's projection based
|
||||
// on the window size when the planet is initialized
|
||||
function autoscale(options) {
|
||||
return function(planet) {
|
||||
planet.onInit(function() {
|
||||
var width = window.innerWidth + (options.extraWidth || 0);
|
||||
var height = window.innerHeight + (options.extraHeight || 0);
|
||||
planet.projection.scale(Math.min(width, height) / 2);
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
// Plugin to automatically rotate the globe around its vertical
|
||||
// axis a configured number of degrees every second.
|
||||
function autorotate(degPerSec) {
|
||||
return function(planet) {
|
||||
var lastTick = null;
|
||||
var paused = false;
|
||||
planet.plugins.autorotate = {
|
||||
pause: function() { paused = true; },
|
||||
resume: function() { paused = false; }
|
||||
};
|
||||
planet.onDraw(function() {
|
||||
if (paused || !lastTick) {
|
||||
lastTick = new Date();
|
||||
} else {
|
||||
var now = new Date();
|
||||
var delta = now - lastTick;
|
||||
var rotation = planet.projection.rotate();
|
||||
rotation[0] += degPerSec * delta / 1000;
|
||||
if (rotation[0] >= 180) rotation[0] -= 360;
|
||||
planet.projection.rotate(rotation);
|
||||
lastTick = now;
|
||||
}
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
// Plugin to allow zooming with the mouse wheel
|
||||
function zoom(options) {
|
||||
return function(planet) {
|
||||
planet.onInit(function() {
|
||||
var zoom = d3.behavior.zoom()
|
||||
.scale(planet.projection.scale())
|
||||
.scaleExtent([50, 5000])
|
||||
.on('zoom', function() {
|
||||
planet.projection.scale(d3.event.scale);
|
||||
});
|
||||
d3.select(planet.canvas).call(zoom);
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
// Plugin to allow rotating the globe by dragging with the mouse
|
||||
function drag(options) {
|
||||
var options = options || {};
|
||||
var noop = function() {};
|
||||
var onDragStart = options.onDragStart || noop;
|
||||
var onDragEnd = options.onDragEnd || noop;
|
||||
var onDrag = options.onDrag || noop;
|
||||
return function(planet) {
|
||||
planet.onInit(function() {
|
||||
var drag = d3.behavior.drag()
|
||||
.on('dragstart', onDragStart)
|
||||
.on('dragend', onDragEnd)
|
||||
.on('drag', function() {
|
||||
onDrag();
|
||||
var dx = d3.event.dx;
|
||||
var dy = d3.event.dy;
|
||||
var rotation = planet.projection.rotate();
|
||||
var radius = planet.projection.scale();
|
||||
// Dragging from the center of the planet to the edge
|
||||
// of the planet should rotate it 90 degrees
|
||||
var scale = d3.scale.linear()
|
||||
.domain([-1 * radius, radius])
|
||||
.range([-90, 90]);
|
||||
var degX = scale(dx);
|
||||
var degY = scale(dy);
|
||||
rotation[0] += degX;
|
||||
rotation[1] -= degY;
|
||||
if (rotation[1] > 90) rotation[1] = 90;
|
||||
if (rotation[1] < -90) rotation[1] = -90;
|
||||
if (rotation[0] >= 180) rotation[0] -= 360;
|
||||
planet.projection.rotate(rotation);
|
||||
});
|
||||
d3.select(planet.canvas).call(drag);
|
||||
});
|
||||
};
|
||||
};
|
||||
})();
|
||||
BIN
site/public/examples/quake/sky.jpg
Normal file
BIN
site/public/examples/quake/sky.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 55 KiB |
1
site/public/examples/quake/year_quakes_small.json
Normal file
1
site/public/examples/quake/year_quakes_small.json
Normal file
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user