This is a Choropleth Map coded in D3/JavaScript using some infomational APIs
Created
November 17, 2018 21:46
-
-
Save Liight/a36cc0a2d47293e4544a4cd795ad659b to your computer and use it in GitHub Desktop.
D3 Choropleth Map (Sass, JavaScript, D3)[FCC]
This file contains hidden or 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
| <div id='main'> | |
| <h1 id='title'>United States Educational Attainment</h1> | |
| <div id='description'>Percentage of adults age 25 and older with a bachelor's degree or higher (2010-2014)</div> | |
| <svg width="960" height="600"></svg> | |
| <div id='source'>Source: <a href='https://www.ers.usda.gov/data-products/county-level-data-sets/download-data.aspx'>USDA Economic Research Service</a></div> | |
| </div> |
This file contains hidden or 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
| // Define body | |
| var body = d3.select("body"); | |
| // Set Scalable Vector Graphic and 2D Dimensions | |
| var svg = d3.select("svg"), | |
| width = +svg.attr("width"), | |
| height = +svg.attr("height"); | |
| // Define the div for the tooltip | |
| var tooltip = body.append("div") | |
| .attr("class", "tooltip") | |
| .attr("id", "tooltip") | |
| .style("opacity", 0); | |
| var unemployment = d3.map(); | |
| var path = d3.geoPath(); | |
| // Set domain and ranges for the scale | |
| var x = d3.scaleLinear() | |
| .domain([2.6, 75.1]) | |
| .rangeRound([600, 860]); | |
| var color = d3.scaleThreshold() | |
| .domain(d3.range(2.6, 75.1, (75.1-2.6)/8)) | |
| .range(d3.schemeGreens[9]); | |
| // Display Map Legend | |
| var g = svg.append("g") | |
| .attr("class", "key") | |
| .attr("id", "legend") | |
| .attr("transform", "translate(0,40)"); | |
| // Returns the extent of values in the domain [x0, x1] for the corresponding value in the range, representing the inverse mapping from range to domain, | |
| // then appends the rectangles to the svg using the color range to fill them. | |
| g.selectAll("rect") | |
| .data(color.range().map(function(d) { | |
| d = color.invertExtent(d); | |
| if (d[0] == null) d[0] = x.domain()[0]; | |
| if (d[1] == null) d[1] = x.domain()[1]; | |
| return d; | |
| })) | |
| .enter().append("rect") | |
| .attr("height", 8) | |
| .attr("x", function(d) { return x(d[0]); }) | |
| .attr("width", function(d) { return x(d[1]) - x(d[0]); }) | |
| .attr("fill", function(d) { return color(d[0]); }); | |
| // Set text attributes | |
| g.append("text") | |
| .attr("class", "caption") | |
| .attr("x", x.range()[0]) | |
| .attr("y", -6) | |
| .attr("fill", "#000") | |
| .attr("text-anchor", "start") | |
| .attr("font-weight", "bold") | |
| // Append ticks as int% | |
| g.call(d3.axisBottom(x) | |
| .tickSize(13) | |
| .tickFormat(function(x) { return Math.round(x) + '%' }) | |
| .tickValues(color.domain())) | |
| .select(".domain") | |
| .remove(); | |
| const EDUCATION_FILE = 'https://raw.githubusercontent.com/no-stack-dub-sack/testable-projects-fcc/master/src/data/choropleth_map/for_user_education.json'; | |
| const COUNTY_FILE = 'https://raw.githubusercontent.com/no-stack-dub-sack/testable-projects-fcc/master/src/data/choropleth_map/counties.json'; | |
| // Load if no error is thrown | |
| d3.queue() | |
| .defer(d3.json, COUNTY_FILE) | |
| .defer(d3.json, EDUCATION_FILE) | |
| .await(ready); | |
| // define ready for the queue check | |
| function ready(error, us, education) { | |
| if (error) throw error; | |
| // TopoJSON is an extension of GeoJSON that encodes topology. | |
| // Give County Ids from the API | |
| // Get education data and pass into each county element | |
| // Display info tooltip on mouseover | |
| // Apply tooltip styles | |
| svg.append("g") | |
| .attr("class", "counties") | |
| .selectAll("path") | |
| .data(topojson.feature(us, us.objects.counties).features) | |
| .enter().append("path") | |
| .attr("class", "county") | |
| .attr("data-fips", function(d) { | |
| return d.id | |
| }) | |
| .attr("data-education", function(d) { | |
| var result = education.filter(function( obj ) { | |
| return obj.fips == d.id; | |
| }); | |
| if(result[0]){ | |
| return result[0].bachelorsOrHigher | |
| } | |
| //could not find a matching fips id in the data | |
| console.log('could find data for: ', d.id); | |
| return 0 | |
| }) | |
| .attr("fill", function(d) { | |
| var result = education.filter(function( obj ) { | |
| return obj.fips == d.id; | |
| }); | |
| if(result[0]){ | |
| return color(result[0].bachelorsOrHigher) | |
| } | |
| //could not find a matching fips id in the data | |
| return color(0) | |
| }) | |
| .attr("d", path) | |
| .on("mouseover", function(d) { | |
| tooltip.style("opacity", .9); | |
| tooltip.html(function() { | |
| var result = education.filter(function( obj ) { | |
| return obj.fips == d.id; | |
| }); | |
| if(result[0]){ | |
| return result[0]['area_name'] + ', ' + result[0]['state'] + ': ' + result[0].bachelorsOrHigher + '%' | |
| } | |
| //could not find a matching fips id in the data | |
| return 0 | |
| }) | |
| .attr("data-education", function() { | |
| var result = education.filter(function( obj ) { | |
| return obj.fips == d.id; | |
| }); | |
| if(result[0]){ | |
| return result[0].bachelorsOrHigher | |
| } | |
| //could not find a matching fips id in the data | |
| return 0 | |
| }) | |
| .style("left", (d3.event.pageX + 10) + "px") | |
| .style("top", (d3.event.pageY - 28) + "px"); }) | |
| .on("mouseout", function(d) { | |
| tooltip.style("opacity", 0); | |
| }); | |
| // Append states to the SVG element. | |
| svg.append("path") | |
| .datum(topojson.mesh(us, us.objects.states, function(a, b) { return a !== b; })) | |
| .attr("class", "states") | |
| .attr("d", path); | |
| } |
This file contains hidden or 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
| <script src="https://d3js.org/d3.v4.min.js"></script> | |
| <script src="https://d3js.org/topojson.v2.min.js"></script> | |
| <script src="https://d3js.org/d3-scale-chromatic.v1.min.js"></script> |
This file contains hidden or 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
| html, body { | |
| padding: 0; | |
| margin: 0; | |
| } | |
| body { | |
| display: flex; | |
| justify-content: center; | |
| font-family: 'Arial'; | |
| } | |
| #main { | |
| width: 1000px; | |
| display: flex; | |
| padding-top: 1rem; | |
| flex-direction: column; | |
| align-items: center; | |
| } | |
| .counties { | |
| fill: none; | |
| } | |
| .states { | |
| fill: none; | |
| stroke: #fff; | |
| stroke-linejoin: round; | |
| } | |
| div.tooltip { | |
| position: absolute; | |
| padding: 10px; | |
| font: 12px Arial; | |
| background: rgba(255, 255, 204, 0.9); | |
| box-shadow: 1px 1px 10px rgba(128, 128, 128, 0.6); | |
| border: 0px; | |
| border-radius: 2px; | |
| pointer-events: none; | |
| } | |
| #title { | |
| font-size: 3.5rem; | |
| } | |
| #description { | |
| text-align: center; | |
| } | |
| #source { | |
| align-self: flex-end; | |
| margin-top: 1rem; | |
| } | |
| a { | |
| text-decoration: none; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment