Built with blockbuilder.org
For StackOverflow question Migration issues using d3.js.
forked from aneeqa86's block: fresh block
xxxxxxxxxx
<html>
<head>
<meta charset="UTF-8">
<!-- Leaflet resources -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.3/leaflet.min.js"></script>
<link rel="stylesheet" href="https://cdn.leafletjs.com/leaflet-0.7.3/leaflet.css" />
<!-- JQuery -->
<script src="https://code.jquery.com/jquery-1.11.2.min.js"></script>
<!-- D3 Resources -->
<script src="https://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="https://d3js.org/queue.v1.min.js"></script>
<title>Test</title>
</head>
<body>
<style>
#map {
height: 850px;
}
#tt {
pointer-events: none;
color: white;
}
#tipContainer {
font-size: 16px;
position: absolute;
width: 180px;
z-index: 100;
background-repeat: no-repeat;
text-align: left;
line-height: 20px;
}
#tipLocation {
font-weight: normal;
font-family: Georgia;
font-style: Italic;
color: white;
margin: 0px;
padding: 10px 10px;
background: #333;
font-size: 14px;
}
#tipCount {
font-weight: bold;
font-size: 32px;
letter-spacing: -1px;
margin: 0px;
padding: 0px 10px 10px 10px;
color: #333;
}
#tipKey {
font-weight: normal;
font-size: 10px;
color: #333;
margin: 0px;
padding: 5px 0px 5px 10px;
background: rgba(218, 218, 218, 0.5);
}
#tt2 {
pointer-events: none;
color: white;
}
#tipContainer2 {
font-size: 16px;
position: absolute;
width: 250px;
z-index: 100;
background-repeat: no-repeat;
text-align: left;
line-height: 20px;
}
#tipLocation2 {
font-weight: normal;
font-family: Georgia;
font-style: Italic;
color: white;
margin: 0px;
padding: 10px 10px;
background: #333;
font-size: 14px;
}
#tipCount2 {
font-weight: bold;
font-size: 32px;
letter-spacing: -1px;
margin: 0px;
padding: 0px 10px 10px 10px;
color: #333;
}
#tipKey2 {
font-weight: normal;
font-size: 10px;
color: #333;
margin: 0px;
padding: 5px 0px 5px 10px;
background: rgba(218, 218, 218, 0.5);
}
.tipClear {
clear: both;
}
</style>
<!-- Add Map -->
<div id="maincontainer">
<div id="map">
</div>
</div>
<script>
function run() {
var map = L.map('map', {
center: [52.52, 13.5],
zoom: 11,
zoomControl: true
});
mapLink = L.tileLayer('https://{s}.basemaps.cartocdn.com/light_nolabels/{z}/{x}/{y}.png', {
attribution: '© <a href="https://osm.org/copyright">OpenStreetMap</a>contributors'
}).addTo(map);
// Add an SVG element to Leaflet’s overlay pane
// var w = 950;
// var h = 600;
var centered;
var formatC = d3.format(",.0f");
var formatD = d3.format("+,.0f");
var immin, immax, exmin, exmax;
var colors = ["#EDF8FB", "#41083E"];
var immdomain = [0, 6068];
var emmdomain = [20056, 566986];
var circleSize = d3.scale.linear().range([0, 25000]).domain([0, 137175]);
var lineSize = d3.scale.linear().range([2, 25]).domain([0, 35000]);
var fillcolor = d3.scale.linear().range(colors).domain(immdomain);
//Define path generator
var path = d3.geo.path()
//Create SVG element
var svg = d3.select(map.getPanes().overlayPane)
.append("svg")
// .attr("width", w)
// .attr("height", h)
// .style("class", "background");
var fp = d3.format(".1f");
var g = svg.append("g").attr("class", "leaflet-zoom-hide");
//initialize html tooltip
var tooltip = d3.select("#maincontainer")
.append("div")
.attr("id", "tt")
.style("z-index", "10")
.style("position", "absolute")
.style("visibility", "hidden");
var tooltip2 = d3.select("#maincontainer")
.append("div")
.attr("id", "tt2")
.style("z-index", "10")
.style("position", "absolute")
.style("visibility", "hidden");
var coming, going;
var by_name = {};
d3.csv("coming.csv", function(data) {
coming = data;
});
d3.csv("going.csv", function(data) {
going = data;
d3.json("lor_migration.geojson", function(json) {
transform = d3.geo.transform({
point: projectPoint
});
path = d3.geo.path().projection(transform);
function projectPoint(x, y) {
var point = map.latLngToLayerPoint(new L.LatLng(y, x));
this.stream.point(point.x, point.y);
}
/* path = d3.geo.path()
.projection(projection);*/
for (var i = 0; i < data.length; i++) {
by_name[ data[i].state ] = {}
for (var propt in data[i]) {
by_name[ data[i].state ][propt] = +data[i][propt];
}
by_name[ data[i].state ].abbrev = data[i].abbrev
by_name[ data[i].state ].state = data[i].state
}
//Find the corresponding state inside the GeoJSON
json.features.forEach( function (j) {
var jsonState = j.properties.name;
if ( by_name[jsonState] ) {
j.properties.state = by_name[jsonState].state;
j.id = by_name[jsonState].state;
j.abbrev = by_name[jsonState].abbrev;
j.properties.total_imm = by_name[jsonState].total_imm
j.properties.total_emm = by_name[jsonState].total_emm
// json.features[j].ind = i;
// for (var propt in by_name[jsonState]) {
// // if (!isNaN(tempObj[propt])) {
// j.properties[propt] = by_name[jsonState][propt];
// // }
// }
// break;
}
else {
console.log('No data for ' + jsonState)
}
})
//Bind data and create one path per GeoJSON feature
var feature = g.selectAll("path")
.data(json.features)
.enter()
.append("path")
// .attr("class", "state")
.attr("id", function(d) {
return d.properties.state;
})
.attr("d", path)
.attr("stroke-width", 0.5)
.style("stroke", "#666")
.style("fill", "#fff")
/* g.selectAll("circle")
.data(json.features)
.enter().append("circle")*/
.attr("cx", function(d) {
// var centname = d.properties.name;
// var ctroid = path.centroid(d)[0];
d.centroid = path.centroid(d);
return d.centroid[0];
})
.attr("cy", function(d) {
// var centname = d.properties.name;
return d.centroid[1];
// var ctroid;
// ctroid = path.centroid(d)[1];
// return ctroid;
})
/* .attr("r", function(d) {
var diff = d.properties.total_imm - d.properties.total_emm;
// return circleSize(Math.sqrt(Math.abs(diff) / Math.PI));
})*/
// .attr("class", "circ")
.attr("id", function(d) {
return d.abbrev;
})
/* .attr("fill", function(d) {
var diff = d.properties.total_imm - d.properties.total_emm;
if (diff > 0) {
return "#65a89d";
}
else {
return "#a96a46";
}
})*/
.attr("fill-opacity", "0.5")
.attr("stroke", "#fff")
.attr("stroke-weight", "0.5")
.on("mouseover", function(d) {
return toolOver(d, this);
})
.on("mousemove", function(d) {
var m = d3.mouse(this);
mx = m[0];
my = m[1];
return toolMove(mx, my, d);
})
.on("mouseout", function(d) {
return toolOut(d, this);
})
.on("click", function(d) {
clicked(d)
});
map.on("viewreset", reset);
reset();
function reset() {
var bounds = path.bounds(json);
topLeft = bounds[0],
bottomRight = bounds[1];
svg.attr("width", bottomRight[0] - topLeft[0])
.attr("height", bottomRight[1] - topLeft[1])
.style("left", topLeft[0] + "px")
.style("top", topLeft[1] + "px");
g.attr("transform", "translate(" + -topLeft[0] + "," + -topLeft[1] + ")");
feature.attr("d", path);
/*circle_test.each(function(d) {
if (d.lon && d.lat) {
p = new L.LatLng(d.lat, d.lon);
var layerPoint = map.latLngToLayerPoint(p);
d.fx = layerPoint.x;
d.fy = layerPoint.y;
}
});*/
//circle_test.attr("d", circle);
}
});
});
function toolOver(v, thepath) {
d3.select(thepath).style({
"fill-opacity": "0.7",
"cursor": "pointer"
});
return tooltip.style("visibility", "visible");
};
function toolOut(m, thepath) {
d3.select(thepath).style({
"fill-opacity": "0.5",
"cursor": ""
});
return tooltip.style("visibility", "hidden");
};
function toolMove(mx, my, data) {
if (mx < 120) {
mx = 120
};
if (my < 40) {
my = 40
};
return tooltip.style("top", my + -140 + "px").style("left", mx - 120 + "px").html("<div id='tipContainer'><div id='tipLocation'><b>" + data.id + "</b></div><div id='tipKey'>Migration in: <b>"
+ formatC(data.properties.total_imm) + "</b><br>Migration out: <b>"
+ formatC(data.properties.total_emm) + "</b><br>Net migration: <b>"
+ formatC((data.properties.total_imm - data.properties.total_emm)) + "</b></div><div class='tipClear'></div> </div>");
};
function toolOver2(v, thepath) {
d3.select(thepath).style({
"opacity": "1",
"cursor": "pointer"
});
return tooltip2.style("visibility", "visible");
};
function toolOut2(m, thepath) {
d3.select(thepath).style({
"opacity": "0.5",
"cursor": ""
});
return tooltip2.style("visibility", "hidden");
};
function toolMove2(mx, my, home, end, v1, v2) {
var diff = v1 - v2;
if (mx < 120) {
mx = 120
};
if (my < 40) {
my = 40
};
return tooltip2.style("top", my + -140 + "px").style("left", mx - 120 + "px").html("<div id='tipContainer2'><div id='tipLocation'><b>" + home + "/" + end + "</b></div><div id='tipKey2'>Migration, " + home + " to " + end + ": <b>" + formatC(v2) + "</b><br>Migration, " + end + " to " + home + ": <b>" + formatC(v1) + "</b><br>Net change, " + home + ": <b>" + formatD(v1 - v2) + "</b></div><div class='tipClear'></div> </div>");
};
function clicked(selected) {
var selname = selected.id;
var homex = selected.centroid[0];
var homey = selected.centroid[1];
g.selectAll(".goingline")
.attr("stroke-dasharray", 0)
.remove()
g.selectAll(".goingline")
.data(going)
.enter().append("path")
.attr("class", "goingline")
.attr("d", function(d, i) {
var finalval = coming[i][selname] - going[i][selname];
try {
var theState = d3.select("#" + d.abbrev).datum();
if (!isNaN(finalval)) {
var startx = theState.centroid[0];
var starty = theState.centroid[1];
if (finalval > 0) {
return "M" + startx + "," + starty + " Q" + (startx + homex) / 2 + " " + (starty + homey) / 1.5 + " " + homex + " " + homey;
}
else {
return "M" + homex + "," + homey + " Q" + (startx + homex) / 2 + " " + (starty + homey) / 2.5 + " " + startx + " " + starty;
}
}
}
catch (err) {
console.log(err)
console.log('No datum found for ' + d.abbrev)
}
})
.call(transition)
.attr("stroke-width", function(d, i) {
var finalval = coming[i][selname] - going[i][selname];
return lineSize(parseFloat(Math.abs(finalval)));
})
.attr("stroke", function(d, i) {
var finalval = coming[i][selname] - going[i][selname];
if (finalval > 0) {
return "#65a89d";
}
else {
return "#a96a46";
}
})
.attr("fill", "none")
.attr("opacity", 0.5)
.attr("stroke-linecap", "round")
.on("mouseover", function(d) {
return toolOver2(d, this);
})
.on("mousemove", function(d, i) {
var m = d3.mouse(this);
mx = m[0];
my = m[1];
return toolMove2(mx, my, selname, d.state, coming[i][selname], going[i][selname]);
})
.on("mouseout", function(d) {
return toolOut2(d, this);
});
}
function transition(path) {
path.transition()
.duration(1500)
.attrTween("stroke-dasharray", tweenDash);
}
function tweenDash() {
var l = this.getTotalLength(),
i = d3.interpolateString("0," + l, l + "," + l);
return function(t) {
return i(t);
};
}
}
run();
</script>
</body>
</html>
Modified http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.js to a secure url
Modified http://code.jquery.com/jquery-1.11.2.min.js to a secure url
Modified http://d3js.org/d3.v3.min.js to a secure url
Modified http://d3js.org/queue.v1.min.js to a secure url
https://cdn.leafletjs.com/leaflet-0.7.3/leaflet.js
https://code.jquery.com/jquery-1.11.2.min.js
https://d3js.org/d3.v3.min.js
https://d3js.org/queue.v1.min.js