block by emeeks 8899a3e8c31d4c5e7cfd

Brush Snapping

Full Screen

index.html

<!DOCTYPE html>
<meta charset="utf-8">
<style>

body {
  font-family: sans-serif;
  color: #000;
  text-rendering: optimizeLegibility;
}

.barchart {
  z-index: 30;
  display: block;
  visibility: visible;
  position: relative;
  padding-top: 15px;
  margin-top: 15px;

}

.axis {
  font: 10px sans-serif;
}

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

.x.axis path {
  display: none;
}

.resize path {
  fill: #666;
  fill-opacity: .8;
  stroke: #000;
  stroke-width: 1.5px;
}

.brush .extent {
  stroke: #fff;
  stroke-opacity: .6;
  stroke-width: 2px;
  fill-opacity: .1;
  shape-rendering: crispEdges;
}

</style>

<body>
<script src="//d3js.org/d3.v3.min.js"></script>
<script src="//d3js.org/d3.geo.projection.v0.min.js"></script>
<script src="//d3js.org/topojson.v1.min.js"></script>
<script>

var margin = {top: 20, right: 20, bottom: 30, left: 40},
    width = 960 - margin.left - margin.right,
    height = 200 - margin.top - margin.bottom;

brushYearStart = 1848;
brushYearEnd = 1905;

// Scales
var x = d3.scale.ordinal().rangeRoundBands([0, width - 60], .1);
var y = d3.scale.linear().range([height, 0]);

// Prepare the barchart canvas
var barchart = d3.select("body").append("svg")
    .attr("class", "barchart")
    .attr("width", "100%")
.attr("height", height + margin.top + margin.bottom)
    .attr("y", height - height - 100)
    .append("g");

var z = d3.scale.ordinal().range(["steelblue", "indianred"]);

var brushYears = barchart.append("g")
brushYears.append("text")
    .attr("id", "brushYears")
    .classed("yearText", true)
    .text(brushYearStart + " - " + brushYearEnd)
    .attr("x", 35)
    .attr("y", 12);

d3.csv("years_count.csv", function (error, post) {

    // Coercion since CSV is untyped
    post.forEach(function (d) {
        d["frequency"] = +d["frequency"];
        d["frequency_discontinued"] = +d["frequency_discontinued"];
        d["year"] = d3.time.format("%Y").parse(d["year"]).getFullYear();
    });

    var freqs = d3.layout.stack()(["frequency", "frequency_discontinued"].map(function (type) {
        return post.map(function (d) {
            return {
                x: d["year"],
                y: +d[type]
            };
        });
    }));

    x.domain(freqs[0].map(function (d) {
        return d.x;
    }));
    y.domain([0, d3.max(freqs[freqs.length - 1], function (d) {
        return d.y0 + d.y;
    })]);

    // Axis variables for the bar chart
    x_axis = d3.svg.axis().scale(x).tickValues([1850, 1855, 1860, 1865, 1870, 1875, 1880, 1885, 1890, 1895, 1900]).orient("bottom");
    y_axis = d3.svg.axis().scale(y).orient("right");

    // x axis
    barchart.append("g")
        .attr("class", "x axis")
        .style("fill", "#000")
        .attr("transform", "translate(0," + height + ")")
        .call(x_axis);

    // y axis
    barchart.append("g")
        .attr("class", "y axis")
        .style("fill", "#000")
        .attr("transform", "translate(" + (width - 85) + ",0)")
        .call(y_axis);

    // Add a group for each cause.
    var freq = barchart.selectAll("g.freq")
        .data(freqs)
      .enter().append("g")
        .attr("class", "freq")
        .style("fill", function (d, i) {
            return z(i);
        })
        .style("stroke", "#CCE5E5");

    // Add a rect for each date.
    rect = freq.selectAll("rect")
        .data(Object)
      .enter().append("rect")
        .attr("class", "bar")
        .attr("x", function (d) {
            return x(d.x);
        })
        .attr("y", function (d) {
            return y(d.y0) + y(d.y) - height;
        })
        .attr("height", function (d) {
            return height - y(d.y);
        })
        .attr("width", x.rangeBand())
        .attr("id", function (d) {
            return d["year"];
        });

    // Draw the brush
    brush = d3.svg.brush()
        .x(x)
        .on("brush", brushmove)
        .on("brushend", brushend);

    var arc = d3.svg.arc()
      .outerRadius(height / 15)
      .startAngle(0)
      .endAngle(function(d, i) { return i ? -Math.PI : Math.PI; });

    brushg = barchart.append("g")
      .attr("class", "brush")
      .call(brush);

    brushg.selectAll(".resize").append("path")
        .attr("transform", "translate(0," +  height / 2 + ")")
        .attr("d", arc);

    brushg.selectAll("rect")
        .attr("height", height);

});

// ****************************************
// Brush functions
// ****************************************

function brushmove() {
    y.domain(x.range()).range(x.domain());
    b = brush.extent();

    var localBrushYearStart = (brush.empty()) ? brushYearStart : Math.ceil(y(b[0])),
        localBrushYearEnd = (brush.empty()) ? brushYearEnd : Math.ceil(y(b[1]));

    // Snap to rect edge
    d3.select("g.brush").call((brush.empty()) ? brush.clear() : brush.extent([y.invert(localBrushYearStart), y.invert(localBrushYearEnd)]));

    // Fade all years in the histogram not within the brush
    d3.selectAll("rect.bar").style("opacity", function(d, i) {
      return d.x >= localBrushYearStart && d.x < localBrushYearEnd || brush.empty() ? "1" : ".4";
    });
}

function brushend() {

  var localBrushYearStart = (brush.empty()) ? brushYearStart : Math.ceil(y(b[0])),
      localBrushYearEnd = (brush.empty()) ? brushYearEnd : Math.floor(y(b[1]));

    d3.selectAll("rect.bar").style("opacity", function(d, i) {
      return d.x >= localBrushYearStart && d.x <= localBrushYearEnd || brush.empty() ? "1" : ".4";
    });

  // Additional calculations happen here...
  // filterPoints();
  // colorPoints();
  // styleOpacity();

  // Update start and end years in upper right-hand corner of the map
  d3.select("#brushYears").text(localBrushYearStart == localBrushYearEnd ? localBrushYearStart : localBrushYearStart + " - " + localBrushYearEnd);

}

function resetBrush() {
  brush
    .clear()
    .event(d3.select(".brush"));
}

</script>

<div id="resetMap">
    <button
      id="returnBrush"
      class="btn btn-default"
      onclick="resetBrush()"/>Remove Brush
</div>

</body>
</html>

years_count.csv

year,frequency,frequency_discontinued
1847,2,0
1848,0,0
1849,14,0
1850,46,6
1851,113,8
1852,83,23
1853,54,20
1854,98,16
1855,81,24
1856,58,17
1857,73,25
1858,101,33
1859,54,24
1860,77,40
1861,90,23
1862,80,31
1863,71,31
1864,122,38
1865,71,26
1866,121,44
1867,124,44
1868,140,54
1869,153,52
1870,190,45
1871,222,65
1872,205,53
1873,205,60
1874,225,69
1875,204,92
1876,181,89
1877,186,66
1878,296,98
1879,350,138
1880,372,135
1881,406,202
1882,428,196
1883,367,210
1884,371,157
1885,212,117
1886,298,135
1887,396,172
1888,525,189
1889,404,101
1890,573,196
1891,420,169
1892,508,198
1893,249,181
1894,375,227
1895,345,266
1896,345,145
1897,184,99
1898,386,174
1899,297,192
1900,475,212
1901,369,246
1902,358,276