Skip to content

Instantly share code, notes, and snippets.

@WillTurman
Created January 25, 2013 02:15
Show Gist options
  • Select an option

  • Save WillTurman/4631136 to your computer and use it in GitHub Desktop.

Select an option

Save WillTurman/4631136 to your computer and use it in GitHub Desktop.

Revisions

  1. William Turman created this gist Jan 25, 2013.
    20 changes: 20 additions & 0 deletions Readme.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,20 @@
    D3 Streamgraph Example
    ----------------------

    ### Series Hover ###

    The series hover interactivity uses the technique from lgrammel seen here: http://bl.ocks.org/1963983

    ### Data Tooltip ###

    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.

    ### Vertical Line Tooltip ###

    I think the vertical line adds a little bit of visual orientation to the streamgraph.

    ### Colors ###

    I left a few alternate color ranges in the code (which are essentially taken straight from colorbrewer), in case orange doesn't sit well.
    127 changes: 127 additions & 0 deletions data.csv
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,127 @@
    key,value,date
    AR,0.1,01/08/13
    AR,0.15,01/09/13
    AR,0.35,01/10/13
    AR,0.38,01/11/13
    AR,0.22,01/12/13
    AR,0.16,01/13/13
    AR,0.07,01/14/13
    AR,0.02,01/15/13
    AR,0.17,01/16/13
    AR,0.33,01/17/13
    AR,0.4,01/18/13
    AR,0.32,01/19/13
    AR,0.26,01/20/13
    AR,0.35,01/21/13
    AR,0.4,01/22/13
    AR,0.32,01/23/13
    AR,0.26,01/24/13
    AR,0.22,01/25/13
    AR,0.16,01/26/13
    AR,0.22,01/27/13
    AR,0.1,01/28/13
    DJ,0.35,01/08/13
    DJ,0.36,01/09/13
    DJ,0.37,01/10/13
    DJ,0.22,01/11/13
    DJ,0.24,01/12/13
    DJ,0.26,01/13/13
    DJ,0.34,01/14/13
    DJ,0.21,01/15/13
    DJ,0.18,01/16/13
    DJ,0.45,01/17/13
    DJ,0.32,01/18/13
    DJ,0.35,01/19/13
    DJ,0.3,01/20/13
    DJ,0.28,01/21/13
    DJ,0.27,01/22/13
    DJ,0.26,01/23/13
    DJ,0.15,01/24/13
    DJ,0.3,01/25/13
    DJ,0.35,01/26/13
    DJ,0.42,01/27/13
    DJ,0.42,01/28/13
    MS,0.21,01/08/13
    MS,0.25,01/09/13
    MS,0.27,01/10/13
    MS,0.23,01/11/13
    MS,0.24,01/12/13
    MS,0.21,01/13/13
    MS,0.35,01/14/13
    MS,0.39,01/15/13
    MS,0.4,01/16/13
    MS,0.36,01/17/13
    MS,0.33,01/18/13
    MS,0.43,01/19/13
    MS,0.4,01/20/13
    MS,0.34,01/21/13
    MS,0.28,01/22/13
    MS,0.26,01/23/13
    MS,0.37,01/24/13
    MS,0.41,01/25/13
    MS,0.46,01/26/13
    MS,0.47,01/27/13
    MS,0.41,01/28/13
    RC,0.1,01/08/13
    RC,0.15,01/09/13
    RC,0.35,01/10/13
    RC,0.38,01/11/13
    RC,0.22,01/12/13
    RC,0.16,01/13/13
    RC,0.07,01/14/13
    RC,0.02,01/15/13
    RC,0.17,01/16/13
    RC,0.33,01/17/13
    RC,0.4,01/18/13
    RC,0.32,01/19/13
    RC,0.26,01/20/13
    RC,0.35,01/21/13
    RC,0.4,01/22/13
    RC,0.32,01/23/13
    RC,0.26,01/24/13
    RC,0.22,01/25/13
    RC,0.16,01/26/13
    RC,0.22,01/27/13
    RC,0.1,01/28/13
    CG,0.1,01/08/13
    CG,0.15,01/09/13
    CG,0.35,01/10/13
    CG,0.38,01/11/13
    CG,0.22,01/12/13
    CG,0.16,01/13/13
    CG,0.07,01/14/13
    CG,0.02,01/15/13
    CG,0.17,01/16/13
    CG,0.33,01/17/13
    CG,0.4,01/18/13
    CG,0.32,01/19/13
    CG,0.26,01/20/13
    CG,0.35,01/21/13
    CG,0.4,01/22/13
    CG,0.32,01/23/13
    CG,0.26,01/24/13
    CG,0.22,01/25/13
    CG,0.16,01/26/13
    CG,0.22,01/27/13
    CG,0.1,01/28/13
    RI,0.1,01/08/13
    RI,0.15,01/09/13
    RI,0.35,01/10/13
    RI,0.38,01/11/13
    RI,0.22,01/12/13
    RI,0.16,01/13/13
    RI,0.07,01/14/13
    RI,0.02,01/15/13
    RI,0.17,01/16/13
    RI,0.33,01/17/13
    RI,0.4,01/18/13
    RI,0.32,01/19/13
    RI,0.26,01/20/13
    RI,0.35,01/21/13
    RI,0.4,01/22/13
    RI,0.32,01/23/13
    RI,0.26,01/24/13
    RI,0.22,01/25/13
    RI,0.16,01/26/13
    RI,0.22,01/27/13
    RI,0.1,01/28/13
    212 changes: 212 additions & 0 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,212 @@
    <!DOCTYPE html>
    <meta charset="utf-8">
    <style>

    body {
    font: 10px sans-serif;
    }

    .chart {
    background: #fff;
    }

    p {
    font: 12px helvetica;
    }


    .axis path, .axis line {
    fill: none;
    stroke: #000;
    stroke-width: 2px;
    shape-rendering: crispEdges;
    }

    button {
    position: absolute;
    right: 50px;
    top: 10px;
    }

    </style>
    <body>
    <script src="http://d3js.org/d3.v2.js"></script>


    <div class="chart">
    </div>

    <script>

    chart("data.csv", "orange");

    var datearray = [];
    var colorrange = [];


    function chart(csvpath, color) {

    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: 40, bottom: 30, left: 30};
    var width = document.body.clientWidth - margin.left - margin.right;
    var height = 400 - 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", "55px");

    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.weeks);

    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", "0.5px"),
    tooltip.html( "<p>" + d.key + "<br>" + pro + "</p>" ).style("visibility", "visible");

    })
    .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", "1px")
    .style("height", "380px")
    .style("top", "10px")
    .style("bottom", "30px")
    .style("left", "0px")
    .style("background", "#fff");

    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>