Created
April 22, 2015 16:50
-
-
Save shaliniravi/6de5e2c00e6539b3112e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Example_cartogram |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<project version="4"> | |
<component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false" /> | |
</project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<module type="WEB_MODULE" version="4"> | |
<component name="NewModuleRootManager"> | |
<content url="file://$MODULE_DIR$" /> | |
<orderEntry type="inheritedJdk" /> | |
<orderEntry type="sourceFolder" forTests="false" /> | |
</component> | |
</module> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<project version="4"> | |
<component name="ProjectRootManager" version="2" /> | |
</project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<project version="4"> | |
<component name="ProjectModuleManager"> | |
<modules> | |
<module fileurl="file://$PROJECT_DIR$/.idea/Example_cartogram.iml" filepath="$PROJECT_DIR$/.idea/Example_cartogram.iml" /> | |
</modules> | |
</component> | |
</project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<component name="DependencyValidationManager"> | |
<state> | |
<option name="SKIP_IMPORT_STATEMENTS" value="false" /> | |
</state> | |
</component> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<project version="4"> | |
<component name="VcsDirectoryMappings"> | |
<mapping directory="" vcs="" /> | |
</component> | |
</project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function(exports) { | |
/* | |
* d3.cartogram is a d3-friendly implementation of An Algorithm to Construct | |
* Continuous Area Cartograms: | |
* | |
* <http://chrisman.scg.ulaval.ca/G360/dougenik.pdf> | |
* | |
* It requires topojson to decode TopoJSON-encoded topologies: | |
* | |
* <http://github.com/mbostock/topojson/> | |
* | |
* Usage: | |
* | |
* var cartogram = d3.cartogram() | |
* .projection(d3.geo.albersUsa()) | |
* .value(function(d) { | |
* return Math.random() * 100; | |
* }); | |
* d3.json("path/to/topology.json", function(topology) { | |
* var features = cartogram(topology, topology.objects.OBJECTNAME.geometries); | |
* d3.select("svg").selectAll("path") | |
* .data(features) | |
* .enter() | |
* .append("path") | |
* .attr("d", cartogram.path); | |
* }); | |
*/ | |
d3.cartogram = function() { | |
function carto(topology, geometries) { | |
// copy it first | |
topology = copy(topology); | |
// objects are projected into screen coordinates | |
// project the arcs into screen space | |
var tf = transformer(topology.transform),x,y,len1,i1,out1,len2=topology.arcs.length,i2=0, | |
projectedArcs = new Array(len2); | |
while(i2<len2){ | |
x = 0; | |
y = 0; | |
len1 = topology.arcs[i2].length; | |
i1 = 0; | |
out1 = new Array(len1); | |
while(i1<len1){ | |
topology.arcs[i2][i1][0] = (x += topology.arcs[i2][i1][0]); | |
topology.arcs[i2][i1][1] = (y += topology.arcs[i2][i1][1]); | |
out1[i1] = projection(tf(topology.arcs[i2][i1])); | |
i1++; | |
} | |
projectedArcs[i2++]=out1; | |
} | |
// path with identity projection | |
var path = d3.geo.path() | |
.projection(null); | |
var objects = object(projectedArcs, {type: "GeometryCollection", geometries: geometries}) | |
.geometries.map(function(geom) { | |
return { | |
type: "Feature", | |
id: geom.id, | |
properties: properties.call(null, geom, topology), | |
geometry: geom | |
}; | |
}); | |
var values = objects.map(value), | |
totalValue = d3.sum(values); | |
// no iterations; just return the features | |
if (iterations <= 0) { | |
return objects; | |
} | |
var i = 0; | |
while (i++ < iterations) { | |
var areas = objects.map(path.area); | |
var totalArea = d3.sum(areas), | |
sizeErrorsTot =0, | |
sizeErrorsNum=0, | |
meta = objects.map(function(o, j) { | |
var area = Math.abs(areas[j]), // XXX: why do we have negative areas? | |
v = +values[j], | |
desired = totalArea * v / totalValue, | |
radius = Math.sqrt(area / Math.PI), | |
mass = Math.sqrt(desired / Math.PI) - radius, | |
sizeError = Math.max(area, desired) / Math.min(area, desired); | |
sizeErrorsTot+=sizeError; | |
sizeErrorsNum++; | |
// console.log(o.id, "@", j, "area:", area, "value:", v, "->", desired, radius, mass, sizeError); | |
return { | |
id: o.id, | |
area: area, | |
centroid: path.centroid(o), | |
value: v, | |
desired: desired, | |
radius: radius, | |
mass: mass, | |
sizeError: sizeError | |
}; | |
}); | |
var sizeError = sizeErrorsTot/sizeErrorsNum, | |
forceReductionFactor = 1 / (1 + sizeError); | |
// console.log("meta:", meta); | |
// console.log(" total area:", totalArea); | |
// console.log(" force reduction factor:", forceReductionFactor, "mean error:", sizeError); | |
var len1,i1,delta,len2=projectedArcs.length,i2=0,delta,len3,i3,centroid,mass,radius,rSquared,dx,dy,distSquared,dist,Fij; | |
while(i2<len2){ | |
len1=projectedArcs[i2].length; | |
i1=0; | |
while(i1<len1){ | |
// create an array of vectors: [x, y] | |
delta = [0,0]; | |
len3 = meta.length; | |
i3=0; | |
while(i3<len3) { | |
centroid = meta[i3].centroid; | |
mass = meta[i3].mass; | |
radius = meta[i3].radius; | |
rSquared = (radius*radius); | |
dx = projectedArcs[i2][i1][0] - centroid[0]; | |
dy = projectedArcs[i2][i1][1] - centroid[1]; | |
distSquared = dx * dx + dy * dy; | |
dist=Math.sqrt(distSquared); | |
Fij = (dist > radius) | |
? mass * radius / dist | |
: mass * | |
(distSquared / rSquared) * | |
(4 - 3 * dist / radius); | |
delta[0]+=(Fij * cosArctan(dy,dx)); | |
delta[1]+=(Fij * sinArctan(dy,dx)); | |
i3++; | |
} | |
projectedArcs[i2][i1][0] += (delta[0]*forceReductionFactor); | |
projectedArcs[i2][i1][1] += (delta[1]*forceReductionFactor); | |
i1++; | |
} | |
i2++; | |
} | |
// break if we hit the target size error | |
if (sizeError <= 1) break; | |
} | |
return { | |
features: objects, | |
arcs: projectedArcs | |
}; | |
} | |
var iterations = 8, | |
projection = d3.geo.albers(), | |
properties = function(id) { | |
return {}; | |
}, | |
value = function(d) { | |
return 1; | |
}; | |
// for convenience | |
carto.path = d3.geo.path() | |
.projection(null); | |
carto.iterations = function(i) { | |
if (arguments.length) { | |
iterations = i; | |
return carto; | |
} else { | |
return iterations; | |
} | |
}; | |
carto.value = function(v) { | |
if (arguments.length) { | |
value = d3.functor(v); | |
return carto; | |
} else { | |
return value; | |
} | |
}; | |
carto.projection = function(p) { | |
if (arguments.length) { | |
projection = p; | |
return carto; | |
} else { | |
return projection; | |
} | |
}; | |
carto.feature = function(topology, geom) { | |
return { | |
type: "Feature", | |
id: geom.id, | |
properties: properties.call(null, geom, topology), | |
geometry: { | |
type: geom.type, | |
coordinates: topojson.feature(topology, geom).geometry.coordinates | |
} | |
}; | |
}; | |
carto.features = function(topo, geometries) { | |
return geometries.map(function(f) { | |
return carto.feature(topo, f); | |
}); | |
}; | |
carto.properties = function(props) { | |
if (arguments.length) { | |
properties = d3.functor(props); | |
return carto; | |
} else { | |
return properties; | |
} | |
}; | |
return carto; | |
}; | |
var transformer = d3.cartogram.transformer = function(tf) { | |
var kx = tf.scale[0], | |
ky = tf.scale[1], | |
dx = tf.translate[0], | |
dy = tf.translate[1]; | |
function transform(c) { | |
return [c[0] * kx + dx, c[1] * ky + dy]; | |
} | |
transform.invert = function(c) { | |
return [(c[0] - dx) / kx, (c[1]- dy) / ky]; | |
}; | |
return transform; | |
}; | |
function angle(a, b) { | |
return Math.atan2(b[1] - a[1], b[0] - a[0]); | |
} | |
function distance(a, b) { | |
var dx = b[0] - a[0], | |
dy = b[1] - a[1]; | |
return Math.sqrt(dx * dx + dy * dy); | |
} | |
function projector(proj) { | |
var types = { | |
Point: proj, | |
LineString: function(coords) { | |
return coords.map(proj); | |
}, | |
MultiLineString: function(arcs) { | |
return arcs.map(types.LineString); | |
}, | |
Polygon: function(rings) { | |
return rings.map(types.LineString); | |
}, | |
MultiPolygon: function(rings) { | |
return rings.map(types.Polygon); | |
} | |
}; | |
return function(geom) { | |
return types[geom.type](geom.coordinates); | |
}; | |
} | |
function cosArctan(dx,dy){ | |
var div = dx/dy; | |
return (dy>0)? | |
(1/Math.sqrt(1+(div*div))): | |
(-1/Math.sqrt(1+(div*div))); | |
} | |
function sinArctan(dx,dy){ | |
var div = dx/dy; | |
return (dy>0)? | |
(div/Math.sqrt(1+(div*div))): | |
(-div/Math.sqrt(1+(div*div))); | |
} | |
function copy(o) { | |
return (o instanceof Array) | |
? o.map(copy) | |
: (typeof o === "string" || typeof o === "number") | |
? o | |
: copyObject(o); | |
} | |
function copyObject(o) { | |
var obj = {}; | |
for (var k in o) obj[k] = copy(o[k]); | |
return obj; | |
} | |
function object(arcs, o) { | |
function arc(i, points) { | |
if (points.length) points.pop(); | |
for (var a = arcs[i < 0 ? ~i : i], k = 0, n = a.length; k < n; ++k) { | |
points.push(a[k]); | |
} | |
if (i < 0) reverse(points, n); | |
} | |
function line(arcs) { | |
var points = []; | |
for (var i = 0, n = arcs.length; i < n; ++i) arc(arcs[i], points); | |
return points; | |
} | |
function polygon(arcs) { | |
return arcs.map(line); | |
} | |
function geometry(o) { | |
o = Object.create(o); | |
o.coordinates = geometryType[o.type](o.arcs); | |
return o; | |
} | |
var geometryType = { | |
LineString: line, | |
MultiLineString: polygon, | |
Polygon: polygon, | |
MultiPolygon: function(arcs) { return arcs.map(polygon); } | |
}; | |
return o.type === "GeometryCollection" | |
? (o = Object.create(o), o.geometries = o.geometries.map(geometry), o) | |
: geometry(o); | |
} | |
function reverse(array, n) { | |
var t, j = array.length, i = j - n; while (i < --j) t = array[i], array[i++] = array[j], array[j] = t; | |
} | |
})(this); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Id | Country | Internet_Users | GDP | Literacy_rates | female_male | Population | |
---|---|---|---|---|---|---|---|
ARG | Argentina | 59.9 | 14715.18002 | 97.91609192 | 156.225 | 41.45 | |
AUS | Australia | 83 | 67458.35541 | 0 | 138.061 | 23.13 | |
AUT | Austria | 80.6188 | 50546.6975 | 0 | 119.556 | 8.47 | |
BHR | Bahrain | 90 | 24689.10563 | 94.55679321 | 198.164 | 1.33 | |
BGD | Bangladesh | 6.5 | 957.824266 | 58.78771973 | 69.034 | 156.59 | |
BEL | Belgium | 82.1702 | 46877.98625 | 0 | 128.087 | 11.2 | |
BEN | Benin | 4.9 | 804.6924986 | 42.4 | 26.963 | 10.32 | |
BWA | Botswana | 15 | 7315.019289 | 86.72881317 | 0 | 2.02 | |
BRA | Brazil | 51.6 | 11208.08274 | 91.33374023 | 0 | 200.36 | |
BFA | Burkina Faso | 4.4 | 683.9484018 | 28.72921371 | 49.558 | 16.93 | |
CMR | Cameroon | 6.4 | 1328.640205 | 71.29050446 | 73.457 | 22.25 | |
CAN | Canada | 85.8 | 51958.38124 | 0 | 0 | 35.16 | |
CHL | Chile | 66.5 | 15732.31377 | 98.55367279 | 111.82 | 17.62 | |
CHN | China | 45.8 | 6807.430824 | 95.12447357 | 112.648 | 1357.38 | |
COL | Colombia | 51.7 | 7831.215313 | 93.58053589 | 112.518 | 48.32 | |
CRI | Costa Rica | 45.96 | 10184.60567 | 97.40658569 | 127.255 | 4.87 | |
CZE | Czech Republic | 74.1104 | 19844.76165 | 0 | 142.037 | 10.52 | |
DNK | Denmark | 94.6297 | 59831.69556 | 0 | 141.113 | 5.61 | |
ECU | Ecuador | 40.35368423 | 6002.885459 | 93.29462433 | 115.102 | 15.74 | |
EGY | Egypt | 49.56 | 3314.462928 | 73.86558533 | 96.39 | 82.06 | |
EST | Estonia | 80.0043 | 18783.05871 | 99.86277771 | 152.837 | 1.32 | |
ETH | Ethiopia | 1.9 | 505.0457458 | 38.99598312 | 0 | 94.1 | |
FIN | Finland | 91.5144 | 49146.64663 | 0 | 120.989 | 5.44 | |
FRA | France | 81.9198 | 42503.30359 | 0 | 125.835 | 66.03 | |
DEU | Germany | 83.9614 | 46268.64107 | 0 | 104.969 | 80.62 | |
GHA | Ghana | 12.3 | 1858.242598 | 71.49707794 | 61.075 | 25.9 | |
GRC | Greece | 59.8663 | 21956.41154 | 97.36376953 | 103.436 | 11.03 | |
HTI | Haiti | 10.6 | 819.9039143 | 0 | 0 | 10.32 | |
HUN | Hungary | 72.6439 | 13480.91026 | 99.37355804 | 130.091 | 9.9 | |
ISL | Iceland | 96.5468 | 47461.18559 | 0 | 170.482 | 0.32 | |
IND | India | 15.1 | 1498.872175 | 0 | 78.126 | 1252.14 | |
IDN | Indonesia | 15.82 | 3475.250474 | 92.81190491 | 103.47 | 249.87 | |
IRL | Ireland | 78.2477 | 50503.4228 | 0 | 103.05 | 4.6 | |
ISR | Israel | 70.8 | 36050.69793 | 97.76419067 | 132.134 | 8.06 | |
ITA | Italy | 58.4593 | 35925.87748 | 99.02561188 | 142.269 | 59.83 | |
JAM | Jamaica | 37.8 | 5289.967803 | 87.48201752 | 205.03 | 2.72 | |
JPN | Japan | 86.25 | 38633.70806 | 0 | 90.22 | 127.34 | |
HKJ | Jordan | 44.2 | 5214.197267 | 97.89031982 | 115.017 | 6.46 | |
KAZ | Kazakhstan | 54 | 13609.75338 | 99.73241425 | 143.479 | 17.04 | |
KEN | Kenya | 39 | 1245.512041 | 72.1570282 | 70.266 | 44.35 | |
MWI | Malawi | 5.4 | 226.4551027 | 61.3097229 | 64.887 | 16.36 | |
MYS | Malaysia | 66.97 | 10538.05789 | 93.11788177 | 119.531 | 29.72 | |
RMM | Mali | 2.3 | 715.133813 | 33.56093979 | 42.571 | 15.3 | |
MUS | Mauritius | 39 | 9202.517324 | 89.24983215 | 132.449 | 1.3 | |
MEX | Mexico | 43.46 | 10307.28304 | 94.22840118 | 95.877 | 122.33 | |
MAR | Morocco | 56 | 3092.606545 | 67.08415985 | 89.118 | 33.01 | |
MOZ | Mozambique | 5.4 | 605.0341744 | 50.58381271 | 62.443 | 25.83 | |
MMR | Myanmar | 1.2 | 1200 | 92.62518311 | 134.45 | 53.26 | |
NAM | Namibia | 13.9 | 5693.129154 | 76.48659515 | 127.641 | 2.3 | |
NPL | Nepal | 13.3 | 694.1047943 | 57.36910248 | 63.685 | 27.8 | |
NLD | Netherlands | 93.9564 | 50793.14296 | 0 | 109.947 | 16.8 | |
NZL | New Zealand | 82.78 | 41555.83441 | 0 | 146.15 | 4.47 | |
WAN | Nigeria | 38 | 3005.513796 | 51.07765961 | 0 | 173.62 | |
NOR | Norway | 95.0534 | 100818.5032 | 0 | 157.639 | 5.08 | |
PAK | Pakistan | 10.9 | 1275.301817 | 54.73801804 | 95.472 | 182.14 | |
PER | Peru | 39.2 | 6661.591112 | 93.84172821 | 109.368 | 30.38 | |
PHL | Philippines | 37 | 2765.084587 | 95.42009735 | 123.837 | 98.39 | |
POL | Poland | 62.8492 | 13647.9647 | 99.74762726 | 155.022 | 38.53 | |
PRT | Portugal | 62.0956 | 21733.07306 | 94.47705078 | 119.754 | 10.46 | |
QAT | Qatar | 85.3 | 93714.06338 | 96.6785965 | 676.162 | 2.17 | |
KOR | Republic Of Korea | 84.77 | 25976.95283 | 0 | 74.951 | 50.22 | |
RUS | Russian Federation | 61.4 | 14611.70078 | 99.68426514 | 125.969 | 143.5 | |
RWA | Rwanda | 8.7 | 638.6657954 | 65.85227203 | 75.715 | 11.78 | |
SAU | Saudi Arabia | 60.5 | 25961.80842 | 94.42634583 | 106.152 | 28.83 | |
SEN | Senegal | 20.9 | 1046.586426 | 52.05195999 | 58.646 | 14.13 | |
SLE | Sierra Leone | 1.7 | 678.9609045 | 44.46472931 | 0 | 6.09 | |
SGP | Singapore | 73 | 55182.48279 | 96.36598206 | 0 | 5.4 | |
ZAF | South Africa | 48.9 | 6617.911609 | 93.7294693 | 0 | 52.98 | |
ESP | Spain | 71.5719 | 29863.17672 | 97.89453888 | 121.912 | 46.65 | |
SWE | Sweden | 94.7836 | 60430.21558 | 0 | 155.356 | 9.59 | |
CHE | Switzerland | 86.7 | 84815.40701 | 0 | 99.158 | 8.08 | |
THA | Thailand | 28.94 | 5778.977216 | 96.4309082 | 134.064 | 67.01 | |
TUN | Tunisia | 43.8 | 4316.685695 | 79.65390778 | 159.05 | 10.89 | |
TUR | Turkey | 46.25 | 10971.65631 | 94.9197464 | 85.19 | 74.93 | |
UGA | Uganda | 16.2 | 571.9600416 | 73.21188354 | 26.899 | 37.58 | |
UKR | Ukraine | 41.8 | 3900.465376 | 99.73021698 | 114.983 | 45.49 | |
ARE | United Arab Emirates | 88 | 43048.85015 | 0 | 0 | 9.35 | |
GBR | United Kingdom Of Great Britain And Northern Ireland | 89.8441 | 41787.46798 | 0 | 135.569 | 64.1 | |
TZA | United Republic Of Tanzania | 4.4 | 694.7711797 | 67.80069733 | 54.727 | 49.25 | |
USA | United States Of America | 84.2 | 53041.98141 | 0 | 139.209 | 316.13 | |
URY | Uruguay | 58.1 | 16350.72817 | 98.39594269 | 172.669 | 3.41 | |
VEN | Venezuela (Bolivarian Republic Of) | 54.9 | 14414.75353 | 95.51199341 | 169.419 | 30.41 | |
VNM | Viet Nam | 43.9 | 1910.512818 | 93.52045441 | 101.619 | 89.71 | |
YEM | Yemen | 20 | 1473.099564 | 66.37377167 | 44.093 | 24.41 | |
RNR | Zambia | 15.4 | 1844.799139 | 61.42828751 | 0 | 14.54 | |
ZWE | Zimbabwe | 18.5 | 953.3806071 | 83.5827179 | 77.545 | 14.15 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<title>Cartograms with d3 & TopoJSON</title> | |
<meta charset="utf-8"> | |
<meta property="og:image" content="placeholder.png"> | |
<script src="http://d3js.org/d3.v3.min.js"></script> | |
<script src="lib/colorbrewer.js"></script> | |
<script src="lib/topojson.js"></script> | |
<script src="cartogram.js"></script> | |
<style type="text/css"> | |
body { | |
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; | |
font-size: 14px; | |
line-height: 1.4em; | |
padding: 0; | |
margin: 0; | |
} | |
#container { | |
width: 960px; | |
margin: 20px auto; | |
} | |
h1 { | |
font-size: 200%; | |
margin: 0 0 15px 0; | |
} | |
h2 { | |
font-size: 160%; | |
margin: 0 0 10px 0; | |
} | |
p { | |
margin: 0 0 10px; | |
} | |
form, form > * { | |
margin: 0; | |
} | |
#status { | |
color: #999; | |
} | |
#map-container { | |
height: 700px; | |
text-align: center; | |
position: relative; | |
margin: 20px 0; | |
} | |
#map { | |
display: block; | |
position: absolute; | |
background: #fff; | |
width: 100%; | |
height: 100%; | |
margin: 0; | |
} | |
path.state { | |
stroke: #666; | |
stroke-width: .5; | |
} | |
path.state:hover { | |
stroke: #000; | |
} | |
form { | |
font-size: 120%; | |
} | |
select { | |
font-size: inherit; | |
} | |
#placeholder { | |
position: absolute; | |
z-index: -1; | |
display: block; | |
left: 0; | |
top: 0; | |
} | |
</style> | |
</head> | |
<body> | |
<div id="container"> | |
<h1>Cartograms with d3 & TopoJSON</h1> | |
<form> | |
<p> | |
<label>Scale by <select id="field"></select></label> | |
<span id="status"></span> | |
</p> | |
</form> | |
<div id="map-container"> | |
<svg id="map"></svg> | |
</div> | |
</div> | |
<script> | |
var margin = 1, | |
width = 970 - margin, | |
height = 700 - margin; | |
// hide the form if the browser doesn't do SVG, | |
// (then just let everything else fail) | |
if (!document.createElementNS) { | |
document.getElementsByTagName("form")[0].style.display = "none"; | |
} | |
// field definitions from: | |
// <http://www.census.gov/popest/data/national/totals/2011/files/NST-EST2011-alldata.pdf> | |
var percent = (function() { | |
var fmt = d3.format(".2f"); | |
return function(n) { return fmt(n) + "%"; }; | |
})(), | |
fields = [ | |
{name: "(no scale)", id: "none"}, | |
{name: "Internet_Users", id: "internet", key: "Internet_Users", format : percent}, | |
{name: "GDP", id: "gdp", key: "GDP"}, | |
{name: "Literacy_rates", id: "literacy", key: "Literacy_rates", format : percent}, | |
{name: "female_male", id: "fm", key: "female_male"}, | |
{name: "Population", id: "pop", key: "Population"}, | |
], | |
fieldsById = d3.nest() | |
.key(function(d) { return d.id; }) | |
.rollup(function(d) { return d[0]; }) | |
.map(fields), | |
field = fields[0], | |
colors = colorbrewer.RdYlBu[3] | |
.reverse() | |
.map(function(rgb) { return d3.hsl(rgb); }); | |
var body = d3.select("body"), | |
stat = d3.select("#status"); | |
var fieldSelect = d3.select("#field") | |
.on("change", function(e) { | |
field = fields[this.selectedIndex]; | |
location.hash = "#" + [field.id] | |
}); | |
fieldSelect.selectAll("option") | |
.data(fields) | |
.enter() | |
.append("option") | |
.attr("value", function(d) { return d.id; }) | |
.text(function(d) { return d.name; }); | |
var map = d3.select("#map").attr("width", width + margin) | |
.attr("height", height + margin), | |
zoom = d3.behavior.zoom() | |
.translate([-38, 32]) | |
.scale(.95) | |
.scaleExtent([0.5, 10.0]) | |
.on("zoom", updateZoom), | |
layer = map.append("g") | |
.attr("id", "layer"), | |
states = layer.append("g") | |
.attr("id", "states") | |
.selectAll("path"); | |
// map.call(zoom); | |
updateZoom(); | |
function updateZoom() { | |
var scale = zoom.scale(); | |
layer.attr("transform", | |
"translate(" + zoom.translate() + ") " + | |
"scale(" + [scale, scale] + ")"); | |
} | |
var proj = d3.geo.mercator().scale(150).translate([width / 2, height / 1.5]), | |
topology, | |
geometries, | |
rawData, | |
dataById = {}, | |
carto = d3.cartogram() | |
.projection(proj) | |
.properties(function(d) { | |
return dataById[d.id]; | |
}) | |
.value(function(d) { | |
return +d.properties[field]; | |
}); | |
window.onhashchange = function() { | |
parseHash(); | |
}; | |
d3.json("data/world_countries_topo.json", function(topo) { | |
topology = topo; | |
// console.log("T",topology) | |
geometries = topology.objects.countries.geometries; | |
d3.csv("data/parallel_score.csv", function(data) { | |
rawData = data; | |
dataById = d3.nest() | |
.key(function(d) { return d.Id; }) | |
.rollup(function(d) { return d[0]; }) | |
.map(data); | |
init(); | |
}); | |
}); | |
function init() { | |
var features = carto.features(topology, geometries), | |
path = d3.geo.path() | |
.projection(proj); | |
states = states.data(features) | |
.enter() | |
.append("path") | |
.attr("class", "state") | |
.attr("id", function(d) { | |
return d.Id; | |
}) | |
.attr("fill", "#000") | |
.attr("d", path); | |
states.append("title"); | |
parseHash(); | |
} | |
function reset() { | |
stat.text(""); | |
body.classed("updating", false); | |
var features = carto.features(topology, geometries), | |
path = d3.geo.path() | |
.projection(proj); | |
states.data(features) | |
.transition() | |
.duration(750) | |
.ease("linear") | |
.attr("fill", "#fafafa") | |
.attr("d", path); | |
states.select("title") | |
.text(function(d) { | |
// console.log("D",d) | |
return d.Id; | |
}); | |
} | |
function update() { | |
var start = Date.now(); | |
body.classed("updating", true); | |
var key = field.key | |
var fmt = (typeof field.format === "function") | |
? field.format | |
: d3.format(field.format || ","), | |
value = function(d) { | |
if(d.properties == undefined){} | |
else { | |
// console.log("D Keyyyy", d) | |
return +d.properties[key]; | |
} | |
}, | |
values = states.data() | |
.map(value) | |
.filter(function(n) { | |
return !isNaN(n); | |
}) | |
.sort(d3.ascending), | |
lo = values[0], | |
hi = values[values.length - 1]; | |
console.log("L",lo) | |
console.log("H",hi) | |
var color = d3.scale.linear() | |
.range(colors) | |
.domain(lo < 0 | |
? [lo, 0, hi] | |
: [lo, d3.mean(values), hi]); | |
// normalize the scale to positive numbers | |
var scale = d3.scale.linear() | |
.domain([lo, hi]) | |
.range([1, 1000]); | |
// tell the cartogram to use the scaled values | |
carto.value(function(d) { | |
if( value(d) == undefined) { | |
return lo | |
} | |
else { | |
console.log("SCale", (value(d))) | |
return scale(value(d)); | |
} | |
}); | |
// generate the new features, pre-projected | |
var features = carto(topology, geometries).features; | |
// update the data | |
states.data(features) | |
.select("title") | |
/*.text(function(d) { | |
return [d.properties.Id, fmt(value(d))].join(": "); | |
});*/ | |
states.transition() | |
.duration(750) | |
.ease("linear") | |
.attr("fill", function(d) { | |
if(d.properties == undefined){ | |
return color(lo) | |
} | |
else { | |
return color(value(d)); | |
} | |
}) | |
.attr("d", carto.path); | |
var delta = (Date.now() - start) / 1000; | |
stat.text(["calculated in", delta.toFixed(1), "seconds"].join(" ")); | |
body.classed("updating", false); | |
} | |
var deferredUpdate = (function() { | |
var timeout; | |
return function() { | |
var args = arguments; | |
clearTimeout(timeout); | |
stat.text("calculating..."); | |
return timeout = setTimeout(function() { | |
update.apply(null, arguments); | |
}, 10); | |
}; | |
})(); | |
var hashish = d3.selectAll("a.hashish") | |
.datum(function() { | |
return this.href; | |
}); | |
function parseHash() { | |
var parts = location.hash.substr(1).split("/"), | |
desiredFieldId = parts[0], | |
field = fieldsById[desiredFieldId] || fields[0]; | |
fieldSelect.property("selectedIndex", fields.indexOf(field)); | |
if (field.id === "none") { | |
reset(); | |
} else { | |
deferredUpdate(); | |
location.replace("#" + [field.id].join("/")); | |
hashish.attr("href", function(href) { | |
return href + location.hash; | |
}); | |
} | |
} | |
</script> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* This product includes color specifications and designs developed by Cynthia | |
* Brewer (http://colorbrewer.org/). | |
*/ | |
var colorbrewer = { | |
YlGn:{3:["rgb(247,252,185)","rgb(173,221,142)","rgb(49,163,84)"],4:["rgb(255,255,204)","rgb(194,230,153)","rgb(120,198,121)","rgb(35,132,67)"],5:["rgb(255,255,204)","rgb(194,230,153)","rgb(120,198,121)","rgb(49,163,84)","rgb(0,104,55)"],6:["rgb(255,255,204)","rgb(217,240,163)","rgb(173,221,142)","rgb(120,198,121)","rgb(49,163,84)","rgb(0,104,55)"],7:["rgb(255,255,204)","rgb(217,240,163)","rgb(173,221,142)","rgb(120,198,121)","rgb(65,171,93)","rgb(35,132,67)","rgb(0,90,50)"],8:["rgb(255,255,229)","rgb(247,252,185)","rgb(217,240,163)","rgb(173,221,142)","rgb(120,198,121)","rgb(65,171,93)","rgb(35,132,67)","rgb(0,90,50)"],9:["rgb(255,255,229)","rgb(247,252,185)","rgb(217,240,163)","rgb(173,221,142)","rgb(120,198,121)","rgb(65,171,93)","rgb(35,132,67)","rgb(0,104,55)","rgb(0,69,41)"]}, | |
YlGnBu:{3:["rgb(237,248,177)","rgb(127,205,187)","rgb(44,127,184)"],4:["rgb(255,255,204)","rgb(161,218,180)","rgb(65,182,196)","rgb(34,94,168)"],5:["rgb(255,255,204)","rgb(161,218,180)","rgb(65,182,196)","rgb(44,127,184)","rgb(37,52,148)"],6:["rgb(255,255,204)","rgb(199,233,180)","rgb(127,205,187)","rgb(65,182,196)","rgb(44,127,184)","rgb(37,52,148)"],7:["rgb(255,255,204)","rgb(199,233,180)","rgb(127,205,187)","rgb(65,182,196)","rgb(29,145,192)","rgb(34,94,168)","rgb(12,44,132)"],8:["rgb(255,255,217)","rgb(237,248,177)","rgb(199,233,180)","rgb(127,205,187)","rgb(65,182,196)","rgb(29,145,192)","rgb(34,94,168)","rgb(12,44,132)"],9:["rgb(255,255,217)","rgb(237,248,177)","rgb(199,233,180)","rgb(127,205,187)","rgb(65,182,196)","rgb(29,145,192)","rgb(34,94,168)","rgb(37,52,148)","rgb(8,29,88)"]}, | |
GnBu:{3:["rgb(224,243,219)","rgb(168,221,181)","rgb(67,162,202)"],4:["rgb(240,249,232)","rgb(186,228,188)","rgb(123,204,196)","rgb(43,140,190)"],5:["rgb(240,249,232)","rgb(186,228,188)","rgb(123,204,196)","rgb(67,162,202)","rgb(8,104,172)"],6:["rgb(240,249,232)","rgb(204,235,197)","rgb(168,221,181)","rgb(123,204,196)","rgb(67,162,202)","rgb(8,104,172)"],7:["rgb(240,249,232)","rgb(204,235,197)","rgb(168,221,181)","rgb(123,204,196)","rgb(78,179,211)","rgb(43,140,190)","rgb(8,88,158)"],8:["rgb(247,252,240)","rgb(224,243,219)","rgb(204,235,197)","rgb(168,221,181)","rgb(123,204,196)","rgb(78,179,211)","rgb(43,140,190)","rgb(8,88,158)"],9:["rgb(247,252,240)","rgb(224,243,219)","rgb(204,235,197)","rgb(168,221,181)","rgb(123,204,196)","rgb(78,179,211)","rgb(43,140,190)","rgb(8,104,172)","rgb(8,64,129)"]}, | |
BuGn:{3:["rgb(229,245,249)","rgb(153,216,201)","rgb(44,162,95)"],4:["rgb(237,248,251)","rgb(178,226,226)","rgb(102,194,164)","rgb(35,139,69)"],5:["rgb(237,248,251)","rgb(178,226,226)","rgb(102,194,164)","rgb(44,162,95)","rgb(0,109,44)"],6:["rgb(237,248,251)","rgb(204,236,230)","rgb(153,216,201)","rgb(102,194,164)","rgb(44,162,95)","rgb(0,109,44)"],7:["rgb(237,248,251)","rgb(204,236,230)","rgb(153,216,201)","rgb(102,194,164)","rgb(65,174,118)","rgb(35,139,69)","rgb(0,88,36)"],8:["rgb(247,252,253)","rgb(229,245,249)","rgb(204,236,230)","rgb(153,216,201)","rgb(102,194,164)","rgb(65,174,118)","rgb(35,139,69)","rgb(0,88,36)"],9:["rgb(247,252,253)","rgb(229,245,249)","rgb(204,236,230)","rgb(153,216,201)","rgb(102,194,164)","rgb(65,174,118)","rgb(35,139,69)","rgb(0,109,44)","rgb(0,68,27)"]}, | |
PuBuGn:{3:["rgb(236,226,240)","rgb(166,189,219)","rgb(28,144,153)"],4:["rgb(246,239,247)","rgb(189,201,225)","rgb(103,169,207)","rgb(2,129,138)"],5:["rgb(246,239,247)","rgb(189,201,225)","rgb(103,169,207)","rgb(28,144,153)","rgb(1,108,89)"],6:["rgb(246,239,247)","rgb(208,209,230)","rgb(166,189,219)","rgb(103,169,207)","rgb(28,144,153)","rgb(1,108,89)"],7:["rgb(246,239,247)","rgb(208,209,230)","rgb(166,189,219)","rgb(103,169,207)","rgb(54,144,192)","rgb(2,129,138)","rgb(1,100,80)"],8:["rgb(255,247,251)","rgb(236,226,240)","rgb(208,209,230)","rgb(166,189,219)","rgb(103,169,207)","rgb(54,144,192)","rgb(2,129,138)","rgb(1,100,80)"],9:["rgb(255,247,251)","rgb(236,226,240)","rgb(208,209,230)","rgb(166,189,219)","rgb(103,169,207)","rgb(54,144,192)","rgb(2,129,138)","rgb(1,108,89)","rgb(1,70,54)"]}, | |
PuBu:{3:["rgb(236,231,242)","rgb(166,189,219)","rgb(43,140,190)"],4:["rgb(241,238,246)","rgb(189,201,225)","rgb(116,169,207)","rgb(5,112,176)"],5:["rgb(241,238,246)","rgb(189,201,225)","rgb(116,169,207)","rgb(43,140,190)","rgb(4,90,141)"],6:["rgb(241,238,246)","rgb(208,209,230)","rgb(166,189,219)","rgb(116,169,207)","rgb(43,140,190)","rgb(4,90,141)"],7:["rgb(241,238,246)","rgb(208,209,230)","rgb(166,189,219)","rgb(116,169,207)","rgb(54,144,192)","rgb(5,112,176)","rgb(3,78,123)"],8:["rgb(255,247,251)","rgb(236,231,242)","rgb(208,209,230)","rgb(166,189,219)","rgb(116,169,207)","rgb(54,144,192)","rgb(5,112,176)","rgb(3,78,123)"],9:["rgb(255,247,251)","rgb(236,231,242)","rgb(208,209,230)","rgb(166,189,219)","rgb(116,169,207)","rgb(54,144,192)","rgb(5,112,176)","rgb(4,90,141)","rgb(2,56,88)"]}, | |
BuPu:{3:["rgb(224,236,244)","rgb(158,188,218)","rgb(136,86,167)"],4:["rgb(237,248,251)","rgb(179,205,227)","rgb(140,150,198)","rgb(136,65,157)"],5:["rgb(237,248,251)","rgb(179,205,227)","rgb(140,150,198)","rgb(136,86,167)","rgb(129,15,124)"],6:["rgb(237,248,251)","rgb(191,211,230)","rgb(158,188,218)","rgb(140,150,198)","rgb(136,86,167)","rgb(129,15,124)"],7:["rgb(237,248,251)","rgb(191,211,230)","rgb(158,188,218)","rgb(140,150,198)","rgb(140,107,177)","rgb(136,65,157)","rgb(110,1,107)"],8:["rgb(247,252,253)","rgb(224,236,244)","rgb(191,211,230)","rgb(158,188,218)","rgb(140,150,198)","rgb(140,107,177)","rgb(136,65,157)","rgb(110,1,107)"],9:["rgb(247,252,253)","rgb(224,236,244)","rgb(191,211,230)","rgb(158,188,218)","rgb(140,150,198)","rgb(140,107,177)","rgb(136,65,157)","rgb(129,15,124)","rgb(77,0,75)"]}, | |
RdPu:{3:["rgb(253,224,221)","rgb(250,159,181)","rgb(197,27,138)"],4:["rgb(254,235,226)","rgb(251,180,185)","rgb(247,104,161)","rgb(174,1,126)"],5:["rgb(254,235,226)","rgb(251,180,185)","rgb(247,104,161)","rgb(197,27,138)","rgb(122,1,119)"],6:["rgb(254,235,226)","rgb(252,197,192)","rgb(250,159,181)","rgb(247,104,161)","rgb(197,27,138)","rgb(122,1,119)"],7:["rgb(254,235,226)","rgb(252,197,192)","rgb(250,159,181)","rgb(247,104,161)","rgb(221,52,151)","rgb(174,1,126)","rgb(122,1,119)"],8:["rgb(255,247,243)","rgb(253,224,221)","rgb(252,197,192)","rgb(250,159,181)","rgb(247,104,161)","rgb(221,52,151)","rgb(174,1,126)","rgb(122,1,119)"],9:["rgb(255,247,243)","rgb(253,224,221)","rgb(252,197,192)","rgb(250,159,181)","rgb(247,104,161)","rgb(221,52,151)","rgb(174,1,126)","rgb(122,1,119)","rgb(73,0,106)"]}, | |
PuRd:{3:["rgb(231,225,239)","rgb(201,148,199)","rgb(221,28,119)"],4:["rgb(241,238,246)","rgb(215,181,216)","rgb(223,101,176)","rgb(206,18,86)"],5:["rgb(241,238,246)","rgb(215,181,216)","rgb(223,101,176)","rgb(221,28,119)","rgb(152,0,67)"],6:["rgb(241,238,246)","rgb(212,185,218)","rgb(201,148,199)","rgb(223,101,176)","rgb(221,28,119)","rgb(152,0,67)"],7:["rgb(241,238,246)","rgb(212,185,218)","rgb(201,148,199)","rgb(223,101,176)","rgb(231,41,138)","rgb(206,18,86)","rgb(145,0,63)"],8:["rgb(247,244,249)","rgb(231,225,239)","rgb(212,185,218)","rgb(201,148,199)","rgb(223,101,176)","rgb(231,41,138)","rgb(206,18,86)","rgb(145,0,63)"],9:["rgb(247,244,249)","rgb(231,225,239)","rgb(212,185,218)","rgb(201,148,199)","rgb(223,101,176)","rgb(231,41,138)","rgb(206,18,86)","rgb(152,0,67)","rgb(103,0,31)"]}, | |
OrRd:{3:["rgb(254,232,200)","rgb(253,187,132)","rgb(227,74,51)"],4:["rgb(254,240,217)","rgb(253,204,138)","rgb(252,141,89)","rgb(215,48,31)"],5:["rgb(254,240,217)","rgb(253,204,138)","rgb(252,141,89)","rgb(227,74,51)","rgb(179,0,0)"],6:["rgb(254,240,217)","rgb(253,212,158)","rgb(253,187,132)","rgb(252,141,89)","rgb(227,74,51)","rgb(179,0,0)"],7:["rgb(254,240,217)","rgb(253,212,158)","rgb(253,187,132)","rgb(252,141,89)","rgb(239,101,72)","rgb(215,48,31)","rgb(153,0,0)"],8:["rgb(255,247,236)","rgb(254,232,200)","rgb(253,212,158)","rgb(253,187,132)","rgb(252,141,89)","rgb(239,101,72)","rgb(215,48,31)","rgb(153,0,0)"],9:["rgb(255,247,236)","rgb(254,232,200)","rgb(253,212,158)","rgb(253,187,132)","rgb(252,141,89)","rgb(239,101,72)","rgb(215,48,31)","rgb(179,0,0)","rgb(127,0,0)"]}, | |
YlOrRd:{3:["rgb(255,237,160)","rgb(254,178,76)","rgb(240,59,32)"],4:["rgb(255,255,178)","rgb(254,204,92)","rgb(253,141,60)","rgb(227,26,28)"],5:["rgb(255,255,178)","rgb(254,204,92)","rgb(253,141,60)","rgb(240,59,32)","rgb(189,0,38)"],6:["rgb(255,255,178)","rgb(254,217,118)","rgb(254,178,76)","rgb(253,141,60)","rgb(240,59,32)","rgb(189,0,38)"],7:["rgb(255,255,178)","rgb(254,217,118)","rgb(254,178,76)","rgb(253,141,60)","rgb(252,78,42)","rgb(227,26,28)","rgb(177,0,38)"],8:["rgb(255,255,204)","rgb(255,237,160)","rgb(254,217,118)","rgb(254,178,76)","rgb(253,141,60)","rgb(252,78,42)","rgb(227,26,28)","rgb(177,0,38)"],9:["rgb(255,255,204)","rgb(255,237,160)","rgb(254,217,118)","rgb(254,178,76)","rgb(253,141,60)","rgb(252,78,42)","rgb(227,26,28)","rgb(189,0,38)","rgb(128,0,38)"]}, | |
YlOrBr:{3:["rgb(255,247,188)","rgb(254,196,79)","rgb(217,95,14)"],4:["rgb(255,255,212)","rgb(254,217,142)","rgb(254,153,41)","rgb(204,76,2)"],5:["rgb(255,255,212)","rgb(254,217,142)","rgb(254,153,41)","rgb(217,95,14)","rgb(153,52,4)"],6:["rgb(255,255,212)","rgb(254,227,145)","rgb(254,196,79)","rgb(254,153,41)","rgb(217,95,14)","rgb(153,52,4)"],7:["rgb(255,255,212)","rgb(254,227,145)","rgb(254,196,79)","rgb(254,153,41)","rgb(236,112,20)","rgb(204,76,2)","rgb(140,45,4)"],8:["rgb(255,255,229)","rgb(255,247,188)","rgb(254,227,145)","rgb(254,196,79)","rgb(254,153,41)","rgb(236,112,20)","rgb(204,76,2)","rgb(140,45,4)"],9:["rgb(255,255,229)","rgb(255,247,188)","rgb(254,227,145)","rgb(254,196,79)","rgb(254,153,41)","rgb(236,112,20)","rgb(204,76,2)","rgb(153,52,4)","rgb(102,37,6)"]}, | |
Purples:{3:["rgb(239,237,245)","rgb(188,189,220)","rgb(117,107,177)"],4:["rgb(242,240,247)","rgb(203,201,226)","rgb(158,154,200)","rgb(106,81,163)"],5:["rgb(242,240,247)","rgb(203,201,226)","rgb(158,154,200)","rgb(117,107,177)","rgb(84,39,143)"],6:["rgb(242,240,247)","rgb(218,218,235)","rgb(188,189,220)","rgb(158,154,200)","rgb(117,107,177)","rgb(84,39,143)"],7:["rgb(242,240,247)","rgb(218,218,235)","rgb(188,189,220)","rgb(158,154,200)","rgb(128,125,186)","rgb(106,81,163)","rgb(74,20,134)"],8:["rgb(252,251,253)","rgb(239,237,245)","rgb(218,218,235)","rgb(188,189,220)","rgb(158,154,200)","rgb(128,125,186)","rgb(106,81,163)","rgb(74,20,134)"],9:["rgb(252,251,253)","rgb(239,237,245)","rgb(218,218,235)","rgb(188,189,220)","rgb(158,154,200)","rgb(128,125,186)","rgb(106,81,163)","rgb(84,39,143)","rgb(63,0,125)"]}, | |
Blues:{3:["rgb(222,235,247)","rgb(158,202,225)","rgb(49,130,189)"],4:["rgb(239,243,255)","rgb(189,215,231)","rgb(107,174,214)","rgb(33,113,181)"],5:["rgb(239,243,255)","rgb(189,215,231)","rgb(107,174,214)","rgb(49,130,189)","rgb(8,81,156)"],6:["rgb(239,243,255)","rgb(198,219,239)","rgb(158,202,225)","rgb(107,174,214)","rgb(49,130,189)","rgb(8,81,156)"],7:["rgb(239,243,255)","rgb(198,219,239)","rgb(158,202,225)","rgb(107,174,214)","rgb(66,146,198)","rgb(33,113,181)","rgb(8,69,148)"],8:["rgb(247,251,255)","rgb(222,235,247)","rgb(198,219,239)","rgb(158,202,225)","rgb(107,174,214)","rgb(66,146,198)","rgb(33,113,181)","rgb(8,69,148)"],9:["rgb(247,251,255)","rgb(222,235,247)","rgb(198,219,239)","rgb(158,202,225)","rgb(107,174,214)","rgb(66,146,198)","rgb(33,113,181)","rgb(8,81,156)","rgb(8,48,107)"]}, | |
Greens:{3:["rgb(229,245,224)","rgb(161,217,155)","rgb(49,163,84)"],4:["rgb(237,248,233)","rgb(186,228,179)","rgb(116,196,118)","rgb(35,139,69)"],5:["rgb(237,248,233)","rgb(186,228,179)","rgb(116,196,118)","rgb(49,163,84)","rgb(0,109,44)"],6:["rgb(237,248,233)","rgb(199,233,192)","rgb(161,217,155)","rgb(116,196,118)","rgb(49,163,84)","rgb(0,109,44)"],7:["rgb(237,248,233)","rgb(199,233,192)","rgb(161,217,155)","rgb(116,196,118)","rgb(65,171,93)","rgb(35,139,69)","rgb(0,90,50)"],8:["rgb(247,252,245)","rgb(229,245,224)","rgb(199,233,192)","rgb(161,217,155)","rgb(116,196,118)","rgb(65,171,93)","rgb(35,139,69)","rgb(0,90,50)"],9:["rgb(247,252,245)","rgb(229,245,224)","rgb(199,233,192)","rgb(161,217,155)","rgb(116,196,118)","rgb(65,171,93)","rgb(35,139,69)","rgb(0,109,44)","rgb(0,68,27)"]}, | |
Oranges:{3:["rgb(254,230,206)","rgb(253,174,107)","rgb(230,85,13)"],4:["rgb(254,237,222)","rgb(253,190,133)","rgb(253,141,60)","rgb(217,71,1)"],5:["rgb(254,237,222)","rgb(253,190,133)","rgb(253,141,60)","rgb(230,85,13)","rgb(166,54,3)"],6:["rgb(254,237,222)","rgb(253,208,162)","rgb(253,174,107)","rgb(253,141,60)","rgb(230,85,13)","rgb(166,54,3)"],7:["rgb(254,237,222)","rgb(253,208,162)","rgb(253,174,107)","rgb(253,141,60)","rgb(241,105,19)","rgb(217,72,1)","rgb(140,45,4)"],8:["rgb(255,245,235)","rgb(254,230,206)","rgb(253,208,162)","rgb(253,174,107)","rgb(253,141,60)","rgb(241,105,19)","rgb(217,72,1)","rgb(140,45,4)"],9:["rgb(255,245,235)","rgb(254,230,206)","rgb(253,208,162)","rgb(253,174,107)","rgb(253,141,60)","rgb(241,105,19)","rgb(217,72,1)","rgb(166,54,3)","rgb(127,39,4)"]}, | |
Reds:{3:["rgb(254,224,210)","rgb(252,146,114)","rgb(222,45,38)"],4:["rgb(254,229,217)","rgb(252,174,145)","rgb(251,106,74)","rgb(203,24,29)"],5:["rgb(254,229,217)","rgb(252,174,145)","rgb(251,106,74)","rgb(222,45,38)","rgb(165,15,21)"],6:["rgb(254,229,217)","rgb(252,187,161)","rgb(252,146,114)","rgb(251,106,74)","rgb(222,45,38)","rgb(165,15,21)"],7:["rgb(254,229,217)","rgb(252,187,161)","rgb(252,146,114)","rgb(251,106,74)","rgb(239,59,44)","rgb(203,24,29)","rgb(153,0,13)"],8:["rgb(255,245,240)","rgb(254,224,210)","rgb(252,187,161)","rgb(252,146,114)","rgb(251,106,74)","rgb(239,59,44)","rgb(203,24,29)","rgb(153,0,13)"],9:["rgb(255,245,240)","rgb(254,224,210)","rgb(252,187,161)","rgb(252,146,114)","rgb(251,106,74)","rgb(239,59,44)","rgb(203,24,29)","rgb(165,15,21)","rgb(103,0,13)"]}, | |
Greys:{3:["rgb(240,240,240)","rgb(189,189,189)","rgb(99,99,99)"],4:["rgb(247,247,247)","rgb(204,204,204)","rgb(150,150,150)","rgb(82,82,82)"],5:["rgb(247,247,247)","rgb(204,204,204)","rgb(150,150,150)","rgb(99,99,99)","rgb(37,37,37)"],6:["rgb(247,247,247)","rgb(217,217,217)","rgb(189,189,189)","rgb(150,150,150)","rgb(99,99,99)","rgb(37,37,37)"],7:["rgb(247,247,247)","rgb(217,217,217)","rgb(189,189,189)","rgb(150,150,150)","rgb(115,115,115)","rgb(82,82,82)","rgb(37,37,37)"],8:["rgb(255,255,255)","rgb(240,240,240)","rgb(217,217,217)","rgb(189,189,189)","rgb(150,150,150)","rgb(115,115,115)","rgb(82,82,82)","rgb(37,37,37)"],9:["rgb(255,255,255)","rgb(240,240,240)","rgb(217,217,217)","rgb(189,189,189)","rgb(150,150,150)","rgb(115,115,115)","rgb(82,82,82)","rgb(37,37,37)","rgb(0,0,0)"]}, | |
PuOr:{3:["rgb(241,163,64)","rgb(247,247,247)","rgb(153,142,195)"],4:["rgb(230,97,1)","rgb(253,184,99)","rgb(178,171,210)","rgb(94,60,153)"],5:["rgb(230,97,1)","rgb(253,184,99)","rgb(247,247,247)","rgb(178,171,210)","rgb(94,60,153)"],6:["rgb(179,88,6)","rgb(241,163,64)","rgb(254,224,182)","rgb(216,218,235)","rgb(153,142,195)","rgb(84,39,136)"],7:["rgb(179,88,6)","rgb(241,163,64)","rgb(254,224,182)","rgb(247,247,247)","rgb(216,218,235)","rgb(153,142,195)","rgb(84,39,136)"],8:["rgb(179,88,6)","rgb(224,130,20)","rgb(253,184,99)","rgb(254,224,182)","rgb(216,218,235)","rgb(178,171,210)","rgb(128,115,172)","rgb(84,39,136)"],9:["rgb(179,88,6)","rgb(224,130,20)","rgb(253,184,99)","rgb(254,224,182)","rgb(247,247,247)","rgb(216,218,235)","rgb(178,171,210)","rgb(128,115,172)","rgb(84,39,136)"],10:["rgb(127,59,8)","rgb(179,88,6)","rgb(224,130,20)","rgb(253,184,99)","rgb(254,224,182)","rgb(216,218,235)","rgb(178,171,210)","rgb(128,115,172)","rgb(84,39,136)","rgb(45,0,75)"],11:["rgb(127,59,8)","rgb(179,88,6)","rgb(224,130,20)","rgb(253,184,99)","rgb(254,224,182)","rgb(247,247,247)","rgb(216,218,235)","rgb(178,171,210)","rgb(128,115,172)","rgb(84,39,136)","rgb(45,0,75)"]}, | |
BrBG:{3:["rgb(216,179,101)","rgb(245,245,245)","rgb(90,180,172)"],4:["rgb(166,97,26)","rgb(223,194,125)","rgb(128,205,193)","rgb(1,133,113)"],5:["rgb(166,97,26)","rgb(223,194,125)","rgb(245,245,245)","rgb(128,205,193)","rgb(1,133,113)"],6:["rgb(140,81,10)","rgb(216,179,101)","rgb(246,232,195)","rgb(199,234,229)","rgb(90,180,172)","rgb(1,102,94)"],7:["rgb(140,81,10)","rgb(216,179,101)","rgb(246,232,195)","rgb(245,245,245)","rgb(199,234,229)","rgb(90,180,172)","rgb(1,102,94)"],8:["rgb(140,81,10)","rgb(191,129,45)","rgb(223,194,125)","rgb(246,232,195)","rgb(199,234,229)","rgb(128,205,193)","rgb(53,151,143)","rgb(1,102,94)"],9:["rgb(140,81,10)","rgb(191,129,45)","rgb(223,194,125)","rgb(246,232,195)","rgb(245,245,245)","rgb(199,234,229)","rgb(128,205,193)","rgb(53,151,143)","rgb(1,102,94)"],10:["rgb(84,48,5)","rgb(140,81,10)","rgb(191,129,45)","rgb(223,194,125)","rgb(246,232,195)","rgb(199,234,229)","rgb(128,205,193)","rgb(53,151,143)","rgb(1,102,94)","rgb(0,60,48)"],11:["rgb(84,48,5)","rgb(140,81,10)","rgb(191,129,45)","rgb(223,194,125)","rgb(246,232,195)","rgb(245,245,245)","rgb(199,234,229)","rgb(128,205,193)","rgb(53,151,143)","rgb(1,102,94)","rgb(0,60,48)"]}, | |
PRGn:{3:["rgb(175,141,195)","rgb(247,247,247)","rgb(127,191,123)"],4:["rgb(123,50,148)","rgb(194,165,207)","rgb(166,219,160)","rgb(0,136,55)"],5:["rgb(123,50,148)","rgb(194,165,207)","rgb(247,247,247)","rgb(166,219,160)","rgb(0,136,55)"],6:["rgb(118,42,131)","rgb(175,141,195)","rgb(231,212,232)","rgb(217,240,211)","rgb(127,191,123)","rgb(27,120,55)"],7:["rgb(118,42,131)","rgb(175,141,195)","rgb(231,212,232)","rgb(247,247,247)","rgb(217,240,211)","rgb(127,191,123)","rgb(27,120,55)"],8:["rgb(118,42,131)","rgb(153,112,171)","rgb(194,165,207)","rgb(231,212,232)","rgb(217,240,211)","rgb(166,219,160)","rgb(90,174,97)","rgb(27,120,55)"],9:["rgb(118,42,131)","rgb(153,112,171)","rgb(194,165,207)","rgb(231,212,232)","rgb(247,247,247)","rgb(217,240,211)","rgb(166,219,160)","rgb(90,174,97)","rgb(27,120,55)"],10:["rgb(64,0,75)","rgb(118,42,131)","rgb(153,112,171)","rgb(194,165,207)","rgb(231,212,232)","rgb(217,240,211)","rgb(166,219,160)","rgb(90,174,97)","rgb(27,120,55)","rgb(0,68,27)"],11:["rgb(64,0,75)","rgb(118,42,131)","rgb(153,112,171)","rgb(194,165,207)","rgb(231,212,232)","rgb(247,247,247)","rgb(217,240,211)","rgb(166,219,160)","rgb(90,174,97)","rgb(27,120,55)","rgb(0,68,27)"]}, | |
PiYG:{3:["rgb(233,163,201)","rgb(247,247,247)","rgb(161,215,106)"],4:["rgb(208,28,139)","rgb(241,182,218)","rgb(184,225,134)","rgb(77,172,38)"],5:["rgb(208,28,139)","rgb(241,182,218)","rgb(247,247,247)","rgb(184,225,134)","rgb(77,172,38)"],6:["rgb(197,27,125)","rgb(233,163,201)","rgb(253,224,239)","rgb(230,245,208)","rgb(161,215,106)","rgb(77,146,33)"],7:["rgb(197,27,125)","rgb(233,163,201)","rgb(253,224,239)","rgb(247,247,247)","rgb(230,245,208)","rgb(161,215,106)","rgb(77,146,33)"],8:["rgb(197,27,125)","rgb(222,119,174)","rgb(241,182,218)","rgb(253,224,239)","rgb(230,245,208)","rgb(184,225,134)","rgb(127,188,65)","rgb(77,146,33)"],9:["rgb(197,27,125)","rgb(222,119,174)","rgb(241,182,218)","rgb(253,224,239)","rgb(247,247,247)","rgb(230,245,208)","rgb(184,225,134)","rgb(127,188,65)","rgb(77,146,33)"],10:["rgb(142,1,82)","rgb(197,27,125)","rgb(222,119,174)","rgb(241,182,218)","rgb(253,224,239)","rgb(230,245,208)","rgb(184,225,134)","rgb(127,188,65)","rgb(77,146,33)","rgb(39,100,25)"],11:["rgb(142,1,82)","rgb(197,27,125)","rgb(222,119,174)","rgb(241,182,218)","rgb(253,224,239)","rgb(247,247,247)","rgb(230,245,208)","rgb(184,225,134)","rgb(127,188,65)","rgb(77,146,33)","rgb(39,100,25)"]}, | |
RdBu:{3:["rgb(239,138,98)","rgb(247,247,247)","rgb(103,169,207)"],4:["rgb(202,0,32)","rgb(244,165,130)","rgb(146,197,222)","rgb(5,113,176)"],5:["rgb(202,0,32)","rgb(244,165,130)","rgb(247,247,247)","rgb(146,197,222)","rgb(5,113,176)"],6:["rgb(178,24,43)","rgb(239,138,98)","rgb(253,219,199)","rgb(209,229,240)","rgb(103,169,207)","rgb(33,102,172)"],7:["rgb(178,24,43)","rgb(239,138,98)","rgb(253,219,199)","rgb(247,247,247)","rgb(209,229,240)","rgb(103,169,207)","rgb(33,102,172)"],8:["rgb(178,24,43)","rgb(214,96,77)","rgb(244,165,130)","rgb(253,219,199)","rgb(209,229,240)","rgb(146,197,222)","rgb(67,147,195)","rgb(33,102,172)"],9:["rgb(178,24,43)","rgb(214,96,77)","rgb(244,165,130)","rgb(253,219,199)","rgb(247,247,247)","rgb(209,229,240)","rgb(146,197,222)","rgb(67,147,195)","rgb(33,102,172)"],10:["rgb(103,0,31)","rgb(178,24,43)","rgb(214,96,77)","rgb(244,165,130)","rgb(253,219,199)","rgb(209,229,240)","rgb(146,197,222)","rgb(67,147,195)","rgb(33,102,172)","rgb(5,48,97)"],11:["rgb(103,0,31)","rgb(178,24,43)","rgb(214,96,77)","rgb(244,165,130)","rgb(253,219,199)","rgb(247,247,247)","rgb(209,229,240)","rgb(146,197,222)","rgb(67,147,195)","rgb(33,102,172)","rgb(5,48,97)"]}, | |
RdGy:{3:["rgb(239,138,98)","rgb(255,255,255)","rgb(153,153,153)"],4:["rgb(202,0,32)","rgb(244,165,130)","rgb(186,186,186)","rgb(64,64,64)"],5:["rgb(202,0,32)","rgb(244,165,130)","rgb(255,255,255)","rgb(186,186,186)","rgb(64,64,64)"],6:["rgb(178,24,43)","rgb(239,138,98)","rgb(253,219,199)","rgb(224,224,224)","rgb(153,153,153)","rgb(77,77,77)"],7:["rgb(178,24,43)","rgb(239,138,98)","rgb(253,219,199)","rgb(255,255,255)","rgb(224,224,224)","rgb(153,153,153)","rgb(77,77,77)"],8:["rgb(178,24,43)","rgb(214,96,77)","rgb(244,165,130)","rgb(253,219,199)","rgb(224,224,224)","rgb(186,186,186)","rgb(135,135,135)","rgb(77,77,77)"],9:["rgb(178,24,43)","rgb(214,96,77)","rgb(244,165,130)","rgb(253,219,199)","rgb(255,255,255)","rgb(224,224,224)","rgb(186,186,186)","rgb(135,135,135)","rgb(77,77,77)"],10:["rgb(103,0,31)","rgb(178,24,43)","rgb(214,96,77)","rgb(244,165,130)","rgb(253,219,199)","rgb(224,224,224)","rgb(186,186,186)","rgb(135,135,135)","rgb(77,77,77)","rgb(26,26,26)"],11:["rgb(103,0,31)","rgb(178,24,43)","rgb(214,96,77)","rgb(244,165,130)","rgb(253,219,199)","rgb(255,255,255)","rgb(224,224,224)","rgb(186,186,186)","rgb(135,135,135)","rgb(77,77,77)","rgb(26,26,26)"]}, | |
RdYlBu:{3:["rgb(252,141,89)","rgb(255,255,191)","rgb(145,191,219)"],4:["rgb(215,25,28)","rgb(253,174,97)","rgb(171,217,233)","rgb(44,123,182)"],5:["rgb(215,25,28)","rgb(253,174,97)","rgb(255,255,191)","rgb(171,217,233)","rgb(44,123,182)"],6:["rgb(215,48,39)","rgb(252,141,89)","rgb(254,224,144)","rgb(224,243,248)","rgb(145,191,219)","rgb(69,117,180)"],7:["rgb(215,48,39)","rgb(252,141,89)","rgb(254,224,144)","rgb(255,255,191)","rgb(224,243,248)","rgb(145,191,219)","rgb(69,117,180)"],8:["rgb(215,48,39)","rgb(244,109,67)","rgb(253,174,97)","rgb(254,224,144)","rgb(224,243,248)","rgb(171,217,233)","rgb(116,173,209)","rgb(69,117,180)"],9:["rgb(215,48,39)","rgb(244,109,67)","rgb(253,174,97)","rgb(254,224,144)","rgb(255,255,191)","rgb(224,243,248)","rgb(171,217,233)","rgb(116,173,209)","rgb(69,117,180)"],10:["rgb(165,0,38)","rgb(215,48,39)","rgb(244,109,67)","rgb(253,174,97)","rgb(254,224,144)","rgb(224,243,248)","rgb(171,217,233)","rgb(116,173,209)","rgb(69,117,180)","rgb(49,54,149)"],11:["rgb(165,0,38)","rgb(215,48,39)","rgb(244,109,67)","rgb(253,174,97)","rgb(254,224,144)","rgb(255,255,191)","rgb(224,243,248)","rgb(171,217,233)","rgb(116,173,209)","rgb(69,117,180)","rgb(49,54,149)"]}, | |
Spectral:{3:["rgb(252,141,89)","rgb(255,255,191)","rgb(153,213,148)"],4:["rgb(215,25,28)","rgb(253,174,97)","rgb(171,221,164)","rgb(43,131,186)"],5:["rgb(215,25,28)","rgb(253,174,97)","rgb(255,255,191)","rgb(171,221,164)","rgb(43,131,186)"],6:["rgb(213,62,79)","rgb(252,141,89)","rgb(254,224,139)","rgb(230,245,152)","rgb(153,213,148)","rgb(50,136,189)"],7:["rgb(213,62,79)","rgb(252,141,89)","rgb(254,224,139)","rgb(255,255,191)","rgb(230,245,152)","rgb(153,213,148)","rgb(50,136,189)"],8:["rgb(213,62,79)","rgb(244,109,67)","rgb(253,174,97)","rgb(254,224,139)","rgb(230,245,152)","rgb(171,221,164)","rgb(102,194,165)","rgb(50,136,189)"],9:["rgb(213,62,79)","rgb(244,109,67)","rgb(253,174,97)","rgb(254,224,139)","rgb(255,255,191)","rgb(230,245,152)","rgb(171,221,164)","rgb(102,194,165)","rgb(50,136,189)"],10:["rgb(158,1,66)","rgb(213,62,79)","rgb(244,109,67)","rgb(253,174,97)","rgb(254,224,139)","rgb(230,245,152)","rgb(171,221,164)","rgb(102,194,165)","rgb(50,136,189)","rgb(94,79,162)"],11:["rgb(158,1,66)","rgb(213,62,79)","rgb(244,109,67)","rgb(253,174,97)","rgb(254,224,139)","rgb(255,255,191)","rgb(230,245,152)","rgb(171,221,164)","rgb(102,194,165)","rgb(50,136,189)","rgb(94,79,162)"]}, | |
RdYlGn:{3:["rgb(252,141,89)","rgb(255,255,191)","rgb(145,207,96)"],4:["rgb(215,25,28)","rgb(253,174,97)","rgb(166,217,106)","rgb(26,150,65)"],5:["rgb(215,25,28)","rgb(253,174,97)","rgb(255,255,191)","rgb(166,217,106)","rgb(26,150,65)"],6:["rgb(215,48,39)","rgb(252,141,89)","rgb(254,224,139)","rgb(217,239,139)","rgb(145,207,96)","rgb(26,152,80)"],7:["rgb(215,48,39)","rgb(252,141,89)","rgb(254,224,139)","rgb(255,255,191)","rgb(217,239,139)","rgb(145,207,96)","rgb(26,152,80)"],8:["rgb(215,48,39)","rgb(244,109,67)","rgb(253,174,97)","rgb(254,224,139)","rgb(217,239,139)","rgb(166,217,106)","rgb(102,189,99)","rgb(26,152,80)"],9:["rgb(215,48,39)","rgb(244,109,67)","rgb(253,174,97)","rgb(254,224,139)","rgb(255,255,191)","rgb(217,239,139)","rgb(166,217,106)","rgb(102,189,99)","rgb(26,152,80)"],10:["rgb(165,0,38)","rgb(215,48,39)","rgb(244,109,67)","rgb(253,174,97)","rgb(254,224,139)","rgb(217,239,139)","rgb(166,217,106)","rgb(102,189,99)","rgb(26,152,80)","rgb(0,104,55)"],11:["rgb(165,0,38)","rgb(215,48,39)","rgb(244,109,67)","rgb(253,174,97)","rgb(254,224,139)","rgb(255,255,191)","rgb(217,239,139)","rgb(166,217,106)","rgb(102,189,99)","rgb(26,152,80)","rgb(0,104,55)"]}}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
!function() { | |
var topojson = { | |
version: "1.4.6", | |
mesh: mesh, | |
feature: featureOrCollection, | |
neighbors: neighbors, | |
presimplify: presimplify | |
}; | |
function merge(topology, arcs) { | |
var fragmentByStart = {}, | |
fragmentByEnd = {}; | |
arcs.forEach(function(i) { | |
var e = ends(i), | |
start = e[0], | |
end = e[1], | |
f, g; | |
if (f = fragmentByEnd[start]) { | |
delete fragmentByEnd[f.end]; | |
f.push(i); | |
f.end = end; | |
if (g = fragmentByStart[end]) { | |
delete fragmentByStart[g.start]; | |
var fg = g === f ? f : f.concat(g); | |
fragmentByStart[fg.start = f.start] = fragmentByEnd[fg.end = g.end] = fg; | |
} else if (g = fragmentByEnd[end]) { | |
delete fragmentByStart[g.start]; | |
delete fragmentByEnd[g.end]; | |
var fg = f.concat(g.map(function(i) { return ~i; }).reverse()); | |
fragmentByStart[fg.start = f.start] = fragmentByEnd[fg.end = g.start] = fg; | |
} else { | |
fragmentByStart[f.start] = fragmentByEnd[f.end] = f; | |
} | |
} else if (f = fragmentByStart[end]) { | |
delete fragmentByStart[f.start]; | |
f.unshift(i); | |
f.start = start; | |
if (g = fragmentByEnd[start]) { | |
delete fragmentByEnd[g.end]; | |
var gf = g === f ? f : g.concat(f); | |
fragmentByStart[gf.start = g.start] = fragmentByEnd[gf.end = f.end] = gf; | |
} else if (g = fragmentByStart[start]) { | |
delete fragmentByStart[g.start]; | |
delete fragmentByEnd[g.end]; | |
var gf = g.map(function(i) { return ~i; }).reverse().concat(f); | |
fragmentByStart[gf.start = g.end] = fragmentByEnd[gf.end = f.end] = gf; | |
} else { | |
fragmentByStart[f.start] = fragmentByEnd[f.end] = f; | |
} | |
} else if (f = fragmentByStart[start]) { | |
delete fragmentByStart[f.start]; | |
f.unshift(~i); | |
f.start = end; | |
if (g = fragmentByEnd[end]) { | |
delete fragmentByEnd[g.end]; | |
var gf = g === f ? f : g.concat(f); | |
fragmentByStart[gf.start = g.start] = fragmentByEnd[gf.end = f.end] = gf; | |
} else if (g = fragmentByStart[end]) { | |
delete fragmentByStart[g.start]; | |
delete fragmentByEnd[g.end]; | |
var gf = g.map(function(i) { return ~i; }).reverse().concat(f); | |
fragmentByStart[gf.start = g.end] = fragmentByEnd[gf.end = f.end] = gf; | |
} else { | |
fragmentByStart[f.start] = fragmentByEnd[f.end] = f; | |
} | |
} else if (f = fragmentByEnd[end]) { | |
delete fragmentByEnd[f.end]; | |
f.push(~i); | |
f.end = start; | |
if (g = fragmentByEnd[start]) { | |
delete fragmentByStart[g.start]; | |
var fg = g === f ? f : f.concat(g); | |
fragmentByStart[fg.start = f.start] = fragmentByEnd[fg.end = g.end] = fg; | |
} else if (g = fragmentByStart[start]) { | |
delete fragmentByStart[g.start]; | |
delete fragmentByEnd[g.end]; | |
var fg = f.concat(g.map(function(i) { return ~i; }).reverse()); | |
fragmentByStart[fg.start = f.start] = fragmentByEnd[fg.end = g.start] = fg; | |
} else { | |
fragmentByStart[f.start] = fragmentByEnd[f.end] = f; | |
} | |
} else { | |
f = [i]; | |
fragmentByStart[f.start = start] = fragmentByEnd[f.end = end] = f; | |
} | |
}); | |
function ends(i) { | |
var arc = topology.arcs[i], p0 = arc[0], p1 = [0, 0]; | |
arc.forEach(function(dp) { p1[0] += dp[0], p1[1] += dp[1]; }); | |
return [p0, p1]; | |
} | |
var fragments = []; | |
for (var k in fragmentByEnd) fragments.push(fragmentByEnd[k]); | |
return fragments; | |
} | |
function mesh(topology, o, filter) { | |
var arcs = []; | |
if (arguments.length > 1) { | |
var geomsByArc = [], | |
geom; | |
function arc(i) { | |
if (i < 0) i = ~i; | |
(geomsByArc[i] || (geomsByArc[i] = [])).push(geom); | |
} | |
function line(arcs) { | |
arcs.forEach(arc); | |
} | |
function polygon(arcs) { | |
arcs.forEach(line); | |
} | |
function geometry(o) { | |
if (o.type === "GeometryCollection") o.geometries.forEach(geometry); | |
else if (o.type in geometryType) { | |
geom = o; | |
geometryType[o.type](o.arcs); | |
} | |
} | |
var geometryType = { | |
LineString: line, | |
MultiLineString: polygon, | |
Polygon: polygon, | |
MultiPolygon: function(arcs) { arcs.forEach(polygon); } | |
}; | |
geometry(o); | |
geomsByArc.forEach(arguments.length < 3 | |
? function(geoms, i) { arcs.push(i); } | |
: function(geoms, i) { if (filter(geoms[0], geoms[geoms.length - 1])) arcs.push(i); }); | |
} else { | |
for (var i = 0, n = topology.arcs.length; i < n; ++i) arcs.push(i); | |
} | |
return object(topology, {type: "MultiLineString", arcs: merge(topology, arcs)}); | |
} | |
function featureOrCollection(topology, o) { | |
return o.type === "GeometryCollection" ? { | |
type: "FeatureCollection", | |
features: o.geometries.map(function(o) { return feature(topology, o); }) | |
} : feature(topology, o); | |
} | |
function feature(topology, o) { | |
var f = { | |
type: "Feature", | |
id: o.id, | |
properties: o.properties || {}, | |
geometry: object(topology, o) | |
}; | |
if (o.id == null) delete f.id; | |
return f; | |
} | |
function object(topology, o) { | |
var absolute = transformAbsolute(topology.transform), | |
arcs = topology.arcs; | |
function arc(i, points) { | |
if (points.length) points.pop(); | |
for (var a = arcs[i < 0 ? ~i : i], k = 0, n = a.length, p; k < n; ++k) { | |
points.push(p = a[k].slice()); | |
absolute(p, k); | |
} | |
if (i < 0) reverse(points, n); | |
} | |
function point(p) { | |
p = p.slice(); | |
absolute(p, 0); | |
return p; | |
} | |
function line(arcs) { | |
var points = []; | |
for (var i = 0, n = arcs.length; i < n; ++i) arc(arcs[i], points); | |
if (points.length < 2) points.push(points[0].slice()); | |
return points; | |
} | |
function ring(arcs) { | |
var points = line(arcs); | |
while (points.length < 4) points.push(points[0].slice()); | |
return points; | |
} | |
function polygon(arcs) { | |
return arcs.map(ring); | |
} | |
function geometry(o) { | |
var t = o.type; | |
return t === "GeometryCollection" ? {type: t, geometries: o.geometries.map(geometry)} | |
: t in geometryType ? {type: t, coordinates: geometryType[t](o)} | |
: null; | |
} | |
var geometryType = { | |
Point: function(o) { return point(o.coordinates); }, | |
MultiPoint: function(o) { return o.coordinates.map(point); }, | |
LineString: function(o) { return line(o.arcs); }, | |
MultiLineString: function(o) { return o.arcs.map(line); }, | |
Polygon: function(o) { return polygon(o.arcs); }, | |
MultiPolygon: function(o) { return o.arcs.map(polygon); } | |
}; | |
return geometry(o); | |
} | |
function reverse(array, n) { | |
var t, j = array.length, i = j - n; while (i < --j) t = array[i], array[i++] = array[j], array[j] = t; | |
} | |
function bisect(a, x) { | |
var lo = 0, hi = a.length; | |
while (lo < hi) { | |
var mid = lo + hi >>> 1; | |
if (a[mid] < x) lo = mid + 1; | |
else hi = mid; | |
} | |
return lo; | |
} | |
function neighbors(objects) { | |
var indexesByArc = {}, // arc index -> array of object indexes | |
neighbors = objects.map(function() { return []; }); | |
function line(arcs, i) { | |
arcs.forEach(function(a) { | |
if (a < 0) a = ~a; | |
var o = indexesByArc[a]; | |
if (o) o.push(i); | |
else indexesByArc[a] = [i]; | |
}); | |
} | |
function polygon(arcs, i) { | |
arcs.forEach(function(arc) { line(arc, i); }); | |
} | |
function geometry(o, i) { | |
if (o.type === "GeometryCollection") o.geometries.forEach(function(o) { geometry(o, i); }); | |
else if (o.type in geometryType) geometryType[o.type](o.arcs, i); | |
} | |
var geometryType = { | |
LineString: line, | |
MultiLineString: polygon, | |
Polygon: polygon, | |
MultiPolygon: function(arcs, i) { arcs.forEach(function(arc) { polygon(arc, i); }); } | |
}; | |
objects.forEach(geometry); | |
for (var i in indexesByArc) { | |
for (var indexes = indexesByArc[i], m = indexes.length, j = 0; j < m; ++j) { | |
for (var k = j + 1; k < m; ++k) { | |
var ij = indexes[j], ik = indexes[k], n; | |
if ((n = neighbors[ij])[i = bisect(n, ik)] !== ik) n.splice(i, 0, ik); | |
if ((n = neighbors[ik])[i = bisect(n, ij)] !== ij) n.splice(i, 0, ij); | |
} | |
} | |
} | |
return neighbors; | |
} | |
function presimplify(topology, triangleArea) { | |
var absolute = transformAbsolute(topology.transform), | |
relative = transformRelative(topology.transform), | |
heap = minHeap(compareArea), | |
maxArea = 0, | |
triangle; | |
if (!triangleArea) triangleArea = cartesianArea; | |
topology.arcs.forEach(function(arc) { | |
var triangles = []; | |
arc.forEach(absolute); | |
for (var i = 1, n = arc.length - 1; i < n; ++i) { | |
triangle = arc.slice(i - 1, i + 2); | |
triangle[1][2] = triangleArea(triangle); | |
triangles.push(triangle); | |
heap.push(triangle); | |
} | |
// Always keep the arc endpoints! | |
arc[0][2] = arc[n][2] = Infinity; | |
for (var i = 0, n = triangles.length; i < n; ++i) { | |
triangle = triangles[i]; | |
triangle.previous = triangles[i - 1]; | |
triangle.next = triangles[i + 1]; | |
} | |
}); | |
while (triangle = heap.pop()) { | |
var previous = triangle.previous, | |
next = triangle.next; | |
// If the area of the current point is less than that of the previous point | |
// to be eliminated, use the latter's area instead. This ensures that the | |
// current point cannot be eliminated without eliminating previously- | |
// eliminated points. | |
if (triangle[1][2] < maxArea) triangle[1][2] = maxArea; | |
else maxArea = triangle[1][2]; | |
if (previous) { | |
previous.next = next; | |
previous[2] = triangle[2]; | |
update(previous); | |
} | |
if (next) { | |
next.previous = previous; | |
next[0] = triangle[0]; | |
update(next); | |
} | |
} | |
topology.arcs.forEach(function(arc) { | |
arc.forEach(relative); | |
}); | |
function update(triangle) { | |
heap.remove(triangle); | |
triangle[1][2] = triangleArea(triangle); | |
heap.push(triangle); | |
} | |
return topology; | |
}; | |
function cartesianArea(triangle) { | |
return Math.abs( | |
(triangle[0][0] - triangle[2][0]) * (triangle[1][1] - triangle[0][1]) | |
- (triangle[0][0] - triangle[1][0]) * (triangle[2][1] - triangle[0][1]) | |
); | |
} | |
function compareArea(a, b) { | |
return a[1][2] - b[1][2]; | |
} | |
function minHeap(compare) { | |
var heap = {}, | |
array = []; | |
heap.push = function() { | |
for (var i = 0, n = arguments.length; i < n; ++i) { | |
var object = arguments[i]; | |
up(object.index = array.push(object) - 1); | |
} | |
return array.length; | |
}; | |
heap.pop = function() { | |
var removed = array[0], | |
object = array.pop(); | |
if (array.length) { | |
array[object.index = 0] = object; | |
down(0); | |
} | |
return removed; | |
}; | |
heap.remove = function(removed) { | |
var i = removed.index, | |
object = array.pop(); | |
if (i !== array.length) { | |
array[object.index = i] = object; | |
(compare(object, removed) < 0 ? up : down)(i); | |
} | |
return i; | |
}; | |
function up(i) { | |
var object = array[i]; | |
while (i > 0) { | |
var up = ((i + 1) >> 1) - 1, | |
parent = array[up]; | |
if (compare(object, parent) >= 0) break; | |
array[parent.index = i] = parent; | |
array[object.index = i = up] = object; | |
} | |
} | |
function down(i) { | |
var object = array[i]; | |
while (true) { | |
var right = (i + 1) << 1, | |
left = right - 1, | |
down = i, | |
child = array[down]; | |
if (left < array.length && compare(array[left], child) < 0) child = array[down = left]; | |
if (right < array.length && compare(array[right], child) < 0) child = array[down = right]; | |
if (down === i) break; | |
array[child.index = i] = child; | |
array[object.index = i = down] = object; | |
} | |
} | |
return heap; | |
} | |
function transformAbsolute(transform) { | |
if (!transform) return noop; | |
var x0, | |
y0, | |
kx = transform.scale[0], | |
ky = transform.scale[1], | |
dx = transform.translate[0], | |
dy = transform.translate[1]; | |
return function(point, i) { | |
if (!i) x0 = y0 = 0; | |
point[0] = (x0 += point[0]) * kx + dx; | |
point[1] = (y0 += point[1]) * ky + dy; | |
}; | |
} | |
function transformRelative(transform) { | |
if (!transform) return noop; | |
var x0, | |
y0, | |
kx = transform.scale[0], | |
ky = transform.scale[1], | |
dx = transform.translate[0], | |
dy = transform.translate[1]; | |
return function(point, i) { | |
if (!i) x0 = y0 = 0; | |
var x1 = (point[0] - dx) / kx | 0, | |
y1 = (point[1] - dy) / ky | 0; | |
point[0] = x1 - x0; | |
point[1] = y1 - y0; | |
x0 = x1; | |
y0 = y1; | |
}; | |
} | |
function noop() {} | |
if (typeof define === "function" && define.amd) define(topojson); | |
else if (typeof module === "object" && module.exports) module.exports = topojson; | |
else this.topojson = topojson; | |
}(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment