Last active
March 14, 2018 19:58
-
-
Save Mbrownshoes/5e36771400038b0c861c6617c622c5f7 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
gistup |
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> | |
<met charset="utf-8"> | |
<meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1"> | |
<!-- <script type="text/javascript" src="https://unipear.api.gov.bc.ca/v1/bcgov/"></script> | |
<script type="text/javascript"> | |
unippear({ | |
"headerContainer": "#wrapper", | |
"footerContainer": "#wrapper" | |
}); | |
</script> --> | |
<!-- Latest compiled and minified CSS --> | |
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/bootstrap-table/1.11.0/bootstrap-table.min.css"> | |
<!-- Optional theme --> | |
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css"> | |
<script src="https://code.jquery.com/jquery-3.1.1.min.js" integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8=" crossorigin="anonymous"></script> | |
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css"> | |
<!-- Latest compiled and minified CSS --> | |
<!-- <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css"> --> | |
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script> | |
<script src="//cdnjs.cloudflare.com/ajax/libs/bootstrap-table/1.11.0/bootstrap-table.min.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-table/1.11.0/extensions/filter-control/bootstrap-table-filter-control.js"></script> | |
<style> | |
#map { | |
/* width: 960px; | |
height: 600px;*/ | |
background: #fff; | |
margin-top: 40px; | |
} | |
:root { | |
--accent-color: #E8336D; | |
} | |
#provinces { | |
fill: #ddd; | |
cursor: pointer; | |
} | |
#label{ | |
font-size: 20px; | |
/*color: white;*/ | |
text-align: left; | |
} | |
#prov-borders { | |
stroke: #fff; | |
stroke-linejoin: round; | |
} | |
.bubble { | |
/*opacity: 1;*/ | |
/*stroke: #fff;*/ | |
stroke-width: .1px; | |
/*z-index: 1000;*/ | |
} | |
.route { | |
fill: none; | |
/*stroke: #000;*/ | |
/*stroke-width: 3px;*/ | |
/*stroke-linecap: round;*/ | |
/*opacity: 1;*/ | |
/*stroke-dasharray: 12,8,4,8/*;*/ | |
} | |
.annotation path { | |
stroke: var(--accent-color); | |
fill: none; | |
} | |
.annotation path.connector-arrow{ | |
fill: var(--accent-color); | |
} | |
.annotation text { | |
fill: var(--accent-color); | |
} | |
.annotation-note-title { | |
font-weight: bold; | |
} | |
.tooltip { | |
position: absolute; | |
display: none; | |
min-width: 80px; | |
height: auto; | |
background: none repeat scroll 0 0 #ffffff; | |
border: 1px solid #6F257F; | |
padding: 14px; | |
text-align: center; | |
} | |
#arrow{ | |
marker: 'red'; | |
} | |
</style> | |
<body> | |
<script src="//d3js.org/d3.v4.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/topojson/1.6.19/topojson.min.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script> | |
<script src="http://d3js.org/queue.v1.min.js"></script> | |
<script src="d3-annotation.min.js"></script> | |
<div id="wrapper" class="hfeed"> | |
<div class="container"> | |
<!-- <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="960" height="500"> --> | |
<!-- <defs> | |
<path id="arrow" d="M-5,0 L-15,15 L15,0 L-15,-15 Z"/> | |
</defs> --> | |
<!-- </svg> --> | |
<!-- <div class="col-lg-8"> | |
<select id="year"> | |
<option value="2017 Q2" selected>2017 Q2</option> | |
</select> | |
</div> --> | |
<div id="nav-container"> | |
<!-- <div class="nav left">left</div> --> | |
<div id="yearDropdown"></div> | |
<!-- <div class="nav right">right</div> --> | |
</div> | |
<div class="map" id="map"></div> | |
<div class="col-md-12"> | |
</div> | |
</div> | |
</div> | |
<script src="main.js"></script> | |
<!-- <script> | |
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
margin = { | |
top: 20, | |
right: 20, | |
bottom: 30, | |
left: 50 | |
}; | |
var width = 960, | |
height = 500 | |
var projection = d3.geoConicConformal() | |
.rotate([98, 0]) | |
.center([0, 60]) | |
.parallels([-10, 85.5]) | |
.scale(1400) | |
var svg = d3.select(".map") | |
.append("svg") | |
.attr("width", width) | |
.attr("height", height); | |
var path = d3.geoPath() | |
.projection(projection); | |
var line_path = d3.geoPath() | |
.projection(null); | |
var radius = d3.scaleSqrt() | |
.domain([0, 3600]) | |
.range([0, 50]); | |
var line_size = d3.scaleLinear() | |
.domain([32, 14103]) | |
.range([2, 30]) | |
var migration, test, net; | |
var line_data = []; | |
g = svg.append("g") | |
var defs = svg.append('svg:defs'); | |
defs.append('svg:marker') | |
.attr('id', 'end-arrow') | |
.attr('viewBox', '0 -5 10 10') | |
.attr('refX', 0) | |
.attr('refY', 0) | |
.attr('stroke', 'none') | |
.attr('markerWidth', 9) | |
.attr('markerHeight', 3) | |
.attr("markerUnits", "strokeWidth") | |
.attr('orient', 'auto') | |
.append('svg:path') | |
.attr('d', 'M0,-5L10,0L0,5') | |
.attr('fill', '#3f51b5'); | |
var defs = svg.append('svg:defs'); | |
defs.append('svg:marker') | |
.attr('id', 'end-arrow-neg') | |
.attr('stroke', 'none') | |
.attr('viewBox', '0 -5 10 10') | |
.attr('refX', 0) | |
.attr('refY', 0) | |
.attr('markerWidth', 9) | |
.attr('markerHeight', 3) | |
.attr("markerUnits", "strokeWidth") | |
.attr('orient', 'auto') | |
.append('svg:path') | |
.attr('d', 'M0,-5L10,0L0,5') | |
.attr('fill', '#D32F2F'); | |
// https://stackoverflow.com/questions/11121465/scaling-an-arrowhead-on-a-d3-force-layout-link-marker | |
// svg.append("defs").append("pattern") | |
// .attr('id','myPattern') | |
// .attr('markerWidth', 16) | |
// .attr('markerHeight', 16) | |
// .attr('patternUnits',"userSpaceOnUse") | |
// .append('path') | |
// .attr('fill','none') | |
// .attr('stroke','#335553') | |
// .attr('stroke-width','3') | |
// .attr('d','M-5,0 L-15,15 L15,0 L-15,-15 Z'); | |
d3.json("can_no_projs.json", function(error, canada) { | |
if (error) throw error; | |
g.append("g") | |
.attr("id", "provinces") | |
.selectAll("path") | |
.data(topojson.feature(canada, canada.objects.cangeo).features) | |
.enter() | |
.append("path") | |
.attr("d", path) | |
.attr("id", "prov-borders") | |
.attr('fill', function(d) { | |
if (d.properties.PRENAME == 'British Columbia') { | |
return 'orange' | |
} | |
// console.log(d.properties.PRENAME) | |
}) | |
tot = 0 | |
var int, alldata, yearMenu; | |
var currYear = '2017 Q2' | |
d3.csv("Quarterly_2017.csv", function(error, dat) { | |
test = dat | |
alldata = dat | |
var yr = d3.map(alldata, function(d) { | |
return d.time_period; | |
}).keys() | |
// console.log(yr) | |
// yr.forEach(function(d){ | |
// var option = $('<option />').text(d); | |
// $("#year").append(option); | |
// }) | |
yearMenu = d3.select("#yearDropdown"); | |
yearMenu | |
.append("select") | |
.attr("id", "locationMenu") | |
.selectAll("option") | |
.data(yr) | |
.enter() | |
.append("option") | |
.attr("value", function(d, i) { | |
return d; | |
}) | |
.text(function(d) { | |
return d; | |
}); | |
// migration = alldata.filter(function(d) { | |
// return d.time_period == currYear; | |
// }) | |
update(alldata, currYear); | |
}) | |
function update(migration, currYear) { | |
migration = alldata.filter(function(d) { | |
return d.time_period == currYear; | |
}) | |
d3.selectAll('.route').remove() | |
d3.selectAll('.annotation-group').remove() | |
// $('#orders-table').bootstrapTable("destroy"); | |
migration.forEach(function(d) { | |
d.net = Number(d.Origin) - Number(d.Destination) | |
if (d.Province != 'International') { | |
tot += d['Origin'] - d['Destination'] | |
} else { | |
int = d['Origin'] - d['Destination'] | |
} | |
}) | |
flow_dat = topojson.feature(canada, canada.objects.cangeo).features | |
flow_dat.forEach(function(d) { | |
// define where arrow start/ends in other provinces | |
cen = line_path.centroid(d) | |
if (d.properties.PRENAME == 'Alberta') { | |
cen[0] += 1 | |
cen[1] = cen[1] - 3.2 | |
} | |
if (d.properties.PRENAME == 'Saskatchewan') { | |
cen[1] = cen[1] - 1.2 | |
console.log(cen) | |
} | |
if (d.properties.PRENAME == 'Manitoba') { | |
cen[1] = cen[1] - 2.2 | |
console.log(cen) | |
} | |
if (d.properties.PRENAME == 'New Brunswick') { | |
cen[1] = cen[1] - 1 | |
} | |
if (d.properties.PRENAME == 'Nunavut') { | |
cen[1] = cen[1] - 5 | |
cen[0] += -6 | |
} | |
// console.log(line_path.centroid(d)) | |
line_data.push({ | |
prov: d.properties, | |
coords: cen | |
}) | |
}) | |
// console.log(flow_dat) | |
yearMenu.on('change', function() { | |
var currYear = d3.select(this) | |
.select('select') | |
.property('value'); | |
// console.log(currYear) | |
update(alldata, currYear) | |
}) | |
// var tooltip = d3.select("body").append("div") | |
// .attr("class", "tooltip") | |
// .style("opacity", 0); | |
var tooltip = d3.select("body").append("div").attr("class", "tooltip").style("opacity", 0);; | |
route_path = g.selectAll(".route") | |
// .data(migration.filter(function(d) { | |
// return d.Province != 'International'; | |
// })) | |
.data(migration) | |
.enter() | |
.append("path") | |
.attr("class", "route") | |
.attr('d', function(d, i) { | |
line_data.forEach(function(j) { | |
// console.log(ii) | |
if (j.prov.PRENAME == d.Province) { | |
d.coords = j.coords | |
} | |
if (d.Province == 'International') { | |
d.coords = [-139.75635246400601, 53.75809690349844] | |
} | |
}) | |
// console.log(d) | |
d.net = Number(d.Origin) - Number(d.Destination) | |
// define the location for arrow to start/end in bc here | |
bc_coords = [-122.75635246400601, 54.75809690349844]; | |
if (d.Province == 'Nunavut') { | |
bc_coords = [-122.75635246400601, 57.75809690349844] | |
} else if (d.Province == 'Alberta') { | |
bc_coords = [-121.245605, 52.263570] | |
} else if (d.Province == 'Yukon') { | |
bc_coords = [-130.417969, 59.562099] | |
} else if (d.Province == 'Saskatchewan') { | |
bc_coords = [-121.394922, 53.469826] | |
} else if (d.Province == 'Manitoba') { | |
bc_coords = [-121.146484, 54.262016] | |
} else if (d.Province == 'Northwest Territories') { | |
bc_coords = [-122.167969, 59.462099] | |
} else if (d.Province == 'Newfoundland and Labrador') { | |
bc_coords = [-122.146484, 56.386543] | |
} else if (d.Province == 'International') { | |
bc_coords = [-138.346484, 53.76543] | |
} else if (d.Province == 'Quebec') { | |
bc_coords = [-122.046484, 55.586543] | |
} | |
if (d.net < 0) { | |
return path({ | |
type: "LineString", | |
coordinates: [ | |
bc_coords, | |
// [-122.75635246400601, 54.75809690349844], // BC | |
d.coords | |
] | |
}) | |
// } | |
} else { | |
// if (d.Province == 'Alberta') { | |
return path({ | |
type: "LineString", | |
coordinates: [ | |
d.coords, bc_coords // BC | |
] | |
}) | |
// } | |
} | |
}) | |
// .style("stroke-dasharray", ("5, 3")) | |
.attr("stroke", function(d, i) { | |
// console.log(d.Destination) | |
if (Number(d.Origin) - Number(d.Destination) > 0) { | |
return "#3f51b5"; | |
} else { | |
return "#D32F2F"; | |
} | |
}) | |
.style("stroke-width", function(d) { | |
// console.log(Math.abs((Number(d.Origin) - Number(d.Destination)))) | |
return line_size(Math.abs((Number(d.Origin) - Number(d.Destination)))); | |
}) | |
.style("opacity", .8) | |
.transition() | |
.duration(2000) | |
.attrTween("stroke-dasharray", function() { | |
var len = this.getTotalLength(); | |
return function(t) { | |
return (d3.interpolateString("0," + len, len + ",0"))(t) | |
}; | |
}).attr("marker-end", function(d) { | |
// console.log(d) | |
if (d.net > 0) { | |
return "url(#end-arrow)" | |
} else { | |
return "url(#end-arrow-neg)" | |
} | |
}) | |
// annotation | |
const type = d3.annotationCallout | |
const annotations = [{ | |
type: d3.annotationCustomType( | |
d3.annotationCallout, { | |
"className": "custom", | |
"note": { | |
"lineType": "horizontal", | |
"align": "middle" | |
} | |
}), | |
note: { | |
label: "moved to BC from outside Canada", | |
title: int | |
}, | |
//can use x, y directly instead of data | |
x: 118, | |
y: 250.02, | |
dy: 157, | |
dx: 42 | |
}, | |
{ | |
note: { | |
label: "moved to BC from other provinces", | |
title: tot | |
}, | |
//can use x, y directly instead of data | |
x: 245, | |
y: 343.02, | |
dy: 87, | |
dx: 23 | |
} | |
] | |
const parseTime = d3.timeParse("%d-%b-%y") | |
const timeFormat = d3.timeFormat("%d-%b-%y") | |
//Skipping setting domains for sake of example | |
const x = d3.scaleTime().range([0, 800]) | |
const y = d3.scaleLinear().range([300, 0]) | |
const makeAnnotations = d3.annotation() | |
// .editMode(true) | |
.type(type) | |
//accessors & accessorsInverse not needed | |
//if using x, y in annotations JSON | |
// .accessors({ | |
// x: d => x(parseTime(d.date)), | |
// y: d => y(d.close) | |
// }) | |
// .accessorsInverse({ | |
// date: d => timeFormat(x.invert(d.x)), | |
// close: d => y.invert(d.y) | |
// }) | |
.annotations(annotations) | |
d3.select("svg") | |
.append("g") | |
.attr("class", "annotation-group") | |
.call(makeAnnotations) | |
// d3.selectAll('route').remove() | |
} | |
}) | |
console.log(migration) |
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
Province | Destination | Origin | time_period | |
---|---|---|---|---|
Newfoundland and Labrador | 98 | 228 | 2017 Q2 | |
Prince Edward Island | 117 | 100 | 2017 Q2 | |
Nova Scotia | 594 | 510 | 2017 Q2 | |
New Brunswick | 348 | 182 | 2017 Q2 | |
Quebec | 1259 | 1291 | 2017 Q2 | |
Ontario | 5694 | 5596 | 2017 Q2 | |
Manitoba | 645 | 1392 | 2017 Q2 | |
Saskatchewan | 886 | 1735 | 2017 Q2 | |
Alberta | 7197 | 10711 | 2017 Q2 | |
Yukon | 78 | 202 | 2017 Q2 | |
Northwest Territories | 74 | 120 | 2017 Q2 | |
Nunavut | 52 | 9 | 2017 Q2 | |
International | 14103 | 2017 Q2 | ||
Newfoundland and Labrador | 98 | 228 | 2017 Q3 | |
Prince Edward Island | 317 | 500 | 2017 Q3 | |
Nova Scotia | 594 | 710 | 2017 Q3 | |
New Brunswick | 348 | 782 | 2017 Q3 | |
Quebec | 1259 | 1291 | 2017 Q3 | |
Ontario | 5694 | 5596 | 2017 Q3 | |
Manitoba | 645 | 1392 | 2017 Q3 | |
Saskatchewan | 886 | 1735 | 2017 Q3 | |
Alberta | 11197 | 10711 | 2017 Q3 | |
Yukon | 78 | 202 | 2017 Q3 | |
Northwest Territories | 74 | 120 | 2017 Q3 | |
Nunavut | 52 | 9 | 2017 Q3 | |
International | 10103 | 2017 Q3 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment