Last active
January 23, 2020 07:30
-
-
Save Alex-Devoid/090691fe85351ebc8eefb0f21515fc2d to your computer and use it in GitHub Desktop.
A viz of all the "remain in Mexico" (MPP) asylum cases.
This file contains hidden or 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
<head> | |
<title>Moving Bubble Tutorial</title> | |
<link rel="stylesheet" href="style/style.css" type="text/css" media="screen" /> | |
<meta charset="utf-8"> | |
</head> | |
<body> | |
<div id="main-wrapper"> | |
<div id="chart"></div> | |
</div> | |
<script src="//d3js.org/d3.v4.min.js"></script> | |
<script> | |
var margin = {top: 16, right: 0, bottom: 0, left: 0}, | |
width = 950 - margin.left - margin.right, | |
height = 700 - margin.top - margin.bottom; | |
var node_radius = 5, | |
padding = 1, | |
cluster_padding = 10, | |
num_nodes = 200; | |
var svg = d3.select("#chart").append("svg") | |
.attr("width", width + margin.left + margin.right) | |
.attr("height", height + margin.top + margin.bottom) | |
.append("g") | |
.attr("transform", "translate(" + margin.left + "," + margin.top + ")"); | |
var mexico; | |
var usa; | |
var usa1; | |
var ven; | |
var canada; | |
var geoMercator = d3.geoMercator() | |
var path = d3.geoPath().projection(d3.geoMercator()); | |
d3.json("110_admin.geojson", function(error, world) { | |
if (error) throw error; | |
d3.csv("mpp_courts_d3_texas.csv", function(errorData, mppData) { | |
if (errorData) throw errorData; | |
var lookup = {}; | |
var sourceCountries = []; | |
//https://stackoverflow.com/questions/17780508/selecting-distinct-values-from-a-json | |
for (var item, i = 0; item = mppData[i++];) { | |
var country = item.source; | |
if (!(country in lookup)) { | |
lookup[country] = 1; | |
sourceCountries.push(country); | |
} | |
} | |
var destinations = | |
[{ | |
name:'elPaso', | |
type: "Point", | |
coordinates: [-97.745015,26.020156], | |
}, | |
{ | |
name:'sanDiego', | |
type: "Point", | |
coordinates: [-117.035644,32.534302], | |
}, | |
{ | |
name:'Texas', | |
type: "Point", | |
coordinates: [-99.533056,27.455729], | |
}] | |
for (var i = 0; i < destinations.length; i++) { | |
destinations[i].point = geoMercator(destinations[i].coordinates) | |
} | |
console.log(sourceCountries) | |
var data1 = [] | |
for (var i = 0; i < world.features.length; i++) { | |
for (var b = 0; b < sourceCountries.length; b++) { | |
if (world.features[i].properties.SOVEREIGNT === sourceCountries[b]){ | |
data1.push({ | |
"class": `${world.features[i].properties.SOVEREIGNT}_${destinations[0].name}`, | |
"source": { | |
"lat": path.centroid(world.features[i])[1], | |
"lon": path.centroid(world.features[i])[0] | |
}, | |
"destination": { | |
"lat": destinations[0].point[1], | |
"lon": destinations[0].point[0] | |
} | |
}, | |
{ | |
"class": `${world.features[i].properties.SOVEREIGNT}_${destinations[1].name}`, | |
"source": { | |
"lat": path.centroid(world.features[i])[1], | |
"lon": path.centroid(world.features[i])[0] | |
}, | |
"destination": { | |
"lat": destinations[1].point[1], | |
"lon": destinations[1].point[0] | |
} | |
}, | |
{ | |
"class": `${world.features[i].properties.SOVEREIGNT}_${destinations[2].name}`, | |
"source": { | |
"lat": path.centroid(world.features[i])[1], | |
"lon": path.centroid(world.features[i])[0] | |
}, | |
"destination": { | |
"lat": destinations[2].point[1], | |
"lon": destinations[2].point[0] | |
} | |
} | |
) | |
} | |
} | |
} | |
svg.selectAll("path") | |
.data(world.features) | |
.enter().append("path") | |
.attr("fill", "grey") | |
.attr("d", path); | |
var projection = d3.geoMercator(); | |
var curve = function(context) { | |
var custom = d3.curveLinear(context); | |
custom._context = context; | |
custom.point = function(x,y) { | |
x = +x, y = +y; | |
switch (this._point) { | |
case 0: this._point = 1; | |
this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); | |
this.x0 = x; this.y0 = y; | |
break; | |
case 1: this._point = 2; | |
default: | |
var x1 = this.x0 * 0.5 + x * 0.5; | |
var y1 = this.y0 * 0.5 + y * 0.5; | |
var m = 1/(y1 - y)/(x1 - x); | |
var r = -100; // offset of mid point. | |
var k = r / Math.sqrt(1 + (m*m) ); | |
if (m == Infinity) { | |
y1 += r; | |
} | |
else { | |
y1 += k; | |
x1 += m*k; | |
} | |
this._context.quadraticCurveTo(x1,y1,x,y); | |
this.x0 = x; this.y0 = y; | |
break; | |
} | |
} | |
return custom; | |
} | |
var line = d3.line() | |
.x(function(d) { | |
return d.lon; | |
}) | |
.y(function(d) { | |
return d.lat; | |
}) | |
.curve(curve); | |
var route = svg.selectAll(null) | |
.data(data1) | |
.enter() | |
.append("path") | |
.attr("class", function(d){ | |
return d.class | |
}) | |
.datum(function(d) { | |
return [d.source,d.destination]; | |
}) | |
.attr("d",line) | |
.attr("fill", "none") | |
.style("stroke","black") | |
.style("stroke-width",1.5) | |
//Everything runs smoothly when I use this very small test dataset. | |
// var testData = [{ | |
// | |
// "source": "Honduras", | |
// "January": "10", | |
// "February": "5", | |
// "March": "10", | |
// "April": "0", | |
// "May": "10", | |
// "June": "10", | |
// "July": "10", | |
// "August": "10", | |
// "September": "10", | |
// "October": "10", | |
// "November": "10", | |
// "destination": "Texas" | |
// }, | |
// { | |
// | |
// "source": "Venezuela", | |
// "January": "5", | |
// "February": "10", | |
// "March": "5", | |
// "April": "10", | |
// "May": "10", | |
// "June": "10", | |
// "July": "10", | |
// "August": "10", | |
// "September": "10", | |
// "October": "10", | |
// "November": "10", | |
// "destination": "Texas" | |
// }] | |
// **** this chunck is wrangling the csv into distinct datapoints | |
var months =["January","February","March","April","May", "June","July","August","September","October","November"] | |
function sumKey(bills,key){ | |
//https://stackoverflow.com/questions/44436041/how-to-sum-value-of-two-json-object-key | |
var res = bills.map(bill => Number(bill[key])).reduce((acc, bill) => bill + acc); | |
return res | |
} | |
function getMax(arr, prop) { | |
var max; | |
for (var i=0 ; i<arr.length ; i++) { | |
if (max == null || parseInt(arr[i][prop]) > parseInt(max[prop])) | |
max = arr[i]; | |
} | |
return max; | |
} | |
var newTestArray = []; | |
console.log(mppData); | |
maxMonthArray = [] | |
for (var b = 0; b < months.length; b++) { | |
var maxMonth = getMax(mppData, months[b]); | |
maxMonthArray.push(maxMonth[months[b]]) | |
for (var i = 0; i < mppData.length; i++) { | |
for (var a = 0; a < Number(mppData[i][months[b]]); a++) { | |
newTestArray.push({ | |
"id": a, | |
"source": mppData[i].source, | |
"destination": mppData[i].destination, | |
'month': b | |
}) | |
} | |
} | |
} | |
// console.log(nodesAt); | |
console.log(newTestArray); | |
var multiCircles = svg.selectAll(".circle") | |
.data(newTestArray) | |
.enter().append("circle") | |
.attr("class", function(d,i){ | |
// console.log(d); | |
return `c_${d.month}_${d.id}`}) | |
.attr("r", function(d){ | |
return 6; | |
}) | |
.attr("fill", function(d){ | |
return 'red'; | |
}) | |
//https://stackoverflow.com/questions/1230233/how-to-find-the-sum-of-an-array-of-numbers | |
var sumMaxMonths = maxMonthArray.reduce(function(acc, val) { return Number(acc) + Number(val) }, 0); | |
console.log(sumMaxMonths) | |
//count twords the sum of the max values in each month | |
var counter = -1; | |
//migrants in a month | |
var a = -1; | |
// months | |
var m = 0; | |
//This loop transitions the circles along the correct path elements | |
(function loop() { | |
//newTestArray.length | |
if (counter++ > sumMaxMonths ) return; | |
setTimeout(function() { | |
if (m < 11) { | |
if (a++ > maxMonthArray[m]-1) { | |
m++ | |
a = 0 | |
} | |
} | |
var thisPolygon = d3.selectAll(`.c_${m}_${a}`) | |
transition1( thisPolygon, counter); | |
loop() | |
}, 300) | |
}()); | |
function transition1(elem,i) { | |
elem.transition() | |
.duration(3000) | |
.attrTween("transform", translateAlong()) | |
// Returns an attrTween for translating along the specified path element. | |
function translateAlong(path1) { | |
return function(d, i, a) { | |
// console.log(`.${d.source}_${d.destination}`); | |
var path = d3.select(`.${d.source}_${d.destination}`).node(); | |
var l = path.getTotalLength(); | |
var t0 = 0; | |
return function(t) { | |
var p0 = path.getPointAtLength(t0 * l); //previous point | |
var p = path.getPointAtLength(t * l); //current point | |
var angle = Math.atan2(p.y - p0.y, p.x - p0.x) * 180 / Math.PI; //angle for tangent | |
t0 = t; | |
//Shifting center to center of arrow | |
// xoffset and yoffset should be half the original width and height | |
var xoffset = 0, | |
yoffset = 0; | |
var centerX = p.x - xoffset; | |
var centerY = p.y - yoffset; | |
return "translate(" + centerX + "," + centerY + ")rotate(" + angle + " " + xoffset + " " + yoffset + ")"; | |
}; | |
}; | |
} | |
} | |
}); | |
}); | |
</script> | |
</body> |
This file contains hidden or 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
source | January | February | March | April | May | June | July | August | September | October | November | destination | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Argentina | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 2 | 0 | 0 | Texas | |
Belize | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | elPaso | |
Belize | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | Texas | |
Belize | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 4 | 0 | 1 | Texas | |
Bolivia | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | Texas | |
Bolivia | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 2 | 0 | Texas | |
Brazil | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | elPaso | |
Brazil | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 3 | 1 | 0 | Texas | |
Brazil | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | sanDiego | |
Chile | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 2 | 0 | elPaso | |
Chile | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | Texas | |
Chile | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 2 | 0 | 0 | Texas | |
Chile | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | sanDiego | |
Colombia | 0 | 0 | 0 | 0 | 0 | 2 | 6 | 3 | 15 | 6 | 3 | elPaso | |
Colombia | 0 | 0 | 0 | 0 | 0 | 0 | 5 | 4 | 5 | 3 | 7 | Texas | |
Colombia | 0 | 0 | 0 | 0 | 0 | 0 | 4 | 6 | 2 | 3 | 5 | Texas | |
Colombia | 0 | 0 | 0 | 0 | 0 | 6 | 11 | 8 | 3 | 0 | 2 | sanDiego | |
Congo | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | Texas | |
Costa Rica | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 0 | 0 | 0 | elPaso | |
Costa Rica | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 2 | 1 | Texas | |
Costa Rica | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 2 | 1 | 0 | Texas | |
Croatia | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | elPaso | |
Cuba | 0 | 0 | 1 | 0 | 4 | 892 | 1002 | 503 | 298 | 326 | 370 | elPaso | |
Cuba | 0 | 0 | 0 | 0 | 0 | 0 | 272 | 867 | 735 | 554 | 85 | Texas | |
Cuba | 0 | 0 | 0 | 0 | 0 | 2 | 384 | 419 | 125 | 63 | 44 | Texas | |
Cuba | 0 | 0 | 0 | 0 | 0 | 38 | 69 | 55 | 63 | 39 | 32 | sanDiego | |
Cyprus | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | elPaso | |
Cyprus | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | Texas | |
Dominican Republic | 0 | 0 | 0 | 0 | 0 | 0 | 3 | 2 | 1 | 0 | 0 | Texas | |
Dominican Republic | 0 | 0 | 0 | 0 | 0 | 0 | 7 | 10 | 4 | 1 | 0 | Texas | |
Ecuador | 0 | 0 | 0 | 0 | 0 | 204 | 290 | 180 | 188 | 1 | 204 | elPaso | |
Ecuador | 0 | 0 | 0 | 0 | 0 | 0 | 13 | 76 | 150 | 2 | 1 | Texas | |
Ecuador | 0 | 0 | 0 | 0 | 0 | 0 | 117 | 98 | 195 | 109 | 61 | Texas | |
Ecuador | 0 | 0 | 0 | 2 | 4 | 41 | 69 | 35 | 37 | 10 | 23 | sanDiego | |
Egypt | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 207 | 0 | elPaso | |
Egypt | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 116 | 104 | Texas | |
El-Salvador | 0 | 0 | 11 | 206 | 391 | 466 | 374 | 311 | 204 | 86 | 56 | elPaso | |
El-Salvador | 0 | 0 | 0 | 0 | 0 | 0 | 236 | 866 | 607 | 376 | 0 | Texas | |
El-Salvador | 0 | 0 | 0 | 0 | 0 | 0 | 448 | 525 | 295 | 121 | 73 | Texas | |
El-Salvador | 1 | 38 | 46 | 203 | 347 | 189 | 131 | 122 | 102 | 63 | 45 | sanDiego | |
Gabon | 0 | 0 | 0 | 0 | 0 | 2 | 0 | 0 | 0 | 0 | 0 | elPaso | |
Gabon | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 290 | Texas | |
Guadeloupe | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | 0 | elPaso | |
Guadeloupe | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | Texas | |
Guadeloupe | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | Texas | |
Guadeloupe | 0 | 0 | 0 | 0 | 2 | 3 | 2 | 0 | 0 | 0 | 0 | sanDiego | |
Guatemala | 0 | 0 | 17 | 538 | 1084 | 831 | 745 | 798 | 235 | 127 | 156 | elPaso | |
Guatemala | 0 | 0 | 0 | 0 | 0 | 0 | 179 | 2013 | 424 | 256 | 252 | Texas | |
Guatemala | 0 | 0 | 0 | 0 | 0 | 0 | 689 | 392 | 320 | 78 | 59 | Texas | |
Guatemala | 1 | 32 | 62 | 674 | 1497 | 1260 | 1551 | 699 | 175 | 104 | 146 | sanDiego | |
Guinea | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | elPaso | |
Guinea | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | Texas | |
Guyana | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | Texas | |
Haiti | 0 | 0 | 0 | 0 | 0 | 2 | 0 | 0 | 0 | 0 | 0 | sanDiego | |
Holland | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | elPaso | |
Holland | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 2 | Texas | |
Holland | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | Texas | |
Holland | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | sanDiego | |
Honduras | 0 | 0 | 15 | 363 | 695 | 812 | 1198 | 804 | 436 | 253 | 224 | elPaso | |
Honduras | 0 | 0 | 0 | 0 | 1 | 0 | 493 | 0 | 1983 | 699 | 488 | Texas | |
Honduras | 0 | 2 | 2 | 6 | 2 | 0 | 1109 | 1516 | 1350 | 761 | 436 | Texas | |
Honduras | 12 | 70 | 77 | 494 | 949 | 892 | 1430 | 502 | 216 | 164 | 134 | sanDiego | |
Hong Kong | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | Texas | |
Hong Kong | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | Texas | |
Hong Kong | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | sanDiego | |
Laos | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | Texas | |
Macedonia | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | Texas | |
Malawi | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | Texas | |
Mexico | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 4 | 3 | 2 | 1 | elPaso | |
Mexico | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 5 | 3 | 0 | 2 | Texas | |
Mexico | 0 | 0 | 0 | 1 | 0 | 0 | 4 | 4 | 1 | 5 | 2 | Texas | |
Mexico | 0 | 0 | 0 | 4 | 3 | 2 | 12 | 2 | 1 | 2 | 0 | sanDiego | |
Namibia | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | elPaso | |
Namibia | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | Texas | |
Namibia | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | sanDiego | |
Nicaragua | 0 | 0 | 0 | 0 | 0 | 95 | 47 | 49 | 19 | 36 | 8 | elPaso | |
Nicaragua | 0 | 0 | 0 | 0 | 0 | 0 | 44 | 145 | 161 | 54 | 73 | Texas | |
Nicaragua | 0 | 0 | 0 | 0 | 0 | 0 | 104 | 88 | 47 | 22 | 18 | Texas | |
Nicaragua | 0 | 0 | 0 | 1 | 3 | 39 | 91 | 60 | 15 | 10 | 19 | sanDiego | |
Oman | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | Texas | |
Oman | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | sanDiego | |
Panama | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 2 | 0 | elPaso | |
Panama | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 1 | Texas | |
Panama | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | sanDiego | |
Paraguay | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | Texas | |
Peru | 0 | 0 | 0 | 0 | 0 | 3 | 5 | 4 | 5 | 5 | 5 | elPaso | |
Peru | 0 | 0 | 0 | 0 | 0 | 0 | 5 | 16 | 6 | 8 | 2 | Texas | |
Peru | 0 | 0 | 0 | 0 | 0 | 0 | 2 | 6 | 3 | 10 | 5 | Texas | |
Peru | 0 | 0 | 0 | 0 | 0 | 3 | 4 | 8 | 2 | 0 | 0 | sanDiego | |
San Marino | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | sanDiego | |
Spain | 0 | 0 | 0 | 0 | 0 | 0 | 2 | 1 | 0 | 1 | 0 | elPaso | |
Spain | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 3 | 1 | 0 | Texas | |
Spain | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | Texas | |
Sudan | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | sanDiego | |
Uruguay | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 3 | 0 | 0 | elPaso | |
Uruguay | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | Texas | |
Vanuatu | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | Texas | |
Venezuela | 0 | 0 | 0 | 0 | 0 | 26 | 55 | 36 | 27 | 66 | 26 | elPaso | |
Venezuela | 0 | 0 | 0 | 0 | 0 | 0 | 86 | 164 | 146 | 78 | 32 | Texas | |
Venezuela | 0 | 0 | 0 | 0 | 0 | 0 | 191 | 170 | 166 | 180 | 195 | Texas | |
Venezuela | 0 | 0 | 0 | 0 | 0 | 17 | 35 | 26 | 51 | 24 | 24 | sanDiego |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment