D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
fatimakoli
Full window
Github gist
Access/Imprisonment Map
Built with
blockbuilder.org
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>Map</title> <script src="https://d3js.org/d3.v4.min.js"></script> <style type="text/css"> path { fill: steelblue; } #button1:hover, #button2:hover { fill-opacity: .7; } .states{ stroke: white; stroke-width: 1; } .states:hover{ fill-opacity: .7; } .title, .subtitle, .comment{ color: #111; font-family: 'Helvetica Neue', sans-serif; font-weight: bold; letter-spacing: -1px; line-height: 1;; } .title{ font-size: 40px; } .subtitle{ font-size: 20px; } .comment{ font-size: 15px; } </style> </head> <body> <script type="text/javascript"> //Width and height var w = 1475; var h = 800; var margin = {top: 25, right: 25, bottom: 25, left: 25}; // define projeciton var projection = d3.geoAlbersUsa() .translate([w/2,h/2]) .scale([1500]); //Define path generator, using the Albers USA projection var path = d3.geoPath() .projection(projection); //Define quantize scale to sort data values into buckets of color // define scale to sort data values var color = d3.scaleQuantile() .range(["rgb(237,248,233)","rgb(186,228,179)","rgb(116,196,118)","rgb(49,163,84)","rgb(0,109,44)"]); //Colors derived from ColorBrewer, by Cynthia Brewer, and included in //https://github.com/d3/d3-scale-chromatic var color2 = d3.scaleQuantile().range(["#f2f0f7", "#cbc9e2", "#9e9ac8", "#756bb1", "#54278f"]); var color3 = d3.scaleQuantile() .range(["rgb(237,248,233)","rgb(186,228,179)","rgb(116,196,118)","rgb(49,163,84)","rgb(0,109,44)"]); //Create SVG element var svg = d3.select("body") .append("svg") .attr("width", w) .attr("height", h); d3.csv("mentalhealth_prisonpop.csv", function(data){ color.domain([ d3.min(data, function(d){return d.imprisonment;}), d3.max(data, function(d){return d.imprisonment;}) ]); color2.domain([ d3.min(data, function(d){return +d.access;}), d3.max(data, function(d){return +d.access;}) ]); //Load in GeoJSON data d3.json("us-states.json", function(json) { //Merge the ag. data and GeoJSON //Loop through once for each ag. data value for (var i = 0; i < data.length; i++) { //Grab state name var dataState = data[i].state; //Grab data value, and convert from string to float var dataValue = parseFloat(data[i].imprisonment); var dataaccess = parseFloat(data[i].access); //Find the corresponding state inside the GeoJSON for (var j = 0; j < json.features.length; j++) { var jsonState = json.features[j].properties.name; if (dataState == jsonState) { //Copy the data value into the JSON json.features[j].properties.imprisonment = dataValue; json.features[j].properties.access = dataaccess; //Stop looking through the JSON break; } } } //Bind data and create one path per GeoJSON feature svg.selectAll("path") .data(json.features) .enter() .append("path") .attr("class", "states") .attr("d", path) .on("mouseover", function(d){ svg.append("rect") .attr("class", "tooltip") .attr("x", path.centroid(d)[0]-15) .attr("y", path.centroid(d)[1]-20) .attr("width", 50) .attr("height", 30) .attr("fill","white") .attr("opacity", 0.7); svg.append("text") .text(d.properties.imprisonment) .attr("class", "tooltip") .attr("x", path.centroid(d)[0]) .attr("y", path.centroid(d)[1]) .attr("fill","black"); }) .on("mouseout", function(){ svg.select("text.tooltip").remove(); svg.select("rect.tooltip").remove(); }) .style("fill", function(d) { //Get data value var value = d.properties.imprisonment; if (value) { //If value exists… return color(value); } else { //If value is undefined… return "#ccc"; } }) d3.select("text.update1").on("click", function(d){ paths = svg.selectAll("path"); paths.transition().duration(1000).ease(d3.easeLinear) .style("fill", "rgb(237,248,233)"); paths.transition().delay(1000).duration(1500).ease(d3.easeLinear) .style("fill", function(d) { //Get data value var value = d.properties.access; if (value) { //If value exists… return color2(value); } else { return "#ccc"; } }); paths.on("mouseover", function(d){ svg.append("rect") .attr("class", "tooltip") .attr("x", path.centroid(d)[0]-15) .attr("y", path.centroid(d)[1]-20) .attr("width", 80) .attr("height", 30) .attr("fill","white") .attr("opacity", 0.7); svg.append("text") .text(d.properties.access) .attr("class", "tooltip") .attr("x", path.centroid(d)[0]) .attr("y", path.centroid(d)[1]) .attr("fill","black"); }) .on("mouseout", function(){ svg.select("text.tooltip").remove(); svg.select("rect.tooltip").remove(); }); var x = d3.scaleLinear() .domain(color2.domain()-1) .rangeRound([600, 860]); var g = svg.select("g.key"); var rects = g.selectAll("rect") .data(color2.range().map(function(d) { d = color2.invertExtent(d); if (d[0] == null) d[0] = x.domain()[0]; if (d[1] == null) d[1] = x.domain()[1]; return d; })); rects.transition().duration(1000).ease(d3.easeLinear) .attr("fill", function(d) { return color2(d[0]); }); var subtitle = svg.select("text.subtitle") subtitle.transition().duration(1000).ease(d3.easeLinear).style("opacity", 0); subtitle.transition().delay(1000).duration(1000).ease(d3.easeLinear).attr("x", 600).style("opacity",1).text("This map shows Access to Care Score"); var comment = svg.append("text") .attr("class", "comment") .text("(Higher numbers reflect areas with lower access to services)") .attr("x", 500) .attr("y", 120) .attr("fill", "black") .style("opacity", 0); comment.transition().delay(1000).duration(1000).ease(d3.easeLinear).attr("x", 625).style("opacity",1); var texts = g.selectAll("text.labels") .data(color2.range().map(function(d) { d = color2.invertExtent(d); if (d[0] == null) d[0] = x.domain()[0]; if (d[1] == null) d[1] = x.domain()[1]; return d; })); texts.transition().duration(1000).ease(d3.easeLinear).style("opacity", 0); texts.transition().delay(1000).duration(1000).ease(d3.easeLinear).style("opacity",1).text(function(d){return d3.format(".3f")(d[0])}); }); d3.select("text.update2").on("click", function(d){ paths = svg.selectAll("path"); paths.transition().duration(1000).ease(d3.easeLinear) .style("fill", "rgb(237,248,233)"); paths.transition().delay(1000).duration(1500).ease(d3.easeLinear) .style("fill", function(d) { //Get data value var value = d.properties.imprisonment; if (value) { //If value exists… return color(value); } else { return "#ccc"; } }); paths.on("mouseover", function(d){ svg.append("rect") .attr("class", "tooltip") .attr("x", path.centroid(d)[0]-15) .attr("y", path.centroid(d)[1]-20) .attr("width", 80) .attr("height", 30) .attr("fill","white") .attr("opacity", 0.7); svg.append("text") .text(d.properties.imprisonment) .attr("class", "tooltip") .attr("x", path.centroid(d)[0]) .attr("y", path.centroid(d)[1]) .attr("fill","black"); }) .on("mouseout", function(){ svg.select("text.tooltip").remove(); svg.select("rect.tooltip").remove(); }); var x = d3.scaleLinear() .domain(color.domain()-1) .rangeRound([600, 860]); var g = svg.select("g.key"); var rects = 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; })); rects.transition().duration(1000).ease(d3.easeLinear) .attr("fill", function(d) { return color(d[0]); }); var subtitle = svg.select("text.subtitle") subtitle.transition().duration(1000).ease(d3.easeLinear).style("opacity", 0); subtitle.transition().delay(1000).duration(1000).ease(d3.easeLinear).attr("x", 500).style("opacity",1).text("This First Map Shows State imprisonment (per 100K)"); svg.select(".comment").transition().duration(1000).ease(d3.easeLinear).style("opacity", 0).remove(); var texts = g.selectAll("text.labels") .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; })); texts.transition().duration(1000).ease(d3.easeLinear).style("opacity", 0); texts.transition().delay(1000).duration(1000).ease(d3.easeLinear).style("opacity",1).text(function(d){return (d[0])}); }); var x = d3.scaleLinear() .domain(color.domain()) .rangeRound([600, 860]); var g = svg.append("g") .attr("class", "key") .attr("transform", "translate(1300,-300)"); 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("width", 8) .attr("y", function(d) { return x(d[0]); }) .attr("height", function(d) { return x(d[1]) - x(d[0]); }) .attr("fill", function(d) { return color(d[0]); }); g.selectAll("text") .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("text") .attr("class", "labels") .attr("x", 15) .attr("y", function(d) { return x(d[0])+10; }) .attr("fill", "#000") .attr("text-anchor", "start") .text(function(d){return d[0]}); }); }); svg.append("text") .attr("class", "title") .text("Imprisonment and Mental Health Access:") .attr("x",300) .attr("y", 50) .attr("fill", "black") .style("text-transform", "uppercase"); svg.append("text") .attr("class", "subtitle") .text("This First Map Shows State imprisonment (per 100K)") .attr("x", 500) .attr("y", 100) .attr("fill", "black") .style("text-transform", "uppercase"); var button = svg.append("g") .attr("class", "buttons") .attr("transform", "translate(10,200)"); button.append("rect") .attr("id", "button1") .attr("x", 0) .attr("y", 0) .attr("width", 180) .attr("height", 60) .attr("fill", "black") .attr("stroke", "black"); button.append("text") .text("Look at Access") .attr("x",30) .attr("y", 30) .attr("class", "update1") .attr("fill","white") .style("text-transform", "uppercase"); button.append("rect") .attr("id", "button2") .attr("x", 0) .attr("y", 75) .attr("width", 180) .attr("height", 60) .attr("fill", "black") .attr("stroke", "black"); button.append("text") .text("Look at Imprisonment") .attr("x", 10) .attr("y", 105) .attr("class", "update2") .attr("fill","white") .style("text-transform", "uppercase"); </script> </body> </html>
https://d3js.org/d3.v4.min.js