-->

DC JS Limiting brushing height

2019-07-27 06:34发布

问题:

Is there a way to limit the brushing height - say 50% of y axis (only from Y axis 0 - 250, brushing should work) ? Example fiddle

JS Code:

var hitslineChart = dc.barChart("#chart-line-hitsperday"); 

            var data = [
        {date: "12/27/2012", http_404: 2, http_200: 190, http_302: 100},
        {date: "12/28/2012", http_404: 2, http_200: 10, http_302: 100},
        {date: "12/29/2012", http_404: 1, http_200: 300, http_302: 200},
        {date: "12/30/2012", http_404: 2, http_200: 90, http_302: 0},
        {date: "12/31/2012", http_404: 2, http_200: 90, http_302: 0},
        {date: "01/01/2013", http_404: 2, http_200: 90, http_302: 0},
        {date: "01/02/2013", http_404: 1, http_200: 10, http_302: 1},
        {date: "01/03/2013", http_404: 2, http_200: 90, http_302: 0},
        {date: "01/04/2013", http_404: 2, http_200: 90, http_302: 0},
        {date: "01/05/2013", http_404: 2, http_200: 90, http_302: 0},
        {date: "01/06/2013", http_404: 2, http_200: 200, http_302: 1},
        {date: "01/07/2013", http_404: 1, http_200: 200, http_302: 100}
        ];

            var ndx = crossfilter(data); 
            var parseDate = d3.time.format("%m/%d/%Y").parse;
            data.forEach(function(d) {
        d.date = Date.parse(d.date);
        d.total= d.http_404+d.http_200+d.http_302;
        });
            var dateDim = ndx.dimension(function(d) {return d.date;});
            var hits = dateDim.group().reduceSum(function(d) {return d.total;});
            var minDate = dateDim.bottom(1)[0].date;
            var maxDate = dateDim.top(1)[0].date;

        hitslineChart.width(500)
                   .height(200)
                     .dimension(dateDim)
                     .group(hits)
                     .x(d3.time.scale().domain([minDate,maxDate]));                                         
            dc.renderAll();

Thanks, Arun

回答1:

Although your example uses dc.js 1.7.0, I'm going to answer for dc.js 2.0, since it's a lot newer and a few APIs have changed.

The technique is to override the functions from the coordinateGridMixin which size the brush. This gets a little hairy, but it's possible.

It turns out we'll have to override three undocumented functions which render the brush, renderBrush, setBrushY, and (unfortunately) resizeHandlePath.

The reason this gets hairy is that we really want to override brushHeight, but that one is a private function.

We'll define our own like this:

function height_over_2() {
  return (hitslineChart._xAxisY() - hitslineChart.margins().top)/2;
}

For renderBrush, we need to shift the brush down by height_over_2(). We'll pass through the call first, then modify the transform:

dc.override(hitslineChart, 'renderBrush', function(g) { 
   hitslineChart._renderBrush(g);
   var gBrush = hitslineChart.select('g.brush')
         .attr('transform', 'translate(' + hitslineChart.margins().left + ',' + (hitslineChart.margins().top + height_over_2()) + ')')
});

setBrushY we'll replace entirely (we could just assign to it, but we'll use dc.override for consistency):

dc.override(hitslineChart, 'setBrushY', function(gBrush) {
  gBrush.selectAll('rect')
      .attr('height', height_over_2());
  gBrush.selectAll('.resize path')
      .attr('d', hitslineChart.resizeHandlePath);  
 });

Finally, resizeHandlePath also uses the height, and here we (ugh) have to copy a big chunk of code out of dc.js, which was itself copied from the crossfilter demo:

dc.override(hitslineChart, 'resizeHandlePath', function (d) {
    var e = +(d === 'e'), x = e ? 1 : -1, y = height_over_2() / 3;
    return 'M' + (0.5 * x) + ',' + y +
        'A6,6 0 0 ' + e + ' ' + (6.5 * x) + ',' + (y + 6) +
        'V' + (2 * y - 6) +
        'A6,6 0 0 ' + e + ' ' + (0.5 * x) + ',' + (2 * y) +
        'Z' +
        'M' + (2.5 * x) + ',' + (y + 8) +
        'V' + (2 * y - 8) +
        'M' + (4.5 * x) + ',' + (y + 8) +
        'V' + (2 * y - 8);
});

Fork of your fiddle: http://jsfiddle.net/gordonwoodhull/anz9gfy0/13/



标签: d3.js dc.js