xxxxxxxxxx
<head>
<meta charset="utf-8">
<style>
g {
stroke: white;
stroke-width: 0.3px;
fill: rgb(239,239,239);
}
g.cell {
fill: rgba(0, 98, 102, 0.8);
stroke: white;
}
text.legendTitle, text.label {
font: 13px sans-serif;
font-family: 'Lato', sans-serif;
color: black;
stroke: none;
fill: gray;
}
svg {
cursor: move; /* fallback if grab cursor is unsupported */
cursor: grab;
cursor: -moz-grab;
cursor: -webkit-grab;
}
svg:active {
cursor: grabbing;
cursor: -moz-grabbing;
cursor: -webkit-grabbing;
}
div.tooltip {
position: absolute;
text-align: center;
padding: 10px;
font: 12px sans-serif;
font-family: 'Lato', sans-serif;
color: rgb(79, 82, 88);
background: rgb(255, 255, 255);
border: 0px;
border-radius: 2px;
line-height: 16px;
pointer-events: none;
}
button {
width: 2rem;
border-radius: 0;
box-shadow: none;
font-size: 1.5em;
font-weight: 400;
text-align: center;
color: gray;
}
#parentDiv {
position: relative;
width: 1200px;
height: 380px;
border: 1px solid lightgray;
background-color: rgb(249,249,249); <!-- rgb(51,51,51); OR #fff; OR rgb(249,249,249) -->
}
#zoomButtons {
position: absolute;
bottom: 0;
right: 0;
}
</style>
<link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro" rel="stylesheet">
<link href="https://fonts.googleapis.com/css?family=Lato" rel="stylesheet">
</head>
<body>
<script src="https://d3js.org/d3.v3.min.js"></script>
<script src="https://d3js.org/topojson.v0.min.js"></script>
<script src="https://d3js.org/d3-array.v1.min.js"></script>
<script src="https://d3js.org/d3-geo.v1.min.js"></script>
<script src="https://d3js.org/d3-geo-projection.v2.min.js"></script>
<script src="d3-legend.js"></script>
<div id="parentDiv">
<div id="zoomButtons">
<button id="zoom_in">+</button><br>
<button id="zoom_out">-</button>
</div>
</div>
<script>
var width = 1200, // 860
height = 380;
var projection = d3.geoRobinson()
.center([-59, -9])
.scale(170) //280
.rotate([0,0]);
var svg = d3.select("#parentDiv")
.append("svg")
.attr("width", width)
.attr("height", height);
var path = d3.geo.path()
.projection(projection);
var div = d3.select("body")
.append("div")
.attr("class", "tooltip")
.style("opacity", 0);
var circleScale = d3.scale.linear()
.domain([1, 708])
.range([3,13]);
var g = svg.append("g"); // world background json
var g2 = svg.append("g"); // countries json
var g3 = svg.append("g"); // oil csv
var g4 = svg.append("g"); // ports csv
var g5 = svg.append("g"); // cities csv
var g6 = svg.append("g"); // retail csv
var g7 = svg.append("g"); // supply chain csv
var g8 = svg.append("g"); // agriculture csv
var g9 = svg.append("g"); // social impact csv
var g10 = svg.append("g"); // dry bulk and mines csv
var g11 = svg.append("g"); // intelligence csv
// legend background
var rectangle = svg.append("rect")
.attr("x", 0) //0
.attr("y", 294) //518
.attr("width", 183)
.attr("height", 86)
.style("fill", 'rgba(255, 255, 255, 0.7)');
var linearSize = d3.scale.linear().domain([1, 708]).range([3,13]);
var svg2 = d3.select("svg");
svg2.append("g")
.attr("class", "legendSize")
.attr("transform", "translate(5, 312)"); //1024
var legendSize = d3.legend.size()
.scale(linearSize)
.shape('circle')
.shapePadding(23)
.labels(["1", "100", "200", "400", "700"])
.cells([1,100,200,400,700])
.labelOffset(20)
.orient('horizontal')
.title("SkySat Image Quantity");
svg2.select(".legendSize")
.call(legendSize);
// *************************************************************
// Radio Menu
var defaultColor = "#8F9399"
var hoverColor = "#009DA4"
var pressedColor = "#006266"
var radioMenu = svg.append("rect")
.attr("id", "radioRect")
.attr("width", "107px")
.attr("height", "256px")
.attr("x", 0)
.attr("y", 0)
.attr("fill", "rgba(255, 255, 255, 0.7)");
var allButtons = svg.append("g")
.attr("id", "toggle");
var labels = ["OIL TANKS", "PORTS", "CITIES", "RETAIL", "SUPPLY CHAIN", "AGRICULTURE", "SOCIAL IMPACT", "BULK/MINES", "INTELLIGENCE", "FULL ARCHIVE"];
var buttonGroups = allButtons.selectAll("g.button")
.data(labels)
.enter()
.append("g")
.attr("class", "button")
.attr("id", function(d){
var theID = d.replace(/\s/g, '');
return theID;
})
.style("cursor", "pointer")
.on("click", function(d,i) { // (d,i)
updateButtonColors(d3.select(this), d3.select(this.parentNode))
if (d == "OIL TANKS") {
g3.style('display', 'inline')
g4.style('display', 'none')
g5.style('display', 'none')
g6.style('display', 'none')
g7.style('display', 'none')
g8.style('display', 'none')
g9.style('display', 'none')
g10.style('display', 'none')
g11.style('display', 'none')
}
else if (d == "PORTS") {
g3.style('display', 'none')
g4.style('display', 'inline')
g5.style('display', 'none')
g6.style('display', 'none')
g7.style('display', 'none')
g8.style('display', 'none')
g9.style('display', 'none')
g10.style('display', 'none')
g11.style('display', 'none')
}
else if (d == "CITIES") {
g3.style('display', 'none')
g4.style('display', 'none')
g5.style('display', 'inline')
g6.style('display', 'none')
g7.style('display', 'none')
g8.style('display', 'none')
g9.style('display', 'none')
g10.style('display', 'none')
g11.style('display', 'none')
}
else if (d == "RETAIL") {
g3.style('display', 'none')
g4.style('display', 'none')
g5.style('display', 'none')
g6.style('display', 'inline')
g7.style('display', 'none')
g8.style('display', 'none')
g9.style('display', 'none')
g10.style('display', 'none')
g11.style('display', 'none')
}
else if (d == "SUPPLY CHAIN") {
g3.style('display', 'none')
g4.style('display', 'none')
g5.style('display', 'none')
g6.style('display', 'none')
g7.style('display', 'inline')
g8.style('display', 'none')
g9.style('display', 'none')
g10.style('display', 'none')
g11.style('display', 'none')
}
else if (d == "AGRICULTURE") {
g3.style('display', 'none')
g4.style('display', 'none')
g5.style('display', 'none')
g6.style('display', 'none')
g7.style('display', 'none')
g8.style('display', 'inline')
g9.style('display', 'none')
g10.style('display', 'none')
g11.style('display', 'none')
}
else if (d == "SOCIAL IMPACT") {
g3.style('display', 'none')
g4.style('display', 'none')
g5.style('display', 'none')
g6.style('display', 'none')
g7.style('display', 'none')
g8.style('display', 'none')
g9.style('display', 'inline')
g10.style('display', 'none')
g11.style('display', 'none')
}
else if (d == "BULK/MINES") {
g3.style('display', 'none')
g4.style('display', 'none')
g5.style('display', 'none')
g6.style('display', 'none')
g7.style('display', 'none')
g8.style('display', 'none')
g9.style('display', 'none')
g10.style('display', 'inline')
g11.style('display', 'none')
}
else if (d == "INTELLIGENCE") {
g3.style('display', 'none')
g4.style('display', 'none')
g5.style('display', 'none')
g6.style('display', 'none')
g7.style('display', 'none')
g8.style('display', 'none')
g9.style('display', 'none')
g10.style('display', 'none')
g11.style('display', 'inline')
}
else if (d == "FULL ARCHIVE") {
g3.style('display', 'inline')
g4.style('display', 'inline')
g5.style('display', 'inline')
g6.style('display', 'inline')
g7.style('display', 'inline')
g8.style('display', 'inline')
g9.style('display', 'inline')
g10.style('display', 'inline')
g11.style('display', 'inline')
}
})
.on("mouseover", function() {
if (d3.select(this).select("rect").attr("fill") != pressedColor) {
d3.select(this)
.select("rect")
.attr("fill", hoverColor);
}
})
.on("mouseout", function() {
if (d3.select(this).select("rect").attr("fill") != pressedColor) {
d3.select(this)
.select("rect")
.attr("fill", defaultColor);
}
});
// hide layers on load
g4.style('display', 'none');
g5.style('display', 'none');
g6.style('display', 'none');
g7.style('display', 'none');
g8.style('display', 'none');
g9.style('display', 'none');
g10.style('display', 'none');
g11.style('display', 'none');
var bWidth = 95; // button width
var bHeight = 20; // button height
var bSpace = 5; // space between buttons
var x0 = 5; // x offset
var y0 = 5; // y offset
// adding a rect to each toggle button group
buttonGroups.append("rect")
.attr("class", "buttonRect")
.attr("width", bWidth)
.attr("height", bHeight)
.attr("x", x0)
.attr("y", function(d,i) {return y0+(bHeight+bSpace)*i;})
// rx and ry for rounded corners
.attr("fill", defaultColor)
// add text to each toggle button group, centered in rect
buttonGroups.append("text")
.attr("class", "buttonText")
.attr("font-family", "Lato")
.attr("font-size", "12px")
.attr("x", x0 + bWidth/2)
.attr("y", function(d,i) {
return y0 + (bHeight + bSpace)*i + bHeight/2;
})
.attr("text-anchor", "middle")
.attr("dominant-baseline", "central")
.attr("fill", "#fff")
.text(function(d) {return d;})
function updateButtonColors(button, parent) {
parent.selectAll("rect")
.attr("fill", defaultColor)
button.select("rect.buttonRect")
.attr("fill", pressedColor)
}
// default "pressed" radio button (oil tanks for now)
d3.select("g#OILTANKS")
.selectAll("rect")
.attr("fill", pressedColor)
d3.json("world-background.json", function(world) {
// load and display the World
d3.json("world-110m.json", function(land) {
// load and display the oil tanks
d3.csv("oil-format.csv", function(data) {
// load and display the ports
d3.csv("ports-format.csv", function(data) {
d3.csv("cities-format.csv", function(data) {
d3.csv("retail-format.csv", function(data) {
d3.csv("supplychain-format.csv", function(data) {
d3.csv("agriculture-format.csv", function(data) {
d3.csv("socialimpact-format.csv", function(data) {
d3.csv("drybulk-format.csv", function(data) {
d3.csv("intelligence-format.csv", function(data) {
g11.selectAll("circle")
.data(data.filter(function(d){
if(d.lon == ""){
return false;
}
else {
return true;
}
}))
.enter()
.append("circle")
.attr("cx", function(d) {
return projection([d.lon, d.lat])[0];
})
.attr("cy", function(d) {
return projection([d.lon, d.lat])[1];
})
.attr("r", function(d){
return circleScale(d.images);
})
.on('mouseover', mouseover)
.on('mouseout', mouseout)
.style("fill", "rgba(0, 98, 102, 0.7)")
.style('stroke', 'white')
.style('stroke-width', 0.3)
});
g10.selectAll("circle")
.data(data.filter(function(d){
if(d.lon == ""){
return false;
}
else {
return true;
}
}))
.enter()
.append("circle")
.attr("cx", function(d) {
return projection([d.lon, d.lat])[0];
})
.attr("cy", function(d) {
return projection([d.lon, d.lat])[1];
})
.attr("r", function(d){
return circleScale(d.images);
})
.on('mouseover', mouseover)
.on('mouseout', mouseout)
.style("fill", "rgba(0, 98, 102, 0.7)")
.style('stroke', 'white')
.style('stroke-width', 0.3)
});
g9.selectAll("circle")
.data(data.filter(function(d){
if(d.lon == ""){
return false;
}
else {
return true;
}
}))
.enter()
.append("circle")
.attr("cx", function(d) {
return projection([d.lon, d.lat])[0];
})
.attr("cy", function(d) {
return projection([d.lon, d.lat])[1];
})
.attr("r", function(d){
return circleScale(d.images);
})
.on('mouseover', mouseover)
.on('mouseout', mouseout)
.style("fill", "rgba(0, 98, 102, 0.7)")
.style('stroke', 'white')
.style('stroke-width', 0.3)
});
g8.selectAll("circle")
.data(data.filter(function(d){
if(d.lon == ""){
return false;
}
else {
return true;
}
}))
.enter()
.append("circle")
.attr("cx", function(d) {
return projection([d.lon, d.lat])[0];
})
.attr("cy", function(d) {
return projection([d.lon, d.lat])[1];
})
.attr("r", function(d){
return circleScale(d.images);
})
.on('mouseover', mouseover)
.on('mouseout', mouseout)
.style("fill", "rgba(0, 98, 102, 0.7)")
.style('stroke', 'white')
.style('stroke-width', 0.3)
});
g7.selectAll("circle")
.data(data.filter(function(d){
if(d.lon == ""){
return false;
}
else {
return true;
}
}))
.enter()
.append("circle")
.attr("cx", function(d) {
return projection([d.lon, d.lat])[0];
})
.attr("cy", function(d) {
return projection([d.lon, d.lat])[1];
})
.attr("r", function(d){
return circleScale(d.images);
})
.on('mouseover', mouseover)
.on('mouseout', mouseout)
.style("fill", "rgba(0, 98, 102, 0.7)")
.style('stroke', 'white')
.style('stroke-width', 0.3)
});
g6.selectAll("circle")
.data(data.filter(function(d){
if(d.lon == ""){
return false;
}
else {
return true;
}
}))
.enter()
.append("circle")
.attr("cx", function(d) {
return projection([d.lon, d.lat])[0];
})
.attr("cy", function(d) {
return projection([d.lon, d.lat])[1];
})
.attr("r", function(d){
return circleScale(d.images);
})
.on('mouseover', mouseover)
.on('mouseout', mouseout)
.style("fill", "rgba(0, 98, 102, 0.7)")
.style('stroke', 'white')
.style('stroke-width', 0.3)
});
g5.selectAll("circle")
.data(data.filter(function(d){
if(d.lon == ""){
return false;
}
else {
return true;
}
}))
.enter()
.append("circle")
.attr("cx", function(d) {
return projection([d.lon, d.lat])[0];
})
.attr("cy", function(d) {
return projection([d.lon, d.lat])[1];
})
.attr("r", function(d){
return circleScale(d.images);
})
.on('mouseover', mouseover)
.on('mouseout', mouseout)
.style("fill", "rgba(0, 98, 102, 0.7)")
.style('stroke', 'white')
.style('stroke-width', 0.3)
});
g4.selectAll("circle")
.data(data.filter(function(d){
if(d.lon == ""){
return false;
}
else {
return true;
}
}))
.enter()
.append("circle")
.attr("cx", function(d) {
return projection([d.lon, d.lat])[0];
})
.attr("cy", function(d) {
return projection([d.lon, d.lat])[1];
})
.attr("r", function(d){
return circleScale(d.images);
})
.on('mouseover', mouseover)
.on('mouseout', mouseout)
.style("fill", "rgba(0, 98, 102, 0.7)")
.style('stroke', 'white')
.style('stroke-width', 0.3)
});
g3.selectAll("circle")
.data(data.filter(function(d){
if(d.lon == ""){
return false;
}
else {
return true;
}
}))
.enter()
.append("circle")
.attr("cx", function(d) {
return projection([d.lon, d.lat])[0];
})
.attr("cy", function(d) {
return projection([d.lon, d.lat])[1];
})
.attr("r", function(d){
return circleScale(d.images);
})
.on('mouseover', mouseover)
.on('mouseout', mouseout)
.style("fill", "rgba(0, 98, 102, 0.7)")
.style('stroke', 'white')
.style('stroke-width', 0.3)
});
g2.selectAll("path")
.data(topojson.object(land, land.objects.countries)
.geometries)
.enter()
.append("path")
.attr("d", path)
.style("fill", "#c7c7c7");
});
g.selectAll("path")
.data(topojson.object(world, world.objects.worldbackground)
.geometries)
.enter()
.append("path")
.attr("d", path)
});
// zoom and pan
var zoom = d3.behavior.zoom()
.scaleExtent([0.8, 3]) // limits zoom range (only change 2nd #)
.on("zoom", zoomed);
function zoomed() {
g.attr("transform",
"translate(" + zoom.translate() + ")" +
"scale(" + zoom.scale() + ")"
);
g2.attr("transform",
"translate(" + zoom.translate() + ")" +
"scale(" + zoom.scale() + ")"
);
g3.attr("transform",
"translate(" + zoom.translate() + ")" +
"scale(" + zoom.scale() + ")"
);
g4.attr("transform",
"translate(" + zoom.translate() + ")" +
"scale(" + zoom.scale() + ")"
);
g5.attr("transform",
"translate(" + zoom.translate() + ")" +
"scale(" + zoom.scale() + ")"
);
g6.attr("transform",
"translate(" + zoom.translate() + ")" +
"scale(" + zoom.scale() + ")"
);
g7.attr("transform",
"translate(" + zoom.translate() + ")" +
"scale(" + zoom.scale() + ")"
);
g8.attr("transform",
"translate(" + zoom.translate() + ")" +
"scale(" + zoom.scale() + ")"
);
g9.attr("transform",
"translate(" + zoom.translate() + ")" +
"scale(" + zoom.scale() + ")"
);
g10.attr("transform",
"translate(" + zoom.translate() + ")" +
"scale(" + zoom.scale() + ")"
);
g11.attr("transform",
"translate(" + zoom.translate() + ")" +
"scale(" + zoom.scale() + ")"
);
circleScale.range([3/zoom.scale(), 13/zoom.scale()]);
g3.selectAll("circle")
.attr("d", path.projection(projection))
// Keeps circle size the same on zoom
.attr("r", function(d){
return circleScale(d.images);
})
g4.selectAll("circle")
.attr("d", path.projection(projection))
// Keeps circle size the same on zoom
.attr("r", function(d){
return circleScale(d.images);
})
g5.selectAll("circle")
.attr("d", path.projection(projection))
// Keeps circle size the same on zoom
.attr("r", function(d){
return circleScale(d.images);
})
g6.selectAll("circle")
.attr("d", path.projection(projection))
// Keeps circle size the same on zoom
.attr("r", function(d){
return circleScale(d.images);
})
g7.selectAll("circle")
.attr("d", path.projection(projection))
// Keeps circle size the same on zoom
.attr("r", function(d){
return circleScale(d.images);
})
g8.selectAll("circle")
.attr("d", path.projection(projection))
// Keeps circle size the same on zoom
.attr("r", function(d){
return circleScale(d.images);
})
g9.selectAll("circle")
.attr("d", path.projection(projection))
// Keeps circle size the same on zoom
.attr("r", function(d){
return circleScale(d.images);
})
g10.selectAll("circle")
.attr("d", path.projection(projection))
// Keeps circle size the same on zoom
.attr("r", function(d){
return circleScale(d.images);
})
g11.selectAll("circle")
.attr("d", path.projection(projection))
// Keeps circle size the same on zoom
.attr("r", function(d){
return circleScale(d.images);
})
};
function interpolateZoom (translate, scale) {
var self = this;
return d3.transition().duration(350).tween("zoom", function() {
var iTranslate = d3.interpolate(zoom.translate(), translate),
iScale = d3.interpolate(zoom.scale(), scale);
return function (t) {
zoom.scale(iScale(t))
.translate(iTranslate(t));
zoomed();
};
});
}
function zoomClick() {
var clicked = d3.event.target,
direction = 1,
factor = 0.2,
target_zoom = 1,
center = [width / 2, height / 2],
extent = zoom.scaleExtent(),
translate = zoom.translate(),
translate0 = [],
l = [],
view = {x: translate[0], y: translate[1], k: zoom.scale()};
d3.event.preventDefault();
direction = (this.id === 'zoom_in') ? 1 : -1;
target_zoom = zoom.scale() * (1 + factor * direction);
if (target_zoom < extent[0] || target_zoom > extent[1]) { return false; }
translate0 = [(center[0] - view.x) / view.k, (center[1] - view.y) / view.k];
view.k = target_zoom;
l = [translate0[0] * view.k + view.x, translate0[1] * view.k + view.y];
view.x += center[0] - l[0];
view.y += center[1] - l[1];
interpolateZoom([view.x, view.y], view.k);
}
d3.selectAll('button').on('click', zoomClick);
function mouseover(d, i){
d3.select(this)
.style('fill', 'rgba(0, 0, 0, 0.7)')
.style('stroke', 'white')
//.style('stroke-width', 0.3)
.style('cursor', 'auto');
div.transition()
.duration(150)
.style("opacity", 0.9);
div.text(d.place)
.style("left", (d3.event.pageX - 50) + "px")
.style("top", (d3.event.pageY - 65) + "px");
div.html("<b>" + d.admin1 + ", " + d.admin2 + "</b>" + "<br/><span>Images: " + d.images + "</span>");
}
function mouseout(d, i){
g3.selectAll("circle")
.style("fill", "rgba(0, 98, 102, 0.7)")
.style('stroke', 'white')
.style('stroke-width', 0.3)
g4.selectAll("circle")
.style("fill", "rgba(0, 98, 102, 0.7)")
.style('stroke', 'white')
.style('stroke-width', 0.3)
g5.selectAll("circle")
.style("fill", "rgba(0, 98, 102, 0.7)")
.style('stroke', 'white')
.style('stroke-width', 0.3)
g6.selectAll("circle")
.style("fill", "rgba(0, 98, 102, 0.7)")
.style('stroke', 'white')
.style('stroke-width', 0.3)
g7.selectAll("circle")
.style("fill", "rgba(0, 98, 102, 0.7)")
.style('stroke', 'white')
.style('stroke-width', 0.3)
g8.selectAll("circle")
.style("fill", "rgba(0, 98, 102, 0.7)")
.style('stroke', 'white')
.style('stroke-width', 0.3)
g9.selectAll("circle")
.style("fill", "rgba(0, 98, 102, 0.7)")
.style('stroke', 'white')
.style('stroke-width', 0.3)
g10.selectAll("circle")
.style("fill", "rgba(0, 98, 102, 0.7)")
.style('stroke', 'white')
.style('stroke-width', 0.3)
g11.selectAll("circle")
.style("fill", "rgba(0, 98, 102, 0.7)")
.style('stroke', 'white')
.style('stroke-width', 0.3)
div.transition()
.duration(200)
.style("opacity", 0);
}
svg.call(zoom).on("wheel.zoom", null);
</script>
</body>
</html>
https://d3js.org/d3.v3.min.js
https://d3js.org/topojson.v0.min.js
https://d3js.org/d3-array.v1.min.js
https://d3js.org/d3-geo.v1.min.js
https://d3js.org/d3-geo-projection.v2.min.js