Built with blockbuilder.org
xxxxxxxxxx
<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 = 1500;
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.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(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 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