score:2

Accepted answer

as in this example where mr. bostock applies a clip path to the area path, you need to apply one to the bars. the easiest way is to put them in their own g then apply the clip-path to that:

svg.append("defs").append("clippath")
    .attr("id", "clip")
    .append("rect")
    .attr("width", width)
    .attr("height", height);

...

// plot the stacked bars
var focus_bar = focus
    .append("g") //<-- g just for the bars to be clipped
    .attr("class","barclipper")
    .style('clip-path', 'url(#clip)') //<-- apply clipping
    .selectall('.g')
    .data(data.answer_counts)
    .enter().append('g')
    .attr('class', 'g bar stack')
    .attr('transform', function(d) {
      return "translate(" + x(d.date) + ",0)"
    });

full code:

<!doctype html>
<html>

<head>
  <script data-require="d3@3.5.3" data-semver="3.5.3" src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.3/d3.js"></script>
  <style>
    #milestones_attempts_combo .context {
      /*fill: #efefef;    */
    }
    
    #milestones_attempts_combo .focus .right,
    #milestones_attempts_combo .context .right {
      fill: #0064cd;
    }
    
    #milestones_attempts_combo .focus .wrong,
    #milestones_attempts_combo .context .wrong {
      fill: #cd001d;
    }
    
    #milestones_attempts_combo .y-axis-label,
    #milestones_attempts_combo .y2-axis-label {
      fill: #aaa;
      font-size: 120%;
    }
    
    #milestones_attempts_combo .focus-line,
    #milestones_attempts_combo .context-line {
      stroke: orange;
      stroke-width: 2;
      fill-opacity: 0;
    }
    
    .brush .extent {
      stroke: #efefef;
      fill: #666;
      fill-opacity: .125;
      shape-rendering: crispedges;
    }
    
    .stats-container {
      width: 700px;
      margin: 0 auto;
    }

    .chart .axis line,
    .chart .axis path,
    .chart .tick line {
      fill: none;
      stroke: #aaa;
      shape-rendering: crispedges;
    }
  </style>
</head>

<body>
  <div id="milestones_attempts_combo"></div>
  <script>
    (function() {
      var myjsondata = {
        "answer_counts": [{
          "date": "2012-09-13",
          "ys": [{
            "y1": 9,
            "y0": 0,
            "class": "right"
          }, {
            "y1": 12,
            "y0": 9,
            "class": "wrong"
          }],
          "total": 12
        }, {
          "date": "2012-09-16",
          "ys": [{
            "y1": 16,
            "y0": 0,
            "class": "right"
          }, {
            "y1": 17,
            "y0": 16,
            "class": "wrong"
          }],
          "total": 17
        }, {
          "date": "2012-09-17",
          "ys": [{
            "y1": 12,
            "y0": 0,
            "class": "right"
          }, {
            "y1": 14,
            "y0": 12,
            "class": "wrong"
          }],
          "total": 14
        }, {
          "date": "2012-09-19",
          "ys": [{
            "y1": 2,
            "y0": 0,
            "class": "right"
          }, {
            "y1": 2,
            "y0": 2,
            "class": "wrong"
          }],
          "total": 2
        }, {
          "date": "2012-09-20",
          "ys": [{
            "y1": 12,
            "y0": 0,
            "class": "right"
          }, {
            "y1": 16,
            "y0": 12,
            "class": "wrong"
          }],
          "total": 16
        }, {
          "date": "2012-09-21",
          "ys": [{
            "y1": 20,
            "y0": 0,
            "class": "right"
          }, {
            "y1": 22,
            "y0": 20,
            "class": "wrong"
          }],
          "total": 22
        }, {
          "date": "2012-09-22",
          "ys": [{
            "y1": 1,
            "y0": 0,
            "class": "right"
          }, {
            "y1": 1,
            "y0": 1,
            "class": "wrong"
          }],
          "total": 1
        }, {
          "date": "2012-09-23",
          "ys": [{
            "y1": 10,
            "y0": 0,
            "class": "right"
          }, {
            "y1": 12,
            "y0": 10,
            "class": "wrong"
          }],
          "total": 12
        }, {
          "date": "2012-09-24",
          "ys": [{
            "y1": 9,
            "y0": 0,
            "class": "right"
          }, {
            "y1": 9,
            "y0": 9,
            "class": "wrong"
          }],
          "total": 9
        }, {
          "date": "2012-09-25",
          "ys": [{
            "y1": 2,
            "y0": 0,
            "class": "right"
          }, {
            "y1": 4,
            "y0": 2,
            "class": "wrong"
          }],
          "total": 4
        }, {
          "date": "2012-09-29",
          "ys": [{
            "y1": 26,
            "y0": 0,
            "class": "right"
          }, {
            "y1": 37,
            "y0": 26,
            "class": "wrong"
          }],
          "total": 37
        }, {
          "date": "2012-10-01",
          "ys": [{
            "y1": 44,
            "y0": 0,
            "class": "right"
          }, {
            "y1": 44,
            "y0": 44,
            "class": "wrong"
          }],
          "total": 44
        }, {
          "date": "2012-10-02",
          "ys": [{
            "y1": 2,
            "y0": 0,
            "class": "right"
          }, {
            "y1": 2,
            "y0": 2,
            "class": "wrong"
          }],
          "total": 2
        }, {
          "date": "2012-10-03",
          "ys": [{
            "y1": 13,
            "y0": 0,
            "class": "right"
          }, {
            "y1": 13,
            "y0": 13,
            "class": "wrong"
          }],
          "total": 13
        }, {
          "date": "2012-10-05",
          "ys": [{
            "y1": 47,
            "y0": 0,
            "class": "right"
          }, {
            "y1": 47,
            "y0": 47,
            "class": "wrong"
          }],
          "total": 47
        }, {
          "date": "2012-10-08",
          "ys": [{
            "y1": 17,
            "y0": 0,
            "class": "right"
          }, {
            "y1": 17,
            "y0": 17,
            "class": "wrong"
          }],
          "total": 17
        }, {
          "date": "2012-10-09",
          "ys": [{
            "y1": 19,
            "y0": 0,
            "class": "right"
          }, {
            "y1": 20,
            "y0": 19,
            "class": "wrong"
          }],
          "total": 20
        }, {
          "date": "2012-10-10",
          "ys": [{
            "y1": 31,
            "y0": 0,
            "class": "right"
          }, {
            "y1": 31,
            "y0": 31,
            "class": "wrong"
          }],
          "total": 31
        }, {
          "date": "2012-10-11",
          "ys": [{
            "y1": 6,
            "y0": 0,
            "class": "right"
          }, {
            "y1": 6,
            "y0": 6,
            "class": "wrong"
          }],
          "total": 6
        }, {
          "date": "2012-10-14",
          "ys": [{
            "y1": 6,
            "y0": 0,
            "class": "right"
          }, {
            "y1": 6,
            "y0": 6,
            "class": "wrong"
          }],
          "total": 6
        }, {
          "date": "2012-10-19",
          "ys": [{
            "y1": 30,
            "y0": 0,
            "class": "right"
          }, {
            "y1": 32,
            "y0": 30,
            "class": "wrong"
          }],
          "total": 32
        }, {
          "date": "2012-10-20",
          "ys": [{
            "y1": 20,
            "y0": 0,
            "class": "right"
          }, {
            "y1": 22,
            "y0": 20,
            "class": "wrong"
          }],
          "total": 22
        }, {
          "date": "2012-10-23",
          "ys": [{
            "y1": 20,
            "y0": 0,
            "class": "right"
          }, {
            "y1": 20,
            "y0": 20,
            "class": "wrong"
          }],
          "total": 20
        }, {
          "date": "2012-10-24",
          "ys": [{
            "y1": 20,
            "y0": 0,
            "class": "right"
          }, {
            "y1": 21,
            "y0": 20,
            "class": "wrong"
          }],
          "total": 21
        }, {
          "date": "2012-10-29",
          "ys": [{
            "y1": 22,
            "y0": 0,
            "class": "right"
          }, {
            "y1": 22,
            "y0": 22,
            "class": "wrong"
          }],
          "total": 22
        }, {
          "date": "2012-11-01",
          "ys": [{
            "y1": 1,
            "y0": 0,
            "class": "right"
          }, {
            "y1": 1,
            "y0": 1,
            "class": "wrong"
          }],
          "total": 1
        }, {
          "date": "2012-11-02",
          "ys": [{
            "y1": 26,
            "y0": 0,
            "class": "right"
          }, {
            "y1": 29,
            "y0": 26,
            "class": "wrong"
          }],
          "total": 29
        }, {
          "date": "2012-11-05",
          "ys": [{
            "y1": 23,
            "y0": 0,
            "class": "right"
          }, {
            "y1": 27,
            "y0": 23,
            "class": "wrong"
          }],
          "total": 27
        }, {
          "date": "2012-11-06",
          "ys": [{
            "y1": 10,
            "y0": 0,
            "class": "right"
          }, {
            "y1": 11,
            "y0": 10,
            "class": "wrong"
          }],
          "total": 11
        }, {
          "date": "2012-11-07",
          "ys": [{
            "y1": 15,
            "y0": 0,
            "class": "right"
          }, {
            "y1": 18,
            "y0": 15,
            "class": "wrong"
          }],
          "total": 18
        }, {
          "date": "2012-11-09",
          "ys": [{
            "y1": 26,
            "y0": 0,
            "class": "right"
          }, {
            "y1": 31,
            "y0": 26,
            "class": "wrong"
          }],
          "total": 31
        }, {
          "date": "2012-11-10",
          "ys": [{
            "y1": 2,
            "y0": 0,
            "class": "right"
          }, {
            "y1": 2,
            "y0": 2,
            "class": "wrong"
          }],
          "total": 2
        }, {
          "date": "2012-11-14",
          "ys": [{
            "y1": 15,
            "y0": 0,
            "class": "right"
          }, {
            "y1": 17,
            "y0": 15,
            "class": "wrong"
          }],
          "total": 17
        }, {
          "date": "2012-11-16",
          "ys": [{
            "y1": 20,
            "y0": 0,
            "class": "right"
          }, {
            "y1": 23,
            "y0": 20,
            "class": "wrong"
          }],
          "total": 23
        }, {
          "date": "2012-11-18",
          "ys": [{
            "y1": 2,
            "y0": 0,
            "class": "right"
          }, {
            "y1": 2,
            "y0": 2,
            "class": "wrong"
          }],
          "total": 2
        }, {
          "date": "2012-11-19",
          "ys": [{
            "y1": 23,
            "y0": 0,
            "class": "right"
          }, {
            "y1": 26,
            "y0": 23,
            "class": "wrong"
          }],
          "total": 26
        }, {
          "date": "2012-11-21",
          "ys": [{
            "y1": 2,
            "y0": 0,
            "class": "right"
          }, {
            "y1": 3,
            "y0": 2,
            "class": "wrong"
          }],
          "total": 3
        }, {
          "date": "2012-11-23",
          "ys": [{
            "y1": 9,
            "y0": 0,
            "class": "right"
          }, {
            "y1": 10,
            "y0": 9,
            "class": "wrong"
          }],
          "total": 10
        }, {
          "date": "2012-11-26",
          "ys": [{
            "y1": 2,
            "y0": 0,
            "class": "right"
          }, {
            "y1": 2,
            "y0": 2,
            "class": "wrong"
          }],
          "total": 2
        }, {
          "date": "2012-11-27",
          "ys": [{
            "y1": 25,
            "y0": 0,
            "class": "right"
          }, {
            "y1": 26,
            "y0": 25,
            "class": "wrong"
          }],
          "total": 26
        }, {
          "date": "2012-11-28",
          "ys": [{
            "y1": 73,
            "y0": 0,
            "class": "right"
          }, {
            "y1": 75,
            "y0": 73,
            "class": "wrong"
          }],
          "total": 75
        }, {
          "date": "2012-12-02",
          "ys": [{
            "y1": 19,
            "y0": 0,
            "class": "right"
          }, {
            "y1": 20,
            "y0": 19,
            "class": "wrong"
          }],
          "total": 20
        }, {
          "date": "2012-12-05",
          "ys": [{
            "y1": 1,
            "y0": 0,
            "class": "right"
          }, {
            "y1": 1,
            "y0": 1,
            "class": "wrong"
          }],
          "total": 1
        }, {
          "date": "2013-01-11",
          "ys": [{
            "y1": 2,
            "y0": 0,
            "class": "right"
          }, {
            "y1": 3,
            "y0": 2,
            "class": "wrong"
          }],
          "total": 3
        }, {
          "date": "2013-01-16",
          "ys": [{
            "y1": 8,
            "y0": 0,
            "class": "right"
          }, {
            "y1": 8,
            "y0": 8,
            "class": "wrong"
          }],
          "total": 8
        }],
        "badge_set_reached": [{
          "date": "2014-05-24",
          "set": 3
        }, {
          "date": "2014-09-29",
          "set": 5
        }, {
          "date": "2014-11-10",
          "set": 6
        }, {
          "date": "2014-08-29",
          "set": 7
        }, {
          "date": "2015-08-12",
          "set": 9
        }, {
          "date": "2016-01-09",
          "set": 9
        }]
      }

      var data = myjsondata;
      // preprocess data to get usable date objects
      var parse_date = d3.time.format('%y-%m-%d').parse
      for (var i in data) {
        var myobj = data[i]
        for (var j in myobj) {
          myobj[j].date = parse_date(myobj[j].date);
        }
      }
      console.log(data);

      // set variables
      var margin = {
          left: 60,
          right: 60,
          top: 10,
          bottom: 140
        },
        navmargin = {
          top: 300,
          right: 60,
          bottom: 40,
          left: 60
        },
        height = 400 - margin.top - margin.bottom,
        width = 800 - margin.left - margin.right,
        navwidth = width, // for context band
        navheight = 400 - navmargin.top - navmargin.bottom,
        max_total_counts = d3.max(data.answer_counts, function(d) {
          return d.total;
        }),
        max_extent_dates = d3.extent(data.answer_counts, function(d) {
          return d.date;
        });
      max_extent_in_days = function(timescale) {
        return d3.time.days(timescale.domain()[0], d3.time.day.offset(timescale.domain()[1], 1))
      };

      // scales
      var y = d3.scale.linear().domain([0, max_total_counts]).rangeround([height, 0]),
        navy = d3.scale.linear().domain([0, max_total_counts]).rangeround([navheight, 0]),
        time = d3.time.scale().domain(max_extent_dates).range([0, width]),
        navtime = d3.time.scale().domain(max_extent_dates).range([0, width]),
        x = d3.scale.ordinal().domain(max_extent_in_days(time)).rangebands([0, width], 0.1, 0), // used to calculate bar widths
        navx = d3.scale.ordinal().domain(max_extent_in_days(navtime)).rangebands([0, width], 0.1, 0),
        y2 = d3.scale.linear().domain([0, d3.max(data.badge_set_reached, function(d) {
          return d.set
        })]).rangeround([height, 0]);
      navy2 = d3.scale.linear().domain([0, d3.max(data.badge_set_reached, function(d) {
        return d.set
      })]).rangeround([navheight, 0]);

      // axes
      var x_axis = d3.svg.axis().scale(time).orient('bottom') //    .tickformat(d3.time.format('%y-%m-%d'))
        .outerticksize(0), // at start and end of axis line
        nav_x_axis = d3.svg.axis().scale(navtime).orient('bottom') //    .tickformat(d3.time.format('%y-%m-%d'))
        .outerticksize(0), // at start and end of axis line
        y_axis = d3.svg.axis().scale(y).orient('left').tickformat(d3.format('d'));
      y2_axis = d3.svg.axis().scale(y2).orient('right').tickformat(d3.format('d'));

      // add brush
      var brush = d3.svg.brush()
        .x(navtime)
        .on("brush", brushed);

      // svg context
      var svg = d3.select("#milestones_attempts_combo")
        .append('svg')
        .attr('class', 'chart')
        .attr('width', width + margin.left + margin.right)
        .attr('height', height + margin.top + margin.bottom)
        
      svg.append("defs").append("clippath")
        .attr("id", "clip")
        .append("rect")
        .attr("width", width)
        .attr("height", height);

      var focus = svg.append('g')
        .attr('class', 'focus')
        .attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');

      var context = svg.append('g')
        .attr('class', 'context')
        .attr('transform', 'translate(' + navmargin.left + ',' + navmargin.top + ')');

      // plot the stacked bars
      var focus_bar = focus
        .append("g")
        .attr("class","barclipper")
        .style('clip-path', 'url(#clip)')
        .selectall('.g')
        .data(data.answer_counts)
        .enter().append('g')
        .attr('class', 'g bar stack')
        .attr('transform', function(d) {
          return "translate(" + x(d.date) + ",0)"
        });

      var focus_rects = focus_bar.selectall('rect')
        .data(function(d) {
          return d.ys;
        })
        .enter().append('rect')
        .attr('width', x.rangeband())
        .attr('height', function(d) {
          return y(d.y0) - y(d.y1);
        })
        .attr('y', function(d) {
          return y(d.y1);
        })
        .attr('class', function(d) {
          return 'rect ' + d['class'];
        });

      var context_bar = context.selectall('.g')
        .data(data.answer_counts)
        .enter().append('g')
        .attr('class', 'g')
        .attr('transform', function(d) {
          return "translate(" + navtime(d.date) + ",0)"
        });

      var context_rects = context_bar.selectall('rect')
        .data(function(d) {
          return d.ys;
        })
        .enter().append('rect')
        .attr('width', navx.rangeband())
        .attr('height', function(d) {
          return navy(d.y0) - navy(d.y1);
        })
        .attr('y', function(d) {
          return navy(d.y1);
        })
        .attr('class', function(d) {
          return 'rect ' + d['class'];
        });

      // plot lines

      var line = d3.svg.line()
        .x(function(d) {
          return time(d.date)
        })
        .y(function(d) {
          return y2(d.set)
        })
        .interpolate('step-after');
      var focus_line = focus.append('path')
        .datum(data.badge_set_reached)
        .attr('class', 'line focus-line')
        .attr('d', line);

      var line2 = d3.svg.line()
        .x(function(d) {
          return time(d.date)
        })
        .y(function(d) {
          return navy2(d.set)
        })
        .interpolate('step-after');
      var context_line = context.append('path')
        .datum(data.badge_set_reached)
        .attr('class', 'line context-line')
        .attr('d', line2);

      // plot axes
      focus.append('g')
        .attr('class', 'x axis')
        .attr('transform', 'translate(0, ' + height + ')')
        .call(x_axis)
        .selectall('text')
        .style('text-anchor', 'end')
        // .attr('transform', 'rotate(-45)')
        //         .attr('dx', '-.5em')
        //         .attr('dy', '.5em');

      focus.append('g')
        .attr('class', 'y axis')
        .attr('transform', 'translate(0, 0)')
        .call(y_axis);

      focus.append('g')
        .attr('class', 'y2 axis')
        .attr('transform', 'translate(' + width + ', 0)')
        .call(y2_axis);

      context.append('g')
        .attr('class', 'navx axis')
        .attr('transform', 'translate(0, ' + navheight + ')')
        .call(nav_x_axis);

      // label axes
      svg.append('text')
        .attr('class', 'label y-axis-label')
        .attr('transform', 'rotate(-90)')
        .attr('x', 0 - ((height + margin.top) / 2))
        .attr('y', 0)
        .attr('dy', 20)
        .style('text-anchor', 'middle')
        .text('paths attempted');

      svg.append('text')
        .attr('class', 'label y2-axis-label')
        .attr('transform', 'rotate(+90)')
        .attr('y', 0 - (width + margin.left + margin.right))
        .attr('x', 0 + ((height + margin.top) / 2))
        .attr('dy', '2em')
        .style('text-anchor', 'middle')
        .text('badge set reached');

      // add brush to svg
      context.append('g')
        .attr('class', 'x brush')
        .call(brush)
        .selectall("rect")
        .attr("y", -6)
        .attr("height", navheight + 7);

      function brushed() {
        time.domain(brush.empty() ? navtime.domain() : brush.extent())
          .range([0, (width)]);
        x.domain(max_extent_in_days(time))
          .rangebands([margin.left, (width)], 0.1, 0);
        focus.selectall('.bar.stack')
          .attr('transform', function(d) {
            return "translate(" + time(d.date) + ",0)";
          })
          .attr('width', x.rangeband());
        focus.selectall('.rect')
          .attr('width', x.rangeband());
        focus.selectall('.line').attr('d', line);
        focus.select(".x.axis").call(x_axis);
      };
    })();
  </script>
</body>

</html>


Related Query