xxxxxxxxxx
<meta charset="utf-8">
<style>
body {
background-color: #E3FDFD;
}
.counties {
stroke: #bfbfbf;
stroke-width: .25;
fill: #fff;
}
.states {
stroke: #000;
stroke-width: .25;
fill: none;
}
#popoverText {
position: absolute;
text-align: center;
padding: 2px;
font-family: Futura;
background: #fff;
border: 0px;
border-radius: 8px;
pointer-events: none;
opacity: 0;
}
</style>
<body>
<svg width="960" height="720"></svg>
<div id='popoverText'> </div>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://d3js.org/topojson.v1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/queue-async/1.0.7/queue.min.js"></script>
<script>
var svg = d3.select("svg"),
width = +svg.attr("width"),
height = +svg.attr("height");
var colorScale = d3.scaleThreshold()
.domain([1,910,1107,1880,2716,15782])
.range(["rgb(247,251,255)","rgb(222,235,247)","rgb(198,219,239)","rgb(158,202,225)","rgb(107,174,214)","rgb(66,146,198)", "rgb(8,48,107)"]);
queue()
.defer(d3.csv, "guns-history.csv")
.defer(d3.json, "us.json")
.await(ready);
function ready(error, guns, us) {
if (error) throw error;
console.log(topojson.feature(us, us.objects.counties).features);
gunsLookup = {};
guns.forEach(function(d) {
d.count3 = +d.count3;
gunsLookup[d.FIPS] = d.count3;
})
locationLookup = {};
guns.forEach(function(d) {
locationLookup[d.FIPS] = d.county;
})
var counties = topojson.feature(us, us.objects.counties),
states = topojson.feature(us, us.objects.states);
var path = d3.geoPath()
.projection(d3.geoAlbersUsa()
.fitSize([width, height], counties));
var defs = svg.append("defs");
//Filter for the outside glow
var filter = defs.append("filter")
.attr("id","glow");
filter.append("feGaussianBlur")
.attr("stdDeviation","3.5")
.attr("result","coloredBlur");
var feMerge = filter.append("feMerge");
feMerge.append("feMergeNode")
.attr("in","coloredBlur");
feMerge.append("feMergeNode")
.attr("in","SourceGraphic");
svg.selectAll(".counties")
.data(counties.features)
.enter().append("path")
.attr("class", "counties")
.attr("d", path)
.style("fill", function(d) { return gunsLookup[d.id] > 0 ? "#efefef" : "#fff" })
.on("mouseenter", function(d) {
d3.select(this)
.style("stroke-width", 1.5)
d3.select("#popoverText")
.transition()
.style("opacity", 1)
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY) + "px")
.text(locationLookup[d.id])
})
.on("mouseleave", function(d) {
d3.select(this)
.style("stroke-width", .25)
d3.select("#popoverText")
.transition()
.style("opacity", 0);
});
svg.selectAll(".states")
.data(states.features)
.enter().append("path")
.attr("class", "states")
.attr("d", path)
d3.selectAll(".states")
.style("filter", "url(#glow)");
svg.selectAll(".bubbles")
.data(counties.features)
.enter().append("g")
.attr("class","bubbles")
.attr("transform",function(d) { return "translate(" + path.centroid(d) + ")"})
.append("circle")
.attr("r", function(d) { return Math.sqrt(gunsLookup[d.id])/Math.PI; })
.style("fill", function(d) { return colorScale(gunsLookup[d.id]); })
.style("fill-opacity", .25)
.style("stroke", "#000")
.style("pointer-events","none")
d3.selectAll(".bubbles")
.style("filter", "url(#glow)");
}
</script>
</body>
https://d3js.org/d3.v4.min.js
https://d3js.org/topojson.v1.min.js
https://cdnjs.cloudflare.com/ajax/libs/queue-async/1.0.7/queue.min.js