https://gist.github.com/4544529 (demo) was my first d3 adventure, where I scraped signatures from a White House petition and showed them as a pie chart.
Here, I show them as a US heat map (based on one of Mike Bostock's map demos). You can click on a state, and see how many signatures came from it.
Darker color means more signatures, but since the numbers range from a few dozens to >4500, the scale is logarithmic.
I don't know yet how to use log()
interpolators (I promise to learn), so I just did it quick and dirty with linear()
and masking tape.
forked from thedod's block: Clickable US heat-map of petition signature count
forked from Craftbd's block: Group Project Bioinformatics
forked from rubin2ma's block: Group Project Bioinformatics
forked from Craftbd's block: Group Project Bioinformaticsnew
forked from rubin2ma's block: Group Project Bioinformaticsnew3
forked from scresawn's block: Group Project Bioinformatics Final Copy!
forked from rubin2ma's block: Group Project Bioinformatics Final Copy!
xxxxxxxxxx
<meta charset="utf-8">
<script src="//d3js.org/d3.v3.min.js"></script>
<script src="histograms.js"></script>
<meta charset="utf-8">
<style>
.background {
fill: none;
pointer-events: all;
}
#states {
stroke: #050505;
stroke-width: 1.5px;
}
#states text {
fill: #000;
stroke: none;
text-anchor:middle;
font-size: 10px;
font-weight:bold;
}
#states .active {
fill: steelblue !important;
}
#states text.active {
font: 10px sans-serif;
font-size: 12px;
font-weight:bold;
fill: #fff;
stroke-width: .5px;
fill: #fe3f2d !important;
stroke: #ffffff;
}
svg {
font: 10px sans-serif;
font-weight:bold;
}
.background path {
fill: none;
stroke: lightgreen;
stroke-opacity: .4;
shape-rendering: crispEdges;
}
.foreground path {
fill: none;
stroke: rebeccapurple;
stroke-opacity: .7;
stroke-width: 1.5;
}
.brush .extent {
fill-opacity: .3;
stroke: #fff;
shape-rendering: crispEdges;
}
.axis line,
.axis path {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.axis text {
text-shadow: 0 1px 0 #ffffff;
cursor: move;
}
</style>
<body>
<script>
var m = [30, 10, 10, 10],
w = 960 - m[1] - m[3],
h = 500 - m[0] - m[2];
var xGraph = d3.scale.ordinal().rangePoints([0, w], 1),
yGraph = {},
dragging = {};
var line = d3.svg.line(),
axis = d3.svg.axis().orient("left"),
background,
foreground;
var svgGraph = d3.select("body").append("svg")
.attr("width", w + m[1] + m[3])
.attr("height", h + m[0] + m[2])
.append("g")
.attr("transform", "translate(" + m[3] + "," + m[0] + ")");
d3.csv("Final_Data1.csv", function(error, stateGraph) {
//console.log(cars);
// Extract the list of dimensions and create a scale for each.
xGraph.domain(dimensions = d3.keys(stateGraph[0]).filter(function(d) {
return d != "name" && (yGraph[d] = d3.scale.linear()
.domain(d3.extent(stateGraph, function(p) { return +p[d]; }))
.range([h, 0]));
}));
// Add grey background lines for context.
background = svgGraph.append("g")
.attr("class", "background")
.selectAll("path")
.data(stateGraph)
.enter().append("path")
.attr("d", path);
// Add blue foreground lines for focus.
foreground = svgGraph.append("g")
.attr("class", "foreground")
.selectAll("path")
.data(stateGraph)
.enter().append("path")
.attr("id", function(d) { return d.name.replace(" ","")})
.attr("d", path);
// Add a group element for each dimension.
var g = svgGraph.selectAll(".dimension")
.data(dimensions)
.enter().append("g")
.attr("class", "dimension")
.attr("transform", function(d) { return "translate(" + xGraph(d) + ")"; })
.call(d3.behavior.drag()
.on("dragstart", function(d) {
dragging[d] = this.__origin__ = xGraph(d);
background.attr("visibility", "hidden");
})
.on("drag", function(d) {
dragging[d] = Math.min(w, Math.max(0, this.__origin__ += d3.event.dx));
foreground.attr("d", path);
dimensions.sort(function(a, b) { return position(a) - position(b); });
xGraph.domain(dimensions);
g.attr("transform", function(d) { return "translate(" + position(d) + ")"; })
})
.on("dragend", function(d) {
delete this.__origin__;
delete dragging[d];
transition(d3.select(this)).attr("transform", "translate(" + xGraph(d) + ")");
transition(foreground)
.attr("d", path);
background
.attr("d", path)
.transition()
.delay(500)
.duration(0)
.attr("visibility", null);
}));
// Add an axis and title.
g.append("g")
.attr("class", "axis")
.each(function(d) { d3.select(this).call(axis.scale(yGraph[d])); })
.append("text")
.attr("text-anchor", "middle")
.attr("y", -9)
.text(String);
// Add and store a brush for each axis.
g.append("g")
.attr("class", "brush")
.each(function(d) { d3.select(this).call(yGraph[d].brush = d3.svg.brush().y(yGraph[d]).on("brushstart", brushstart).on("brush", brush)); })
.selectAll("rect")
.attr("x", -8)
.attr("width", 16);
});
function position(d) {
var v = dragging[d];
return v == null ? xGraph(d) : v;
}
function transition(g) {
return g.transition().duration(500);
}
// Returns the path for a given data point.
function path(d) {
return line(dimensions.map(function(p) { return [position(p), yGraph[p](d[p])]; }));
}
// When brushing, don’t trigger axis dragging.
function brushstart() {
d3.event.sourceEvent.stopPropagation();
}
// Handles a brush event, toggling the display of foreground lines.
function brush() {
var actives = dimensions.filter(function(p) { return !yGraph[p].brush.empty(); }),
extents = actives.map(function(p) { return yGraph[p].brush.extent(); });
foreground.style("display", function(d) {
return actives.every(function(p, i) {
return extents[i][0] <= d[p] && d[p] <= extents[i][1];
}) ? null : "none";
});
}
<!-- This is where the code starts for the map drawning -->
var hits = {};
var width = 960,
height =500,
centered;
var projection = d3.geo.albersUsa()
.scale(width)
.translate([0, 0]);
var pathMap = d3.geo.path()
.projection(projection);
var svgMap = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
svgMap.append("rect")
.attr("class", "background")
.attr("width", width)
.attr("height", height)
.on("click", click);
var gMap = svgMap.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")")
.append("g")
.attr("id", "states");
UFO_color = [];
var color_by = "total";
var color = d3.scale.log()
.range(["firebrick", "mintcream"]);
d3.csv("UFO_color.csv", function(data){
data.forEach(function(d){
d["total"] = +d["total"];
})
color.domain([d3.min(data, function(d){ return d.total}),
d3.max(data,function(d) {return d.total; })]);
d3.json("states.json", function(json) {
data.forEach(function(d){
//console.log('d:', d);
//console.log("json:", json);
json.features.forEach(function(s){
//console.log('s', s);
if (d.state == s.properties.abbr){
s.total = d.total;
}
})
})
var states = gMap.selectAll("pathMap")
.data(json.features)
.enter().append("path")
.attr("d", pathMap)
.attr("id", function(d) { return d.properties.abbr; })
.style("fill", function(d) { return color(d.total); })
.on("click", click)
var labels = gMap.selectAll("text")
.data(json.features)
.enter().append("text")
.attr("transform", function(d) { return "translate(" + pathMap.centroid(d) + ")"; })
.attr("id", function(d) { return 'label-'+d.properties.abbr; })
.attr("dy", ".35em")
.on("click", click)
.text(function(d) { return d.properties.abbr; });
});
})
function click(d) {
var x = 0,
y = 0,
k = 1;
if (d && centered !== d) {
var centroid = pathMap.centroid(d);
x = -centroid[0];
y = -centroid[1];
k = 4;
centered = d;
} else {
centered = null;
}
if (centered) { console.log(d.properties.name) }
else {
d3.selectAll(".foreground").selectAll("path").style("visibility", "visible");
}
//console.log("eachstate:", eachstate);
if (centered) {
d3.selectAll(".foreground").selectAll("path").style("visibility", "hidden");
d3.selectAll(".foreground").selectAll("path#" + d.properties.name.replace(" ","")).style("visibility", "visible");
}
gMap.selectAll("pathMap")
.classed("active", centered && function(d) { return d === centered; });
gMap.selectAll("text")
.text(function(d) { return d.properties.abbr; })
.classed("active",false);
if (centered) {
gMap.select("#label-"+centered.properties.abbr)
.text(function(d) { return d.properties.name+'[ '+ '1:' +( Math.round(d.total) + ' ]' ||'(none)'); })
.classed("active", centered && function(d) { return d === centered; });
}
//Zooming Function
gMap.transition()
.duration(1000)
.attr("transform", "scale(" + k + ")translate(" + x + "," + y + ")")
.style("stroke-width", 1.5 / k + "px");
}
//connect graph to state "each one", number of sighting to popup in each state.
</script>
</body>
https://d3js.org/d3.v3.min.js