The series hover interactivity uses the technique from lgrammel seen here: http://bl.ocks.org/1963983
It isn’t necessarily a tooltip, but data is displayed by inverting the x-axis value into a date, and mapping the date to the corresponding data value for the series.
If there is a simpler way to do this, I’d love to see an example, as I couldn’t find any other examples of this out there.
I think the vertical line adds a little bit of visual orientation to the streamgraph.
I left a few alternate color ranges in the code (which are essentially taken straight from colorbrewer), in case orange doesn’t sit well.
<!DOCTYPE html>
<meta charset="utf-8">
<link href='//fonts.googleapis.com/css?family=Open+Sans:400,300' rel='stylesheet' type='text/css'>
<style>
body {
font: 300 10px "Open Sans", Arial, sans-serif;
font-color: #96999b;
}
.axis path, .axis line {
fill: none;
stroke: #96999b;
stroke-width: 1px;
shape-rendering: crispEdges;
}
.tick {
fill: #96999b;
}
button {
position: absolute;
right: 50px;
top: 10px;
}
</style>
<body>
<script src="//d3js.org/d3.v3.js"></script>
<div class="chart">
</div>
<script>
chart("sep2013.csv", "globalpulse");
var datearray = [];
var colorrange = [];
function chart(csvpath, color) {
if (color == "globalpulse") {
colorrange = ["#00aeef", "#e1f4fd", "#96999b", "#e1d8ad", "#cf5c42", "#00447c", "#f4d5e3"];
}
else if (color == "blue") {
colorrange = ["#045A8D", "#2B8CBE", "#74A9CF", "#A6BDDB", "#D0D1E6", "#F1EEF6"];
}
else if (color == "pink") {
colorrange = ["#980043", "#DD1C77", "#DF65B0", "#C994C7", "#D4B9DA", "#F1EEF6"];
}
else if (color == "orange") {
colorrange = ["#B30000", "#E34A33", "#FC8D59", "#FDBB84", "#FDD49E", "#FEF0D9"];
}
strokecolor = colorrange[0];
var format = d3.time.format("%m/%d/%y");
var margin = {top: 20, right: 60, bottom: 30, left: 30};
var width = document.body.clientWidth - margin.left - margin.right;
var height = 600 - margin.top - margin.bottom;
var tooltip = d3.select("body")
.append("div")
.attr("class", "remove")
.style("position", "absolute")
.style("z-index", "20")
.style("visibility", "hidden")
.style("top", "30px")
.style("left", "30px");
var x = d3.time.scale()
.range([0, width]);
var y = d3.scale.linear()
.range([height-10, 0]);
var z = d3.scale.ordinal()
.range(colorrange);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
.ticks(d3.time.days);
var yAxis = d3.svg.axis()
.scale(y);
var yAxisr = d3.svg.axis()
.scale(y);
var stack = d3.layout.stack()
.offset("silhouette")
.values(function(d) { return d.values; })
.x(function(d) { return d.date; })
.y(function(d) { return d.value; });
var nest = d3.nest()
.key(function(d) { return d.key; });
var area = d3.svg.area()
.interpolate("cardinal")
.x(function(d) { return x(d.date); })
.y0(function(d) { return y(d.y0); })
.y1(function(d) { return y(d.y0 + d.y); });
var svg = d3.select(".chart").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var graph = d3.csv(csvpath, function(data) {
data.forEach(function(d) {
d.date = format.parse(d.date);
d.value = +d.value;
});
var layers = stack(nest.entries(data));
x.domain(d3.extent(data, function(d) { return d.date; }));
y.domain([0, d3.max(data, function(d) { return d.y0 + d.y; })]);
svg.selectAll(".layer")
.data(layers)
.enter().append("path")
.attr("class", "layer")
.attr("d", function(d) { return area(d.values); })
.style("fill", function(d, i) { return z(i); });
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
svg.append("g")
.attr("class", "y axis")
.attr("transform", "translate(" + width + ", 0)")
.call(yAxis.orient("right"));
// svg.append("g")
// .attr("class", "y axis")
// .call(yAxis.orient("left"));
svg.selectAll(".layer")
.attr("opacity", 1)
.on("mouseover", function(d, i) {
svg.selectAll(".layer").transition()
.duration(250)
.attr("opacity", function(d, j) {
return j != i ? 0.6 : 1;
})})
.on("mousemove", function(d, i) {
mousex = d3.mouse(this);
mousex = mousex[0];
var invertedx = x.invert(mousex);
invertedx = invertedx.getMonth() + invertedx.getDate();
var selected = (d.values);
for (var k = 0; k < selected.length; k++) {
datearray[k] = selected[k].date
datearray[k] = datearray[k].getMonth() + datearray[k].getDate();
}
mousedate = datearray.indexOf(invertedx);
pro = d.values[mousedate].value;
d3.select(this)
.classed("hover", true)
.attr("stroke", strokecolor)
.attr("stroke-width", ".5px"),
tooltip.html( d.key + ": " + pro )
.style("visibility", "visible")
.style("color", "#FFF")
.style("font-size", "40px")
.style("background", function(d, i) { return z(i); });
})
.on("mouseout", function(d, i) {
svg.selectAll(".layer")
.transition()
.duration(250)
.attr("opacity", "1");
d3.select(this)
.classed("hover", false)
.attr("stroke-width", "0px"), tooltip.html( "<p>" + d.key + "<br>" + pro + "</p>" ).style("visibility", "hidden");
})
var vertical = d3.select(".chart")
.append("div")
.attr("class", "remove")
.style("position", "absolute")
.style("z-index", "19")
.style("width", "3px")
.style("height", "600px")
.style("top", "10px")
.style("bottom", "30px")
.style("left", "0px")
.style("background", "#00aeef");
d3.select(".chart")
.on("mousemove", function(){
mousex = d3.mouse(this);
mousex = mousex[0] + 5;
vertical.style("left", mousex + "px" )})
.on("mouseover", function(){
mousex = d3.mouse(this);
mousex = mousex[0] + 5;
vertical.style("left", mousex + "px")});
});
}
</script>
date,value,key
9/1/13,183,#post2015
9/2/13,429,#post2015
9/3/13,441,#post2015
9/4/13,557,#post2015
9/5/13,338,#post2015
9/6/13,282,#post2015
9/7/13,154,#post2015
9/8/13,98,#post2015
9/9/13,718,#post2015
9/10/13,837,#post2015
9/11/13,965,#post2015
9/12/13,856,#post2015
9/13/13,579,#post2015
9/14/13,325,#post2015
9/15/13,282,#post2015
9/16/13,664,#post2015
9/17/13,736,#post2015
9/18/13,1055,#post2015
9/19/13,1106,#post2015
9/20/13,1246,#post2015
9/21/13,569,#post2015
9/22/13,1378,#post2015
9/23/13,2766,#post2015
9/24/13,2937,#post2015
9/25/13,4922,#post2015
9/26/13,2251,#post2015
9/27/13,1172,#post2015
9/28/13,349,#post2015
9/29/13,193,#post2015
9/30/13,780,#post2015
9/1/13,8,#futurewewant
9/2/13,10,#futurewewant
9/3/13,17,#futurewewant
9/4/13,8,#futurewewant
9/5/13,2,#futurewewant
9/6/13,4,#futurewewant
9/7/13,2,#futurewewant
9/8/13,5,#futurewewant
9/9/13,33,#futurewewant
9/10/13,25,#futurewewant
9/11/13,17,#futurewewant
9/12/13,24,#futurewewant
9/13/13,11,#futurewewant
9/14/13,6,#futurewewant
9/15/13,7,#futurewewant
9/16/13,350,#futurewewant
9/17/13,46,#futurewewant
9/18/13,35,#futurewewant
9/19/13,29,#futurewewant
9/20/13,17,#futurewewant
9/21/13,18,#futurewewant
9/22/13,14,#futurewewant
9/23/13,59,#futurewewant
9/24/13,153,#futurewewant
9/25/13,271,#futurewewant
9/26/13,126,#futurewewant
9/27/13,42,#futurewewant
9/28/13,45,#futurewewant
9/29/13,31,#futurewewant
9/30/13,89,#futurewewant
9/1/13,10,#mdgmomentum
9/2/13,11,#mdgmomentum
9/3/13,12,#mdgmomentum
9/4/13,15,#mdgmomentum
9/5/13,25,#mdgmomentum
9/6/13,20,#mdgmomentum
9/7/13,9,#mdgmomentum
9/8/13,4,#mdgmomentum
9/9/13,35,#mdgmomentum
9/10/13,51,#mdgmomentum
9/11/13,57,#mdgmomentum
9/12/13,34,#mdgmomentum
9/13/13,129,#mdgmomentum
9/14/13,25,#mdgmomentum
9/15/13,18,#mdgmomentum
9/16/13,18,#mdgmomentum
9/17/13,53,#mdgmomentum
9/18/13,53,#mdgmomentum
9/19/13,128,#mdgmomentum
9/20/13,126,#mdgmomentum
9/21/13,31,#mdgmomentum
9/22/13,28,#mdgmomentum
9/23/13,360,#mdgmomentum
9/24/13,94,#mdgmomentum
9/25/13,944,#mdgmomentum
9/26/13,252,#mdgmomentum
9/27/13,63,#mdgmomentum
9/28/13,55,#mdgmomentum
9/29/13,23,#mdgmomentum
9/30/13,65,#mdgmomentum
9/1/13,175,#mdgs
9/2/13,245,#mdgs
9/3/13,645,#mdgs
9/4/13,625,#mdgs
9/5/13,712,#mdgs
9/6/13,371,#mdgs
9/7/13,267,#mdgs
9/8/13,297,#mdgs
9/9/13,502,#mdgs
9/10/13,1040,#mdgs
9/11/13,532,#mdgs
9/12/13,364,#mdgs
9/13/13,1103,#mdgs
9/14/13,414,#mdgs
9/15/13,228,#mdgs
9/16/13,389,#mdgs
9/17/13,466,#mdgs
9/18/13,1162,#mdgs
9/19/13,1891,#mdgs
9/20/13,1048,#mdgs
9/21/13,372,#mdgs
9/22/13,595,#mdgs
9/23/13,1683,#mdgs
9/24/13,2541,#mdgs
9/25/13,4934,#mdgs
9/26/13,2416,#mdgs
9/27/13,1647,#mdgs
9/28/13,491,#mdgs
9/29/13,308,#mdgs
9/30/13,469,#mdgs
9/1/13,0,#MDGSuccess
9/2/13,4,#MDGSuccess
9/3/13,0,#MDGSuccess
9/4/13,4,#MDGSuccess
9/5/13,0,#MDGSuccess
9/6/13,1,#MDGSuccess
9/7/13,1,#MDGSuccess
9/8/13,0,#MDGSuccess
9/9/13,1,#MDGSuccess
9/10/13,3,#MDGSuccess
9/11/13,4,#MDGSuccess
9/12/13,7,#MDGSuccess
9/13/13,0,#MDGSuccess
9/14/13,2,#MDGSuccess
9/15/13,0,#MDGSuccess
9/16/13,5,#MDGSuccess
9/17/13,7,#MDGSuccess
9/18/13,8,#MDGSuccess
9/19/13,14,#MDGSuccess
9/20/13,68,#MDGSuccess
9/21/13,26,#MDGSuccess
9/22/13,118,#MDGSuccess
9/23/13,2237,#MDGSuccess
9/24/13,1018,#MDGSuccess
9/25/13,250,#MDGSuccess
9/26/13,210,#MDGSuccess
9/27/13,117,#MDGSuccess
9/28/13,95,#MDGSuccess
9/29/13,21,#MDGSuccess
9/30/13,43,#MDGSuccess
9/1/13,11,#unga
9/2/13,24,#unga
9/3/13,36,#unga
9/4/13,31,#unga
9/5/13,207,#unga
9/6/13,94,#unga
9/7/13,33,#unga
9/8/13,13,#unga
9/9/13,83,#unga
9/10/13,164,#unga
9/11/13,259,#unga
9/12/13,190,#unga
9/13/13,136,#unga
9/14/13,68,#unga
9/15/13,250,#unga
9/16/13,262,#unga
9/17/13,1282,#unga
9/18/13,907,#unga
9/19/13,1342,#unga
9/20/13,1435,#unga
9/21/13,869,#unga
9/22/13,1778,#unga
9/23/13,9561,#unga
9/24/13,49480,#unga
9/25/13,16639,#unga
9/26/13,11880,#unga
9/27/13,9527,#unga
9/28/13,3830,#unga
9/29/13,2141,#unga
9/30/13,2055,#unga