- Planetary.js
+ Planetary.js: Awesome interactive globes for the web
@@ -87,6 +87,7 @@
Zoom - enables mouse-based zooming of the globe via the mousewheel
Drag - enables mouse-based rotation of the globe via dragging
+
Built-in plugins exposed as properties on planetaryjs.plugins.
diff --git a/documentation/builtin_borders.html b/documentation/builtin_borders.html
index 1c9f204..9fe27ed 100644
--- a/documentation/builtin_borders.html
+++ b/documentation/builtin_borders.html
@@ -1,7 +1,7 @@
- Planetary.js
+ Planetary.js: Awesome interactive globes for the web
@@ -76,6 +76,26 @@
Borders Plugin
+
The borders plugin renders the borders around (and between) countries. It uses TopoJSON data published to planet.plugins.topojson.world by the TopoJSON plugin.
+
API
+
planetaryjs.plugins.borders([config])
+
Valid keys for config are:
+
+
stroke: the strokeStyle to use for the context; defaults to "gray"
+
lineWidth the lineWidth to set on the context; defaults to no value, and the context's lineWidth is not modified
+
type: valid options are "internal", "external", or "both". "internal" draws borders between countries but not coastlines; "external" does the opposite. "both", unsurprisingly, draws both. Defaults to "internal".
diff --git a/documentation/builtin_drag.html b/documentation/builtin_drag.html
index d542db1..897a24e 100644
--- a/documentation/builtin_drag.html
+++ b/documentation/builtin_drag.html
@@ -1,7 +1,7 @@
- Planetary.js
+ Planetary.js: Awesome interactive globes for the web
diff --git a/documentation/builtin_earth.html b/documentation/builtin_earth.html
index 3c14bba..711b832 100644
--- a/documentation/builtin_earth.html
+++ b/documentation/builtin_earth.html
@@ -1,7 +1,7 @@
- Planetary.js
+ Planetary.js: Awesome interactive globes for the web
@@ -76,6 +76,33 @@
Earth Plugin
+
The earth plugin is simply a wrapper around the topojson, oceans, land, and borders plugins. It parses its configuration and passes pieces of it to the individual plugins.
diff --git a/documentation/builtin_land.html b/documentation/builtin_land.html
index 5d6d7e5..b46aeed 100644
--- a/documentation/builtin_land.html
+++ b/documentation/builtin_land.html
@@ -1,7 +1,7 @@
- Planetary.js
+ Planetary.js: Awesome interactive globes for the web
@@ -76,6 +76,26 @@
Land Plugin
+
The land plugin renders Earth's landmasses. It uses TopoJSON data published to planet.plugins.topojson.world by the TopoJSON plugin.
+
API
+
planetaryjs.plugins.land([config])
+
Valid keys for config are:
+
+
fill: the fillStyle to use for the context; defaults to "white"
+
stroke: the strokeStyle to use for the context; defaults to no value, resulting in no stroke around the landmasses
+
lineWidth the lineWidth to set on the context; only effective if stroke is set. Defaults to no value, resulting in no change to the context's lineWidth
diff --git a/documentation/builtin_pings.html b/documentation/builtin_pings.html
index 93c1823..7d9e650 100644
--- a/documentation/builtin_pings.html
+++ b/documentation/builtin_pings.html
@@ -1,7 +1,7 @@
- Planetary.js
+ Planetary.js: Awesome interactive globes for the web
@@ -76,6 +76,36 @@
Pings Plugin
+
The pings plugin allows you to display animated "pings" at any location on the planet. It publishes a method to create pings at planet.plugins.pings.add.
+
API
+
planetaryjs.plugins.pings([config])
+
Valid keys for config are:
+
+
color: the default color for pings; defaults to "white"
+
ttl: the default TTL for pings in milliseconds (how long they take to fade out); defaults to 2000
+
angle: the maximum angle for the ping (it will grow to this size over the course of its TTL); defaults to 5
Add a new ping to the globe at the latitudinal and longitudinal coordinates specified by lat and lng. config may take all the same keys as the configuration option for the plugin itself; any values will overwrite values from that object, if any were set.
+
+
JavaScript
+
+
var colors = ['red', 'yellow', 'white', 'orange', 'green', 'cyan', 'pink'];
+setInterval(function() {
+ var lat = Math.random() * 170 - 85;
+ var lng = Math.random() * 360 - 180;
+ var color = colors[Math.floor(Math.random() * colors.length)];
+ var angle = Math.random() * 10;
+ planet.plugins.pings.add(lat, lng, { color: color, ttl: 2000, angle: angle });
+}, 250);
+
diff --git a/documentation/builtin_topojson.html b/documentation/builtin_topojson.html
index d832961..1e6ddee 100644
--- a/documentation/builtin_topojson.html
+++ b/documentation/builtin_topojson.html
@@ -1,7 +1,7 @@
- Planetary.js
+ Planetary.js: Awesome interactive globes for the web
@@ -76,6 +76,37 @@
TopoJSON Plugin
+
The topojson plugin parses TopoJSON data and publishes it on planet.plugins.topojson.world for other plugins to use (particularly for rendering geographical data using D3).
+
The plugin can load data from a file using Ajax, or can be provided an object that has come from some other source.
+
API
+
planetaryjs.plugins.topojson([config])
+
Valid keys for config are:
+
+
world: a JavaScript object representing TopoJSON data (not JSON data); defaults to no value, which will cause the plugin to load data from the file configuration option
+
file: the path to a TopoJSON data file to be loaded via Ajax; defaults to "world-110m.json", which can be downloaded with the Planetary.js library from the download page.
+
+
If you plan on creating more than one planet from the same TopoJSON data, you can load the data once before loading the plugin and pass the parsed data to the plugin via the world property rather than letting the plugin load the data via Ajax each time a new planet is created.
diff --git a/documentation/builtin_zoom.html b/documentation/builtin_zoom.html
index 3a6af0b..46c18f0 100644
--- a/documentation/builtin_zoom.html
+++ b/documentation/builtin_zoom.html
@@ -1,7 +1,7 @@
- Planetary.js
+ Planetary.js: Awesome interactive globes for the web
diff --git a/documentation/core.html b/documentation/core.html
index 30f3141..c353c6e 100644
--- a/documentation/core.html
+++ b/documentation/core.html
@@ -1,7 +1,7 @@
- Planetary.js
+ Planetary.js: Awesome interactive globes for the web
diff --git a/documentation/index.html b/documentation/index.html
index c5cda02..40f2dac 100644
--- a/documentation/index.html
+++ b/documentation/index.html
@@ -1,7 +1,7 @@
- Planetary.js
+ Planetary.js: Awesome interactive globes for the web
diff --git a/documentation/planet.html b/documentation/planet.html
index d93d184..92d952a 100644
--- a/documentation/planet.html
+++ b/documentation/planet.html
@@ -1,7 +1,7 @@
- Planetary.js
+ Planetary.js: Awesome interactive globes for the web
diff --git a/documentation/plugins.html b/documentation/plugins.html
index fe71c4e..75c67bc 100644
--- a/documentation/plugins.html
+++ b/documentation/plugins.html
@@ -1,7 +1,7 @@
- Planetary.js
+ Planetary.js: Awesome interactive globes for the web
@@ -205,6 +205,14 @@ setTimeout(function() {
planet.plugins.autorotate.pause();
}, 5000);
+
Best Practices
+
There are a few things you can do to make your plugin all it can be:
+
+
Make your plugin very small; ideally, it should do only one thing very well. Be extremely liberal with splitting plugins into smaller plugins, which makes them easier to understand, test, and compose. It's easy to say "this plugin renders the Earth," but it really renders oceans, land masses, and borders.
+
Use function generators to generate your plugin (as described above in "Plugin Generators"), even if it doesn't take any configuration options. It makes for a more consistent API, and allows you to add the ability to specify configuration options in the future without changing the base API.
+
Make configuration optional if at all possible. Write your plugin so that it checks for missing values and uses sensible defaults.
+
Only publish public data and API methods to planet.plugins.pluginName, where pluginName is the name of your plugin.
+
diff --git a/index.html b/index.html
index 8bae7e5..552af5b 100644
--- a/index.html
+++ b/index.html
@@ -1,7 +1,7 @@
- Planetary.js
+ Planetary.js: Awesome interactive globes for the web
diff --git a/js/lib/planetaryjs.min.js b/js/lib/planetaryjs.min.js
index 28b9557..bbbbd47 100644
--- a/js/lib/planetaryjs.min.js
+++ b/js/lib/planetaryjs.min.js
@@ -1,2 +1,2 @@
-/*! Planetary.js 0.1.1 | (c) 2013 Brandon Tilley | Released under MIT License */
-!function(n,t){"function"==typeof define&&define.amd?define(["d3","topojson"],t):"object"==typeof exports?module.exports=t(require("d3"),require("topojson")):n.planetaryjs=t(n.d3,n.topojson,n)}(this,function(n,t,o){"use strict";var i=null;o&&(i=o.planetaryjs);var e=[],r=function(t,o,i){n.timer(function(){t.context.clearRect(0,0,o.width,o.height);for(var n=0;n=o.onInit.length?r(n,t,o):e(l)};e(l)}else r(n,t,o)},s=function(n,t,o,i){l(n,o),n.canvas=t,n.context=t.getContext("2d"),u(n,t,i)},a={plugins:{},noConflict:function(){return o.planetaryjs=i,a},loadPlugin:function(n){e.push(n)},planet:function(){var t=[],o={onInit:[],onDraw:[]},i={plugins:{},draw:function(n){s(i,n,t,o)},onInit:function(n){o.onInit.push(n)},onDraw:function(n){o.onDraw.push(n)},loadPlugin:function(n){t.push(n)},withSavedContext:function(n){if(!this.context)throw new Error("No canvas to fetch context for");this.context.save(),n(this.context),this.context.restore()}};return i.projection=n.geo.orthographic().clipAngle(90).precision(0),i.path=n.geo.path().projection(i.projection),i}};return a.plugins.topojson=function(t){return function(o){o.plugins.topojson={},o.onInit(function(i){if(t.world)o.plugins.topojson.world=t.world,setTimeout(i,0);else{var e=t.file||"world-110m.json";n.json(e,function(n,t){if(n)throw new Error("Could not load JSON "+e);o.plugins.topojson.world=t,i()})}})}},a.plugins.oceans=function(n){return function(t){t.onDraw(function(){t.withSavedContext(function(o){o.beginPath(),t.path.context(o)({type:"Sphere"}),o.fillStyle=n.fill||"black",o.fill(),0!=n.stroke&&(o.strokeStyle=n.stroke,o.stroke())})})}},a.plugins.land=function(n){return function(o){var i=null;o.onInit(function(){var n=o.plugins.topojson.world;i=t.feature(n,n.objects.land)}),o.onDraw(function(){o.withSavedContext(function(t){t.beginPath(),o.path.context(t)(i),0!=n.fill&&(t.fillStyle=n.fill||"white",t.fill()),n.stroke&&(t.strokeStyle=n.stroke,t.stroke())})})}},a.plugins.borders=function(n){return function(o){var i=null;o.onInit(function(){var n=o.plugins.topojson.world,e=n.objects.countries;i=t.mesh(n,e,function(n,t){return n.id!==t.id})}),o.onDraw(function(){o.withSavedContext(function(t){t.beginPath(),o.path.context(t)(i),t.strokeStyle=n.stroke||"gray",t.stroke()})})}},a.plugins.earth=function(n){var n=n||{},t=n.topojson||{},o=n.oceans||{},i=n.land||{},e=n.borders||{};return function(n){a.plugins.topojson(t)(n),a.plugins.oceans(o)(n),a.plugins.land(i)(n),a.plugins.borders(e)(n)}},a.plugins.pings=function(){var t=[],o=function(n,o,i){var i=i||{};i.color=i.color||"white",i.ttl=i.ttl||2e3,i.angle=i.angle||5,t.push({lat:n,lng:o,time:new Date,options:i})},i=function(n,o,i){for(var r=[],l=0;l=o.onInit.length?r(n,t,o):e(l)};e(l)}else r(n,t,o)},a=function(n,t,o,i){l(n,o),n.canvas=t,n.context=t.getContext("2d"),u(n,t,i)},s={plugins:{},noConflict:function(){return o.planetaryjs=i,s},loadPlugin:function(n){e.push(n)},planet:function(){var t=[],o={onInit:[],onDraw:[]},i={plugins:{},draw:function(n){a(i,n,t,o)},onInit:function(n){o.onInit.push(n)},onDraw:function(n){o.onDraw.push(n)},loadPlugin:function(n){t.push(n)},withSavedContext:function(n){if(!this.context)throw new Error("No canvas to fetch context for");this.context.save(),n(this.context),this.context.restore()}};return i.projection=n.geo.orthographic().clipAngle(90).precision(0),i.path=n.geo.path().projection(i.projection),i}};return s.plugins.topojson=function(t){return function(o){o.plugins.topojson={},o.onInit(function(i){if(t.world)o.plugins.topojson.world=t.world,setTimeout(i,0);else{var e=t.file||"world-110m.json";n.json(e,function(n,t){if(n)throw new Error("Could not load JSON "+e);o.plugins.topojson.world=t,i()})}})}},s.plugins.oceans=function(n){return function(t){t.onDraw(function(){t.withSavedContext(function(o){o.beginPath(),t.path.context(o)({type:"Sphere"}),o.fillStyle=n.fill||"black",o.fill()})})}},s.plugins.land=function(n){return function(o){var i=null;o.onInit(function(){var n=o.plugins.topojson.world;i=t.feature(n,n.objects.land)}),o.onDraw(function(){o.withSavedContext(function(t){t.beginPath(),o.path.context(t)(i),0!=n.fill&&(t.fillStyle=n.fill||"white",t.fill()),n.stroke&&(n.lineWidth&&(t.lineWidth=n.lineWidth),t.strokeStyle=n.stroke,t.stroke())})})}},s.plugins.borders=function(n){return function(o){var i=null,e={internal:function(n,t){return n.id!==t.id},external:function(n,t){return n.id===t.id},both:function(){return!0}};o.onInit(function(){var r=o.plugins.topojson.world,l=r.objects.countries,u=n.type||"internal";i=t.mesh(r,l,e[u])}),o.onDraw(function(){o.withSavedContext(function(t){t.beginPath(),o.path.context(t)(i),t.strokeStyle=n.stroke||"gray",n.lineWidth&&(t.lineWidth=n.lineWidth),t.stroke()})})}},s.plugins.earth=function(n){var n=n||{},t=n.topojson||{},o=n.oceans||{},i=n.land||{},e=n.borders||{};return function(n){s.plugins.topojson(t)(n),s.plugins.oceans(o)(n),s.plugins.land(i)(n),s.plugins.borders(e)(n)}},s.plugins.pings=function(t){var o=[],i=function(n,i,e){var e=e||{};e.color=e.color||t.color||"white",e.ttl=e.ttl||t.ttl||2e3,e.angle=e.angle||t.angle||5,o.push({lat:n,lng:i,time:new Date,options:e})},e=function(n,t,i){for(var e=[],l=0;l