D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
harrisoncramer
Full window
Github gist
Color by Latitude
<!doctype html> <html> <head> <title>World TopoJSON</title> <meta charset="utf-8" /> <script src="https://d3js.org/d3.v4.min.js" charset="utf-8"></script> <script src="https://d3js.org/d3-geo-projection.v2.min.js"></script> <script src="topojson.js"></script> <script src="colorbrewer.v1.min.js"></script> <link rel="stylesheet" type="text/css" href="styles.css"> </head> <body> <input type="range" min="-90" max="90" class="slider" value="0"/> </body> <script> var width = 600 var height = 500 var xTranslate = -4475 var yTranslate = 2700 var scaleStart = 4000 // Create a more versatile promiseWrapper that can take multiple types of data, including geoJSON and CSV files. The XHR object is the request type (d3.json, d3.csv, etc) for processing the data, the d is the data string URL itself. var promiseWrapper = (xhr, d) => new Promise(resolve => xhr(d, (p) => resolve(p))); // Feed it the data, on resolve call the function to draw the map. Promise.all([ promiseWrapper(d3.json,"world.topojson"), promiseWrapper(d3.csv,"cities.csv") ]).then(resolve =>{ createMap(resolve[0],resolve[1],mergepoint) }); var svg = d3.select("body").append("svg") .attr("width", width) .attr("height", height) var mergepoint = document.getElementsByClassName("slider")["0"].value function createMap(topoCountries, cities, mergepoint){ // console.log("TopoJSON Data: ", topoCountries) // To format the topojson file to turn it into geoJSON features, we use the topojson.feature() method. It accepts the topojson data as the first argument, and then the accessor (.objects.countries) to get to the relevant features. The ".objects" method will be relevant for all topojson files, but the ".countries" is specific to this file. var countries = topojson.feature(topoCountries, topoCountries.objects.countries) // console.log("Formatted Data: ", countries) // When the topoJSON data is formatted, the relevant coordinates are put inside the ".features" property of the geoJSON data, which we later access using "countries.features" // console.log("JSON Coordinates: ", countries.features) // Now, we can draw our map as we would a geoJSON file. // 1. Define our projection var projection = d3.geoMollweide() .scale(120) .translate([250,250]) .center([20,0]) // 2. Pass the projection to our geoPath function. var geoPath = d3.geoPath().projection(projection) // 3. Define coloring var featureSize = d3.extent(countries.features, d => geoPath.area(d)) var countryColor = d3.scaleQuantize() .domain(featureSize).range(colorbrewer.Greens[7]); // 4. Append our data, draw the SVGs. As was previously mentioned, the data for our SVGs is accessed by the ".features" method of the countries array. svg.selectAll("path.countries") .data(countries.features) .enter() .append("path") .attr("d", geoPath) .classed("countries", true) .style("fill", d => countryColor(geoPath.area(d))) function mergeAt(latitude){ // We're working with hthe TopoJSON dataset. Filter for countries whose Centroid has a latitude coordinate greater than 0. var filteredCountries = topoCountries.objects.countries.geometries .filter(d => { // Convert countries to GEOJSON using topojson.feature, find center. var thisCenter = d3.geoCentroid( topojson.feature(topoCountries, d)) // If latitude coordinate is greater than 0 (any point on country above latitude of 0) then return true. return thisCenter[1] > latitude ? true : false; }) d3.select("svg").append("g") .datum(topojson.merge(topoCountries, filteredCountries)) .insert("path") .attr("class", "merged") .attr("d", geoPath) } mergeAt(mergepoint) d3.select("input.slider").on("mousemove", function(d){ d3.selectAll("path").remove(); var mergepoint = this.value; mergeAt(mergepoint); createMap(topoCountries, cities, mergepoint) }) } </script> </html>
https://d3js.org/d3.v4.min.js
https://d3js.org/d3-geo-projection.v2.min.js