├── LICENSE ├── Makefile ├── README.mkd ├── examples ├── bing │ ├── map.html │ └── map.js ├── bounds │ ├── bounds.html │ ├── bounds.js │ └── district.json ├── breakout │ └── breakout.html ├── canvas │ ├── cell-worker.js │ ├── cell.html │ ├── cell.js │ ├── mandelbrot-worker.js │ ├── mandelbrot.html │ ├── mandelbrot.js │ └── procedural.js ├── cloudmade │ ├── midnight-commander.html │ ├── midnight-commander.js │ ├── pale-dawn.html │ └── pale-dawn.js ├── cluster │ ├── cluster.html │ ├── cluster.js │ └── kmeans.js ├── example.css ├── features │ └── features.html ├── grid │ ├── grid.html │ ├── grid.js │ ├── tiles.html │ └── tiles.js ├── hilbert │ ├── hilbert.html │ └── hilbert.js ├── invert │ └── invert.html ├── iphone4 │ ├── iphone4.html │ └── iphone4.js ├── kml │ ├── kml.html │ ├── kml.js │ └── sample.kml ├── loupe │ ├── loupe-map.js │ ├── loupe.html │ └── loupe.js ├── marker │ ├── marker.html │ └── marker.js ├── nasa │ ├── blue-marble.html │ └── blue-marble.js ├── overlay │ ├── overlay.html │ ├── overlay.js │ └── sf1906.png ├── population │ ├── population.css │ ├── population.html │ └── population.js ├── shadow │ ├── shadow.html │ └── shadow.js ├── small │ ├── small.html │ └── static.html ├── statehood │ ├── fips.js │ ├── statehood.html │ └── statehood.js ├── streets │ ├── streets.html │ ├── streets.js │ └── streets.json ├── tilestache │ ├── dot.gif │ ├── flickr.html │ └── flickr.js ├── tipsy │ ├── berkeley.png │ ├── stanford.png │ └── tipsy.html ├── transform │ ├── nypl.js │ ├── transform-inverse.html │ ├── transform.html │ ├── transform.js │ └── transparent.png ├── transition │ ├── ease.js │ └── transition.html ├── unemployment │ ├── unemployment-data.js │ ├── unemployment.html │ └── unemployment.js └── world │ ├── area.tsv │ ├── internet.tsv │ ├── population.tsv │ ├── tsv.js │ ├── world.html │ ├── world.js │ └── world.json ├── lib ├── blueprint │ ├── LICENSE │ ├── ie.css │ ├── plugins │ │ └── fancy-type │ │ │ └── screen.css │ ├── print.css │ └── screen.css ├── colorbrewer │ ├── LICENSE │ ├── colorbrewer.css │ └── colorbrewer.js ├── crimespotting │ └── crimespotting.js ├── google-compiler │ ├── COPYING │ ├── README │ └── compiler-20100616.jar ├── jquery │ ├── LICENSE │ └── jquery.min.js ├── modernizr │ ├── LICENSE │ └── modernizr.min.js ├── nns │ ├── LICENSE │ ├── nns.js │ └── nns.min.js ├── protovis │ ├── LICENSE │ ├── protodata.js │ └── protodata.min.js ├── raphaeljs │ ├── LICENSE │ └── icons.js └── tipsy │ ├── LICENSE │ ├── jquery.tipsy.js │ ├── tipsy.css │ └── tipsy.gif ├── polymaps.js ├── polymaps.min.js └── src ├── Arrow.js ├── Cache.js ├── Compass.js ├── Dblclick.js ├── Dispatch.js ├── Drag.js ├── GeoJson.js ├── Grid.js ├── Hash.js ├── Id.js ├── Image.js ├── Interact.js ├── Layer.js ├── Map.js ├── Queue.js ├── Stylist.js ├── Svg.js ├── Touch.js ├── Transform.js ├── Url.js ├── Wheel.js ├── end.js ├── ns.js └── start.js /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2010, SimpleGeo and Stamen Design 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | * Redistributions of source code must retain the above copyright 7 | notice, this list of conditions and the following disclaimer. 8 | * Redistributions in binary form must reproduce the above copyright 9 | notice, this list of conditions and the following disclaimer in the 10 | documentation and/or other materials provided with the distribution. 11 | * Neither the name of SimpleGeo nor the 12 | names of its contributors may be used to endorse or promote products 13 | derived from this software without specific prior written permission. 14 | 15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | DISCLAIMED. IN NO EVENT SHALL SIMPLEGEO BE LIABLE FOR ANY 19 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | JS_FILES = \ 2 | src/start.js \ 3 | src/ns.js \ 4 | src/Id.js \ 5 | src/Svg.js \ 6 | src/Transform.js \ 7 | src/Cache.js \ 8 | src/Url.js \ 9 | src/Dispatch.js \ 10 | src/Queue.js \ 11 | src/Map.js \ 12 | src/Layer.js \ 13 | src/Image.js \ 14 | src/GeoJson.js \ 15 | src/Dblclick.js \ 16 | src/Drag.js \ 17 | src/Wheel.js \ 18 | src/Arrow.js \ 19 | src/Hash.js \ 20 | src/Touch.js \ 21 | src/Interact.js \ 22 | src/Compass.js \ 23 | src/Grid.js \ 24 | src/Stylist.js \ 25 | src/end.js 26 | 27 | JS_COMPILER = \ 28 | java -jar lib/google-compiler/compiler-20100616.jar \ 29 | --charset UTF-8 30 | 31 | all: polymaps.min.js polymaps.js 32 | 33 | %.min.js: %.js 34 | $(JS_COMPILER) < $^ > $@ 35 | 36 | polymaps.min.js: polymaps.js 37 | rm -f $@ 38 | $(JS_COMPILER) < polymaps.js >> $@ 39 | 40 | polymaps.js: $(JS_FILES) Makefile 41 | rm -f $@ 42 | cat $(JS_FILES) >> $@ 43 | chmod a-w $@ 44 | 45 | clean: 46 | rm -rf polymaps.js polymaps.min.js 47 | -------------------------------------------------------------------------------- /README.mkd: -------------------------------------------------------------------------------- 1 | # Polymaps 2 | 3 | Polymaps is a free JavaScript library for making dynamic, interactive maps in 4 | modern web browsers. See for more details. 5 | 6 | This is the `master` branch, which contains the Polymaps source code. If 7 | you're looking for the Polymaps website, you should checkout the `gh-pages` 8 | branch instead. 9 | 10 | ## Viewing Examples 11 | 12 | You'll find lots of Polymaps examples in the suitably-named `examples` 13 | directory. Open any of the HTML files there in your browser to view the 14 | examples, or open them in your text editor of choice to view the source. Most 15 | of the examples are replicated on the [Polymaps website](http://polymaps.org), 16 | though a few of them are only visible locally. 17 | 18 | Some of the examples depend on third-party libraries, such as jQuery. These 19 | third-party libraries are not required to use Polymaps but can certainly make 20 | it easier! All third-party libraries should be stored in the `lib` directory, 21 | with an associated `LICENSE` file and optional `README`. 22 | 23 | ## Filing Bugs 24 | 25 | We use GitHub to track issues with Polymaps. You can search for existing 26 | issues, and file new issues, here: 27 | 28 | 29 | 30 | You are welcome to file issues either for bugs in the source code, feature 31 | requests, or issues with the Polymaps website. 32 | 33 | ## Support 34 | 35 | If you have questions or problems regarding Polymaps, you can get help by 36 | joining the `#polymaps` IRC channel on irc.freenode.net. You are also welcome 37 | to send GitHub messages or tweets to `mbostock`. 38 | 39 | ## Build Instructions 40 | 41 | You do not need to build Polymaps in order to view the examples; a compiled 42 | copy of Polymaps (`polymaps.js` and `polymaps.min.js`) is included in the 43 | repository. 44 | 45 | To edit and build a new version of Polymaps, you must first install Java and 46 | GNU Make. If you are on Mac OS X, you can install Make as part of the UNIX 47 | tools included with 48 | [XCode](http://developer.apple.com/technologies/xcode.html). Once you've setup 49 | your development environment, you can rebuild Polymaps by running the 50 | following command from the repo's root directory: 51 | 52 | make 53 | 54 | The Polymaps build process is exceptionally simple. First, all the JavaScript 55 | files are concatenated (using `cat`); the order of files is important to 56 | preserve dependencies. This produces the file `polymaps.js`. Second, this file 57 | is put through Google's [Closure 58 | Compiler](http://code.google.com/closure/compiler/) to minify the JavaScript, 59 | resulting in a smaller `polymaps.min.js`. 60 | 61 | If you are doing development, it is highly recommended that you use the 62 | non-minified JavaScript for easier debugging. The minified JavaScript is only 63 | intended for production, where file size matters. Note that the development 64 | version is marked as read-only so that you don't accidentally overwrite your 65 | edits after a re-build. 66 | -------------------------------------------------------------------------------- /examples/bing/map.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 32 | 33 | 34 | 35 |
36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /examples/bing/map.js: -------------------------------------------------------------------------------- 1 | var po = org.polymaps; 2 | 3 | var div = document.getElementById("map"); 4 | 5 | var map = po.map() 6 | .container(div.appendChild(po.svg("svg"))) 7 | .add(po.interact()) 8 | .add(po.hash()); 9 | 10 | /* 11 | * Load the "AerialWithLabels" metadata. "Aerial" and "Road" also work. For more 12 | * information about the Imagery Metadata service, see 13 | * http://msdn.microsoft.com/en-us/library/ff701716.aspx 14 | * You should register for your own key at https://www.bingmapsportal.com/. 15 | */ 16 | var script = document.createElement("script"); 17 | script.setAttribute("type", "text/javascript"); 18 | script.setAttribute("src", "http://dev.virtualearth.net" 19 | + "/REST/V1/Imagery/Metadata/AerialWithLabels" 20 | + "?key=AmT-ZC3HPevQq5IBJ7v8qiDUxrojNaqbW1zBsKF0oMNEs53p7Nk5RlAuAmwSG7bg" 21 | + "&jsonp=callback"); 22 | document.body.appendChild(script); 23 | 24 | function callback(data) { 25 | 26 | /* Display each resource as an image layer. */ 27 | var resourceSets = data.resourceSets; 28 | for (var i = 0; i < resourceSets.length; i++) { 29 | var resources = data.resourceSets[i].resources; 30 | for (var j = 0; j < resources.length; j++) { 31 | var resource = resources[j]; 32 | map.add(po.image() 33 | .url(template(resource.imageUrl, resource.imageUrlSubdomains))) 34 | .tileSize({x: resource.imageWidth, y: resource.imageHeight}); 35 | } 36 | } 37 | 38 | /* Display brand logo. */ 39 | document.getElementById("logo").src = data.brandLogoUri; 40 | 41 | /* Display copyright notice. */ 42 | document.getElementById("copy").appendChild(document.createTextNode(data.copyright)); 43 | 44 | /* Display compass control. */ 45 | map.add(po.compass() 46 | .pan("none")); 47 | 48 | } 49 | 50 | /** Returns a Bing URL template given a string and a list of subdomains. */ 51 | function template(url, subdomains) { 52 | var n = subdomains.length, 53 | salt = ~~(Math.random() * n); // per-session salt 54 | 55 | /** Returns the given coordinate formatted as a 'quadkey'. */ 56 | function quad(column, row, zoom) { 57 | var key = ""; 58 | for (var i = 1; i <= zoom; i++) { 59 | key += (((row >> zoom - i) & 1) << 1) | ((column >> zoom - i) & 1); 60 | } 61 | return key; 62 | } 63 | 64 | return function(c) { 65 | var quadKey = quad(c.column, c.row, c.zoom), 66 | server = Math.abs(salt + c.column + c.row + c.zoom) % n; 67 | return url 68 | .replace("{quadkey}", quadKey) 69 | .replace("{subdomain}", subdomains[server]); 70 | }; 71 | } 72 | -------------------------------------------------------------------------------- /examples/bounds/bounds.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 16 | 17 | 18 | 19 | 20 | © 2010 21 | CloudMade, 22 | OpenStreetMap contributors, 23 | CCBYSA. 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /examples/bounds/bounds.js: -------------------------------------------------------------------------------- 1 | var po = org.polymaps; 2 | 3 | var map = po.map() 4 | .container(document.getElementById("map").appendChild(po.svg("svg"))) 5 | .add(po.interact()); 6 | 7 | map.add(po.image() 8 | .url(po.url("http://{S}tile.cloudmade.com" 9 | + "/1a1b06b230af4efdbb989ea99e9841af" // http://cloudmade.com/register 10 | + "/998/256/{Z}/{X}/{Y}.png") 11 | .hosts(["a.", "b.", "c.", ""]))); 12 | 13 | map.add(po.geoJson() 14 | .url("district.json") 15 | .id("district") 16 | .on("load", load)); 17 | 18 | map.add(po.compass() 19 | .pan("none")); 20 | 21 | function load(e) { 22 | map.extent(bounds(e.features)).zoomBy(-.5); 23 | } 24 | 25 | function bounds(features) { 26 | var i = -1, 27 | n = features.length, 28 | geometry, 29 | bounds = [{lon: Infinity, lat: Infinity}, {lon: -Infinity, lat: -Infinity}]; 30 | while (++i < n) { 31 | geometry = features[i].data.geometry; 32 | boundGeometry[geometry.type](bounds, geometry.coordinates); 33 | } 34 | return bounds; 35 | } 36 | 37 | function boundPoint(bounds, coordinate) { 38 | var x = coordinate[0], y = coordinate[1]; 39 | if (x < bounds[0].lon) bounds[0].lon = x; 40 | if (x > bounds[1].lon) bounds[1].lon = x; 41 | if (y < bounds[0].lat) bounds[0].lat = y; 42 | if (y > bounds[1].lat) bounds[1].lat = y; 43 | } 44 | 45 | function boundPoints(bounds, coordinates) { 46 | var i = -1, n = coordinates.length; 47 | while (++i < n) boundPoint(bounds, coordinates[i]); 48 | } 49 | 50 | function boundMultiPoints(bounds, coordinates) { 51 | var i = -1, n = coordinates.length; 52 | while (++i < n) boundPoints(bounds, coordinates[i]); 53 | } 54 | 55 | var boundGeometry = { 56 | Point: boundPoint, 57 | MultiPoint: boundPoints, 58 | LineString: boundPoints, 59 | MultiLineString: boundMultiPoints, 60 | Polygon: function(bounds, coordinates) { 61 | boundPoints(bounds, coordinates[0]); // exterior ring 62 | }, 63 | MultiPolygon: function(bounds, coordinates) { 64 | var i = -1, n = coordinates.length; 65 | while (++i < n) boundPoints(bounds, coordinates[i][0]); 66 | } 67 | }; 68 | -------------------------------------------------------------------------------- /examples/breakout/breakout.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 40 | 41 | 42 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /examples/canvas/cell-worker.js: -------------------------------------------------------------------------------- 1 | onmessage = function(e) { 2 | var z0 = Math.max(0, 4 - e.data.zoom), 3 | z1 = Math.max(0, e.data.zoom - 4), 4 | w = e.data.size.x >> z0, 5 | h = e.data.size.y >> z0, 6 | n = 1 << z0, 7 | col = e.data.column >> z1 << z0, 8 | row = e.data.row >> z1 << z0, 9 | data = e.data.data = [], 10 | state = []; 11 | 12 | for (var j = 0, y = 0; j < n; j++, y += h) { 13 | for (var i = 0, x = 0; i < n; i++, x += w) { 14 | draw((j | row) | ((i | col) << 4), x, y); 15 | } 16 | } 17 | 18 | function draw(r, x, y) { 19 | for (var i = 0; i < w; i++) { 20 | state[i] = ~~(Math.random() * 2); 21 | } 22 | for (var j = 0; j < h; j++) { 23 | var p = state.slice(), 24 | k = 4 * (e.data.size.x * (j + y) + x); 25 | for (var i = 0; i < w; i++) { 26 | data[k++] = data[k++] = data[k++] = 255 * state[i]; 27 | data[k++] = 255; 28 | state[i] = (r >> (p[i - 1] << 2 | p[i] << 1 | p[i + 1])) & 1; 29 | } 30 | } 31 | } 32 | 33 | postMessage(e.data); 34 | }; 35 | -------------------------------------------------------------------------------- /examples/canvas/cell.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /examples/canvas/cell.js: -------------------------------------------------------------------------------- 1 | var po = org.polymaps; 2 | 3 | var map = po.map() 4 | .container(document.getElementById("map").appendChild(po.svg("svg"))) 5 | .zoomRange([0, 5]) 6 | .zoom(1) 7 | .tileSize({x: 512, y: 512}) 8 | .center({lat: 0, lon: 0}) 9 | .add(po.interact()) 10 | .add(po.hash()); 11 | 12 | map.add(po.procedural() 13 | .zoom(function(z) { return Math.min(4, z); }) 14 | .worker("cell-worker.js")); 15 | 16 | map.add(po.compass() 17 | .pan("none")); 18 | -------------------------------------------------------------------------------- /examples/canvas/mandelbrot-worker.js: -------------------------------------------------------------------------------- 1 | onmessage = function(e) { 2 | 3 | // following code adapted blindly from 4 | // http://blogs.msdn.com/mikeormond/archive/2008/08/22 5 | // /deep-zoom-multiscaletilesource-and-the-mandelbrot-set.aspx 6 | 7 | var tileCount = 1 << e.data.zoom; 8 | 9 | var ReStart = -2.0; 10 | var ReDiff = 3.0; 11 | 12 | var MinRe = ReStart + ReDiff * e.data.column / tileCount; 13 | var MaxRe = MinRe + ReDiff / tileCount; 14 | 15 | var ImStart = -1.2; 16 | var ImDiff = 2.4; 17 | 18 | var MinIm = ImStart + ImDiff * e.data.row / tileCount; 19 | var MaxIm = MinIm + ImDiff / tileCount; 20 | 21 | var Re_factor = (MaxRe - MinRe) / (e.data.size.x - 1); 22 | var Im_factor = (MaxIm - MinIm) / (e.data.size.y - 1); 23 | 24 | var MaxIterations = 32; 25 | 26 | var data = e.data.data = []; 27 | 28 | for (var y = 0, i = 0; y < e.data.size.y; ++y) { 29 | var c_im = MinIm + y * Im_factor; 30 | for (var x = 0; x < e.data.size.x; ++x) { 31 | var c_re = MinRe + x * Re_factor; 32 | var Z_re = c_re; 33 | var Z_im = c_im; 34 | var isInside = true; 35 | var n = 0; 36 | for (n = 0; n < MaxIterations; ++n) { 37 | var Z_re2 = Z_re * Z_re; 38 | var Z_im2 = Z_im * Z_im; 39 | if (Z_re2 + Z_im2 > 4) { 40 | isInside = false; 41 | break; 42 | } 43 | Z_im = 2 * Z_re * Z_im + c_im; 44 | Z_re = Z_re2 - Z_im2 + c_re; 45 | } 46 | if (isInside) { 47 | data[i++] = data[i++] = data[i++] = 0; 48 | } else if (n < MaxIterations / 2) { 49 | data[i++] = 255 / (MaxIterations / 2) * n; 50 | data[i++] = data[i++] = 0; 51 | } else { 52 | data[i++] = 255; 53 | data[i++] = data[i++] = (n - MaxIterations / 2) * 255 / (MaxIterations / 2); 54 | } 55 | data[i++] = 255; 56 | } 57 | } 58 | 59 | postMessage(e.data); 60 | }; 61 | -------------------------------------------------------------------------------- /examples/canvas/mandelbrot.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /examples/canvas/mandelbrot.js: -------------------------------------------------------------------------------- 1 | var po = org.polymaps; 2 | 3 | var map = po.map() 4 | .container(document.getElementById("map").appendChild(po.svg("svg"))) 5 | .zoomRange([0, 20]) 6 | .zoom(1) 7 | .center({lat: 0, lon: 0}) 8 | .add(po.interact()) 9 | .add(po.hash()); 10 | 11 | map.add(po.procedural() 12 | .worker("mandelbrot-worker.js")); 13 | 14 | map.add(po.compass() 15 | .pan("none")); 16 | -------------------------------------------------------------------------------- /examples/canvas/procedural.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | var po = org.polymaps; 3 | 4 | po.procedural = function() { 5 | var procedural = po.layer(load), 6 | manager, 7 | worker; 8 | 9 | procedural.worker = function(x) { 10 | if (!arguments.length) return worker; 11 | worker = x; 12 | manager = _manager(x); 13 | return procedural; 14 | }; 15 | 16 | function load(tile) { 17 | if (tile.column < 0 || tile.column >= (1 << tile.zoom)) { 18 | tile.element = po.svg("g"); 19 | return; // no wrap 20 | } 21 | 22 | var size = procedural.map().tileSize(), 23 | o = tile.element = po.svg("foreignObject"), 24 | c = o.appendChild(document.createElement("canvas")), 25 | w = size.x, 26 | h = size.y; 27 | 28 | o.setAttribute("width", w); 29 | o.setAttribute("height", h); 30 | c.setAttribute("width", w); 31 | c.setAttribute("height", h); 32 | 33 | tile.request = manager.work({ 34 | row: tile.row, 35 | column: tile.column, 36 | zoom: tile.zoom, 37 | size: size 38 | }, callback); 39 | 40 | function callback(e) { 41 | var g = c.getContext("2d"), 42 | d = g.createImageData(w, h); 43 | tile.ready = true; 44 | procedural.dispatch({type: "load", tile: tile}); 45 | for (var i = 0, n = w * h * 4; i < n; i++) d.data[i] = e.data[i]; 46 | g.putImageData(d, 0, 0); 47 | } 48 | } 49 | 50 | return procedural; 51 | }; 52 | 53 | // like po.queue, but for workers! 54 | function _manager(src) { 55 | var queue = {}, 56 | queued = [], 57 | active = 0, 58 | size = 6, 59 | nextId = 0, 60 | callbacks = {}, 61 | worker = new Worker(src); 62 | 63 | function process() { 64 | if ((active >= size) || !queued.length) return; 65 | active++; 66 | queued.pop()(); 67 | } 68 | 69 | function dequeue(send) { 70 | for (var i = 0; i < queued.length; i++) { 71 | if (queued[i] == send) { 72 | queued.splice(i, 1); 73 | return true; 74 | } 75 | } 76 | return false; 77 | } 78 | 79 | worker.onmessage = function(e) { 80 | var id = e.data.id; 81 | active--; 82 | process(); 83 | callbacks[id](e.data); 84 | delete callbacks[id]; 85 | }; 86 | 87 | queue.work = function(data, callback) { 88 | 89 | function send() { 90 | callbacks[data.id = nextId++] = callback; 91 | worker.postMessage(data); 92 | } 93 | 94 | function abort() { 95 | return dequeue(send); 96 | } 97 | 98 | queued.push(send); 99 | process(); 100 | return {abort: abort}; 101 | }; 102 | 103 | return queue; 104 | } 105 | 106 | })(); 107 | -------------------------------------------------------------------------------- /examples/cloudmade/midnight-commander.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 26 | 27 | 28 | 29 | 30 | © 2010 31 | CloudMade, 32 | OpenStreetMap contributors, 33 | CCBYSA. 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /examples/cloudmade/midnight-commander.js: -------------------------------------------------------------------------------- 1 | var po = org.polymaps; 2 | 3 | var map = po.map() 4 | .container(document.getElementById("map").appendChild(po.svg("svg"))) 5 | .add(po.interact()) 6 | .add(po.hash()); 7 | 8 | map.add(po.image() 9 | .url(po.url("http://{S}tile.cloudmade.com" 10 | + "/1a1b06b230af4efdbb989ea99e9841af" // http://cloudmade.com/register 11 | + "/999/256/{Z}/{X}/{Y}.png") 12 | .hosts(["a.", "b.", "c.", ""]))); 13 | 14 | map.add(po.compass() 15 | .pan("none")); 16 | -------------------------------------------------------------------------------- /examples/cloudmade/pale-dawn.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 10 | 11 | 12 | 13 | 14 | © 2010 15 | CloudMade, 16 | OpenStreetMap contributors, 17 | CCBYSA. 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /examples/cloudmade/pale-dawn.js: -------------------------------------------------------------------------------- 1 | var po = org.polymaps; 2 | 3 | var map = po.map() 4 | .container(document.getElementById("map").appendChild(po.svg("svg"))) 5 | .add(po.interact()) 6 | .add(po.hash()); 7 | 8 | map.add(po.image() 9 | .url(po.url("http://{S}tile.cloudmade.com" 10 | + "/1a1b06b230af4efdbb989ea99e9841af" // http://cloudmade.com/register 11 | + "/998/256/{Z}/{X}/{Y}.png") 12 | .hosts(["a.", "b.", "c.", ""]))); 13 | 14 | map.add(po.compass() 15 | .pan("none")); 16 | -------------------------------------------------------------------------------- /examples/cluster/cluster.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 32 | 33 | 34 | 35 | 36 | © 2010 37 | CloudMade, 38 | OpenStreetMap contributors, 39 | CCBYSA. 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /examples/cluster/cluster.js: -------------------------------------------------------------------------------- 1 | var po = org.polymaps; 2 | 3 | var map = po.map() 4 | .container(document.getElementById("map").appendChild(po.svg("svg"))) 5 | .center({lat: 37.787, lon: -122.228}) 6 | .zoom(14) 7 | .zoomRange([12, 16]) 8 | .add(po.interact()); 9 | 10 | map.add(po.image() 11 | .url(po.url("http://{S}tile.cloudmade.com" 12 | + "/1a1b06b230af4efdbb989ea99e9841af" // http://cloudmade.com/register 13 | + "/20760/256/{Z}/{X}/{Y}.png") 14 | .hosts(["a.", "b.", "c.", ""]))); 15 | 16 | map.add(po.geoJson() 17 | .url(crimespotting("http://oakland.crimespotting.org" 18 | + "/crime-data" 19 | + "?count=1000" 20 | + "&format=json" 21 | + "&bbox={B}" 22 | + "&dstart=2010-04-01" 23 | + "&dend=2010-05-01")) 24 | .on("load", load) 25 | .clip(false) 26 | .zoom(14)); 27 | 28 | map.add(po.compass() 29 | .pan("none")); 30 | 31 | function load(e) { 32 | var cluster = e.tile.cluster || (e.tile.cluster = kmeans() 33 | .iterations(16) 34 | .size(64)); 35 | 36 | for (var i = 0; i < e.features.length; i++) { 37 | cluster.add(e.features[i].data.geometry.coordinates); 38 | } 39 | 40 | var tile = e.tile, g = tile.element; 41 | while (g.lastChild) g.removeChild(g.lastChild); 42 | 43 | var means = cluster.means(); 44 | means.sort(function(a, b) { return b.size - a.size; }); 45 | for (var i = 0; i < means.length; i++) { 46 | var mean = means[i], point = g.appendChild(po.svg("circle")); 47 | point.setAttribute("cx", mean.x); 48 | point.setAttribute("cy", mean.y); 49 | point.setAttribute("r", Math.pow(2, tile.zoom - 11) * Math.sqrt(mean.size)); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /examples/cluster/kmeans.js: -------------------------------------------------------------------------------- 1 | // k-means clustering 2 | function kmeans() { 3 | var kmeans = {}, 4 | points = [], 5 | iterations = 1, 6 | size = 1; 7 | 8 | kmeans.size = function(x) { 9 | if (!arguments.length) return size; 10 | size = x; 11 | return kmeans; 12 | }; 13 | 14 | kmeans.iterations = function(x) { 15 | if (!arguments.length) return iterations; 16 | iterations = x; 17 | return kmeans; 18 | }; 19 | 20 | kmeans.add = function(x) { 21 | points.push(x); 22 | return kmeans; 23 | }; 24 | 25 | kmeans.means = function() { 26 | var means = [], 27 | seen = {}, 28 | n = Math.min(size, points.length); 29 | 30 | // Initialize k random (unique!) means. 31 | for (var i = 0, m = 2 * n; i < m; i++) { 32 | var p = points[~~(Math.random() * points.length)], id = p.x + "/" + p.y; 33 | if (!(id in seen)) { 34 | seen[id] = 1; 35 | if (means.push({x: p.x, y: p.y}) >= n) break; 36 | } 37 | } 38 | n = means.length; 39 | 40 | // For each iteration, create a kd-tree of the current means. 41 | for (var j = 0; j < iterations; j++) { 42 | var kd = kdtree().points(means); 43 | 44 | // Clear the state. 45 | for (var i = 0; i < n; i++) { 46 | var mean = means[i]; 47 | mean.sumX = 0; 48 | mean.sumY = 0; 49 | mean.size = 0; 50 | mean.points = []; 51 | } 52 | 53 | // Find the mean closest to each point. 54 | for (var i = 0; i < points.length; i++) { 55 | var point = points[i], mean = kd.find(point); 56 | mean.sumX += point.x; 57 | mean.sumY += point.y; 58 | mean.size++; 59 | mean.points.push(point); 60 | } 61 | 62 | // Compute the new means. 63 | for (var i = 0; i < n; i++) { 64 | var mean = means[i]; 65 | if (!mean.size) continue; // overlapping mean 66 | mean.x = mean.sumX / mean.size; 67 | mean.y = mean.sumY / mean.size; 68 | } 69 | } 70 | 71 | return means; 72 | }; 73 | 74 | return kmeans; 75 | } 76 | 77 | // kd-tree 78 | function kdtree() { 79 | var kdtree = {}, 80 | axes = ["x", "y"], 81 | root, 82 | points = []; 83 | 84 | kdtree.axes = function(x) { 85 | if (!arguments.length) return axes; 86 | axes = x; 87 | return kdtree; 88 | }; 89 | 90 | kdtree.points = function(x) { 91 | if (!arguments.length) return points; 92 | points = x; 93 | root = null; 94 | return kdtree; 95 | }; 96 | 97 | kdtree.find = function(x) { 98 | return find(kdtree.root(), x, root).point; 99 | }; 100 | 101 | kdtree.root = function(x) { 102 | return root || (root = node(points, 0)); 103 | }; 104 | 105 | function node(points, depth) { 106 | if (!points.length) return; 107 | var axis = axes[depth % axes.length], median = points.length >> 1; 108 | points.sort(order(axis)); // could use random sample to speed up here 109 | return { 110 | axis: axis, 111 | point: points[median], 112 | left: node(points.slice(0, median), depth + 1), 113 | right: node(points.slice(median + 1), depth + 1) 114 | }; 115 | } 116 | 117 | function distance(a, b) { 118 | var sum = 0; 119 | for (var i = 0; i < axes.length; i++) { 120 | var axis = axes[i], d = a[axis] - b[axis]; 121 | sum += d * d; 122 | } 123 | return sum; 124 | } 125 | 126 | function order(axis) { 127 | return function(a, b) { 128 | a = a[axis]; 129 | b = b[axis]; 130 | return a < b ? -1 : a > b ? 1 : 0; 131 | }; 132 | } 133 | 134 | function find(node, point, best) { 135 | if (distance(node.point, point) < distance(best.point, point)) best = node; 136 | if (node.left) best = find(node.left, point, best); 137 | if (node.right) { 138 | var d = node.point[node.axis] - point[node.axis]; 139 | if (d * d < distance(best.point, point)) best = find(node.right, point, best); 140 | } 141 | return best; 142 | } 143 | 144 | return kdtree; 145 | } 146 | -------------------------------------------------------------------------------- /examples/example.css: -------------------------------------------------------------------------------- 1 | html, body { 2 | height: 100%; 3 | } 4 | 5 | body { 6 | margin: 0; 7 | background: #E5E0D9; 8 | } 9 | 10 | svg { 11 | display: block; 12 | overflow: hidden; 13 | width: 100%; 14 | height: 100%; 15 | } 16 | 17 | #copy { 18 | position: absolute; 19 | left: 0; 20 | bottom: 4px; 21 | padding-left: 5px; 22 | font: 9px sans-serif; 23 | color: #fff; 24 | cursor: default; 25 | } 26 | 27 | #copy a { 28 | color: #fff; 29 | } 30 | 31 | .compass .back { 32 | fill: #eee; 33 | fill-opacity: .8; 34 | } 35 | 36 | .compass .fore { 37 | stroke: #999; 38 | stroke-width: 1.5px; 39 | } 40 | 41 | .compass rect.back.fore { 42 | fill: #999; 43 | fill-opacity: .3; 44 | stroke: #eee; 45 | stroke-width: 1px; 46 | shape-rendering: crispEdges; 47 | } 48 | 49 | .compass .direction { 50 | fill: none; 51 | } 52 | 53 | .compass .chevron { 54 | fill: none; 55 | stroke: #999; 56 | stroke-width: 5px; 57 | } 58 | 59 | .compass .zoom .chevron { 60 | stroke-width: 4px; 61 | } 62 | 63 | .compass .active .chevron, .compass .chevron.active { 64 | stroke: #fff; 65 | } 66 | 67 | .compass.active .active .direction { 68 | fill: #999; 69 | } 70 | -------------------------------------------------------------------------------- /examples/features/features.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 22 | 23 | 24 | 70 | 71 | © 2010 72 | CloudMade, 73 | OpenStreetMap contributors, 74 | CCBYSA. 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /examples/grid/grid.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 16 | 17 | 18 | 19 | 20 | © 2010 21 | CloudMade, 22 | OpenStreetMap contributors, 23 | CCBYSA. 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /examples/grid/grid.js: -------------------------------------------------------------------------------- 1 | var po = org.polymaps; 2 | 3 | var map = po.map() 4 | .container(document.getElementById("map").appendChild(po.svg("svg"))) 5 | .add(po.interact()); 6 | 7 | map.add(po.image() 8 | .url(po.url("http://{S}tile.cloudmade.com" 9 | + "/1a1b06b230af4efdbb989ea99e9841af" // http://cloudmade.com/register 10 | + "/998/256/{Z}/{X}/{Y}.png") 11 | .hosts(["a.", "b.", "c.", ""]))); 12 | 13 | map.add(po.grid()); 14 | 15 | map.add(po.compass() 16 | .pan("none")); 17 | -------------------------------------------------------------------------------- /examples/grid/tiles.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /examples/grid/tiles.js: -------------------------------------------------------------------------------- 1 | var po = org.polymaps; 2 | 3 | var div = document.getElementById("map"), 4 | svg = div.appendChild(po.svg("svg")), 5 | g = svg.appendChild(po.svg("g")); 6 | 7 | var map = po.map() 8 | .container(g) 9 | .tileSize({x: 128, y: 128}) 10 | .angle(.3) 11 | .add(po.interact()) 12 | .on("resize", resize); 13 | 14 | resize(); 15 | 16 | map.add(po.layer(grid)); 17 | 18 | var rect = g.appendChild(po.svg("rect")); 19 | rect.setAttribute("width", "50%"); 20 | rect.setAttribute("height", "50%"); 21 | 22 | function resize() { 23 | if (resize.ignore) return; 24 | var x = div.clientWidth / 2, 25 | y = div.clientHeight / 2; 26 | g.setAttribute("transform", "translate(" + (x / 2) + "," + (y / 2) + ")"); 27 | resize.ignore = true; 28 | map.size({x: x, y: y}); 29 | resize.ignore = false; 30 | } 31 | 32 | function grid(tile) { 33 | var g = tile.element = po.svg("g"); 34 | 35 | var rect = g.appendChild(po.svg("rect")), 36 | size = map.tileSize(); 37 | rect.setAttribute("width", size.x); 38 | rect.setAttribute("height", size.y); 39 | 40 | var text = g.appendChild(po.svg("text")); 41 | text.setAttribute("x", 6); 42 | text.setAttribute("y", 6); 43 | text.setAttribute("dy", ".71em"); 44 | text.appendChild(document.createTextNode(tile.key)); 45 | } 46 | 47 | var spin = 0; 48 | setInterval(function() { 49 | if (spin) map.angle(map.angle() + spin); 50 | }, 30); 51 | 52 | function key(e) { 53 | switch (e.keyCode) { 54 | case 65: spin = e.type == "keydown" ? -.004 : 0; break; 55 | case 68: spin = e.type == "keydown" ? .004 : 0; break; 56 | } 57 | } 58 | 59 | window.addEventListener("keydown", key, true); 60 | window.addEventListener("keyup", key, true); 61 | window.addEventListener("resize", resize, false); 62 | -------------------------------------------------------------------------------- /examples/hilbert/hilbert.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /examples/hilbert/hilbert.js: -------------------------------------------------------------------------------- 1 | hilbert = (function() { 2 | // Adapted from Nick Johnson: http://bit.ly/biWkkq 3 | var pairs = [ 4 | [[0, 3], [1, 0], [3, 1], [2, 0]], 5 | [[2, 1], [1, 1], [3, 0], [0, 2]], 6 | [[2, 2], [3, 3], [1, 2], [0, 1]], 7 | [[0, 0], [3, 2], [1, 3], [2, 3]] 8 | ]; 9 | return function(x, y, z) { 10 | var quad = 0, 11 | pair, 12 | i = 0; 13 | while (--z >= 0) { 14 | pair = pairs[quad][(x & (1 << z) ? 2 : 0) | (y & (1 << z) ? 1 : 0)]; 15 | i = (i << 2) | pair[0]; 16 | quad = pair[1]; 17 | } 18 | return i; 19 | }; 20 | })(); 21 | 22 | var po = org.polymaps; 23 | 24 | var size = {x: 32, y: 32}; 25 | 26 | var map = po.map() 27 | .container(document.getElementById("map").appendChild(po.svg("svg"))) 28 | .zoomRange([0, 6]) 29 | .tileSize(size) 30 | .add(po.interact()) 31 | .add(po.hash()); 32 | 33 | map.add(po.layer(rainbow)); 34 | 35 | map.add(po.compass() 36 | .pan("none")); 37 | 38 | function rainbow(tile) { 39 | var rect = tile.element = po.svg("rect"), 40 | i = hilbert(tile.column, tile.row, tile.zoom), 41 | j = i / (Math.pow(4, tile.zoom) - 1), 42 | k = 1 << tile.zoom; 43 | if (tile.column < 0 || tile.column >= k) return; 44 | rect.setAttribute("width", size.x); 45 | rect.setAttribute("height", size.y); 46 | rect.setAttribute("fill", hsl(30, .2, j)); 47 | } 48 | 49 | function hsl(h, s, l) { 50 | var m1, 51 | m2; 52 | 53 | /* Some simple corrections for h, s and l. */ 54 | h = h % 360; if (h < 0) h += 360; 55 | s = s < 0 ? 0 : s > 1 ? 1 : s; 56 | l = l < 0 ? 0 : l > 1 ? 1 : l; 57 | 58 | /* From FvD 13.37, CSS Color Module Level 3 */ 59 | m2 = l <= .5 ? l * (1 + s) : l + s - l * s; 60 | m1 = 2 * l - m2; 61 | 62 | function v(h) { 63 | if (h > 360) h -= 360; 64 | else if (h < 0) h += 360; 65 | if (h < 60) return m1 + (m2 - m1) * h / 60; 66 | if (h < 180) return m2; 67 | if (h < 240) return m1 + (m2 - m1) * (240 - h) / 60; 68 | return m1; 69 | } 70 | 71 | function vv(h) { 72 | return Math.round(v(h) * 255); 73 | } 74 | 75 | return "rgb(" + vv(h + 120) + "," + vv(h) + "," + vv(h - 120) + ")"; 76 | } 77 | -------------------------------------------------------------------------------- /examples/invert/invert.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 19 | 20 | 21 | 64 | 65 | © 2010 66 | CloudMade, 67 | OpenStreetMap contributors, 68 | CCBYSA. 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /examples/iphone4/iphone4.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 11 | 12 | 13 | 14 | 15 | © 2011 16 | CloudMade, 17 | OpenStreetMap contributors, 18 | CCBYSA. 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /examples/iphone4/iphone4.js: -------------------------------------------------------------------------------- 1 | var po = org.polymaps; 2 | 3 | // Note: po.interact has built-in touch support! 4 | var map = po.map() 5 | .container(document.getElementById("map").appendChild(po.svg("svg"))) 6 | .add(po.interact()); 7 | 8 | // Compute zoom offset for retina display. 9 | var dz = Math.log(window.devicePixelRatio || 1) / Math.LN2; 10 | 11 | // CloudMade image tiles, hooray! 12 | map.add(po.image() 13 | .url(po.url("http://{S}tile.cloudmade.com" 14 | + "/1a1b06b230af4efdbb989ea99e9841af" // http://cloudmade.com/register 15 | + "/998/256/{Z}/{X}/{Y}.png") 16 | .hosts(["a.", "b.", "c.", ""])) 17 | .zoom(function(z) { return z + dz; })); 18 | 19 | // no compass! pinch-to-zoom ftw 20 | -------------------------------------------------------------------------------- /examples/kml/kml.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | KML 5 | 6 | 7 | 25 | 26 | 27 | 61 | 62 | © 2010 63 | CloudMade, 64 | OpenStreetMap contributors, 65 | CCBYSA. 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /examples/kml/kml.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | var po = org.polymaps; 3 | 4 | po.kml = function() { 5 | var kml = po.geoJson(fetch); 6 | 7 | function fetch(url, update) { 8 | return po.queue.xml(url, function(xml) { 9 | update(geoJson(xml)); 10 | }); 11 | } 12 | 13 | var types = { 14 | 15 | Point: function(e) { 16 | return { 17 | type: "Point", 18 | coordinates: e.getElementsByTagName("coordinates")[0] 19 | .textContent 20 | .split(",") 21 | .map(Number) 22 | }; 23 | }, 24 | 25 | LineString: function(e) { 26 | return { 27 | type: "LineString", 28 | coordinates: e.getElementsByTagName("coordinates")[0] 29 | .textContent 30 | .trim() 31 | .split(/\s+/) 32 | .map(function(a) { return a.split(",").slice(0, 2).map(Number); }) 33 | }; 34 | } 35 | 36 | }; 37 | 38 | function geometry(e) { 39 | return e && e.tagName in types && types[e.tagName](e); 40 | } 41 | 42 | function geoJson(xml) { 43 | var features = [], 44 | placemarks = xml.getElementsByTagName("Placemark"); 45 | for (var i = 0; i < placemarks.length; i++) { 46 | var e = placemarks[i], 47 | f = {id: e.getAttribute("id"), properties: {}}; 48 | for (var c = e.firstChild; c; c = c.nextSibling) { 49 | switch (c.tagName) { 50 | case "name": f.properties.name = c.textContent; continue; 51 | case "description": f.properties.description = c.textContent; continue; 52 | } 53 | var g = geometry(c); 54 | if (g) f.geometry = g; 55 | } 56 | if (f.geometry) features.push(f); 57 | } 58 | return {type: "FeatureCollection", features: features}; 59 | } 60 | 61 | return kml; 62 | }; 63 | })(); 64 | -------------------------------------------------------------------------------- /examples/loupe/loupe-map.js: -------------------------------------------------------------------------------- 1 | var po = org.polymaps; 2 | 3 | var map = po.map() 4 | .container(document.getElementById("map").appendChild(po.svg("svg"))) 5 | .add(po.interact()) 6 | .add(po.hash()); 7 | 8 | map.add(po.image() 9 | .url(po.url("http://{S}tile.cloudmade.com" 10 | + "/1a1b06b230af4efdbb989ea99e9841af" // http://cloudmade.com/register 11 | + "/998/256/{Z}/{X}/{Y}.png") 12 | .hosts(["a.", "b.", "c.", ""]))); 13 | 14 | map.add(po.loupe() 15 | .add(po.image() 16 | .url(po.url("http://{S}tile.cloudmade.com" 17 | + "/1a1b06b230af4efdbb989ea99e9841af" // http://cloudmade.com/register 18 | + "/999/256/{Z}/{X}/{Y}.png") 19 | .hosts(["a.", "b.", "c.", ""])))); 20 | 21 | map.add(po.compass() 22 | .pan("none")); 23 | -------------------------------------------------------------------------------- /examples/loupe/loupe.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 21 | 22 | 23 | 24 | 25 | © 2010 26 | CloudMade, 27 | OpenStreetMap contributors, 28 | CCBYSA. 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /examples/loupe/loupe.js: -------------------------------------------------------------------------------- 1 | (function(po) { 2 | po.loupe = function() { 3 | var loupe = po.map(), 4 | container = po.svg("g"), 5 | clipId = "org.polymaps." + po.id(), 6 | clipHref = "url(#" + clipId + ")", 7 | clipPath = container.appendChild(po.svg("clipPath")), 8 | clipCircle = clipPath.appendChild(po.svg("circle")), 9 | back = po.svg("circle"), 10 | tab = po.svg("path"), 11 | fore = po.svg("circle"), 12 | centerPoint = null, 13 | zoomDelta = 0, 14 | tabPosition = "bottom-right", 15 | tabAngles = {"top-left": 180, "top-right": 270, "bottom-left": 90}, 16 | visible = true, 17 | r = 128, 18 | rr = [64, 384], 19 | k = 1, 20 | map, 21 | f0, 22 | m0, 23 | p0, 24 | repeatInterval, 25 | repeatRate = 30, 26 | repeatPan = {x: 0, y: 0}; 27 | 28 | loupe 29 | .size({x: r * 2, y: r * 2}) 30 | .container(container) 31 | .centerRange(null) 32 | .zoomRange(null) 33 | .on("move", loupemove); 34 | 35 | container.appendChild(back).setAttribute("class", "back"); 36 | container.appendChild(tab).setAttribute("class", "tab"); 37 | container.appendChild(fore).setAttribute("class", "fore"); 38 | clipPath.setAttribute("id", clipId); 39 | container.setAttribute("class", "map loupe"); 40 | 41 | back.addEventListener("mousedown", mousedown, false); 42 | tab.addEventListener("mousedown", mousedown, false); 43 | fore.addEventListener("mousedown", foredown, false); 44 | fore.setAttribute("fill", "none"); 45 | fore.setAttribute("cursor", "ew-resize"); 46 | window.addEventListener("mouseup", mouseup, false); 47 | window.addEventListener("mousemove", mousemove, false); 48 | 49 | // update the center point if the center is set explicitly 50 | function loupemove() { 51 | if (!map) return; 52 | loupe.centerPoint(map.locationPoint(loupe.center())); 53 | } 54 | 55 | // update the center and zoom level if the underlying map moves 56 | function mapmove() { 57 | if (!map) return; 58 | var z0 = map.zoom() + zoomDelta, 59 | z1 = loupe.zoom(); 60 | loupe.off("move", loupemove) 61 | .zoomBy(z0 - z1, {x: r, y: r}, map.pointLocation(centerPoint)) 62 | .on("move", loupemove); 63 | clipCircle.setAttribute("r", r * (k = Math.pow(2, Math.round(z0) - z0))); 64 | container.setAttribute("transform", "translate(" + (centerPoint.x - r) + "," + (centerPoint.y - r) + ")"); 65 | } 66 | 67 | function foredown(e) { 68 | f0 = true; 69 | document.body.style.setProperty("cursor", "ew-resize", null); 70 | map.focusableParent().focus(); 71 | return cancel(e); 72 | } 73 | 74 | function foremove(e) { 75 | var p0 = map.mouse(e), 76 | p1 = loupe.centerPoint(), 77 | dx = p1.x - p0.x, 78 | dy = p1.y - p0.y, 79 | r = Math.sqrt(dx * dx + dy * dy); 80 | loupe.radius(r ^ (r & 1)); 81 | return cancel(e); 82 | } 83 | 84 | function mousedown(e) { 85 | m0 = map.mouse(e); 86 | p0 = loupe.centerPoint(); 87 | map.focusableParent().focus(); 88 | return cancel(e); 89 | } 90 | 91 | function mousemove(e) { 92 | if (f0) return foremove(e); 93 | if (!m0) return; 94 | var m1 = map.mouse(e), 95 | size = map.size(), 96 | x = p0.x - m0.x + m1.x, 97 | y = p0.y - m0.y + m1.y; 98 | 99 | // determine whether we're offscreen 100 | repeatPan.x = x < 0 ? -x : x > size.x ? size.x - x : 0; 101 | repeatPan.y = y < 0 ? -y : y > size.y ? size.y - y : 0; 102 | 103 | // if the loupe is offscreen, start a new pan interval 104 | if (repeatPan.x || repeatPan.y) { 105 | repeatPan.x /= 10; 106 | repeatPan.y /= 10; 107 | if (!repeatInterval) repeatInterval = setInterval(mouserepeat, repeatRate); 108 | } else if (repeatInterval) { 109 | repeatInterval = clearInterval(repeatInterval); 110 | } 111 | 112 | centerPoint = {x: Math.round(x), y: Math.round(y)}; 113 | mapmove(); 114 | return cancel(e); 115 | } 116 | 117 | function mouserepeat() { 118 | map.panBy(repeatPan); 119 | } 120 | 121 | function mouseup(e) { 122 | if (f0) { 123 | f0 = null; 124 | document.body.style.removeProperty("cursor"); 125 | } 126 | if (m0) { 127 | if (repeatInterval) repeatInterval = clearInterval(repeatInterval); 128 | m0 = p0 = null; 129 | } 130 | return cancel(e); 131 | } 132 | 133 | function cancel(e) { 134 | e.stopPropagation(); 135 | e.preventDefault(); 136 | return false; 137 | } 138 | 139 | loupe.map = function(x) { 140 | if (!arguments.length) return map; 141 | if (map) { 142 | map.container().removeChild(loupe.container()); 143 | map.off("move", move).off("resize", move); 144 | } 145 | if (map = x) { 146 | if (!centerPoint) { 147 | var size = map.size(); 148 | centerPoint = {x: size.x >> 1, y: size.y >> 1}; 149 | } 150 | map.on("move", mapmove).on("resize", mapmove); 151 | map.container().appendChild(loupe.container()); 152 | mapmove(); 153 | } 154 | return loupe; 155 | }; 156 | 157 | var __add__ = loupe.add; 158 | loupe.add = function(x) { 159 | __add__(x); 160 | if (x.container) { 161 | x = x.container(); 162 | x.setAttribute("clip-path", clipHref); 163 | x.setAttribute("pointer-events", "none"); 164 | } 165 | container.appendChild(fore); // move to end 166 | return loupe; 167 | }; 168 | 169 | loupe.centerPoint = function(x) { 170 | if (!arguments.length) return centerPoint; 171 | centerPoint = {x: Math.round(x.x), y: Math.round(x.y)}; 172 | if (map) mapmove(); 173 | return loupe; 174 | }; 175 | 176 | loupe.radiusRange = function(x) { 177 | if (!arguments.length) return rr; 178 | rr = x; 179 | return loupe.radius(r); 180 | }; 181 | 182 | loupe.radius = function(x) { 183 | if (!arguments.length) return r; 184 | r = rr ? Math.max(rr[0], Math.min(rr[1], x)) : x; 185 | 186 | // update back, fore and clip 187 | back.setAttribute("cx", r); 188 | back.setAttribute("cy", r); 189 | back.setAttribute("r", r); 190 | fore.setAttribute("cx", r); 191 | fore.setAttribute("cy", r); 192 | fore.setAttribute("r", r); 193 | clipCircle.setAttribute("r", r * k); 194 | 195 | // update the tab path 196 | tab.setAttribute("d", "M" + r + "," + 2 * r 197 | + "H" + 1.9 * r 198 | + "A" + r * .1 + "," + r * .1 + " 0 0,0 " + 2 * r + "," + 1.9 * r 199 | + "V" + r 200 | + "A" + r + "," + r + " 0 0,1 " + r + "," + 2 * r 201 | + "Z"); 202 | 203 | // update the tab position 204 | if (tabPosition == "none") tab.setAttribute("display", "none"); 205 | else { 206 | tab.removeAttribute("display"); 207 | var a = tabAngles[tabPosition]; 208 | if (a) tab.setAttribute("transform", "rotate(" + a + " " + r + "," + r + ")"); 209 | else tab.removeAttribute("transform"); 210 | } 211 | 212 | // update map size 213 | loupe.size({x: r * 2, y: r * 2}) 214 | 215 | if (map) mapmove(); 216 | return loupe; 217 | }; 218 | 219 | loupe.tab = function(x) { 220 | if (!arguments.length) return tabPosition; 221 | tabPosition = x; 222 | return loupe.radius(r); 223 | }; 224 | 225 | loupe.zoomDelta = function(x) { 226 | if (!arguments.length) return zoomDelta; 227 | zoomDelta = x; 228 | if (map) mapmove(); 229 | return loupe; 230 | }; 231 | 232 | loupe.visible = function(x) { 233 | if (!arguments.length) return visible; 234 | visible = x; 235 | if (x) g.removeAttribute("visibility"); 236 | else g.setAttribute("visibility", "hidden"); 237 | return loupe; 238 | }; 239 | 240 | loupe.radius(r); // initialize circles 241 | 242 | return loupe; 243 | }; 244 | })(org.polymaps); 245 | -------------------------------------------------------------------------------- /examples/marker/marker.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 30 | 31 | 32 | 33 | 34 | © 2010 35 | CloudMade, 36 | OpenStreetMap contributors, 37 | CCBYSA. 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /examples/marker/marker.js: -------------------------------------------------------------------------------- 1 | var po = org.polymaps; 2 | 3 | var svg = document.getElementById("map").appendChild(po.svg("svg")), 4 | defs = svg.appendChild(po.svg("defs")); 5 | 6 | /* Create three linear gradients for each category. */ 7 | defs.appendChild(gradient("#D90000", "#A30000")).setAttribute("id", "gradient-violent"); 8 | defs.appendChild(gradient("#23965E", "#1A7046")).setAttribute("id", "gradient-property"); 9 | defs.appendChild(gradient("#3489BA", "#27678B")).setAttribute("id", "gradient-quality"); 10 | 11 | /* Create a marker path. */ 12 | defs.appendChild(icons.marker()).setAttribute("id", "marker"); 13 | 14 | var map = po.map() 15 | .container(svg) 16 | .center({lat: 37.787, lon: -122.228}) 17 | .zoomRange([11,16]) 18 | .zoom(12) 19 | .add(po.interact()); 20 | 21 | map.add(po.image() 22 | .url(po.url("http://{S}tile.cloudmade.com" 23 | + "/1a1b06b230af4efdbb989ea99e9841af" // http://cloudmade.com/register 24 | + "/998/256/{Z}/{X}/{Y}.png") 25 | .hosts(["a.", "b.", "c.", ""]))); 26 | 27 | map.add(po.geoJson() 28 | .url(crimespotting("http://oakland.crimespotting.org" 29 | + "/crime-data" 30 | + "?count=100" 31 | + "&format=json" 32 | + "&bbox={B}" 33 | + "&dstart=2010-04-01" 34 | + "&dend=2010-04-01")) 35 | .on("load", load) 36 | .clip(false) 37 | .scale("fixed") 38 | .zoom(12)); 39 | 40 | map.add(po.compass() 41 | .pan("none")); 42 | 43 | /* Post-process the GeoJSON points and replace them with markers! */ 44 | function load(e) { 45 | e.features.sort(function(a, b) { 46 | return b.data.geometry.coordinates[1] - a.data.geometry.coordinates[1]; 47 | }); 48 | for (var i = 0; i < e.features.length; i++) { 49 | var f = e.features[i], 50 | d = f.data, 51 | c = f.element, 52 | p = c.parentNode, 53 | u = f.element = po.svg("use"); 54 | u.setAttributeNS(po.ns.xlink, "href", "url(#marker)"); 55 | u.setAttribute("transform", c.getAttribute("transform")); 56 | u.setAttribute("fill", "url(#gradient-" + crimespotting.categorize(d) + ")"); 57 | p.removeChild(c); 58 | p.appendChild(u); 59 | } 60 | } 61 | 62 | /* Helper method for constructing a linear gradient. */ 63 | function gradient(a, b) { 64 | var g = po.svg("linearGradient"); 65 | g.setAttribute("x1", 0); 66 | g.setAttribute("y1", 1); 67 | g.setAttribute("x2", 0); 68 | g.setAttribute("y2", 0); 69 | var s0 = g.appendChild(po.svg("stop")); 70 | s0.setAttribute("offset", "0%"); 71 | s0.setAttribute("stop-color", a); 72 | var s1 = g.appendChild(po.svg("stop")); 73 | s1.setAttribute("offset", "100%"); 74 | s1.setAttribute("stop-color", b); 75 | return g; 76 | } 77 | -------------------------------------------------------------------------------- /examples/nasa/blue-marble.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 18 | 19 | 20 |
21 | 22 |
23 | Courtesy NASA Earth Observatory. 24 |
25 | 26 | 27 | -------------------------------------------------------------------------------- /examples/nasa/blue-marble.js: -------------------------------------------------------------------------------- 1 | var po = org.polymaps; 2 | 3 | var map = po.map() 4 | .container(document.getElementById("map").appendChild(po.svg("svg"))) 5 | .zoomRange([0, 9]) 6 | .zoom(7) 7 | .add(po.image().url("http://s3.amazonaws.com/com.modestmaps.bluemarble/{Z}-r{Y}-c{X}.jpg")) 8 | .add(po.interact()) 9 | .add(po.compass().pan("none")); 10 | -------------------------------------------------------------------------------- /examples/overlay/overlay.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 10 | 11 | 12 | 13 | 14 | © 2010 15 | CloudMade, 16 | OpenStreetMap contributors, 17 | CCBYSA. 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /examples/overlay/overlay.js: -------------------------------------------------------------------------------- 1 | var po = org.polymaps; 2 | 3 | var map = po.map() 4 | .container(document.getElementById("map").appendChild(po.svg("svg"))) 5 | .zoomRange([12, 15]) 6 | .add(po.interact()); 7 | 8 | map.add(po.image() 9 | .url(po.url("http://{S}tile.cloudmade.com" 10 | + "/1a1b06b230af4efdbb989ea99e9841af" // http://cloudmade.com/register 11 | + "/998/256/{Z}/{X}/{Y}.png") 12 | .hosts(["a.", "b.", "c.", ""]))); 13 | 14 | map.add(po.layer(overlay) 15 | .tile(false)); 16 | 17 | map.add(po.compass() 18 | .pan("none")); 19 | 20 | /** A lightweight layer implementation for an image overlay. */ 21 | function overlay(tile, proj) { 22 | proj = proj(tile); 23 | var tl = proj.locationPoint({lon: -122.518, lat: 37.816}), 24 | br = proj.locationPoint({lon: -122.375, lat: 37.755}), 25 | image = tile.element = po.svg("image"); 26 | image.setAttribute("preserveAspectRatio", "none"); 27 | image.setAttribute("x", tl.x); 28 | image.setAttribute("y", tl.y); 29 | image.setAttribute("width", br.x - tl.x); 30 | image.setAttribute("height", br.y - tl.y); 31 | image.setAttributeNS("http://www.w3.org/1999/xlink", "href", "sf1906.png"); 32 | } 33 | -------------------------------------------------------------------------------- /examples/overlay/sf1906.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mbostock/polymaps/6cc4513810c3c063229f7f74d474418ce1929d6c/examples/overlay/sf1906.png -------------------------------------------------------------------------------- /examples/population/population.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Population Density 5 | 6 | 41 | 42 | 43 | 44 | 45 | © 2010 46 | CloudMade, 47 | OpenStreetMap contributors, 48 | CCBYSA. 49 | Colors by Cynthia Brewer. 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /examples/population/population.js: -------------------------------------------------------------------------------- 1 | var po = org.polymaps; 2 | 3 | var map = po.map() 4 | .container(document.getElementById("map").appendChild(po.svg("svg"))) 5 | .center({lat: 39, lon: -96}) 6 | .zoom(4) 7 | .zoomRange([3, 7]) 8 | .add(po.interact()); 9 | 10 | map.add(po.image() 11 | .url(po.url("http://{S}tile.cloudmade.com" 12 | + "/1a1b06b230af4efdbb989ea99e9841af" // http://cloudmade.com/register 13 | + "/20760/256/{Z}/{X}/{Y}.png") 14 | .hosts(["a.", "b.", "c.", ""]))); 15 | 16 | map.add(po.geoJson() 17 | .url("http://polymaps.appspot.com/county/{Z}/{X}/{Y}.json") 18 | .on("load", load) 19 | .id("county")); 20 | 21 | map.add(po.geoJson() 22 | .url("http://polymaps.appspot.com/state/{Z}/{X}/{Y}.json") 23 | .id("state")); 24 | 25 | map.add(po.compass() 26 | .pan("none")); 27 | 28 | function load(e) { 29 | for (var i = 0; i < e.features.length; i++) { 30 | var feature = e.features[i]; 31 | feature.element.setAttribute("id", feature.data.id); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /examples/shadow/shadow.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 11 | 12 | 13 | 14 | 15 | © 2010 16 | CloudMade, 17 | OpenStreetMap contributors, 18 | CCBYSA. 19 | Ball by Dmitry Baranovskiy. 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /examples/shadow/shadow.js: -------------------------------------------------------------------------------- 1 | var po = org.polymaps; 2 | 3 | var svg = n$("#map").add("svg:svg"); 4 | 5 | var map = po.map() 6 | .container($n(svg)) 7 | .center({lat: 37.787, lon: -122.228}) 8 | .zoom(12) 9 | .add(po.interact()); 10 | 11 | map.add(po.image() 12 | .url(po.url("http://{S}tile.cloudmade.com" 13 | + "/1a1b06b230af4efdbb989ea99e9841af" // http://cloudmade.com/register 14 | + "/998/256/{Z}/{X}/{Y}.png") 15 | .hosts(["a.", "b.", "c.", ""]))); 16 | 17 | map.add(po.geoJson() 18 | .features([{geometry: {coordinates: [-122.258, 37.805], type: "Point"}}]) 19 | .on("load", load)); 20 | 21 | map.add(po.compass() 22 | .pan("none")); 23 | 24 | /* Create a shadow filter. */ 25 | svg.add("svg:filter") 26 | .attr("id", "shadow") 27 | .attr("width", "140%") 28 | .attr("height", "140%") 29 | .add("svg:feGaussianBlur") 30 | .attr("in", "SourceAlpha") 31 | .attr("stdDeviation", 3); 32 | 33 | /* Create radial gradient r1. */ 34 | svg.add("svg:radialGradient") 35 | .attr("id", "r1") 36 | .attr("fx", 0.5) 37 | .attr("fy", 0.9) 38 | .add("svg:stop") 39 | .attr("offset", "0%") 40 | .attr("stop-color", "#00bf17") 41 | .parent() 42 | .add("svg:stop") 43 | .attr("offset", "100%") 44 | .attr("stop-color", "#0f2f13"); 45 | 46 | /* Create radial gradient r2. */ 47 | svg.add("svg:radialGradient") 48 | .attr("id", "r2") 49 | .attr("fx", 0.5) 50 | .attr("fy", 0.1) 51 | .add("svg:stop") 52 | .attr("offset", "0%") 53 | .attr("stop-color", "#cccccc") 54 | .parent() 55 | .add("svg:stop") 56 | .attr("offset", "100%") 57 | .attr("stop-color", "#cccccc") 58 | .attr("stop-opacity", 0); 59 | 60 | /** Post-process the GeoJSON points and replace them with shiny balls! */ 61 | function load(e) { 62 | var r = 20 * Math.pow(2, e.tile.zoom - 12); 63 | for (var i = 0; i < e.features.length; i++) { 64 | var c = n$(e.features[i].element), 65 | g = c.parent().add("svg:g", c); 66 | 67 | g.attr("transform", "translate(" + c.attr("cx") + "," + c.attr("cy") + ")"); 68 | 69 | g.add("svg:circle") 70 | .attr("r", r) 71 | .attr("transform", "translate(" + r + ",0)skewX(-45)") 72 | .attr("opacity", .5) 73 | .attr("filter", "url(#shadow)"); 74 | 75 | g.add(c 76 | .attr("fill", "url(#r1)") 77 | .attr("r", r) 78 | .attr("cx", null) 79 | .attr("cy", null)); 80 | 81 | g.add("svg:circle") 82 | .attr("transform", "scale(.95,1)") 83 | .attr("fill", "url(#r2)") 84 | .attr("r", r); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /examples/small/small.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 22 | 23 | 24 |
25 | 40 |
41 | © 2010 42 | CloudMade, 43 | OpenStreetMap contributors, 44 | CCBYSA. 45 |
46 | 47 | 48 | -------------------------------------------------------------------------------- /examples/small/static.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 32 | 33 | 34 |
35 |
36 | © 2010 37 | CloudMade, 38 | OpenStreetMap contributors, 39 | CCBYSA. 40 |
41 |
42 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /examples/statehood/fips.js: -------------------------------------------------------------------------------- 1 | var fips = { 2 | "Alabama": "01", 3 | "Alaska": "02", 4 | "Arizona": "04", 5 | "Arkansas": "05", 6 | "California": "06", 7 | "Colorado": "08", 8 | "Connecticut": "09", 9 | "Delaware": "10", 10 | "District of Columbia": "11", 11 | "Florida": "12", 12 | "Georgia": "13", 13 | "Hawaii": "15", 14 | "Idaho": "16", 15 | "Illinois": "17", 16 | "Indiana": "18", 17 | "Iowa": "19", 18 | "Kansas": "20", 19 | "Kentucky": "21", 20 | "Louisiana": "22", 21 | "Maine": "23", 22 | "Maryland": "24", 23 | "Massachusetts": "25", 24 | "Michigan": "26", 25 | "Minnesota": "27", 26 | "Mississippi": "28", 27 | "Missouri": "29", 28 | "Montana": "30", 29 | "Nebraska": "31", 30 | "Nevada": "32", 31 | "New Hampshire": "33", 32 | "New Jersey": "34", 33 | "New Mexico": "35", 34 | "New York": "36", 35 | "North Carolina": "37", 36 | "North Dakota": "38", 37 | "Ohio": "39", 38 | "Oklahoma": "40", 39 | "Oregon": "41", 40 | "Pennsylvania": "42", 41 | "Rhode Island": "44", 42 | "South Carolina": "45", 43 | "South Dakota": "46", 44 | "Tennessee": "47", 45 | "Texas": "48", 46 | "Utah": "49", 47 | "Vermont": "50", 48 | "Virginia": "51", 49 | "Washington": "53", 50 | "West Virginia": "54", 51 | "Wisconsin": "55", 52 | "Wyoming": "56" 53 | }; 54 | 55 | var statehood = { 56 | "Delaware": "December 7, 1787", 57 | "Pennsylvania": "December 12, 1787", 58 | "New Jersey": "December 18, 1787", 59 | "Georgia": "January 2, 1788", 60 | "Connecticut": "January 9, 1788", 61 | "Massachusetts": "February 6, 1788", 62 | "Maryland": "April 28, 1788", 63 | "South Carolina": "May 23, 1788", 64 | "New Hampshire": "June 21, 1788", 65 | "Virginia": "June 25, 1788", 66 | "New York": "July 26, 1788", 67 | "North Carolina": "November 21, 1789", 68 | "Rhode Island": "May 29, 1790", 69 | "Vermont": "March 4, 1791", 70 | "Kentucky": "June 1, 1792", 71 | "Tennessee": "June 1, 1796", 72 | "Ohio": "March 1, 1803*", 73 | "Louisiana": "April 30, 1812", 74 | "Indiana": "December 11, 1816", 75 | "Mississippi": "December 10, 1817", 76 | "Illinois": "December 3, 1818", 77 | "Alabama": "December 14, 1819", 78 | "Maine": "March 15, 1820", 79 | "Missouri": "August 10, 1821", 80 | "Arkansas": "June 15, 1836", 81 | "Michigan": "January 26, 1837", 82 | "Florida": "March 3, 1845", 83 | "Texas": "December 29, 1845", 84 | "Iowa": "December 28, 1846", 85 | "Wisconsin": "May 29, 1848", 86 | "California": "September 9, 1850", 87 | "Minnesota": "May 11, 1858", 88 | "Oregon": "February 14, 1859", 89 | "Kansas": "January 29, 1861", 90 | "West Virginia": "June 20, 1863", 91 | "Nevada": "October 31, 1864", 92 | "Nebraska": "March 1, 1867", 93 | "Colorado": "August 1, 1876", 94 | "North Dakota": "November 2, 1889", 95 | "South Dakota": "November 2, 1889", 96 | "Montana": "November 8, 1889", 97 | "Washington": "November 11, 1889", 98 | "Idaho": "July 3, 1890", 99 | "Wyoming": "July 10, 1890", 100 | "Utah": "January 4, 1896", 101 | "Oklahoma": "November 16, 1907", 102 | "New Mexico": "January 6, 1912", 103 | "Arizona": "February 14, 1912", 104 | "Alaska": "January 3, 1959", 105 | "Hawaii": "August 21, 1959" 106 | }; 107 | 108 | // Parse dates and convert to FIPS codes. 109 | var states = {}; 110 | for (var state in statehood) { 111 | states[fips[state]] = new Date(statehood[state]); 112 | } 113 | -------------------------------------------------------------------------------- /examples/statehood/statehood.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | U.S. Statehood by Date 5 | 6 | 7 | 8 | 33 | 34 | 35 | 36 | 37 | © 2010 38 | CloudMade, 39 | OpenStreetMap contributors, 40 | CCBYSA. 41 | Colors by Cynthia Brewer. 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /examples/statehood/statehood.js: -------------------------------------------------------------------------------- 1 | var po = org.polymaps; 2 | 3 | // Compute noniles. 4 | var quantile = pv.Scale.quantile() 5 | .quantiles(9) 6 | .domain(pv.values(states)) 7 | .range(0, 8); 8 | 9 | // Date format. 10 | var format = pv.Format.date("%B %e, %Y"); 11 | 12 | var map = po.map() 13 | .container(document.getElementById("map").appendChild(po.svg("svg"))) 14 | .center({lat: 40, lon: -95}) 15 | .zoomRange([3, 7]) 16 | .zoom(4) 17 | .add(po.interact()); 18 | 19 | map.add(po.image() 20 | .url(po.url("http://{S}tile.cloudmade.com" 21 | + "/1a1b06b230af4efdbb989ea99e9841af" // http://cloudmade.com/register 22 | + "/20760/256/{Z}/{X}/{Y}.png") 23 | .hosts(["a.", "b.", "c.", ""]))); 24 | 25 | map.add(po.geoJson() 26 | .url("http://polymaps.appspot.com/state/{Z}/{X}/{Y}.json") 27 | .on("load", load)) 28 | 29 | map.add(po.compass() 30 | .pan("none")); 31 | 32 | map.container().setAttribute("class", "Blues"); 33 | 34 | function load(e) { 35 | for (var i = 0; i < e.features.length; i++) { 36 | var feature = e.features[i], d = states[feature.data.id.substring(6)]; 37 | if (d == undefined) { 38 | feature.element.setAttribute("display", "none"); 39 | } else { 40 | feature.element.setAttribute("class", "q" + quantile(d) + "-" + 9); 41 | feature.element.appendChild(po.svg("title").appendChild( 42 | document.createTextNode(feature.data.properties.name + ": " 43 | + format(d).replace(/ [ ]+/, " "))) 44 | .parentNode); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /examples/streets/streets.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | San Francisco Street Pavement 5 | 6 | 7 | 33 | 34 | 35 | 36 | 37 | © 2010 38 | CloudMade, 39 | OpenStreetMap contributors, 40 | CCBYSA. 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /examples/streets/streets.js: -------------------------------------------------------------------------------- 1 | var po = org.polymaps; 2 | 3 | var color = pv.Scale.linear() 4 | .domain(0, 50, 70, 100) 5 | .range("#F00", "#930", "#FC0", "#3B0"); 6 | 7 | var map = po.map() 8 | .container(document.getElementById("map").appendChild(po.svg("svg"))) 9 | .center({lat: 37.76, lon: -122.44}) 10 | .zoom(13) 11 | .zoomRange([12, 16]) 12 | .add(po.interact()); 13 | 14 | map.add(po.image() 15 | .url(po.url("http://{S}tile.cloudmade.com" 16 | + "/1a1b06b230af4efdbb989ea99e9841af" // http://cloudmade.com/register 17 | + "/999/256/{Z}/{X}/{Y}.png") 18 | .hosts(["a.", "b.", "c.", ""]))); 19 | 20 | map.add(po.geoJson() 21 | .url("streets.json") 22 | .id("streets") 23 | .zoom(12) 24 | .tile(false) 25 | .on("load", po.stylist() 26 | .attr("stroke", function(d) { return color(d.properties.PCI).color; }) 27 | .title(function(d) { return d.properties.STREET + ": " + d.properties.PCI + " PCI"; }))); 28 | 29 | map.add(po.compass() 30 | .pan("none")); 31 | -------------------------------------------------------------------------------- /examples/tilestache/dot.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mbostock/polymaps/6cc4513810c3c063229f7f74d474418ce1929d6c/examples/tilestache/dot.gif -------------------------------------------------------------------------------- /examples/tilestache/flickr.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 27 | 28 | 29 | 30 | 31 | Courtesy 32 | Aaron Straup Cope. 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /examples/tilestache/flickr.js: -------------------------------------------------------------------------------- 1 | var po = org.polymaps; 2 | 3 | var map = po.map() 4 | .container(document.getElementById("map").appendChild(po.svg("svg"))) 5 | .zoomRange([1, 10]) 6 | .zoom(3) 7 | .add(po.image().url(tilestache("http://s3.amazonaws.com/info.aaronland.tiles.shapetiles/{Z}/{X}/{Y}.png"))) 8 | .add(po.interact()) 9 | .add(po.compass().pan("none")); 10 | 11 | /** Returns a TileStache URL template given a string. */ 12 | function tilestache(template) { 13 | 14 | /** Pads the specified string to length n with character c. */ 15 | function pad(s, n, c) { 16 | var m = n - s.length; 17 | return (m < 1) ? s : new Array(m + 1).join(c) + s; 18 | } 19 | 20 | /** Formats the specified number per TileStache. */ 21 | function format(i) { 22 | var s = pad(String(i), 6, "0"); 23 | return s.substr(0, 3) + "/" + s.substr(3); 24 | } 25 | 26 | return function(c) { 27 | var max = 1 << c.zoom, column = c.column % max; 28 | if (column < 0) column += max; 29 | return template.replace(/{(.)}/g, function(s, v) { 30 | switch (v) { 31 | case "Z": return c.zoom; 32 | case "X": return format(column); 33 | case "Y": return format(c.row); 34 | } 35 | return v; 36 | }); 37 | }; 38 | } 39 | -------------------------------------------------------------------------------- /examples/tipsy/berkeley.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mbostock/polymaps/6cc4513810c3c063229f7f74d474418ce1929d6c/examples/tipsy/berkeley.png -------------------------------------------------------------------------------- /examples/tipsy/stanford.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mbostock/polymaps/6cc4513810c3c063229f7f74d474418ce1929d6c/examples/tipsy/stanford.png -------------------------------------------------------------------------------- /examples/tipsy/tipsy.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 31 | 32 | 33 | 150 | 151 | © 2010 152 | CloudMade, 153 | OpenStreetMap contributors, 154 | CCBYSA. 155 | 156 | 157 | 158 | -------------------------------------------------------------------------------- /examples/transform/nypl.js: -------------------------------------------------------------------------------- 1 | var nypl = {}; 2 | 3 | nypl.image = function() { 4 | var image = po.layer(load, unload), 5 | scanInfo, 6 | scanId, 7 | tiles = {}; 8 | 9 | var infoTemplate = "http://maps.nypl.org/warper-dev/maps/{I}.json" 10 | + "?callback=nypl.image.$callback{I}"; 11 | 12 | var imageTemplate = "http://dev.maps.nypl.org/warper/mapscans/wms/{I}" 13 | + "?FORMAT=image%2Fjpeg" 14 | + "&STATUS=unwarped" 15 | + "&SERVICE=WMS" 16 | + "&VERSION=1.1.1" 17 | + "&REQUEST=GetMap" 18 | + "&STYLES=" 19 | + "&EXCEPTIONS=application%2Fvnd.ogc.se_inimage" 20 | + "&SRS=EPSG%3A4326" 21 | + "&WIDTH={W}" 22 | + "&HEIGHT={H}" 23 | + "&BBOX={B}"; 24 | 25 | function load(tile) { 26 | var element = tile.element = po.svg("image"); 27 | if (scanInfo) request(tile); 28 | tiles[tile.key] = tile; 29 | } 30 | 31 | function request(tile) { 32 | var element = tile.element, 33 | size = image.map().tileSize(), 34 | w = size.x, 35 | h = size.y, 36 | k = Math.pow(2, -tile.zoom) * Math.max(scanInfo.width, scanInfo.height), 37 | x = ~~(tile.column * k), 38 | y = scanInfo.height - ~~(tile.row * k), 39 | z = ~~k, 40 | dx = z, 41 | dy = z; 42 | 43 | if (y < dy) { 44 | dy = y; 45 | h = ~~(size.y * dy / z); 46 | } 47 | 48 | if (x > scanInfo.width - dx) { 49 | dx = scanInfo.width - x; 50 | w = ~~(size.x * dx / z); 51 | } 52 | 53 | element.setAttribute("opacity", 0); 54 | if ((x < 0) || (dx <= 0) || (dy <= 0)) return; // nothing to display 55 | element.setAttribute("width", w); 56 | element.setAttribute("height", h); 57 | 58 | var url = imageTemplate.replace(/{(.)}/g, function(s, v) { 59 | switch (v) { 60 | case "I": return scanId; 61 | case "W": return w; 62 | case "H": return h; 63 | case "B": return [x, y - dy, x + dx, y].join(","); 64 | } 65 | return v; 66 | }); 67 | 68 | tile.request = po.queue.image(element, url, function() { 69 | delete tile.request; 70 | tile.ready = true; 71 | element.removeAttribute("opacity"); 72 | image.dispatch({type: "load", tile: tile}); 73 | }); 74 | } 75 | 76 | function unload(tile) { 77 | if (tile.request) tile.request.abort(true); 78 | delete tiles[tiles.key]; 79 | } 80 | 81 | image.scan = function(x) { 82 | if (!arguments.length) return scanId; 83 | scanId = x; 84 | // JSONP, since nypl.org doesn't Access-Control-Allow-Origin: * 85 | nypl.image["$callback" + x] = function(x) { 86 | self.scanInfo = scanInfo = x.items[0]; 87 | for (var key in tiles) request(tiles[key]); 88 | }; 89 | var script = document.createElement("script"); 90 | script.setAttribute("type", "text/javascript"); 91 | script.setAttribute("src", infoTemplate.replace(/{I}/g, x)); 92 | document.body.appendChild(script); 93 | return image; 94 | } 95 | 96 | return image; 97 | }; 98 | 99 | function derive(a0, a1, b0, b1, c0, c1) { 100 | 101 | function solve(r1, s1, t1, r2, s2, t2, r3, s3, t3) { 102 | var a = (((t2 - t3) * (s1 - s2)) - ((t1 - t2) * (s2 - s3))) 103 | / (((r2 - r3) * (s1 - s2)) - ((r1 - r2) * (s2 - s3))), 104 | b = (((t2 - t3) * (r1 - r2)) - ((t1 - t2) * (r2 - r3))) 105 | / (((s2 - s3) * (r1 - r2)) - ((s1 - s2) * (r2 - r3))); 106 | c = t1 - (r1 * a) - (s1 * b); 107 | return [a, b, c]; 108 | } 109 | 110 | function normalize(c) { 111 | var k = Math.pow(2, -c.zoom); 112 | return { 113 | x: c.column * k, 114 | y: c.row * k 115 | }; 116 | } 117 | 118 | a0 = normalize(a0); 119 | a1 = normalize(a1); 120 | b0 = normalize(b0); 121 | b1 = normalize(b1); 122 | c0 = normalize(c0); 123 | c1 = normalize(c1); 124 | 125 | var x = solve(a0.x, a0.y, a1.x, 126 | b0.x, b0.y, b1.x, 127 | c0.x, c0.y, c1.x), 128 | y = solve(a0.x, a0.y, a1.y, 129 | b0.x, b0.y, b1.y, 130 | c0.x, c0.y, c1.y); 131 | 132 | return po.transform(x[0], y[0], x[1], y[1], x[2], y[2]); 133 | } 134 | -------------------------------------------------------------------------------- /examples/transform/transform-inverse.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 16 | 17 | 18 | 67 | 68 | © 2010 69 | CloudMade, 70 | OpenStreetMap contributors, 71 | CCBYSA. 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /examples/transform/transform.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 16 | 17 | 18 | 19 | 20 | © 2010 21 | CloudMade, 22 | OpenStreetMap contributors, 23 | CCBYSA. 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /examples/transform/transform.js: -------------------------------------------------------------------------------- 1 | var po = org.polymaps; 2 | 3 | var transform = derive( 4 | // broadway & kent 5 | {column: 2.7943515, row: 7.5530137, zoom: 4}, 6 | {column: 0.2945320, row: 0.3759881, zoom: 0}, 7 | // havemeyer & north 6th 8 | {column: 12.818008, row: 5.0867895, zoom: 4}, 9 | {column: 0.2945710, row: 0.3759732, zoom: 0}, 10 | // river & north 1st 11 | {column: 5.3814725, row: 1.9752101, zoom: 4}, 12 | {column: 0.2945396, row: 0.3759645, zoom: 0} 13 | ); 14 | 15 | var map = po.map() 16 | .container(document.getElementById("map").appendChild(po.svg("svg"))) 17 | .center({lon: -73.96115978350677, lat: 40.712867431331716}) 18 | .zoomRange([15, 18]) 19 | .zoom(15) 20 | .add(po.interact()); 21 | 22 | map.add(po.image() 23 | .url(po.url("http://{S}tile.cloudmade.com" 24 | + "/1a1b06b230af4efdbb989ea99e9841af" // http://cloudmade.com/register 25 | + "/998/256/{Z}/{X}/{Y}.png") 26 | .hosts(["a.", "b.", "c.", ""]))); 27 | 28 | map.add(nypl.image() 29 | .id("nypl") 30 | .scan("8021") 31 | .transform(transform)); 32 | 33 | map.add(po.compass() 34 | .pan("none")); 35 | 36 | function key(e) { 37 | var nypl = document.getElementById("nypl"); 38 | switch (e.keyCode) { 39 | case 49: nypl.style.opacity = e.type == "keydown" ? 1 : .5; break; 40 | case 50: nypl.style.opacity = e.type == "keydown" ? 0 : .5; break; 41 | } 42 | } 43 | 44 | window.addEventListener("keydown", key, false); 45 | window.addEventListener("keyup", key, false); 46 | -------------------------------------------------------------------------------- /examples/transform/transparent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mbostock/polymaps/6cc4513810c3c063229f7f74d474418ce1929d6c/examples/transform/transparent.png -------------------------------------------------------------------------------- /examples/transition/ease.js: -------------------------------------------------------------------------------- 1 | /* 2 | * TERMS OF USE - EASING EQUATIONS 3 | * 4 | * Open source under the BSD License. 5 | * 6 | * Copyright 2001 Robert Penner 7 | * All rights reserved. 8 | * 9 | * Redistribution and use in source and binary forms, with or without 10 | * modification, are permitted provided that the following conditions are met: 11 | * 12 | * - Redistributions of source code must retain the above copyright notice, this 13 | * list of conditions and the following disclaimer. 14 | * 15 | * - Redistributions in binary form must reproduce the above copyright notice, 16 | * this list of conditions and the following disclaimer in the documentation 17 | * and/or other materials provided with the distribution. 18 | * 19 | * - Neither the name of the author nor the names of contributors may be used to 20 | * endorse or promote products derived from this software without specific 21 | * prior written permission. 22 | * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 24 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 27 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 28 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 29 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 30 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 31 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 32 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 33 | * POSSIBILITY OF SUCH DAMAGE. 34 | */ 35 | 36 | function reflect(f) { 37 | return function(t) { 38 | return .5 * (t < .5 ? f(2 * t) : (2 - f(2 - 2 * t))); 39 | }; 40 | } 41 | 42 | function poly(e) { 43 | return function(t) { 44 | return t < 0 ? 0 : t > 1 ? 1 : Math.pow(t, e); 45 | }; 46 | } 47 | -------------------------------------------------------------------------------- /examples/transition/transition.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 11 | 12 | 13 | 85 |
86 | © 2010 87 | CloudMade, 88 | OpenStreetMap contributors, 89 | CCBYSA. 90 |
91 | 92 | 93 | -------------------------------------------------------------------------------- /examples/unemployment/unemployment.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Unemployment 5 | 6 | 7 | 8 | 40 | 41 | 42 | 43 | 44 | © 2010 45 | CloudMade, 46 | OpenStreetMap contributors, 47 | CCBYSA. 48 | Colors by Cynthia Brewer. 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /examples/unemployment/unemployment.js: -------------------------------------------------------------------------------- 1 | var po = org.polymaps; 2 | 3 | // Compute noniles. 4 | var quantile = pv.Scale.quantile() 5 | .quantiles(9) 6 | .domain(pv.values(unemployment)) 7 | .range(0, 8); 8 | 9 | var map = po.map() 10 | .container(document.getElementById("map").appendChild(po.svg("svg"))) 11 | .center({lat: 39, lon: -96}) 12 | .zoom(4) 13 | .zoomRange([3, 7]) 14 | .add(po.interact()); 15 | 16 | map.add(po.image() 17 | .url(po.url("http://{S}tile.cloudmade.com" 18 | + "/1a1b06b230af4efdbb989ea99e9841af" // http://cloudmade.com/register 19 | + "/20760/256/{Z}/{X}/{Y}.png") 20 | .hosts(["a.", "b.", "c.", ""]))); 21 | 22 | map.add(po.geoJson() 23 | .url("http://polymaps.appspot.com/county/{Z}/{X}/{Y}.json") 24 | .on("load", load) 25 | .id("county")); 26 | 27 | map.add(po.geoJson() 28 | .url("http://polymaps.appspot.com/state/{Z}/{X}/{Y}.json") 29 | .id("state")); 30 | 31 | map.add(po.compass() 32 | .pan("none")); 33 | 34 | function load(e) { 35 | for (var i = 0; i < e.features.length; i++) { 36 | var feature = e.features[i]; 37 | if (feature.data.id.substring(9) == "000") continue; // skip bogus counties 38 | var d = unemployment[feature.data.id.substring(7)]; 39 | feature.element.setAttribute("class", "q" + quantile(d) + "-" + 9); 40 | feature.element.appendChild(po.svg("title").appendChild( 41 | document.createTextNode(feature.data.properties.name + ": " + d + "%")) 42 | .parentNode); 43 | } 44 | } 45 | 46 | map.container().setAttribute("class", "Blues"); 47 | -------------------------------------------------------------------------------- /examples/world/area.tsv: -------------------------------------------------------------------------------- 1 | 1 Russia 17,098,242 2 | 2 Canada 9,984,670 3 | 3 United States 9,826,675 4 | 4 China 9,596,961 5 | 5 Brazil 8,514,877 6 | 6 Australia 7,741,220 7 | 7 India 3,287,263 8 | 8 Argentina 2,780,400 9 | 9 Kazakhstan 2,724,900 10 | 10 Sudan 2,505,813 11 | 11 Algeria 2,381,741 12 | 12 Congo, Democratic Republic of the 2,344,858 13 | 13 Greenland 2,166,086 14 | 14 Saudi Arabia 2,149,690 15 | 15 Mexico 1,964,375 16 | 16 Indonesia 1,904,569 17 | 17 Libya 1,759,540 18 | 18 Iran 1,648,195 19 | 19 Mongolia 1,564,116 20 | 20 Peru 1,285,216 21 | 21 Chad 1,284,000 22 | 22 Niger 1,267,000 23 | 23 Angola 1,246,700 24 | 24 Mali 1,240,192 25 | 25 South Africa 1,219,090 26 | 26 Colombia 1,138,914 27 | 27 Ethiopia 1,104,300 28 | 28 Bolivia 1,098,581 29 | 29 Mauritania 1,030,700 30 | 30 Egypt 1,001,450 31 | 31 Tanzania 947,300 32 | 32 Nigeria 923,768 33 | 33 Venezuela 912,050 34 | 34 Namibia 824,292 35 | 35 Mozambique 799,380 36 | 36 Pakistan 796,095 37 | 37 Turkey 783,562 38 | 38 Chile 756,102 39 | 39 Zambia 752,618 40 | 40 Burma 676,578 41 | 41 Afghanistan 652,230 42 | 42 France 643,427 43 | 43 Somalia 637,657 44 | 44 Central African Republic 622,984 45 | 45 Ukraine 603,550 46 | 46 Madagascar 587,041 47 | 47 Botswana 581,730 48 | 48 Kenya 580,367 49 | 49 Yemen 527,968 50 | 50 Thailand 513,120 51 | 51 Spain 505,370 52 | 52 Turkmenistan 488,100 53 | 53 Cameroon 475,440 54 | 54 Papua New Guinea 462,840 55 | 55 Sweden 450,295 56 | 56 Uzbekistan 447,400 57 | 57 Morocco 446,550 58 | 58 Iraq 438,317 59 | 59 Paraguay 406,752 60 | 60 Zimbabwe 390,757 61 | 61 Japan 377,915 62 | 62 Germany 357,022 63 | 63 Congo, Republic of the 342,000 64 | 64 Finland 338,145 65 | 65 Vietnam 331,210 66 | 66 Malaysia 329,847 67 | 67 Norway 323,802 68 | 68 Cote d'Ivoire 322,463 69 | 69 Poland 312,685 70 | 70 Oman 309,500 71 | 71 Italy 301,340 72 | 72 Philippines 300,000 73 | 73 Ecuador 283,561 74 | 74 Burkina Faso 274,200 75 | 75 New Zealand 267,710 76 | 76 Gabon 267,667 77 | 77 Western Sahara 266,000 78 | 78 Guinea 245,857 79 | 79 United Kingdom 243,610 80 | 80 Uganda 241,038 81 | 81 Ghana 238,533 82 | 82 Romania 238,391 83 | 83 Laos 236,800 84 | 84 Guyana 214,969 85 | 85 Belarus 207,600 86 | 86 Kyrgyzstan 199,951 87 | 87 Senegal 196,722 88 | 88 Syria 185,180 89 | 89 Cambodia 181,035 90 | 90 Uruguay 176,215 91 | 91 Suriname 163,820 92 | 92 Tunisia 163,610 93 | 93 Nepal 147,181 94 | 94 Bangladesh 143,998 95 | 95 Tajikistan 143,100 96 | 96 Greece 131,957 97 | 97 Nicaragua 130,370 98 | 98 Korea, North 120,538 99 | 99 Malawi 118,484 100 | 100 Eritrea 117,600 101 | 101 Benin 112,622 102 | 102 Honduras 112,090 103 | 103 Liberia 111,369 104 | 104 Bulgaria 110,879 105 | 105 Cuba 110,860 106 | 106 Guatemala 108,889 107 | 107 Iceland 103,000 108 | 108 Korea, South 99,720 109 | 109 Hungary 93,028 110 | 110 Portugal 92,090 111 | 111 Jordan 89,342 112 | 112 Azerbaijan 86,600 113 | 113 Austria 83,871 114 | 114 United Arab Emirates 83,600 115 | 115 Czech Republic 78,867 116 | 116 Serbia 77,474 117 | 117 Panama 75,420 118 | 118 Sierra Leone 71,740 119 | 119 Ireland 70,273 120 | 120 Georgia 69,700 121 | 121 Sri Lanka 65,610 122 | 122 Lithuania 65,300 123 | 123 Latvia 64,589 124 | 124 Svalbard 62,045 125 | 125 Togo 56,785 126 | 126 Croatia 56,594 127 | 127 British Indian Ocean Territory 54,400 128 | 128 Bosnia and Herzegovina 51,197 129 | 129 Costa Rica 51,100 130 | 130 Slovakia 49,035 131 | 131 Dominican Republic 48,670 132 | 132 Estonia 45,228 133 | 133 Denmark 43,094 134 | 134 Netherlands 41,543 135 | 135 Switzerland 41,277 136 | 136 Bhutan 38,394 137 | 137 Guinea-Bissau 36,125 138 | 138 Taiwan 35,980 139 | 139 Moldova 33,851 140 | 140 Belgium 30,528 141 | 141 Lesotho 30,355 142 | 142 Armenia 29,743 143 | 143 Solomon Islands 28,896 144 | 144 Albania 28,748 145 | 145 Equatorial Guinea 28,051 146 | 146 Burundi 27,830 147 | 147 Haiti 27,750 148 | 148 Rwanda 26,338 149 | 149 Macedonia 25,713 150 | 150 Djibouti 23,200 151 | 151 Belize 22,966 152 | 152 Israel 22,072 153 | 153 El Salvador 21,041 154 | 154 Slovenia 20,273 155 | 155 New Caledonia 18,575 156 | 156 Fiji 18,274 157 | 157 Kuwait 17,818 158 | 158 Swaziland 17,364 159 | 159 Timor-Leste 14,874 160 | 160 Bahamas, The 13,880 161 | 161 Montenegro 13,812 162 | 162 Puerto Rico 13,790 163 | 163 Vanuatu 12,189 164 | 164 Falkland Islands (Islas Malvinas) 12,173 165 | 165 Qatar 11,586 166 | 166 Gambia, The 11,295 167 | 167 Jamaica 10,991 168 | 168 Kosovo 10,887 169 | 169 Lebanon 10,400 170 | 170 Cyprus 9,251 171 | 171 West Bank 5,860 172 | 172 Brunei 5,765 173 | 173 Trinidad and Tobago 5,128 174 | 174 French Polynesia 4,167 175 | 175 Cape Verde 4,033 176 | 176 South Georgia and South Sandwich Islands 3,903 177 | 177 Samoa 2,831 178 | 178 Luxembourg 2,586 179 | 179 Comoros 2,235 180 | 180 Mauritius 2,040 181 | 181 Virgin Islands 1,910 182 | 182 Faroe Islands 1,393 183 | 183 Hong Kong 1,104 184 | 184 Sao Tome and Principe 964 185 | 185 Turks and Caicos Islands 948 186 | 186 Kiribati 811 187 | 187 Netherlands Antilles 800 188 | 188 Dominica 751 189 | 189 Tonga 747 190 | 190 Bahrain 741 191 | 191 Micronesia, Federated States of 702 192 | 192 Singapore 697 193 | 193 Saint Lucia 616 194 | 194 Isle of Man 572 195 | 195 Andorra 468 196 | 196 Northern Mariana Islands 464 197 | 197 Palau 459 198 | 198 Seychelles 455 199 | 199 Antigua and Barbuda 443 200 | 200 Barbados 430 201 | 201 Heard Island and McDonald Islands 412 202 | 202 Saint Vincent and the Grenadines 389 203 | 203 Jan Mayen 377 204 | 204 Mayotte 374 205 | 205 Gaza Strip 360 206 | 206 Grenada 344 207 | 207 Malta 316 208 | 208 Saint Helena, Ascension, and Tristan da Cunha 308 209 | 209 Maldives 298 210 | 210 Cayman Islands 264 211 | 211 Saint Kitts and Nevis 261 212 | 212 Niue 260 213 | 213 Saint Pierre and Miquelon 242 214 | 214 Cook Islands 236 215 | 215 American Samoa 199 216 | 216 Marshall Islands 181 217 | 217 Aruba 180 218 | 218 Liechtenstein 160 219 | 219 British Virgin Islands 151 220 | 220 Wallis and Futuna 142 221 | 221 Christmas Island 135 222 | 222 Dhekelia 131 223 | 223 Akrotiri 123 224 | 224 Jersey 116 225 | 225 Montserrat 102 226 | 226 Anguilla 91 227 | 227 Guernsey 78 228 | 228 San Marino 61 229 | 229 French Southern and Antarctic Lands 55 230 | 230 Saint Martin 54 231 | 231 Bermuda 54 232 | 232 Bouvet Island 49 233 | 233 Pitcairn Islands 47 234 | 234 Norfolk Island 36 235 | 235 Macau 28 236 | 236 Tuvalu 26 237 | 237 United States Pacific Island Wildlife Refuges 22 238 | 238 Nauru 21 239 | 239 Cocos (Keeling) Islands 14 240 | 240 Tokelau 12 241 | 241 Gibraltar 7 242 | 242 Wake Island 7 243 | 243 Clipperton Island 6 244 | 244 Navassa Island 5 245 | 245 Ashmore and Cartier Islands 5 246 | 246 Spratly Islands 5 247 | 247 Coral Sea Islands 3 248 | 248 Monaco 2 249 | 249 Holy See (Vatican City) 0 250 | -------------------------------------------------------------------------------- /examples/world/internet.tsv: -------------------------------------------------------------------------------- 1 | 1 China 298,000,000 2 | 2 United States 231,000,000 3 | 3 Japan 90,910,000 4 | 4 India 81,000,000 5 | 5 Brazil 64,948,000 6 | 6 Germany 61,973,000 7 | 7 United Kingdom 48,755,000 8 | 8 Russia 45,250,000 9 | 9 France 42,912,000 10 | 10 Korea, South 37,476,000 11 | 11 Indonesia 30,000,000 12 | 12 Spain 25,240,000 13 | 13 Canada 25,086,000 14 | 14 Italy 24,992,000 15 | 15 Turkey 24,483,000 16 | 16 Mexico 23,260,000 17 | 17 Iran 23,000,000 18 | 18 Vietnam 20,834,000 19 | 19 Poland 18,679,000 20 | 20 Pakistan 18,500,000 21 | 21 Colombia 17,117,000 22 | 22 Malaysia 16,903,000 23 | 23 Thailand 16,100,000 24 | 24 Australia 15,170,000 25 | 25 Taiwan 15,143,000 26 | 26 Netherlands 14,273,000 27 | 27 Egypt 11,414,000 28 | 28 Argentina 11,212,000 29 | 29 Nigeria 11,000,000 30 | 30 Ukraine 10,354,000 31 | 31 Morocco 10,300,000 32 | 32 Sweden 8,100,000 33 | 33 Saudi Arabia 7,700,000 34 | 34 Belgium 7,292,000 35 | 35 Venezuela 7,167,000 36 | 36 Peru 7,128,000 37 | 37 Romania 6,132,000 38 | 38 Czech Republic 6,028,000 39 | 39 Austria 5,937,000 40 | 40 Hungary 5,873,000 41 | 41 Switzerland 5,739,000 42 | 42 Philippines 5,618,000 43 | 43 Chile 5,456,000 44 | 44 Denmark 4,579,000 45 | 45 Portugal 4,476,000 46 | 46 Finland 4,383,000 47 | 47 Greece 4,253,000 48 | 48 Sudan 4,200,000 49 | 49 South Africa 4,187,000 50 | 50 Hong Kong 4,124,000 51 | 51 Algeria 4,100,000 52 | 52 Norway 3,935,000 53 | 53 Slovakia 3,566,000 54 | 54 Syria 3,565,000 55 | 55 Singapore 3,370,000 56 | 56 Kenya 3,360,000 57 | 57 Belarus 3,107,000 58 | 58 New Zealand 3,047,000 59 | 59 Serbia 2,936,000 60 | 60 United Arab Emirates 2,922,000 61 | 61 Ireland 2,830,000 62 | 62 Tunisia 2,800,000 63 | 63 Bulgaria 2,647,000 64 | 64 Uganda 2,500,000 65 | 65 Uzbekistan 2,469,000 66 | 66 Kazakhstan 2,300,000 67 | 67 Lebanon 2,190,000 68 | 68 Dominican Republic 2,147,000 69 | 69 Israel 2,106,000 70 | 70 Guatemala 1,960,000 71 | 71 Croatia 1,880,000 72 | 72 Lithuania 1,777,000 73 | 73 Jamaica 1,540,000 74 | 74 Jordan 1,500,000 75 | 75 Azerbaijan 1,485,000 76 | 76 Costa Rica 1,460,000 77 | 77 Cuba 1,450,000 78 | 78 Zimbabwe 1,421,000 79 | 79 Uruguay 1,340,000 80 | 80 Ecuador 1,310,000 81 | 81 Bosnia and Herzegovina 1,308,000 82 | 82 Latvia 1,254,000 83 | 83 Sri Lanka 1,164,000 84 | 84 Slovenia 1,126,000 85 | 85 Georgia 1,024,000 86 | 86 Senegal 1,020,000 87 | 87 Bolivia 1,000,000 88 | 88 Puerto Rico 1,000,000 89 | 89 Kuwait 1,000,000 90 | 90 Haiti 1,000,000 91 | 91 Ghana 997,000 92 | 92 Panama 934,500 93 | 93 Paraguay 894,200 94 | 94 Estonia 888,100 95 | 95 Kyrgyzstan 850,000 96 | 96 Moldova 850,000 97 | 97 Macedonia 847,900 98 | 98 El Salvador 826,000 99 | 99 Cameroon 725,000 100 | 100 Zambia 700,000 101 | 101 Cote d'Ivoire 660,000 102 | 102 Honduras 658,500 103 | 103 Tajikistan 600,000 104 | 104 Bangladesh 556,000 105 | 105 Angola 550,000 106 | 106 Tanzania 520,000 107 | 107 Afghanistan 500,000 108 | 108 Nepal 499,000 109 | 109 Albania 471,000 110 | 110 Oman 465,000 111 | 111 Qatar 436,000 112 | 112 Bahrain 402,900 113 | 113 Luxembourg 387,000 114 | 114 Mauritius 380,000 115 | 115 Yemen 370,000 116 | 116 Ethiopia 360,000 117 | 117 Gaza Strip 356,000 118 | 118 West Bank 356,000 119 | 119 Mozambique 350,000 120 | 120 Togo 350,000 121 | 121 Cyprus 334,400 122 | 122 Mongolia 330,000 123 | 123 Libya 323,000 124 | 124 Madagascar 316,100 125 | 125 Malawi 316,100 126 | 126 Iraq 300,000 127 | 127 Rwanda 300,000 128 | 128 Montenegro 294,000 129 | 129 Congo, Democratic Republic of the 290,000 130 | 130 Macau 259,000 131 | 131 Iceland 250,000 132 | 132 Trinidad and Tobago 227,000 133 | 133 Brunei 217,000 134 | 134 Guyana 205,000 135 | 135 Eritrea 200,000 136 | 136 Mali 200,000 137 | 137 Malta 198,800 138 | 138 Armenia 191,000 139 | 139 Barbados 188,000 140 | 140 Nicaragua 185,000 141 | 141 Benin 160,000 142 | 142 Congo, Republic of the 155,000 143 | 143 Burkina Faso 140,000 144 | 144 Chad 130,000 145 | 145 Laos 130,000 146 | 146 Botswana 120,000 147 | 147 Papua New Guinea 120,000 148 | 148 Gambia, The 114,200 149 | 149 Namibia 113,500 150 | 150 Burma 108,900 151 | 151 Bahamas, The 106,500 152 | 152 Fiji 103,000 153 | 153 Cape Verde 102,800 154 | 154 Somalia 102,000 155 | 155 Saint Lucia 100,000 156 | 156 French Polynesia 90,000 157 | 157 Guinea 90,000 158 | 158 Gabon 90,000 159 | 159 New Caledonia 85,000 160 | 160 Niger 80,000 161 | 161 Turkmenistan 75,000 162 | 162 Cambodia 74,000 163 | 163 Lesotho 73,300 164 | 164 Maldives 71,700 165 | 165 Saint Vincent and the Grenadines 66,000 166 | 166 Antigua and Barbuda 65,000 167 | 167 Burundi 65,000 168 | 168 Andorra 59,100 169 | 169 Bermuda 51,000 170 | 170 Suriname 50,000 171 | 171 Swaziland 48,200 172 | 172 Guernsey 46,100 173 | 173 Mauritania 45,000 174 | 174 Bhutan 40,000 175 | 175 Faroe Islands 37,500 176 | 176 Guinea-Bissau 37,100 177 | 177 Greenland 36,000 178 | 178 Belize 34,000 179 | 179 Seychelles 32,000 180 | 180 Virgin Islands 30,000 181 | 181 Jersey 29,000 182 | 182 Dominica 27,500 183 | 183 Sao Tome and Principe 24,800 184 | 184 Aruba 24,000 185 | 185 Grenada 24,000 186 | 186 Cayman Islands 23,000 187 | 187 Liechtenstein 23,000 188 | 188 Comoros 23,000 189 | 189 Monaco 22,000 190 | 190 Liberia 20,000 191 | 191 Central African Republic 19,000 192 | 192 San Marino 17,000 193 | 193 Vanuatu 17,000 194 | 194 Micronesia, Federated States of 16,000 195 | 195 Saint Kitts and Nevis 16,000 196 | 196 Sierra Leone 13,900 197 | 197 Djibouti 13,000 198 | 198 Equatorial Guinea 12,000 199 | 199 Solomon Islands 10,000 200 | 200 Samoa 9,000 201 | 201 Tonga 8,400 202 | 202 Gibraltar 6,500 203 | 203 Cook Islands 5,000 204 | 204 Anguilla 4,500 205 | 205 Tuvalu 4,200 206 | 206 British Virgin Islands 4,000 207 | 207 Falkland Islands (Islas Malvinas) 2,800 208 | 208 Marshall Islands 2,200 209 | 209 Kiribati 2,000 210 | 210 Timor-Leste 1,800 211 | 211 Montserrat 1,200 212 | 212 Wallis and Futuna 1,200 213 | 213 Saint Helena, Ascension, and Tristan da Cunha 1,100 214 | 214 Niue 1,000 215 | 215 Tokelau 800 216 | 216 Christmas Island 464 217 | -------------------------------------------------------------------------------- /examples/world/population.tsv: -------------------------------------------------------------------------------- 1 | 1 China 1,330,141,295 2 | 2 India 1,173,108,018 3 | 3 United States 310,232,863 4 | 4 Indonesia 242,968,342 5 | 5 Brazil 201,103,330 6 | 6 Pakistan 177,276,594 7 | 7 Bangladesh 158,065,841 8 | 8 Nigeria 152,217,341 9 | 9 Russia 139,390,205 10 | 10 Japan 126,804,433 11 | 11 Mexico 112,468,855 12 | 12 Philippines 99,900,177 13 | 13 Vietnam 89,571,130 14 | 14 Ethiopia 88,013,491 15 | 15 Germany 82,282,988 16 | 16 Egypt 80,471,869 17 | 17 Turkey 77,804,122 18 | 18 Congo, Democratic Republic of the 70,916,439 19 | 19 Iran 67,037,517 20 | 20 Thailand 66,404,688 21 | 21 France 64,057,792 22 | 22 United Kingdom 61,284,806 23 | 23 Italy 58,090,681 24 | 24 Burma 53,414,374 25 | 25 South Africa 49,109,107 26 | 26 Korea, South 48,636,068 27 | 27 Ukraine 45,415,596 28 | 28 Colombia 44,205,293 29 | 29 Sudan 41,980,182 30 | 30 Tanzania 41,892,895 31 | 31 Argentina 41,343,201 32 | 32 Spain 40,548,753 33 | 33 Kenya 40,046,566 34 | 34 Poland 38,463,689 35 | 35 Algeria 34,586,184 36 | 36 Canada 33,759,742 37 | 37 Uganda 33,398,682 38 | 38 Morocco 31,627,428 39 | 39 Peru 29,907,003 40 | 40 Iraq 29,671,605 41 | 41 Saudi Arabia 29,207,277 42 | 42 Afghanistan 29,121,286 43 | 43 Nepal 28,951,852 44 | 44 Uzbekistan 27,865,738 45 | 45 Venezuela 27,223,228 46 | 46 Malaysia 26,160,256 47 | 47 Ghana 24,339,838 48 | 48 Yemen 23,495,361 49 | 49 Taiwan 23,024,956 50 | 50 Korea, North 22,757,275 51 | 51 Syria 22,198,110 52 | 52 Romania 22,181,287 53 | 53 Mozambique 22,061,451 54 | 54 Australia 21,515,754 55 | 55 Sri Lanka 21,513,990 56 | 56 Madagascar 21,281,844 57 | 57 Cote d'Ivoire 21,058,798 58 | 58 Cameroon 19,294,149 59 | 59 Netherlands 16,783,092 60 | 60 Chile 16,746,491 61 | 61 Burkina Faso 16,241,811 62 | 62 Niger 15,878,271 63 | 63 Kazakhstan 15,460,484 64 | 64 Malawi 15,447,500 65 | 65 Ecuador 14,790,608 66 | 66 Cambodia 14,753,320 67 | 67 Senegal 14,086,103 68 | 68 Mali 13,796,354 69 | 69 Guatemala 13,550,440 70 | 70 Angola 13,068,161 71 | 71 Zambia 12,056,923 72 | 72 Zimbabwe 11,651,858 73 | 73 Cuba 11,477,459 74 | 74 Rwanda 11,055,976 75 | 75 Greece 10,749,943 76 | 76 Portugal 10,735,765 77 | 77 Tunisia 10,589,025 78 | 78 Chad 10,543,464 79 | 79 Belgium 10,423,493 80 | 80 Guinea 10,324,025 81 | 81 Czech Republic 10,201,707 82 | 82 Somalia 10,112,453 83 | 83 Bolivia 9,947,418 84 | 84 Hungary 9,880,059 85 | 85 Burundi 9,863,117 86 | 86 Dominican Republic 9,794,487 87 | 87 Belarus 9,612,632 88 | 88 Haiti 9,203,083 89 | 89 Sweden 9,074,055 90 | 90 Benin 9,056,010 91 | 91 Azerbaijan 8,303,512 92 | 92 Austria 8,214,160 93 | 93 Honduras 7,989,415 94 | 94 Switzerland 7,623,438 95 | 95 Tajikistan 7,487,489 96 | 96 Israel 7,353,985 97 | 97 Serbia 7,344,847 98 | 98 Bulgaria 7,148,785 99 | 99 Hong Kong 7,089,705 100 | 100 Laos 6,993,767 101 | 101 Libya 6,461,454 102 | 102 Jordan 6,407,085 103 | 103 Paraguay 6,375,830 104 | 104 Togo 6,199,841 105 | 105 Papua New Guinea 6,064,515 106 | 106 El Salvador 6,052,064 107 | 107 Nicaragua 5,995,928 108 | 108 Eritrea 5,792,984 109 | 109 Denmark 5,515,575 110 | 110 Kyrgyzstan 5,508,626 111 | 111 Slovakia 5,470,306 112 | 112 Finland 5,255,068 113 | 113 Sierra Leone 5,245,695 114 | 114 United Arab Emirates 4,975,593 115 | 115 Turkmenistan 4,940,916 116 | 116 Central African Republic 4,844,927 117 | 117 Singapore 4,701,069 118 | 118 Norway 4,676,305 119 | 119 Bosnia and Herzegovina 4,621,598 120 | 120 Georgia 4,600,825 121 | 121 Costa Rica 4,516,220 122 | 122 Croatia 4,486,881 123 | 123 Moldova 4,317,483 124 | 124 New Zealand 4,252,277 125 | 125 Ireland 4,250,163 126 | 126 Congo, Republic of the 4,125,916 127 | 127 Lebanon 4,125,247 128 | 128 Puerto Rico 3,977,663 129 | 129 Liberia 3,685,076 130 | 130 Albania 3,659,616 131 | 131 Lithuania 3,545,319 132 | 132 Uruguay 3,510,386 133 | 133 Panama 3,410,676 134 | 134 Mauritania 3,205,060 135 | 135 Mongolia 3,086,918 136 | 136 Oman 2,967,717 137 | 137 Armenia 2,966,802 138 | 138 Jamaica 2,847,232 139 | 139 Kuwait 2,789,132 140 | 140 West Bank 2,514,845 141 | 141 Latvia 2,217,969 142 | 142 Namibia 2,128,471 143 | 143 Macedonia 2,072,086 144 | 144 Botswana 2,029,307 145 | 145 Slovenia 2,003,136 146 | 146 Lesotho 1,919,552 147 | 147 Gambia, The 1,824,158 148 | 148 Kosovo 1,815,048 149 | 149 Gaza Strip 1,604,238 150 | 150 Guinea-Bissau 1,565,126 151 | 151 Gabon 1,545,255 152 | 152 Swaziland 1,354,051 153 | 153 Mauritius 1,294,104 154 | 154 Estonia 1,291,170 155 | 155 Trinidad and Tobago 1,228,691 156 | 156 Timor-Leste 1,154,625 157 | 157 Cyprus 1,102,677 158 | 158 Fiji 957,780 159 | 159 Qatar 840,926 160 | 160 Comoros 773,407 161 | 161 Guyana 748,486 162 | 162 Djibouti 740,528 163 | 163 Bahrain 738,004 164 | 164 Bhutan 699,847 165 | 165 Montenegro 666,730 166 | 166 Equatorial Guinea 650,702 167 | 167 Solomon Islands 609,794 168 | 168 Macau 567,957 169 | 169 Cape Verde 508,659 170 | 170 Luxembourg 497,538 171 | 171 Western Sahara 491,519 172 | 172 Suriname 486,618 173 | 173 Malta 406,771 174 | 174 Maldives 395,650 175 | 175 Brunei 395,027 176 | 176 Belize 314,522 177 | 177 Bahamas, The 310,426 178 | 178 Iceland 308,910 179 | 179 French Polynesia 291,000 180 | 180 Barbados 285,653 181 | 181 Mayotte 231,139 182 | 182 New Caledonia 229,993 183 | 183 Netherlands Antilles 228,693 184 | 184 Vanuatu 221,552 185 | 185 Samoa 192,001 186 | 186 Sao Tome and Principe 175,808 187 | 187 Saint Lucia 160,922 188 | 188 Tonga 122,580 189 | 189 Virgin Islands 109,775 190 | 190 Grenada 107,818 191 | 191 Micronesia, Federated States of 107,154 192 | 192 Aruba 104,589 193 | 193 Saint Vincent and the Grenadines 104,217 194 | 194 Kiribati 99,482 195 | 195 Jersey 91,812 196 | 196 Seychelles 88,340 197 | 197 Antigua and Barbuda 86,754 198 | 198 Andorra 84,525 199 | 199 Isle of Man 76,913 200 | 200 Dominica 72,813 201 | 201 Bermuda 68,268 202 | 202 American Samoa 66,432 203 | 203 Marshall Islands 65,859 204 | 204 Guernsey 65,632 205 | 205 Greenland 57,637 206 | 206 Cayman Islands 50,209 207 | 207 Saint Kitts and Nevis 49,898 208 | 208 Faroe Islands 49,057 209 | 209 Northern Mariana Islands 48,317 210 | 210 Liechtenstein 35,002 211 | 211 San Marino 31,477 212 | 212 Monaco 30,586 213 | 213 Saint Martin 30,235 214 | 214 Gibraltar 28,877 215 | 215 British Virgin Islands 24,939 216 | 216 Turks and Caicos Islands 23,528 217 | 217 Palau 20,879 218 | 218 Akrotiri 15,700 219 | 219 Dhekelia 15,700 220 | 220 Wallis and Futuna 15,343 221 | 221 Anguilla 14,764 222 | 222 Nauru 14,264 223 | 223 Cook Islands 11,488 224 | 224 Tuvalu 10,472 225 | 225 Saint Helena, Ascension, and Tristan da Cunha 7,670 226 | 226 Saint Barthelemy 7,406 227 | 227 Saint Pierre and Miquelon 6,010 228 | 228 Montserrat 5,118 229 | 229 Falkland Islands (Islas Malvinas) 3,140 230 | 230 Norfolk Island 2,155 231 | 231 Svalbard 2,067 232 | 232 Christmas Island 1,402 233 | 233 Tokelau 1,400 234 | 234 Niue 1,354 235 | 235 Holy See (Vatican City) 829 236 | 236 Cocos (Keeling) Islands 596 237 | 237 Pitcairn Islands 48 238 | -------------------------------------------------------------------------------- /examples/world/tsv.js: -------------------------------------------------------------------------------- 1 | function tsv(url) { 2 | var tsv = {}, 3 | key, 4 | value; 5 | 6 | tsv.key = function(x) { 7 | if (!arguments.length) return key; 8 | key = x; 9 | return tsv; 10 | }; 11 | 12 | tsv.value = function(x) { 13 | if (!arguments.length) return value; 14 | value = x; 15 | return tsv; 16 | }; 17 | 18 | tsv.map = function(x) { 19 | var map = {}, req = new XMLHttpRequest(); 20 | req.overrideMimeType("text/plain"); 21 | req.open("GET", url, false); 22 | req.send(null); 23 | var lines = req.responseText.split(/\n/g); 24 | for (var i = 0; i < lines.length; i++) { 25 | var columns = lines[i].split(/\t/g), 26 | k = key(columns); 27 | if (k != null) map[k] = value(columns); 28 | } 29 | return map; 30 | }; 31 | 32 | return tsv; 33 | } 34 | -------------------------------------------------------------------------------- /examples/world/world.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Internet Users 5 | 6 | 7 | 8 | 32 | 33 | 34 | 35 | 36 | Courtesy NASA Earth 37 | Observatory. © 38 | 2009 thematicmapping.org. Colors by Cynthia Brewer. 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /examples/world/world.js: -------------------------------------------------------------------------------- 1 | var po = org.polymaps; 2 | 3 | /* Country name -> population (July 2010 Est.). */ 4 | var population = tsv("population.tsv") 5 | .key(function(l) { return l[1]; }) 6 | .value(function(l) { return l[2].replace(/,/g, ""); }) 7 | .map(); 8 | 9 | /* Country name -> internet users (2008). */ 10 | var internet = tsv("internet.tsv") 11 | .key(function(l) { return l[1]; }) 12 | .value(function(l) { return l[2].replace(/,/g, ""); }) 13 | .map(); 14 | 15 | var map = po.map() 16 | .container(document.getElementById("map").appendChild(po.svg("svg"))) 17 | .center({lat: 40, lon: 0}) 18 | .zoomRange([1, 4]) 19 | .zoom(2) 20 | .add(po.interact()); 21 | 22 | map.add(po.image() 23 | .url("http://s3.amazonaws.com/com.modestmaps.bluemarble/{Z}-r{Y}-c{X}.jpg")); 24 | 25 | map.add(po.geoJson() 26 | .url("world.json") 27 | .tile(false) 28 | .zoom(3) 29 | .on("load", load)); 30 | 31 | map.add(po.compass() 32 | .pan("none")); 33 | 34 | map.container().setAttribute("class", "YlOrRd"); 35 | 36 | /** Set feature class and add tooltip on tile load. */ 37 | function load(e) { 38 | for (var i = 0; i < e.features.length; i++) { 39 | var feature = e.features[i], 40 | n = feature.data.properties.name, 41 | v = internet[n] / population[n]; 42 | n$(feature.element) 43 | .attr("class", isNaN(v) ? null : "q" + ~~(v * 9) + "-" + 9) 44 | .add("svg:title") 45 | .text(n + (isNaN(v) ? "" : ": " + percent(v))); 46 | } 47 | } 48 | 49 | /** Formats a given number as a percentage, e.g., 10% or 0.02%. */ 50 | function percent(v) { 51 | return (v * 100).toPrecision(Math.min(2, 2 - Math.log(v) / Math.LN2)) + "%"; 52 | } 53 | -------------------------------------------------------------------------------- /lib/blueprint/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2007 - 2010 blueprintcss.org 2 | 3 | Permission is hereby granted, free of charge, to any person 4 | obtaining a copy of this software and associated documentation 5 | files (the "Software"), to deal in the Software without 6 | restriction, including without limitation the rights to use, 7 | copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the 9 | Software is furnished to do so, subject to the following 10 | conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | -------------------------------------------------------------------------------- /lib/blueprint/ie.css: -------------------------------------------------------------------------------- 1 | /* ----------------------------------------------------------------------- 2 | 3 | 4 | Blueprint CSS Framework 0.9 5 | http://blueprintcss.org 6 | 7 | * Copyright (c) 2007-Present. See LICENSE for more info. 8 | * See README for instructions on how to use Blueprint. 9 | * For credits and origins, see AUTHORS. 10 | * This is a compressed file. See the sources in the 'src' directory. 11 | 12 | ----------------------------------------------------------------------- */ 13 | 14 | /* ie.css */ 15 | body {text-align:center;} 16 | .container {text-align:left;} 17 | * html .column, * html .span-1, * html .span-2, * html .span-3, * html .span-4, * html .span-5, * html .span-6, * html .span-7, * html .span-8, * html .span-9, * html .span-10, * html .span-11, * html .span-12, * html .span-13, * html .span-14, * html .span-15, * html .span-16, * html .span-17, * html .span-18, * html .span-19, * html .span-20, * html .span-21, * html .span-22, * html .span-23, * html .span-24 {display:inline;overflow-x:hidden;} 18 | * html legend {margin:0px -8px 16px 0;padding:0;} 19 | sup {vertical-align:text-top;} 20 | sub {vertical-align:text-bottom;} 21 | html>body p code {*white-space:normal;} 22 | hr {margin:-8px auto 11px;} 23 | img {-ms-interpolation-mode:bicubic;} 24 | .clearfix, .container {display:inline-block;} 25 | * html .clearfix, * html .container {height:1%;} 26 | fieldset {padding-top:0;} 27 | textarea {overflow:auto;} 28 | input.text, input.title, textarea {background-color:#fff;border:1px solid #bbb;} 29 | input.text:focus, input.title:focus {border-color:#666;} 30 | input.text, input.title, textarea, select {margin:0.5em 0;} 31 | input.checkbox, input.radio {position:relative;top:.25em;} 32 | form.inline div, form.inline p {vertical-align:middle;} 33 | form.inline label {position:relative;top:-0.25em;} 34 | form.inline input.checkbox, form.inline input.radio, form.inline input.button, form.inline button {margin:0.5em 0;} 35 | button, input.button {position:relative;top:0.25em;} 36 | -------------------------------------------------------------------------------- /lib/blueprint/plugins/fancy-type/screen.css: -------------------------------------------------------------------------------- 1 | /* -------------------------------------------------------------- 2 | 3 | fancy-type.css 4 | * Lots of pretty advanced classes for manipulating text. 5 | 6 | See the Readme file in this folder for additional instructions. 7 | 8 | -------------------------------------------------------------- */ 9 | 10 | /* Indentation instead of line shifts for sibling paragraphs. */ 11 | p + p { text-indent:2em; margin-top:-1.5em; } 12 | form p + p { text-indent: 0; } /* Don't want this in forms. */ 13 | 14 | 15 | /* For great looking type, use this code instead of asdf: 16 | asdf 17 | Best used on prepositions and ampersands. */ 18 | 19 | .alt { 20 | color: #666; 21 | font-family: "Warnock Pro", "Goudy Old Style","Palatino","Book Antiqua", Georgia, serif; 22 | font-style: italic; 23 | font-weight: normal; 24 | } 25 | 26 | 27 | /* For great looking quote marks in titles, replace "asdf" with: 28 | asdf” 29 | (That is, when the title starts with a quote mark). 30 | (You may have to change this value depending on your font size). */ 31 | 32 | .dquo { margin-left: -.5em; } 33 | 34 | 35 | /* Reduced size type with incremental leading 36 | (http://www.markboulton.co.uk/journal/comments/incremental_leading/) 37 | 38 | This could be used for side notes. For smaller type, you don't necessarily want to 39 | follow the 1.5x vertical rhythm -- the line-height is too much. 40 | 41 | Using this class, it reduces your font size and line-height so that for 42 | every four lines of normal sized type, there is five lines of the sidenote. eg: 43 | 44 | New type size in em's: 45 | 10px (wanted side note size) / 12px (existing base size) = 0.8333 (new type size in ems) 46 | 47 | New line-height value: 48 | 12px x 1.5 = 18px (old line-height) 49 | 18px x 4 = 72px 50 | 72px / 5 = 14.4px (new line height) 51 | 14.4px / 10px = 1.44 (new line height in em's) */ 52 | 53 | p.incr, .incr p { 54 | font-size: 10px; 55 | line-height: 1.44em; 56 | margin-bottom: 1.5em; 57 | } 58 | 59 | 60 | /* Surround uppercase words and abbreviations with this class. 61 | Based on work by Jørgen Arnor Gårdsø Lom [http://twistedintellect.com/] */ 62 | 63 | .caps { 64 | font-variant: small-caps; 65 | letter-spacing: 1px; 66 | text-transform: lowercase; 67 | font-size:1.2em; 68 | line-height:1%; 69 | font-weight:bold; 70 | padding:0 2px; 71 | } 72 | -------------------------------------------------------------------------------- /lib/blueprint/print.css: -------------------------------------------------------------------------------- 1 | /* ----------------------------------------------------------------------- 2 | 3 | 4 | Blueprint CSS Framework 0.9 5 | http://blueprintcss.org 6 | 7 | * Copyright (c) 2007-Present. See LICENSE for more info. 8 | * See README for instructions on how to use Blueprint. 9 | * For credits and origins, see AUTHORS. 10 | * This is a compressed file. See the sources in the 'src' directory. 11 | 12 | ----------------------------------------------------------------------- */ 13 | 14 | /* print.css */ 15 | body {line-height:1.5;font-family:"Helvetica Neue", Arial, Helvetica, sans-serif;color:#000;background:none;font-size:10pt;} 16 | .container {background:none;} 17 | hr {background:#ccc;color:#ccc;width:100%;height:2px;margin:2em 0;padding:0;border:none;} 18 | hr.space {background:#fff;color:#fff;visibility:hidden;} 19 | h1, h2, h3, h4, h5, h6 {font-family:"Helvetica Neue", Arial, "Lucida Grande", sans-serif;} 20 | code {font:.9em "Courier New", Monaco, Courier, monospace;} 21 | a img {border:none;} 22 | p img.top {margin-top:0;} 23 | blockquote {margin:1.5em;padding:1em;font-style:italic;font-size:.9em;} 24 | .small {font-size:.9em;} 25 | .large {font-size:1.1em;} 26 | .quiet {color:#999;} 27 | .hide {display:none;} 28 | a:link, a:visited {background:transparent;font-weight:700;text-decoration:underline;} 29 | a:link:after, a:visited:after {content:" (" attr(href) ")";font-size:90%;} 30 | -------------------------------------------------------------------------------- /lib/colorbrewer/LICENSE: -------------------------------------------------------------------------------- 1 | Apache-Style Software License for ColorBrewer software and ColorBrewer Color 2 | Schemes 3 | 4 | Copyright (c) 2002 Cynthia Brewer, Mark Harrower, and The Pennsylvania State 5 | University. 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use 8 | this file except in compliance with the License. You may obtain a copy of the 9 | License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software distributed 14 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 15 | CONDITIONS OF ANY KIND, either express or implied. See the License for the 16 | specific language governing permissions and limitations under the License. 17 | 18 | Redistribution and use in source and binary forms, with or without modification, 19 | are permitted provided that the following conditions are met: 20 | 21 | 1. Redistributions as source code must retain the above copyright notice, this 22 | list of conditions and the following disclaimer. 23 | 24 | 2. The end-user documentation included with the redistribution, if any, must 25 | include the following acknowledgment: "This product includes color 26 | specifications and designs developed by Cynthia Brewer 27 | (http://colorbrewer.org/)." Alternately, this acknowledgment may appear in the 28 | software itself, if and wherever such third-party acknowledgments normally 29 | appear. 30 | 31 | 4. The name "ColorBrewer" must not be used to endorse or promote products 32 | derived from this software without prior written permission. For written 33 | permission, please contact Cynthia Brewer at cbrewer@psu.edu. 34 | 35 | 5. Products derived from this software may not be called "ColorBrewer", nor may 36 | "ColorBrewer" appear in their name, without prior written permission of Cynthia 37 | Brewer. 38 | -------------------------------------------------------------------------------- /lib/crimespotting/crimespotting.js: -------------------------------------------------------------------------------- 1 | /* URL template for loading Crimespotting data. */ 2 | function crimespotting(template) { 3 | return function(c) { 4 | var max = 1 << c.zoom, column = c.column % max; 5 | if (column < 0) column += max; 6 | return template.replace(/{(.)}/g, function(s, v) { 7 | switch (v) { 8 | case "B": { 9 | var nw = map.coordinateLocation({row: c.row, column: column, zoom: c.zoom}), 10 | se = map.coordinateLocation({row: c.row + 1, column: column + 1, zoom: c.zoom}), 11 | pn = Math.ceil(Math.log(c.zoom) / Math.LN2); 12 | return nw.lon.toFixed(pn) 13 | + "," + se.lat.toFixed(pn) 14 | + "," + se.lon.toFixed(pn) 15 | + "," + nw.lat.toFixed(pn); 16 | } 17 | } 18 | return v; 19 | }); 20 | }; 21 | } 22 | 23 | crimespotting.categorize = (function() { 24 | var categories = { 25 | "aggravated assault": "violent", 26 | "murder": "violent", 27 | "robbery": "violent", 28 | "simple assault": "violent", 29 | "arson": "property", 30 | "burglary": "property", 31 | "theft": "property", 32 | "vandalism": "property", 33 | "vehicle theft": "property", 34 | "alcohol": "quality", 35 | "disturbing the peace": "quality", 36 | "narcotics": "quality", 37 | "prostitution": "quality" 38 | }; 39 | return function(d) { 40 | return categories[d.properties.crime_type.toLowerCase()]; 41 | }; 42 | })(); 43 | -------------------------------------------------------------------------------- /lib/google-compiler/README: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | // 18 | // Contents 19 | // 20 | 21 | The Closure Compiler performs checking, instrumentation, and 22 | optimizations on JavaScript code. The purpose of this README is to 23 | explain how to build and run the Closure Compiler. 24 | 25 | The Closure Compiler requires Java 6 or higher. 26 | http://www.java.com/ 27 | 28 | 29 | // 30 | // Building The Closure Compiler 31 | // 32 | 33 | There are three ways to get a Closure Compiler executable. 34 | 35 | 1) Use one we built for you. 36 | 37 | Pre-built Closure binaries can be found at 38 | http://code.google.com/p/closure-compiler/downloads/list 39 | 40 | 41 | 2) Check out the source and build it with Apache Ant. 42 | 43 | First, check out the full source tree of the Closure Compiler. There 44 | are instructions on how to do this at the project site. 45 | http://code.google.com/p/closure-compiler/source/checkout 46 | 47 | Apache Ant is a cross-platform build tool. 48 | http://ant.apache.org/ 49 | 50 | At the root of the source tree, there is an Ant file named 51 | build.xml. To use it, navigate to the same directory and type the 52 | command 53 | 54 | ant jar 55 | 56 | This will produce a jar file called "build/compiler.jar". 57 | 58 | 59 | 3) Check out the source and build it with Eclipse. 60 | 61 | Eclipse is a cross-platform IDE. 62 | http://www.eclipse.org/ 63 | 64 | Under Eclipse's File menu, click "New > Project ..." and create a 65 | "Java Project." You will see an options screen. Give the project a 66 | name, select "Create project from existing source," and choose the 67 | root of the checked-out source tree as the existing directory. Verify 68 | that you are using JRE version 6 or higher. 69 | 70 | Eclipse can use the build.xml file to discover rules. When you 71 | navigate to the build.xml file, you will see all the build rules in 72 | the "Outline" pane. Run the "jar" rule to build the compiler in 73 | build/compiler.jar. 74 | 75 | 76 | // 77 | // Running The Closure Compiler 78 | // 79 | 80 | Once you have the jar binary, running the Closure Compiler is straightforward. 81 | 82 | On the command line, type 83 | 84 | java -jar compiler.jar 85 | 86 | This starts the compiler in interactive mode. Type 87 | 88 | var x = 17 + 25; 89 | 90 | then hit "Enter", then hit "Ctrl-Z" (on Windows) or "Ctrl-D" (on Mac or Linux) 91 | and "Enter" again. The Compiler will respond: 92 | 93 | var x=42; 94 | 95 | The Closure Compiler has many options for reading input from a file, 96 | writing output to a file, checking your code, and running 97 | optimizations. To learn more, type 98 | 99 | java -jar compiler.jar --help 100 | 101 | You can read more detailed documentation about the many flags at 102 | http://code.google.com/closure/compiler/docs/gettingstarted_app.html 103 | 104 | 105 | // 106 | // Compiling Multiple Scripts 107 | // 108 | 109 | If you have multiple scripts, you should compile them all together with 110 | one compile command. 111 | 112 | java -jar compiler.jar --js=in1.js --js=in2.js ... --js_output_file=out.js 113 | 114 | The Closure Compiler will concatenate the files in the order they're 115 | passed at the command line. 116 | 117 | If you need to compile many, many scripts together, you may start to 118 | run into problems with managing dependencies between scripts. You 119 | should check out the Closure Library. It contains functions for 120 | enforcing dependencies between scripts, and a tool called calcdeps.py 121 | that knows how to give scripts to the Closure Compiler in the right 122 | order. 123 | 124 | http://code.google.com/p/closure-library/ 125 | 126 | // 127 | // Licensing 128 | // 129 | 130 | Unless otherwise stated, all source files are licensed under 131 | the Apache License, Version 2.0. 132 | 133 | 134 | ----- 135 | Code under: 136 | src/com/google/javascript/rhino 137 | test/com/google/javascript/rhino 138 | 139 | URL: http://www.mozilla.org/rhino 140 | Version: 1.5R3, with heavy modifications 141 | License: Netscape Public License and MPL / GPL dual license 142 | 143 | Description: A partial copy of Mozilla Rhino. Mozilla Rhino is an 144 | implementation of JavaScript for the JVM. The JavaScript parser and 145 | the parse tree data structures were extracted and modified 146 | significantly for use by Google's JavaScript compiler. 147 | 148 | Local Modifications: The packages have been renamespaced. All code not 149 | relavant to parsing has been removed. A JSDoc parser and static typing 150 | system have been added. 151 | 152 | 153 | ----- 154 | Code in: 155 | lib/libtrunk_rhino_parser_jarjared.jar 156 | 157 | Rhino 158 | URL: http://www.mozilla.org/rhino 159 | Version: Trunk 160 | License: Netscape Public License and MPL / GPL dual license 161 | 162 | Description: Mozilla Rhino is an implementation of JavaScript for the JVM. 163 | 164 | Local Modifications: None. We've used JarJar to renamespace the code 165 | post-compilation. See: 166 | http://code.google.com/p/jarjar/ 167 | 168 | 169 | ----- 170 | Code in: 171 | lib/args4j_deploy.jar 172 | 173 | Args4j 174 | URL: https://args4j.dev.java.net/ 175 | Version: 2.0.9 176 | License: MIT 177 | 178 | Description: 179 | args4j is a small Java class library that makes it easy to parse command line 180 | options/arguments in your CUI application. 181 | 182 | Local Modifications: None. 183 | 184 | 185 | ----- 186 | Code in: 187 | lib/google_common_deploy.jar 188 | 189 | Guava Libraries 190 | URL: http://code.google.com/p/guava-libraries/ 191 | Version: Trunk 192 | License: Apache License 2.0 193 | 194 | Description: Google's core Java libraries. 195 | 196 | Local Modifications: None. 197 | 198 | 199 | ----- 200 | Code in: 201 | lib/hamcrest-core-1.1.jar 202 | 203 | Hamcrest 204 | URL: http://code.google.com/p/hamcrest 205 | License: BSD 206 | License File: LICENSE 207 | 208 | Description: 209 | Provides a library of matcher objects (also known as constraints or 210 | predicates) allowing 'match' rules to be defined declaratively, to be used in 211 | other frameworks. Typical scenarios include testing frameworks, mocking 212 | libraries and UI validation rules. 213 | 214 | Local modifications: 215 | The original jars contained both source code and compiled classes. 216 | 217 | hamcrest-core-1.1.jar just contains the compiled classes. 218 | 219 | 220 | ---- 221 | Code in: 222 | lib/junit.jar 223 | 224 | JUnit 225 | URL: http://sourceforge.net/projects/junit/ 226 | Version: 4.5 227 | License: Common Public License 1.0 228 | 229 | Description: A framework for writing and running automated tests in Java. 230 | 231 | Local Modifications: None. 232 | 233 | 234 | --- 235 | Code in: 236 | lib/protobuf_deploy.jar 237 | 238 | Protocol Buffers 239 | URL: http://code.google.com/p/protobuf/ 240 | Version: 2.2.0a 241 | License: New BSD License 242 | 243 | Description: Supporting libraries for protocol buffers, 244 | an encoding of structured data. 245 | 246 | Local Modifications: None 247 | 248 | 249 | --- 250 | Code in: 251 | lib/ant_deploy.jar 252 | 253 | URL: http://ant.apache.org/bindownload.cgi 254 | Version: 1.6.5 255 | License: Apache License 2.0 256 | Description: 257 | Ant is a Java based build tool. In theory it is kind of like "make" 258 | without make's wrinkles and with the full portability of pure java code. 259 | 260 | Local Modifications: 261 | Modified apache-ant-1.6.5/bin/ant to look in the ant.runfiles directory 262 | -------------------------------------------------------------------------------- /lib/google-compiler/compiler-20100616.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mbostock/polymaps/6cc4513810c3c063229f7f74d474418ce1929d6c/lib/google-compiler/compiler-20100616.jar -------------------------------------------------------------------------------- /lib/jquery/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2010 John Resig, http://jquery.com/ 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /lib/modernizr/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2010, Faruk Ateş 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | * Redistributions of source code must retain the above copyright 7 | notice, this list of conditions and the following disclaimer. 8 | * Redistributions in binary form must reproduce the above copyright 9 | notice, this list of conditions and the following disclaimer in the 10 | documentation and/or other materials provided with the distribution. 11 | * Neither the name of the Organization nor the 12 | names of its contributors may be used to endorse or promote products 13 | derived from this software without specific prior written permission. 14 | 15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY 19 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | -------------------------------------------------------------------------------- /lib/nns/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2010, Michael Bostock 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, 5 | are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, 8 | this list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * Neither the name of Michael Bostock nor the names of its contributors may be 15 | used to endorse or promote products derived from this software without 16 | specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 19 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 22 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 25 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /lib/nns/nns.js: -------------------------------------------------------------------------------- 1 | (function(_) { 2 | 3 | function create(n) { 4 | if (/^#/.test(n)) return document.getElementById(n.substring(1)); 5 | n = qualify(n); 6 | return n.space == null 7 | ? document.createElement(n.local) 8 | : document.createElementNS(n.space, n.local); 9 | } 10 | 11 | function qualify(n) { 12 | var i = n.indexOf(":"); 13 | return { 14 | space: n$.prefix[n.substring(0, i)], 15 | local: n.substring(i + 1) 16 | }; 17 | } 18 | 19 | function N$(e) { 20 | this.element = e; 21 | } 22 | 23 | N$.prototype = { 24 | 25 | add: function(c, s) { 26 | return n$(this.element.insertBefore( 27 | typeof c == "string" ? create(c) : $n(c), 28 | arguments.length == 1 ? null : $n(s))); 29 | }, 30 | 31 | remove: function(c) { 32 | this.element.removeChild($n(c)); 33 | return this; 34 | }, 35 | 36 | parent: function() { 37 | return n$(this.element.parentNode); 38 | }, 39 | 40 | child: function(i) { 41 | var children = this.element.childNodes; 42 | return n$(children[i < 0 ? children.length - i - 1 : i]); 43 | }, 44 | 45 | previous: function() { 46 | return n$(this.element.previousSibling); 47 | }, 48 | 49 | next: function() { 50 | return n$(this.element.nextSibling); 51 | }, 52 | 53 | attr: function(n, v) { 54 | var e = this.element; 55 | n = qualify(n); 56 | if (arguments.length == 1) { 57 | return n.space == null 58 | ? e.getAttribute(n.local) 59 | : e.getAttributeNS(n.space, n.local); 60 | } 61 | if (n.space == null) { 62 | if (v == null) e.removeAttribute(n.local); 63 | else e.setAttribute(n.local, v); 64 | } else { 65 | if (v == null) e.removeAttributeNS(n.space, n.local); 66 | else e.setAttributeNS(n.space, n.local, v); 67 | } 68 | return this; 69 | }, 70 | 71 | style: function(n, v, p) { 72 | var style = this.element.style; 73 | if (arguments.length == 1) return style.getPropertyValue(n); 74 | if (v == null) style.removeProperty(n); 75 | else style.setProperty(n, v, arguments.length == 3 ? p : null); 76 | return this; 77 | }, 78 | 79 | on: function(t, l, c) { 80 | this.element.addEventListener(t, l, arguments.length == 3 ? c : false); 81 | return this; 82 | }, 83 | 84 | off: function(t, l, c) { 85 | this.element.removeEventListener(t, l, arguments.length == 3 ? c : false); 86 | return this; 87 | }, 88 | 89 | text: function(v) { 90 | var t = this.element.firstChild; 91 | if (!arguments.length) return t && t.nodeValue; 92 | if (t) t.nodeValue = v; 93 | else if (v != null) t = this.element.appendChild(document.createTextNode(v)); 94 | return this; 95 | } 96 | } 97 | 98 | function n$(e) { 99 | return e == null || e.element ? e : new N$(typeof e == "string" ? create(e) : e); 100 | } 101 | 102 | function $n(o) { 103 | return o && o.element || o; 104 | } 105 | 106 | n$.prefix = { 107 | svg: "http://www.w3.org/2000/svg", 108 | xlink: "http://www.w3.org/1999/xlink", 109 | xml: "http://www.w3.org/XML/1998/namespace", 110 | xmlns: "http://www.w3.org/2000/xmlns/" 111 | }; 112 | 113 | n$.version = "1.1.0"; 114 | 115 | _.n$ = n$; 116 | _.$n = $n; 117 | })(this); 118 | -------------------------------------------------------------------------------- /lib/nns/nns.min.js: -------------------------------------------------------------------------------- 1 | (function(g){function h(a){if(/^#/.test(a))return document.getElementById(a.substring(1));a=i(a);return a.space==null?document.createElement(a.local):document.createElementNS(a.space,a.local)}function i(a){var b=a.indexOf(":");return{space:d.prefix[a.substring(0,b)],local:a.substring(b+1)}}function j(a){this.element=a}function d(a){return a==null||a.element?a:new j(typeof a=="string"?h(a):a)}function e(a){return a&&a.element||a}j.prototype={add:function(a,b){return d(this.element.insertBefore(typeof a== 2 | "string"?h(a):e(a),arguments.length==1?null:e(b)))},remove:function(a){this.element.removeChild(e(a));return this},parent:function(){return d(this.element.parentNode)},child:function(a){var b=this.element.childNodes;return d(b[a<0?b.length-a-1:a])},previous:function(){return d(this.element.previousSibling)},next:function(){return d(this.element.nextSibling)},attr:function(a,b){var c=this.element;a=i(a);if(arguments.length==1)return a.space==null?c.getAttribute(a.local):c.getAttributeNS(a.space,a.local); 3 | if(a.space==null)b==null?c.removeAttribute(a.local):c.setAttribute(a.local,b);else b==null?c.removeAttributeNS(a.space,a.local):c.setAttributeNS(a.space,a.local,b);return this},style:function(a,b,c){var f=this.element.style;if(arguments.length==1)return f.getPropertyValue(a);b==null?f.removeProperty(a):f.setProperty(a,b,arguments.length==3?c:null);return this},on:function(a,b,c){this.element.addEventListener(a,b,arguments.length==3?c:false);return this},off:function(a,b,c){this.element.removeEventListener(a, 4 | b,arguments.length==3?c:false);return this},text:function(a){var b=this.element.firstChild;if(!arguments.length)return b&&b.nodeValue;if(b)b.nodeValue=a;else a!=null&&this.element.appendChild(document.createTextNode(a));return this}};d.prefix={svg:"http://www.w3.org/2000/svg",xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"};d.version="1.1.0";g.n$=d;g.$n=e})(this); 5 | -------------------------------------------------------------------------------- /lib/protovis/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2010, Stanford Visualization Group 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, 5 | are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, 8 | this list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * Neither the name of Stanford University nor the names of its contributors 15 | may be used to endorse or promote products derived from this software 16 | without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 19 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 22 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 25 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /lib/raphaeljs/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2008 Dmitry Baranovskiy 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 7 | the Software, and to permit persons to whom the Software is furnished to do so, 8 | subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 15 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 16 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 17 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 18 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 19 | -------------------------------------------------------------------------------- /lib/raphaeljs/icons.js: -------------------------------------------------------------------------------- 1 | // http://raphaeljs.com/icons/ 2 | 3 | var icons = (function(po) { 4 | return { 5 | marker: function() { 6 | var path = po.svg("path"); 7 | path.setAttribute("transform", "translate(-16,-28)"); 8 | path.setAttribute("d", "M16,3.5c-4.142,0-7.5,3.358-7.5,7.5c0,4.143,7.5,18.121,7.5,18.121S23.5,15.143,23.5,11C23.5,6.858,20.143,3.5,16,3.5z M16,14.584c-1.979,0-3.584-1.604-3.584-3.584S14.021,7.416,16,7.416S19.584,9.021,19.584,11S17.979,14.584,16,14.584z"); 9 | return path; 10 | } 11 | }; 12 | })(org.polymaps); 13 | -------------------------------------------------------------------------------- /lib/tipsy/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright (c) 2008 Jason Frame (jason@onehackoranother.com) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /lib/tipsy/jquery.tipsy.js: -------------------------------------------------------------------------------- 1 | // tipsy, facebook style tooltips for jquery 2 | // version 1.0.0a 3 | // (c) 2008-2010 jason frame [jason@onehackoranother.com] 4 | // released under the MIT license 5 | 6 | (function($) { 7 | 8 | function Tipsy(element, options) { 9 | this.$element = $(element); 10 | this.options = options; 11 | this.enabled = true; 12 | this.fixTitle(); 13 | } 14 | 15 | Tipsy.prototype = { 16 | show: function() { 17 | var title = this.getTitle(); 18 | if (title && this.enabled) { 19 | var $tip = this.tip(); 20 | 21 | $tip.find('.tipsy-inner')[this.options.html ? 'html' : 'text'](title); 22 | $tip[0].className = 'tipsy'; // reset classname in case of dynamic gravity 23 | $tip.remove().css({top: 0, left: 0, visibility: 'hidden', display: 'block'}).appendTo(document.body); 24 | 25 | var pos = $.extend({}, this.$element.offset(), { 26 | width: this.$element[0].offsetWidth, 27 | height: this.$element[0].offsetHeight 28 | }); 29 | 30 | var actualWidth = $tip[0].offsetWidth, actualHeight = $tip[0].offsetHeight; 31 | var gravity = (typeof this.options.gravity == 'function') 32 | ? this.options.gravity.call(this.$element[0]) 33 | : this.options.gravity; 34 | 35 | var tp; 36 | switch (gravity.charAt(0)) { 37 | case 'n': 38 | tp = {top: pos.top + pos.height + this.options.offset, left: pos.left + pos.width / 2 - actualWidth / 2}; 39 | break; 40 | case 's': 41 | tp = {top: pos.top - actualHeight - this.options.offset, left: pos.left + pos.width / 2 - actualWidth / 2}; 42 | break; 43 | case 'e': 44 | tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth - this.options.offset}; 45 | break; 46 | case 'w': 47 | tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width + this.options.offset}; 48 | break; 49 | } 50 | 51 | if (gravity.length == 2) { 52 | if (gravity.charAt(1) == 'w') { 53 | tp.left = pos.left + pos.width / 2 - 15; 54 | } else { 55 | tp.left = pos.left + pos.width / 2 - actualWidth + 15; 56 | } 57 | } 58 | 59 | $tip.css(tp).addClass('tipsy-' + gravity); 60 | 61 | if (this.options.fade) { 62 | $tip.stop().css({opacity: 0, display: 'block', visibility: 'visible'}).animate({opacity: this.options.opacity}); 63 | } else { 64 | $tip.css({visibility: 'visible', opacity: this.options.opacity}); 65 | } 66 | } 67 | }, 68 | 69 | hide: function() { 70 | if (this.options.fade) { 71 | this.tip().stop().fadeOut(function() { $(this).remove(); }); 72 | } else { 73 | this.tip().remove(); 74 | } 75 | }, 76 | 77 | fixTitle: function() { 78 | var $e = this.$element; 79 | if ($e.attr('title') || typeof($e.attr('original-title')) != 'string') { 80 | $e.attr('original-title', $e.attr('title') || '').removeAttr('title'); 81 | } 82 | }, 83 | 84 | getTitle: function() { 85 | var title, $e = this.$element, o = this.options; 86 | this.fixTitle(); 87 | var title, o = this.options; 88 | if (typeof o.title == 'string') { 89 | title = $e.attr(o.title == 'title' ? 'original-title' : o.title); 90 | } else if (typeof o.title == 'function') { 91 | title = o.title.call($e[0]); 92 | } 93 | title = ('' + title).replace(/(^\s*|\s*$)/, ""); 94 | return title || o.fallback; 95 | }, 96 | 97 | tip: function() { 98 | if (!this.$tip) { 99 | this.$tip = $('
').html('
'); 100 | } 101 | return this.$tip; 102 | }, 103 | 104 | validate: function() { 105 | if (!this.$element[0].parentNode) { 106 | this.hide(); 107 | this.$element = null; 108 | this.options = null; 109 | } 110 | }, 111 | 112 | enable: function() { this.enabled = true; }, 113 | disable: function() { this.enabled = false; }, 114 | toggleEnabled: function() { this.enabled = !this.enabled; } 115 | }; 116 | 117 | $.fn.tipsy = function(options) { 118 | 119 | if (options === true) { 120 | return this.data('tipsy'); 121 | } else if (typeof options == 'string') { 122 | var tipsy = this.data('tipsy'); 123 | if (tipsy) tipsy[options](); 124 | return this; 125 | } 126 | 127 | options = $.extend({}, $.fn.tipsy.defaults, options); 128 | 129 | function get(ele) { 130 | var tipsy = $.data(ele, 'tipsy'); 131 | if (!tipsy) { 132 | tipsy = new Tipsy(ele, $.fn.tipsy.elementOptions(ele, options)); 133 | $.data(ele, 'tipsy', tipsy); 134 | } 135 | return tipsy; 136 | } 137 | 138 | function enter() { 139 | var tipsy = get(this); 140 | tipsy.hoverState = 'in'; 141 | if (options.delayIn == 0) { 142 | tipsy.show(); 143 | } else { 144 | tipsy.fixTitle(); 145 | setTimeout(function() { if (tipsy.hoverState == 'in') tipsy.show(); }, options.delayIn); 146 | } 147 | }; 148 | 149 | function leave() { 150 | var tipsy = get(this); 151 | tipsy.hoverState = 'out'; 152 | if (options.delayOut == 0) { 153 | tipsy.hide(); 154 | } else { 155 | setTimeout(function() { if (tipsy.hoverState == 'out') tipsy.hide(); }, options.delayOut); 156 | } 157 | }; 158 | 159 | if (!options.live) this.each(function() { get(this); }); 160 | 161 | if (options.trigger != 'manual') { 162 | var binder = options.live ? 'live' : 'bind', 163 | eventIn = options.trigger == 'hover' ? 'mouseenter' : 'focus', 164 | eventOut = options.trigger == 'hover' ? 'mouseleave' : 'blur'; 165 | this[binder](eventIn, enter)[binder](eventOut, leave); 166 | } 167 | 168 | return this; 169 | 170 | }; 171 | 172 | $.fn.tipsy.defaults = { 173 | delayIn: 0, 174 | delayOut: 0, 175 | fade: false, 176 | fallback: '', 177 | gravity: 'n', 178 | html: false, 179 | live: false, 180 | offset: 0, 181 | opacity: 0.8, 182 | title: 'title', 183 | trigger: 'hover' 184 | }; 185 | 186 | // Overwrite this method to provide options on a per-element basis. 187 | // For example, you could store the gravity in a 'tipsy-gravity' attribute: 188 | // return $.extend({}, options, {gravity: $(ele).attr('tipsy-gravity') || 'n' }); 189 | // (remember - do not modify 'options' in place!) 190 | $.fn.tipsy.elementOptions = function(ele, options) { 191 | return $.metadata ? $.extend({}, options, $(ele).metadata()) : options; 192 | }; 193 | 194 | $.fn.tipsy.autoNS = function() { 195 | return $(this).offset().top > ($(document).scrollTop() + $(window).height() / 2) ? 's' : 'n'; 196 | }; 197 | 198 | $.fn.tipsy.autoWE = function() { 199 | return $(this).offset().left > ($(document).scrollLeft() + $(window).width() / 2) ? 'e' : 'w'; 200 | }; 201 | 202 | })(jQuery); 203 | -------------------------------------------------------------------------------- /lib/tipsy/tipsy.css: -------------------------------------------------------------------------------- 1 | .tipsy { padding: 5px; font-size: 10px; position: absolute; z-index: 100000; } 2 | .tipsy-inner { padding: 5px 8px 4px 8px; background-color: black; color: white; max-width: 200px; text-align: center; } 3 | .tipsy-inner { border-radius: 3px; -moz-border-radius:3px; -webkit-border-radius:3px; } 4 | .tipsy-arrow { position: absolute; background: url('tipsy.gif') no-repeat top left; width: 9px; height: 5px; } 5 | .tipsy-n .tipsy-arrow { top: 0; left: 50%; margin-left: -4px; } 6 | .tipsy-nw .tipsy-arrow { top: 0; left: 10px; } 7 | .tipsy-ne .tipsy-arrow { top: 0; right: 10px; } 8 | .tipsy-s .tipsy-arrow { bottom: 0; left: 50%; margin-left: -4px; background-position: bottom left; } 9 | .tipsy-sw .tipsy-arrow { bottom: 0; left: 10px; background-position: bottom left; } 10 | .tipsy-se .tipsy-arrow { bottom: 0; right: 10px; background-position: bottom left; } 11 | .tipsy-e .tipsy-arrow { top: 50%; margin-top: -4px; right: 0; width: 5px; height: 9px; background-position: top right; } 12 | .tipsy-w .tipsy-arrow { top: 50%; margin-top: -4px; left: 0; width: 5px; height: 9px; } 13 | -------------------------------------------------------------------------------- /lib/tipsy/tipsy.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mbostock/polymaps/6cc4513810c3c063229f7f74d474418ce1929d6c/lib/tipsy/tipsy.gif -------------------------------------------------------------------------------- /src/Arrow.js: -------------------------------------------------------------------------------- 1 | po.arrow = function() { 2 | var arrow = {}, 3 | key = {left: 0, right: 0, up: 0, down: 0}, 4 | last = 0, 5 | repeatTimer, 6 | repeatDelay = 250, 7 | repeatInterval = 50, 8 | speed = 16, 9 | map, 10 | parent; 11 | 12 | function keydown(e) { 13 | if (e.ctrlKey || e.altKey || e.metaKey) return; 14 | var now = Date.now(), dx = 0, dy = 0; 15 | switch (e.keyCode) { 16 | case 37: { 17 | if (!key.left) { 18 | last = now; 19 | key.left = 1; 20 | if (!key.right) dx = speed; 21 | } 22 | break; 23 | } 24 | case 39: { 25 | if (!key.right) { 26 | last = now; 27 | key.right = 1; 28 | if (!key.left) dx = -speed; 29 | } 30 | break; 31 | } 32 | case 38: { 33 | if (!key.up) { 34 | last = now; 35 | key.up = 1; 36 | if (!key.down) dy = speed; 37 | } 38 | break; 39 | } 40 | case 40: { 41 | if (!key.down) { 42 | last = now; 43 | key.down = 1; 44 | if (!key.up) dy = -speed; 45 | } 46 | break; 47 | } 48 | default: return; 49 | } 50 | if (dx || dy) map.panBy({x: dx, y: dy}); 51 | if (!repeatTimer && (key.left | key.right | key.up | key.down)) { 52 | repeatTimer = setInterval(repeat, repeatInterval); 53 | } 54 | e.preventDefault(); 55 | } 56 | 57 | function keyup(e) { 58 | last = Date.now(); 59 | switch (e.keyCode) { 60 | case 37: key.left = 0; break; 61 | case 39: key.right = 0; break; 62 | case 38: key.up = 0; break; 63 | case 40: key.down = 0; break; 64 | default: return; 65 | } 66 | if (repeatTimer && !(key.left | key.right | key.up | key.down)) { 67 | repeatTimer = clearInterval(repeatTimer); 68 | } 69 | e.preventDefault(); 70 | } 71 | 72 | function keypress(e) { 73 | switch (e.charCode) { 74 | case 45: case 95: map.zoom(Math.ceil(map.zoom()) - 1); break; // - _ 75 | case 43: case 61: map.zoom(Math.floor(map.zoom()) + 1); break; // = + 76 | default: return; 77 | } 78 | e.preventDefault(); 79 | } 80 | 81 | function repeat() { 82 | if (!map) return; 83 | if (Date.now() < last + repeatDelay) return; 84 | var dx = (key.left - key.right) * speed, 85 | dy = (key.up - key.down) * speed; 86 | if (dx || dy) map.panBy({x: dx, y: dy}); 87 | } 88 | 89 | arrow.map = function(x) { 90 | if (!arguments.length) return map; 91 | if (map) { 92 | parent.removeEventListener("keypress", keypress, false); 93 | parent.removeEventListener("keydown", keydown, false); 94 | parent.removeEventListener("keyup", keyup, false); 95 | parent = null; 96 | } 97 | if (map = x) { 98 | parent = map.focusableParent(); 99 | parent.addEventListener("keypress", keypress, false); 100 | parent.addEventListener("keydown", keydown, false); 101 | parent.addEventListener("keyup", keyup, false); 102 | } 103 | return arrow; 104 | }; 105 | 106 | arrow.speed = function(x) { 107 | if (!arguments.length) return speed; 108 | speed = x; 109 | return arrow; 110 | }; 111 | 112 | return arrow; 113 | }; 114 | -------------------------------------------------------------------------------- /src/Cache.js: -------------------------------------------------------------------------------- 1 | po.cache = function(load, unload) { 2 | var cache = {}, 3 | locks = {}, 4 | map = {}, 5 | head = null, 6 | tail = null, 7 | size = 64, 8 | n = 0; 9 | 10 | function remove(tile) { 11 | n--; 12 | if (unload) unload(tile); 13 | delete map[tile.key]; 14 | if (tile.next) tile.next.prev = tile.prev; 15 | else if (tail = tile.prev) tail.next = null; 16 | if (tile.prev) tile.prev.next = tile.next; 17 | else if (head = tile.next) head.prev = null; 18 | } 19 | 20 | function flush() { 21 | for (var tile = tail; n > size; tile = tile.prev) { 22 | if (!tile) break; 23 | if (tile.lock) continue; 24 | remove(tile); 25 | } 26 | } 27 | 28 | cache.peek = function(c) { 29 | return map[[c.zoom, c.column, c.row].join("/")]; 30 | }; 31 | 32 | cache.load = function(c, projection) { 33 | var key = [c.zoom, c.column, c.row].join("/"), 34 | tile = map[key]; 35 | if (tile) { 36 | if (tile.prev) { 37 | tile.prev.next = tile.next; 38 | if (tile.next) tile.next.prev = tile.prev; 39 | else tail = tile.prev; 40 | tile.prev = null; 41 | tile.next = head; 42 | head.prev = tile; 43 | head = tile; 44 | } 45 | tile.lock = 1; 46 | locks[key] = tile; 47 | return tile; 48 | } 49 | tile = { 50 | key: key, 51 | column: c.column, 52 | row: c.row, 53 | zoom: c.zoom, 54 | next: head, 55 | prev: null, 56 | lock: 1 57 | }; 58 | load.call(null, tile, projection); 59 | locks[key] = map[key] = tile; 60 | if (head) head.prev = tile; 61 | else tail = tile; 62 | head = tile; 63 | n++; 64 | return tile; 65 | }; 66 | 67 | cache.unload = function(key) { 68 | if (!(key in locks)) return false; 69 | var tile = locks[key]; 70 | tile.lock = 0; 71 | delete locks[key]; 72 | if (tile.request && tile.request.abort(false)) remove(tile); 73 | return tile; 74 | }; 75 | 76 | cache.locks = function() { 77 | return locks; 78 | }; 79 | 80 | cache.size = function(x) { 81 | if (!arguments.length) return size; 82 | size = x; 83 | flush(); 84 | return cache; 85 | }; 86 | 87 | cache.flush = function() { 88 | flush(); 89 | return cache; 90 | }; 91 | 92 | cache.clear = function() { 93 | for (var key in map) { 94 | var tile = map[key]; 95 | if (tile.request) tile.request.abort(false); 96 | if (unload) unload(map[key]); 97 | if (tile.lock) { 98 | tile.lock = 0; 99 | tile.element.parentNode.removeChild(tile.element); 100 | } 101 | } 102 | locks = {}; 103 | map = {}; 104 | head = tail = null; 105 | n = 0; 106 | return cache; 107 | }; 108 | 109 | return cache; 110 | }; 111 | -------------------------------------------------------------------------------- /src/Dblclick.js: -------------------------------------------------------------------------------- 1 | po.dblclick = function() { 2 | var dblclick = {}, 3 | zoom = "mouse", 4 | map, 5 | container; 6 | 7 | function handle(e) { 8 | var z = map.zoom(); 9 | if (e.shiftKey) z = Math.ceil(z) - z - 1; 10 | else z = 1 - z + Math.floor(z); 11 | zoom === "mouse" ? map.zoomBy(z, map.mouse(e)) : map.zoomBy(z); 12 | } 13 | 14 | dblclick.zoom = function(x) { 15 | if (!arguments.length) return zoom; 16 | zoom = x; 17 | return dblclick; 18 | }; 19 | 20 | dblclick.map = function(x) { 21 | if (!arguments.length) return map; 22 | if (map) { 23 | container.removeEventListener("dblclick", handle, false); 24 | container = null; 25 | } 26 | if (map = x) { 27 | container = map.container(); 28 | container.addEventListener("dblclick", handle, false); 29 | } 30 | return dblclick; 31 | }; 32 | 33 | return dblclick; 34 | }; 35 | -------------------------------------------------------------------------------- /src/Dispatch.js: -------------------------------------------------------------------------------- 1 | po.dispatch = function(that) { 2 | var types = {}; 3 | 4 | that.on = function(type, handler) { 5 | var listeners = types[type] || (types[type] = []); 6 | for (var i = 0; i < listeners.length; i++) { 7 | if (listeners[i].handler == handler) return that; // already registered 8 | } 9 | listeners.push({handler: handler, on: true}); 10 | return that; 11 | }; 12 | 13 | that.off = function(type, handler) { 14 | var listeners = types[type]; 15 | if (listeners) for (var i = 0; i < listeners.length; i++) { 16 | var l = listeners[i]; 17 | if (l.handler == handler) { 18 | l.on = false; 19 | listeners.splice(i, 1); 20 | break; 21 | } 22 | } 23 | return that; 24 | }; 25 | 26 | return function(event) { 27 | var listeners = types[event.type]; 28 | if (!listeners) return; 29 | listeners = listeners.slice(); // defensive copy 30 | for (var i = 0; i < listeners.length; i++) { 31 | var l = listeners[i]; 32 | if (l.on) l.handler.call(that, event); 33 | } 34 | }; 35 | }; 36 | -------------------------------------------------------------------------------- /src/Drag.js: -------------------------------------------------------------------------------- 1 | po.drag = function() { 2 | var drag = {}, 3 | map, 4 | container, 5 | dragging; 6 | 7 | function mousedown(e) { 8 | if (e.shiftKey) return; 9 | dragging = { 10 | x: e.clientX, 11 | y: e.clientY 12 | }; 13 | map.focusableParent().focus(); 14 | e.preventDefault(); 15 | document.body.style.setProperty("cursor", "move", null); 16 | } 17 | 18 | function mousemove(e) { 19 | if (!dragging) return; 20 | map.panBy({x: e.clientX - dragging.x, y: e.clientY - dragging.y}); 21 | dragging.x = e.clientX; 22 | dragging.y = e.clientY; 23 | } 24 | 25 | function mouseup(e) { 26 | if (!dragging) return; 27 | mousemove(e); 28 | dragging = null; 29 | document.body.style.removeProperty("cursor"); 30 | } 31 | 32 | drag.map = function(x) { 33 | if (!arguments.length) return map; 34 | if (map) { 35 | container.removeEventListener("mousedown", mousedown, false); 36 | container = null; 37 | } 38 | if (map = x) { 39 | container = map.container(); 40 | container.addEventListener("mousedown", mousedown, false); 41 | } 42 | return drag; 43 | }; 44 | 45 | window.addEventListener("mousemove", mousemove, false); 46 | window.addEventListener("mouseup", mouseup, false); 47 | 48 | return drag; 49 | }; 50 | -------------------------------------------------------------------------------- /src/GeoJson.js: -------------------------------------------------------------------------------- 1 | po.geoJson = function(fetch) { 2 | var geoJson = po.layer(load, unload), 3 | container = geoJson.container(), 4 | url, 5 | clip = true, 6 | clipId = "org.polymaps." + po.id(), 7 | clipHref = "url(#" + clipId + ")", 8 | clipPath = container.insertBefore(po.svg("clipPath"), container.firstChild), 9 | clipRect = clipPath.appendChild(po.svg("rect")), 10 | scale = "auto", 11 | zoom = null, 12 | features; 13 | 14 | container.setAttribute("fill-rule", "evenodd"); 15 | clipPath.setAttribute("id", clipId); 16 | 17 | if (!arguments.length) fetch = po.queue.json; 18 | 19 | function projection(proj) { 20 | var l = {lat: 0, lon: 0}; 21 | return function(coordinates) { 22 | l.lat = coordinates[1]; 23 | l.lon = coordinates[0]; 24 | var p = proj(l); 25 | coordinates.x = p.x; 26 | coordinates.y = p.y; 27 | return p; 28 | }; 29 | } 30 | 31 | function geometry(o, proj) { 32 | return o && o.type in types && types[o.type](o, proj); 33 | } 34 | 35 | var types = { 36 | 37 | Point: function(o, proj) { 38 | var p = proj(o.coordinates), 39 | c = po.svg("circle"); 40 | c.setAttribute("r", 4.5); 41 | c.setAttribute("transform", "translate(" + p.x + "," + p.y + ")"); 42 | return c; 43 | }, 44 | 45 | MultiPoint: function(o, proj) { 46 | var g = po.svg("g"), 47 | c = o.coordinates, 48 | p, // proj(c[i]) 49 | x, // svg:circle 50 | i = -1, 51 | n = c.length; 52 | while (++i < n) { 53 | x = g.appendChild(po.svg("circle")); 54 | x.setAttribute("r", 4.5); 55 | x.setAttribute("transform", "translate(" + (p = proj(c[i])).x + "," + p.y + ")"); 56 | } 57 | return g; 58 | }, 59 | 60 | LineString: function(o, proj) { 61 | var x = po.svg("path"), 62 | d = ["M"], 63 | c = o.coordinates, 64 | p, // proj(c[i]) 65 | i = -1, 66 | n = c.length; 67 | while (++i < n) d.push((p = proj(c[i])).x, ",", p.y, "L"); 68 | d.pop(); 69 | if (!d.length) return; 70 | x.setAttribute("d", d.join("")); 71 | return x; 72 | }, 73 | 74 | MultiLineString: function(o, proj) { 75 | var x = po.svg("path"), 76 | d = [], 77 | ci = o.coordinates, 78 | cj, // ci[i] 79 | i = -1, 80 | j, 81 | n = ci.length, 82 | m; 83 | while (++i < n) { 84 | cj = ci[i]; 85 | j = -1; 86 | m = cj.length; 87 | d.push("M"); 88 | while (++j < m) d.push((p = proj(cj[j])).x, ",", p.y, "L"); 89 | d.pop(); 90 | } 91 | if (!d.length) return; 92 | x.setAttribute("d", d.join("")); 93 | return x; 94 | }, 95 | 96 | Polygon: function(o, proj) { 97 | var x = po.svg("path"), 98 | d = [], 99 | ci = o.coordinates, 100 | cj, // ci[i] 101 | i = -1, 102 | j, 103 | n = ci.length, 104 | m; 105 | while (++i < n) { 106 | cj = ci[i]; 107 | j = -1; 108 | m = cj.length - 1; 109 | d.push("M"); 110 | while (++j < m) d.push((p = proj(cj[j])).x, ",", p.y, "L"); 111 | d[d.length - 1] = "Z"; 112 | } 113 | if (!d.length) return; 114 | x.setAttribute("d", d.join("")); 115 | return x; 116 | }, 117 | 118 | MultiPolygon: function(o, proj) { 119 | var x = po.svg("path"), 120 | d = [], 121 | ci = o.coordinates, 122 | cj, // ci[i] 123 | ck, // cj[j] 124 | i = -1, 125 | j, 126 | k, 127 | n = ci.length, 128 | m, 129 | l; 130 | while (++i < n) { 131 | cj = ci[i]; 132 | j = -1; 133 | m = cj.length; 134 | while (++j < m) { 135 | ck = cj[j]; 136 | k = -1; 137 | l = ck.length - 1; 138 | d.push("M"); 139 | while (++k < l) d.push((p = proj(ck[k])).x, ",", p.y, "L"); 140 | d[d.length - 1] = "Z"; 141 | } 142 | } 143 | if (!d.length) return; 144 | x.setAttribute("d", d.join("")); 145 | return x; 146 | }, 147 | 148 | GeometryCollection: function(o, proj) { 149 | var g = po.svg("g"), 150 | i = -1, 151 | c = o.geometries, 152 | n = c.length, 153 | x; 154 | while (++i < n) { 155 | x = geometry(c[i], proj); 156 | if (x) g.appendChild(x); 157 | } 158 | return g; 159 | } 160 | 161 | }; 162 | 163 | function rescale(o, e, k) { 164 | return o.type in rescales && rescales[o.type](o, e, k); 165 | } 166 | 167 | var rescales = { 168 | 169 | Point: function (o, e, k) { 170 | var p = o.coordinates; 171 | e.setAttribute("transform", "translate(" + p.x + "," + p.y + ")" + k); 172 | }, 173 | 174 | MultiPoint: function (o, e, k) { 175 | var c = o.coordinates, 176 | i = -1, 177 | n = p.length, 178 | x = e.firstChild, 179 | p; 180 | while (++i < n) { 181 | p = c[i]; 182 | x.setAttribute("transform", "translate(" + p.x + "," + p.y + ")" + k); 183 | x = x.nextSibling; 184 | } 185 | } 186 | 187 | }; 188 | 189 | function load(tile, proj) { 190 | var g = tile.element = po.svg("g"); 191 | tile.features = []; 192 | 193 | proj = projection(proj(tile).locationPoint); 194 | 195 | function update(data) { 196 | var updated = []; 197 | 198 | /* Fetch the next batch of features, if so directed. */ 199 | if (data.next) tile.request = fetch(data.next.href, update); 200 | 201 | /* Convert the GeoJSON to SVG. */ 202 | switch (data.type) { 203 | case "FeatureCollection": { 204 | for (var i = 0; i < data.features.length; i++) { 205 | var feature = data.features[i], 206 | element = geometry(feature.geometry, proj); 207 | if (element) updated.push({element: g.appendChild(element), data: feature}); 208 | } 209 | break; 210 | } 211 | case "Feature": { 212 | var element = geometry(data.geometry, proj); 213 | if (element) updated.push({element: g.appendChild(element), data: data}); 214 | break; 215 | } 216 | default: { 217 | var element = geometry(data, proj); 218 | if (element) updated.push({element: g.appendChild(element), data: {type: "Feature", geometry: data}}); 219 | break; 220 | } 221 | } 222 | 223 | tile.ready = true; 224 | updated.push.apply(tile.features, updated); 225 | geoJson.dispatch({type: "load", tile: tile, features: updated}); 226 | } 227 | 228 | if (url != null) { 229 | tile.request = fetch(typeof url == "function" ? url(tile) : url, update); 230 | } else { 231 | update({type: "FeatureCollection", features: features || []}); 232 | } 233 | } 234 | 235 | function unload(tile) { 236 | if (tile.request) tile.request.abort(true); 237 | } 238 | 239 | function move() { 240 | var zoom = geoJson.map().zoom(), 241 | tiles = geoJson.cache.locks(), // visible tiles 242 | key, // key in locks 243 | tile, // locks[key] 244 | features, // tile.features 245 | i, // current feature index 246 | n, // current feature count, features.length 247 | feature, // features[i] 248 | k; // scale transform 249 | if (scale == "fixed") { 250 | for (key in tiles) { 251 | if ((tile = tiles[key]).scale != zoom) { 252 | k = "scale(" + Math.pow(2, tile.zoom - zoom) + ")"; 253 | i = -1; 254 | n = (features = tile.features).length; 255 | while (++i < n) rescale((feature = features[i]).data.geometry, feature.element, k); 256 | tile.scale = zoom; 257 | } 258 | } 259 | } else { 260 | for (key in tiles) { 261 | i = -1; 262 | n = (features = (tile = tiles[key]).features).length; 263 | while (++i < n) rescale((feature = features[i]).data.geometry, feature.element, ""); 264 | delete tile.scale; 265 | } 266 | } 267 | } 268 | 269 | geoJson.url = function(x) { 270 | if (!arguments.length) return url; 271 | url = typeof x == "string" && /{.}/.test(x) ? po.url(x) : x; 272 | if (url != null) features = null; 273 | if (typeof url == "string") geoJson.tile(false); 274 | return geoJson.reload(); 275 | }; 276 | 277 | geoJson.features = function(x) { 278 | if (!arguments.length) return features; 279 | if (features = x) { 280 | url = null; 281 | geoJson.tile(false); 282 | } 283 | return geoJson.reload(); 284 | }; 285 | 286 | geoJson.clip = function(x) { 287 | if (!arguments.length) return clip; 288 | if (clip) container.removeChild(clipPath); 289 | if (clip = x) container.insertBefore(clipPath, container.firstChild); 290 | var locks = geoJson.cache.locks(); 291 | for (var key in locks) { 292 | if (clip) locks[key].element.setAttribute("clip-path", clipHref); 293 | else locks[key].element.removeAttribute("clip-path"); 294 | } 295 | return geoJson; 296 | }; 297 | 298 | var __tile__ = geoJson.tile; 299 | geoJson.tile = function(x) { 300 | if (arguments.length && !x) geoJson.clip(x); 301 | return __tile__.apply(geoJson, arguments); 302 | }; 303 | 304 | var __map__ = geoJson.map; 305 | geoJson.map = function(x) { 306 | if (x && clipRect) { 307 | var size = x.tileSize(); 308 | clipRect.setAttribute("width", size.x); 309 | clipRect.setAttribute("height", size.y); 310 | } 311 | return __map__.apply(geoJson, arguments); 312 | }; 313 | 314 | geoJson.scale = function(x) { 315 | if (!arguments.length) return scale; 316 | if (scale = x) geoJson.on("move", move); 317 | else geoJson.off("move", move); 318 | if (geoJson.map()) move(); 319 | return geoJson; 320 | }; 321 | 322 | geoJson.show = function(tile) { 323 | if (clip) tile.element.setAttribute("clip-path", clipHref); 324 | else tile.element.removeAttribute("clip-path"); 325 | geoJson.dispatch({type: "show", tile: tile, features: tile.features}); 326 | return geoJson; 327 | }; 328 | 329 | geoJson.reshow = function() { 330 | var locks = geoJson.cache.locks(); 331 | for (var key in locks) geoJson.show(locks[key]); 332 | return geoJson; 333 | }; 334 | 335 | return geoJson; 336 | }; 337 | -------------------------------------------------------------------------------- /src/Grid.js: -------------------------------------------------------------------------------- 1 | po.grid = function() { 2 | var grid = {}, 3 | map, 4 | g = po.svg("g"); 5 | 6 | g.setAttribute("class", "grid"); 7 | 8 | function move(e) { 9 | var p, 10 | line = g.firstChild, 11 | size = map.size(), 12 | nw = map.pointLocation(zero), 13 | se = map.pointLocation(size), 14 | step = Math.pow(2, 4 - Math.round(map.zoom())); 15 | 16 | // Round to step. 17 | nw.lat = Math.floor(nw.lat / step) * step; 18 | nw.lon = Math.ceil(nw.lon / step) * step; 19 | 20 | // Longitude ticks. 21 | for (var x; (x = map.locationPoint(nw).x) <= size.x; nw.lon += step) { 22 | if (!line) line = g.appendChild(po.svg("line")); 23 | line.setAttribute("x1", x); 24 | line.setAttribute("x2", x); 25 | line.setAttribute("y1", 0); 26 | line.setAttribute("y2", size.y); 27 | line = line.nextSibling; 28 | } 29 | 30 | // Latitude ticks. 31 | for (var y; (y = map.locationPoint(nw).y) <= size.y; nw.lat -= step) { 32 | if (!line) line = g.appendChild(po.svg("line")); 33 | line.setAttribute("y1", y); 34 | line.setAttribute("y2", y); 35 | line.setAttribute("x1", 0); 36 | line.setAttribute("x2", size.x); 37 | line = line.nextSibling; 38 | } 39 | 40 | // Remove extra ticks. 41 | while (line) { 42 | var next = line.nextSibling; 43 | g.removeChild(line); 44 | line = next; 45 | } 46 | } 47 | 48 | grid.map = function(x) { 49 | if (!arguments.length) return map; 50 | if (map) { 51 | g.parentNode.removeChild(g); 52 | map.off("move", move).off("resize", move); 53 | } 54 | if (map = x) { 55 | map.on("move", move).on("resize", move); 56 | map.container().appendChild(g); 57 | map.dispatch({type: "move"}); 58 | } 59 | return grid; 60 | }; 61 | 62 | return grid; 63 | }; 64 | -------------------------------------------------------------------------------- /src/Hash.js: -------------------------------------------------------------------------------- 1 | po.hash = function() { 2 | var hash = {}, 3 | s0, // cached location.hash 4 | lat = 90 - 1e-8, // allowable latitude range 5 | map; 6 | 7 | var parser = function(map, s) { 8 | var args = s.split("/").map(Number); 9 | if (args.length < 3 || args.some(isNaN)) return true; // replace bogus hash 10 | else { 11 | var size = map.size(); 12 | map.zoomBy(args[0] - map.zoom(), 13 | {x: size.x / 2, y: size.y / 2}, 14 | {lat: Math.min(lat, Math.max(-lat, args[1])), lon: args[2]}); 15 | } 16 | }; 17 | 18 | var formatter = function(map) { 19 | var center = map.center(), 20 | zoom = map.zoom(), 21 | precision = Math.max(0, Math.ceil(Math.log(zoom) / Math.LN2)); 22 | return "#" + zoom.toFixed(2) 23 | + "/" + center.lat.toFixed(precision) 24 | + "/" + center.lon.toFixed(precision); 25 | }; 26 | 27 | function move() { 28 | var s1 = formatter(map); 29 | if (s0 !== s1) location.replace(s0 = s1); // don't recenter the map! 30 | } 31 | 32 | function hashchange() { 33 | if (location.hash === s0) return; // ignore spurious hashchange events 34 | if (parser(map, (s0 = location.hash).substring(1))) 35 | move(); // replace bogus hash 36 | } 37 | 38 | hash.map = function(x) { 39 | if (!arguments.length) return map; 40 | if (map) { 41 | map.off("move", move); 42 | window.removeEventListener("hashchange", hashchange, false); 43 | } 44 | if (map = x) { 45 | map.on("move", move); 46 | window.addEventListener("hashchange", hashchange, false); 47 | location.hash ? hashchange() : move(); 48 | } 49 | return hash; 50 | }; 51 | 52 | hash.parser = function(x) { 53 | if (!arguments.length) return parser; 54 | parser = x; 55 | return hash; 56 | }; 57 | 58 | hash.formatter = function(x) { 59 | if (!arguments.length) return formatter; 60 | formatter = x; 61 | return hash; 62 | }; 63 | 64 | return hash; 65 | }; 66 | -------------------------------------------------------------------------------- /src/Id.js: -------------------------------------------------------------------------------- 1 | po.id = (function() { 2 | var id = 0; 3 | return function() { 4 | return ++id; 5 | }; 6 | })(); 7 | -------------------------------------------------------------------------------- /src/Image.js: -------------------------------------------------------------------------------- 1 | po.image = function() { 2 | var image = po.layer(load, unload), 3 | url; 4 | 5 | function load(tile) { 6 | var element = tile.element = po.svg("image"), size = image.map().tileSize(); 7 | element.setAttribute("preserveAspectRatio", "none"); 8 | element.setAttribute("width", size.x); 9 | element.setAttribute("height", size.y); 10 | 11 | if (typeof url == "function") { 12 | element.setAttribute("opacity", 0); 13 | var tileUrl = url(tile); 14 | if (tileUrl != null) { 15 | tile.request = po.queue.image(element, tileUrl, function(img) { 16 | delete tile.request; 17 | tile.ready = true; 18 | tile.img = img; 19 | element.removeAttribute("opacity"); 20 | image.dispatch({type: "load", tile: tile}); 21 | }); 22 | } else { 23 | tile.ready = true; 24 | image.dispatch({type: "load", tile: tile}); 25 | } 26 | } else { 27 | tile.ready = true; 28 | if (url != null) element.setAttributeNS(po.ns.xlink, "href", url); 29 | image.dispatch({type: "load", tile: tile}); 30 | } 31 | } 32 | 33 | function unload(tile) { 34 | if (tile.request) tile.request.abort(true); 35 | } 36 | 37 | image.url = function(x) { 38 | if (!arguments.length) return url; 39 | url = typeof x == "string" && /{.}/.test(x) ? po.url(x) : x; 40 | return image.reload(); 41 | }; 42 | 43 | return image; 44 | }; 45 | -------------------------------------------------------------------------------- /src/Interact.js: -------------------------------------------------------------------------------- 1 | // Default map controls. 2 | po.interact = function() { 3 | var interact = {}, 4 | drag = po.drag(), 5 | wheel = po.wheel(), 6 | dblclick = po.dblclick(), 7 | touch = po.touch(), 8 | arrow = po.arrow(); 9 | 10 | interact.map = function(x) { 11 | drag.map(x); 12 | wheel.map(x); 13 | dblclick.map(x); 14 | touch.map(x); 15 | arrow.map(x); 16 | return interact; 17 | }; 18 | 19 | return interact; 20 | }; 21 | -------------------------------------------------------------------------------- /src/Queue.js: -------------------------------------------------------------------------------- 1 | po.queue = (function() { 2 | var queued = [], active = 0, size = 6; 3 | 4 | function process() { 5 | if ((active >= size) || !queued.length) return; 6 | active++; 7 | queued.pop()(); 8 | } 9 | 10 | function dequeue(send) { 11 | for (var i = 0; i < queued.length; i++) { 12 | if (queued[i] == send) { 13 | queued.splice(i, 1); 14 | return true; 15 | } 16 | } 17 | return false; 18 | } 19 | 20 | function request(url, callback, mimeType) { 21 | var req; 22 | 23 | function send() { 24 | req = new XMLHttpRequest(); 25 | if (mimeType && req.overrideMimeType) { 26 | req.overrideMimeType(mimeType); 27 | } 28 | req.open("GET", url, true); 29 | req.onreadystatechange = function(e) { 30 | if (req.readyState == 4) { 31 | active--; 32 | if (req.status < 300) callback(req); 33 | process(); 34 | } 35 | }; 36 | req.send(null); 37 | } 38 | 39 | function abort(hard) { 40 | if (dequeue(send)) return true; 41 | if (hard && req) { req.abort(); return true; } 42 | return false; 43 | } 44 | 45 | queued.push(send); 46 | process(); 47 | return {abort: abort}; 48 | } 49 | 50 | function text(url, callback, mimeType) { 51 | return request(url, function(req) { 52 | if (req.responseText) callback(req.responseText); 53 | }, mimeType); 54 | } 55 | 56 | /* 57 | * We the override MIME type here so that you can load local files; some 58 | * browsers don't assign a proper MIME type for local files. 59 | */ 60 | 61 | function json(url, callback) { 62 | return request(url, function(req) { 63 | if (req.responseText) callback(JSON.parse(req.responseText)); 64 | }, "application/json"); 65 | } 66 | 67 | function xml(url, callback) { 68 | return request(url, function(req) { 69 | if (req.responseXML) callback(req.responseXML); 70 | }, "application/xml"); 71 | } 72 | 73 | function image(image, src, callback) { 74 | var img; 75 | 76 | function send() { 77 | img = document.createElement("img"); 78 | img.onerror = function() { 79 | active--; 80 | process(); 81 | }; 82 | img.onload = function() { 83 | active--; 84 | callback(img); 85 | process(); 86 | }; 87 | img.src = src; 88 | image.setAttributeNS(po.ns.xlink, "href", src); 89 | } 90 | 91 | function abort(hard) { 92 | if (dequeue(send)) return true; 93 | if (hard && img) { img.src = "about:"; return true; } // cancels request 94 | return false; 95 | } 96 | 97 | queued.push(send); 98 | process(); 99 | return {abort: abort}; 100 | } 101 | 102 | return {text: text, xml: xml, json: json, image: image}; 103 | })(); 104 | -------------------------------------------------------------------------------- /src/Stylist.js: -------------------------------------------------------------------------------- 1 | po.stylist = function() { 2 | var attrs = [], 3 | styles = [], 4 | title; 5 | 6 | function stylist(e) { 7 | var ne = e.features.length, 8 | na = attrs.length, 9 | ns = styles.length, 10 | f, // feature 11 | d, // data 12 | o, // element 13 | x, // attr or style or title descriptor 14 | v, // attr or style or title value 15 | i, 16 | j; 17 | for (i = 0; i < ne; ++i) { 18 | if (!(o = (f = e.features[i]).element)) continue; 19 | d = f.data; 20 | for (j = 0; j < na; ++j) { 21 | v = (x = attrs[j]).value; 22 | if (typeof v === "function") v = v.call(null, d); 23 | v == null ? (x.name.local 24 | ? o.removeAttributeNS(x.name.space, x.name.local) 25 | : o.removeAttribute(x.name)) : (x.name.local 26 | ? o.setAttributeNS(x.name.space, x.name.local, v) 27 | : o.setAttribute(x.name, v)); 28 | } 29 | for (j = 0; j < ns; ++j) { 30 | v = (x = styles[j]).value; 31 | if (typeof v === "function") v = v.call(null, d); 32 | v == null 33 | ? o.style.removeProperty(x.name) 34 | : o.style.setProperty(x.name, v, x.priority); 35 | } 36 | if (v = title) { 37 | if (typeof v === "function") v = v.call(null, d); 38 | while (o.lastChild) o.removeChild(o.lastChild); 39 | if (v != null) o.appendChild(po.svg("title")).appendChild(document.createTextNode(v)); 40 | } 41 | } 42 | } 43 | 44 | stylist.attr = function(n, v) { 45 | attrs.push({name: ns(n), value: v}); 46 | return stylist; 47 | }; 48 | 49 | stylist.style = function(n, v, p) { 50 | styles.push({name: n, value: v, priority: arguments.length < 3 ? null : p}); 51 | return stylist; 52 | }; 53 | 54 | stylist.title = function(v) { 55 | title = v; 56 | return stylist; 57 | }; 58 | 59 | return stylist; 60 | }; 61 | -------------------------------------------------------------------------------- /src/Svg.js: -------------------------------------------------------------------------------- 1 | po.svg = function(type) { 2 | return document.createElementNS(po.ns.svg, type); 3 | }; 4 | -------------------------------------------------------------------------------- /src/Touch.js: -------------------------------------------------------------------------------- 1 | po.touch = function() { 2 | var touch = {}, 3 | map, 4 | container, 5 | rotate = false, 6 | last = 0, 7 | zoom, 8 | angle, 9 | locations = {}; // touch identifier -> location 10 | 11 | window.addEventListener("touchmove", touchmove, false); 12 | 13 | function touchstart(e) { 14 | var i = -1, 15 | n = e.touches.length, 16 | t = Date.now(); 17 | 18 | // doubletap detection 19 | if ((n == 1) && (t - last < 300)) { 20 | var z = map.zoom(); 21 | map.zoomBy(1 - z + Math.floor(z), map.mouse(e.touches[0])); 22 | e.preventDefault(); 23 | } 24 | last = t; 25 | 26 | // store original zoom & touch locations 27 | zoom = map.zoom(); 28 | angle = map.angle(); 29 | while (++i < n) { 30 | t = e.touches[i]; 31 | locations[t.identifier] = map.pointLocation(map.mouse(t)); 32 | } 33 | } 34 | 35 | function touchmove(e) { 36 | switch (e.touches.length) { 37 | case 1: { // single-touch pan 38 | var t0 = e.touches[0]; 39 | map.zoomBy(0, map.mouse(t0), locations[t0.identifier]); 40 | e.preventDefault(); 41 | break; 42 | } 43 | case 2: { // double-touch pan + zoom + rotate 44 | var t0 = e.touches[0], 45 | t1 = e.touches[1], 46 | p0 = map.mouse(t0), 47 | p1 = map.mouse(t1), 48 | p2 = {x: (p0.x + p1.x) / 2, y: (p0.y + p1.y) / 2}, // center point 49 | c0 = po.map.locationCoordinate(locations[t0.identifier]), 50 | c1 = po.map.locationCoordinate(locations[t1.identifier]), 51 | c2 = {row: (c0.row + c1.row) / 2, column: (c0.column + c1.column) / 2, zoom: 0}, 52 | l2 = po.map.coordinateLocation(c2); // center location 53 | map.zoomBy(Math.log(e.scale) / Math.LN2 + zoom - map.zoom(), p2, l2); 54 | if (rotate) map.angle(e.rotation / 180 * Math.PI + angle); 55 | e.preventDefault(); 56 | break; 57 | } 58 | } 59 | } 60 | 61 | touch.rotate = function(x) { 62 | if (!arguments.length) return rotate; 63 | rotate = x; 64 | return touch; 65 | }; 66 | 67 | touch.map = function(x) { 68 | if (!arguments.length) return map; 69 | if (map) { 70 | container.removeEventListener("touchstart", touchstart, false); 71 | container = null; 72 | } 73 | if (map = x) { 74 | container = map.container(); 75 | container.addEventListener("touchstart", touchstart, false); 76 | } 77 | return touch; 78 | }; 79 | 80 | return touch; 81 | }; 82 | -------------------------------------------------------------------------------- /src/Transform.js: -------------------------------------------------------------------------------- 1 | po.transform = function(a, b, c, d, e, f) { 2 | var transform = {}, 3 | zoomDelta, 4 | zoomFraction, 5 | k; 6 | 7 | if (!arguments.length) { 8 | a = 1; c = 0; e = 0; 9 | b = 0; d = 1; f = 0; 10 | } 11 | 12 | transform.zoomFraction = function(x) { 13 | if (!arguments.length) return zoomFraction; 14 | zoomFraction = x; 15 | zoomDelta = Math.floor(zoomFraction + Math.log(Math.sqrt(a * a + b * b + c * c + d * d)) / Math.LN2); 16 | k = Math.pow(2, -zoomDelta); 17 | return transform; 18 | }; 19 | 20 | transform.apply = function(x) { 21 | var k0 = Math.pow(2, -x.zoom), 22 | k1 = Math.pow(2, x.zoom - zoomDelta); 23 | return { 24 | column: (a * x.column * k0 + c * x.row * k0 + e) * k1, 25 | row: (b * x.column * k0 + d * x.row * k0 + f) * k1, 26 | zoom: x.zoom - zoomDelta 27 | }; 28 | }; 29 | 30 | transform.unapply = function(x) { 31 | var k0 = Math.pow(2, -x.zoom), 32 | k1 = Math.pow(2, x.zoom + zoomDelta); 33 | return { 34 | column: (x.column * k0 * d - x.row * k0 * c - e * d + f * c) / (a * d - b * c) * k1, 35 | row: (x.column * k0 * b - x.row * k0 * a - e * b + f * a) / (c * b - d * a) * k1, 36 | zoom: x.zoom + zoomDelta 37 | }; 38 | }; 39 | 40 | transform.toString = function() { 41 | return "matrix(" + [a * k, b * k, c * k, d * k].join(" ") + " 0 0)"; 42 | }; 43 | 44 | return transform.zoomFraction(0); 45 | }; 46 | -------------------------------------------------------------------------------- /src/Url.js: -------------------------------------------------------------------------------- 1 | po.url = function(template) { 2 | var hosts = [], 3 | repeat = true; 4 | 5 | function format(c) { 6 | var max = c.zoom < 0 ? 1 : 1 << c.zoom, 7 | column = c.column; 8 | if (repeat) { 9 | column = c.column % max; 10 | if (column < 0) column += max; 11 | } else if ((column < 0) || (column >= max)) { 12 | return null; 13 | } 14 | return template.replace(/{(.)}/g, function(s, v) { 15 | switch (v) { 16 | case "S": return hosts[(Math.abs(c.zoom) + c.row + column) % hosts.length]; 17 | case "Z": return c.zoom; 18 | case "X": return column; 19 | case "Y": return c.row; 20 | case "B": { 21 | var nw = po.map.coordinateLocation({row: c.row, column: column, zoom: c.zoom}), 22 | se = po.map.coordinateLocation({row: c.row + 1, column: column + 1, zoom: c.zoom}), 23 | pn = Math.ceil(Math.log(c.zoom) / Math.LN2); 24 | return se.lat.toFixed(pn) 25 | + "," + nw.lon.toFixed(pn) 26 | + "," + nw.lat.toFixed(pn) 27 | + "," + se.lon.toFixed(pn); 28 | } 29 | } 30 | return v; 31 | }); 32 | } 33 | 34 | format.template = function(x) { 35 | if (!arguments.length) return template; 36 | template = x; 37 | return format; 38 | }; 39 | 40 | format.hosts = function(x) { 41 | if (!arguments.length) return hosts; 42 | hosts = x; 43 | return format; 44 | }; 45 | 46 | format.repeat = function(x) { 47 | if (!arguments.length) return repeat; 48 | repeat = x; 49 | return format; 50 | }; 51 | 52 | return format; 53 | }; 54 | -------------------------------------------------------------------------------- /src/Wheel.js: -------------------------------------------------------------------------------- 1 | po.wheel = function() { 2 | var wheel = {}, 3 | timePrev = 0, 4 | last = 0, 5 | smooth = true, 6 | zoom = "mouse", 7 | location, 8 | map, 9 | container; 10 | 11 | function move(e) { 12 | location = null; 13 | } 14 | 15 | // mousewheel events are totally broken! 16 | // https://bugs.webkit.org/show_bug.cgi?id=40441 17 | // not only that, but Chrome and Safari differ in re. to acceleration! 18 | var inner = document.createElement("div"), 19 | outer = document.createElement("div"); 20 | outer.style.visibility = "hidden"; 21 | outer.style.top = "0px"; 22 | outer.style.height = "0px"; 23 | outer.style.width = "0px"; 24 | outer.style.overflowY = "scroll"; 25 | inner.style.height = "2000px"; 26 | outer.appendChild(inner); 27 | document.body.appendChild(outer); 28 | 29 | function mousewheel(e) { 30 | var delta = e.wheelDelta || -e.detail, 31 | point; 32 | 33 | /* Detect the pixels that would be scrolled by this wheel event. */ 34 | if (delta) { 35 | if (smooth) { 36 | try { 37 | outer.scrollTop = 1000; 38 | outer.dispatchEvent(e); 39 | delta = 1000 - outer.scrollTop; 40 | } catch (error) { 41 | // Derp! Hope for the best? 42 | } 43 | delta *= .005; 44 | } 45 | 46 | /* If smooth zooming is disabled, batch events into unit steps. */ 47 | else { 48 | var timeNow = Date.now(); 49 | if (timeNow - timePrev > 200) { 50 | delta = delta > 0 ? +1 : -1; 51 | timePrev = timeNow; 52 | } else { 53 | delta = 0; 54 | } 55 | } 56 | } 57 | 58 | if (delta) { 59 | switch (zoom) { 60 | case "mouse": { 61 | point = map.mouse(e); 62 | if (!location) location = map.pointLocation(point); 63 | map.off("move", move).zoomBy(delta, point, location).on("move", move); 64 | break; 65 | } 66 | case "location": { 67 | map.zoomBy(delta, map.locationPoint(location), location); 68 | break; 69 | } 70 | default: { // center 71 | map.zoomBy(delta); 72 | break; 73 | } 74 | } 75 | } 76 | 77 | e.preventDefault(); 78 | return false; // for Firefox 79 | } 80 | 81 | wheel.smooth = function(x) { 82 | if (!arguments.length) return smooth; 83 | smooth = x; 84 | return wheel; 85 | }; 86 | 87 | wheel.zoom = function(x, l) { 88 | if (!arguments.length) return zoom; 89 | zoom = x; 90 | location = l; 91 | if (map) { 92 | if (zoom == "mouse") map.on("move", move); 93 | else map.off("move", move); 94 | } 95 | return wheel; 96 | }; 97 | 98 | wheel.map = function(x) { 99 | if (!arguments.length) return map; 100 | if (map) { 101 | container.removeEventListener("mousemove", move, false); 102 | container.removeEventListener("mousewheel", mousewheel, false); 103 | container.removeEventListener("MozMousePixelScroll", mousewheel, false); 104 | container = null; 105 | map.off("move", move); 106 | } 107 | if (map = x) { 108 | if (zoom == "mouse") map.on("move", move); 109 | container = map.container(); 110 | container.addEventListener("mousemove", move, false); 111 | container.addEventListener("mousewheel", mousewheel, false); 112 | container.addEventListener("MozMousePixelScroll", mousewheel, false); 113 | } 114 | return wheel; 115 | }; 116 | 117 | return wheel; 118 | }; 119 | -------------------------------------------------------------------------------- /src/end.js: -------------------------------------------------------------------------------- 1 | })(org.polymaps); 2 | -------------------------------------------------------------------------------- /src/ns.js: -------------------------------------------------------------------------------- 1 | po.ns = { 2 | svg: "http://www.w3.org/2000/svg", 3 | xlink: "http://www.w3.org/1999/xlink" 4 | }; 5 | 6 | function ns(name) { 7 | var i = name.indexOf(":"); 8 | return i < 0 ? name : { 9 | space: po.ns[name.substring(0, i)], 10 | local: name.substring(i + 1) 11 | }; 12 | } 13 | -------------------------------------------------------------------------------- /src/start.js: -------------------------------------------------------------------------------- 1 | if (!org) var org = {}; 2 | if (!org.polymaps) org.polymaps = {}; 3 | (function(po){ 4 | 5 | po.version = "2.5.1"; // semver.org 6 | 7 | var zero = {x: 0, y: 0}; 8 | --------------------------------------------------------------------------------