|
<!DOCTYPE html> |
|
<head> |
|
<meta charset="utf-8"> |
|
<script src="https://d3js.org/d3.v4.js"></script> |
|
<!--<script src="https://d3js.org/topojson.v2.min.js"></script>--> |
|
<script src="https://unpkg.com/topojson-client@3"></script> |
|
<script src="https://d3js.org/queue.v1.min.js"></script> |
|
<style> |
|
body { margin:10px;position:fixed;top:0;right:0;bottom:0;left:0; } |
|
#map { border:1px solid #000; background:#C6ECFF; } |
|
.country {fill:#FDFBEA;stroke: #000;} |
|
.graticule { |
|
fill: none; |
|
stroke: #bbb; |
|
stroke-width: .5px; |
|
stroke-opacity: .5; |
|
} |
|
svg text {display:none;} |
|
.zoom1 text.zoom1 {display:block;font-size:14px} |
|
.zoom1 text.zoom2 {display:block;font-size:10px} |
|
/* |
|
text {display:block;} |
|
text.init {display:block;} |
|
.zoom1 text.rest,.zoom2 text.rest {display:none;} |
|
.zoom1 text {font-size:14px;} |
|
.zoom2 text {font-size:12px;} |
|
.zoom3 text {font-size:10px;} |
|
.zoom4 text {font-size:8px;} |
|
.zoom5 text {font-size:6px;} |
|
.zoom6 text {font-size:4px;} |
|
.zoom7 text,.zoom8 text,.zoom9 text {font-size:2px;} |
|
*/ |
|
</style> |
|
</head> |
|
|
|
<body> |
|
<div id="map"></div> |
|
<script> |
|
const map = d3.select("#map"); |
|
const width = map.node().getBoundingClientRect().width; |
|
const height = width / 2; |
|
|
|
const projection = d3.geoMercator(); |
|
const path = d3.geoPath().projection(projection); |
|
|
|
const zoom = d3.zoom() |
|
.scaleExtent([1, 40]) |
|
.translateExtent([[0,0], [width, height]]) |
|
.extent([[0, 0], [width, height]]) |
|
.on("zoom", zoomed); |
|
|
|
const svg = map.append("svg") |
|
.attr("width", width) |
|
.attr("height", height) |
|
.attr("class", "zoom1") |
|
.call(zoom); |
|
|
|
const g = svg.append("g"); |
|
|
|
queue() |
|
.defer(d3.json, "https://cdn.rawgit.com/mbostock/4090846/raw/d534aba169207548a8a3d670c9c2cc719ff05c47/world-50m.json") |
|
.defer(d3.tsv, "https://cdn.rawgit.com/mbostock/4090846/raw/d534aba169207548a8a3d670c9c2cc719ff05c47/world-country-names.tsv") |
|
.await(ready); |
|
|
|
function ready(error, world, names) { |
|
if (error) throw error; |
|
|
|
var countries = topojson.feature(world, world.objects.countries).features; |
|
|
|
//map country names to IDs used on map |
|
var names_arr=[]; |
|
names.forEach(function(i){ |
|
names_arr[i.id]=i.name; |
|
}); |
|
|
|
|
|
|
|
// Compute each country’s centroid and its area |
|
countries.forEach(function(feature) { |
|
feature.properties.area = d3.geoArea(feature); |
|
//feature.properties.center = d3.geoCentroid(feature); |
|
feature.properties.center = projection(d3.geoCentroid(feature)); |
|
feature.properties.name = names_arr[feature.id]; |
|
}); |
|
//console.log(countries[0]); |
|
|
|
// Sort the countries by area |
|
countries.sort(function(countryA, countryB) { |
|
return countryB.properties.area - countryA.properties.area; |
|
}); |
|
|
|
|
|
var c_min = countries[0].properties.area.toFixed(8); |
|
var c_max = countries[countries.length-1].properties.area.toFixed(8); |
|
console.log( c_min ); |
|
console.log( c_max ); |
|
|
|
//https://github.com/d3/d3-scale |
|
//d3.scaleSqrt(), d3.scaleLog() |
|
|
|
//this isnt great as .4 to .1 is zoom1 to zoom6! |
|
var textrange = d3.scaleLinear().domain([c_min,c_max]).range([1, 9]); |
|
console.log( textrange(0.11519723) ); |
|
//console.log( textrange(0.00001112) ); |
|
|
|
//https://github.com/d3/d3-array/blob/master/README.md#histogram_thresholds |
|
//var histogram = d3.histogram().domain([0,100]).thresholds(5); |
|
//console.log(histogram([1,2,3,11,21,55,77])); |
|
|
|
//countries.forEach(function(c){ |
|
//console.log(c.properties.name+' area is '+c.properties.area.toFixed(8)) |
|
//}); |
|
|
|
g.selectAll("path") |
|
.data(countries) |
|
.enter() |
|
.append("path") |
|
.attr("id", function (d){ return 'id_'+d.id; }) |
|
.attr("class", "country") |
|
.attr("d", path); |
|
|
|
g.selectAll("text").data(countries) |
|
.enter().append("text") |
|
.attr("x", function (d){ return d.properties.center[0]; }) |
|
.attr("y", function (d){ return d.properties.center[1]; }) |
|
.attr("class", function (d,i){ |
|
return "zoom"+parseInt(textrange(d.properties.area.toFixed(8))) |
|
//could use d to base it of area but its sorted so using i |
|
//if(i<10){ |
|
// return "init"; |
|
//} else { |
|
// return "rest"; |
|
//} |
|
}) |
|
.attr("text-anchor", "middle") |
|
.text(function(d) { |
|
return d.properties.name; |
|
}) |
|
//.style('fill', 'red'); |
|
//.style('font-size', function (d){ |
|
// return textrange(d.properties.area.toFixed(8)) |
|
//}); |
|
|
|
//you dont need to preslice! |
|
/* |
|
var big = countries.slice(0,100); |
|
var small = countries.slice(100,240); |
|
|
|
g.selectAll("text").data(big) |
|
.enter().append("text") |
|
.attr("x", function (d){ return d.properties.center[0]; }) |
|
.attr("y", function (d){ return d.properties.center[1]; }) |
|
.attr("class", "big") |
|
.attr("text-anchor", "middle") |
|
.text(function(d) { |
|
//return d.properties.name; |
|
//return d.properties.area; |
|
}); |
|
|
|
g.selectAll("text").data(small) |
|
.enter().append("text") |
|
.attr("x", function (d){ return d.properties.center[0]; }) |
|
.attr("y", function (d){ return d.properties.center[1]; }) |
|
.attr("class", "small") |
|
.attr("text-anchor", "middle") |
|
.text(function(d) { |
|
//return d.properties.name; |
|
}); |
|
*/ |
|
|
|
|
|
|
|
|
|
//Did not need polylabel.js for labels |
|
//https://bl.ocks.org/Fil/da021023d58b8ddefd165c65e37f796b |
|
//http://blockbuilder.org/pnavarrc/75ec1502f51f86c2f43e |
|
//http://bl.ocks.org/hugolpz/42955069888057aff8c2 |
|
//http://blockbuilder.org/d3noob/401237468c9e38cea8c7 |
|
|
|
|
|
//dont put text inside of path but maybe group them in their own g |
|
/* |
|
g.selectAll("path") |
|
.data(countries) |
|
.enter() |
|
.append("path") |
|
.attr("d", path) |
|
.append("text") |
|
.attr("x", function (d){ return d.properties.center[0]; }) |
|
.attr("y", function (d){ return d.properties.center[1]; }) |
|
.attr("class", "name") |
|
.text(function(d) { |
|
return d.properties.name; |
|
}); |
|
*/ |
|
|
|
/* |
|
g.selectAll("path") |
|
.data(countries) |
|
.enter() |
|
.append("path") |
|
.attr("d", path); |
|
|
|
//g.selectAll("text").data(centroids) |
|
g.selectAll("text").data(countries) |
|
.enter().append("text") |
|
//.attr("x", function (d){ return d[0]; }) |
|
//.attr("y", function (d){ return d[1]; }) |
|
.attr("x", function (d){ return d.properties.center[0]; }) |
|
.attr("y", function (d){ return d.properties.center[1]; }) |
|
.attr("class", "name") |
|
//.attr("dy", 5) |
|
//.style("fill", "black") |
|
.attr("text-anchor", "middle") |
|
.text(function(d) { |
|
//console.log(arr[countries[i].id]); |
|
//return arr[countries[i].id]; |
|
return d.properties.name; |
|
}); |
|
*/ |
|
|
|
|
|
}; |
|
|
|
|
|
function zoomed(){ |
|
g.attr("transform", d3.event.transform); |
|
|
|
var s = d3.event.transform.k; |
|
d3.selectAll(".country").style("stroke-width", 1 / s); |
|
|
|
//better to adjust text zoom with CSS |
|
//d3.selectAll("text").style("font-size", 14-parseInt(s)+"px"); |
|
console.log( "zoom"+parseInt(s) ); |
|
svg.attr("class","zoom"+parseInt(s)); |
|
} |
|
</script> |
|
</body> |