Disable brush resize (DC.js, D3.js)

后端 未结 2 1474
一整个雨季
一整个雨季 2020-12-18 04:18

Brush extent needs to be changed only from a dropdown as shown here: https://jsfiddle.net/dani2011/67jopfj8/3/

Need to disable brush extendi

相关标签:
2条回答
  • 2020-12-18 04:29

    This is from the accepted answer in Disable d3 brush resize, as suggested by @altocumulus. I didn't see a response from @Dani on this idea in particular, but thought I'd go ahead and try it, since I've seen other people try it in the past. (Probably on the dc.js users group.)

    It looks a little twitchy, because d3.js will draw the brush at the new extent, and then a moment later we reset the extent to what we want, but functionally it seems to do what we want.

    In dc.js the function that handles brush "rounding" is coordinateGridMixin.extendBrush:

    _chart.extendBrush = function () {
        var extent = _brush.extent();
        if (_chart.round()) {
            extent[0] = extent.map(_chart.round())[0];
            extent[1] = extent.map(_chart.round())[1];
    
            _g.select('.brush')
                .call(_brush.extent(extent));
        }
        return extent;
    };
    

    Notice that it's following the same pattern as Lars' answer. Well, this is sort of like rounding, right? Let's override it.

    First, let's store the current number of hours when it's set through the dropdown:

    var graphSpan;
    function addHours(amountHours) {
      graphSpan = amountHours;
      // ...
    

    Next let's override coordinateGridMixin.extendBrush:

    timeSlider.extendBrush = function() {
        var extent = timeSlider.brush().extent();
        if(graphSpan) {
            extent[1] = moment(extent[0]).add(graphSpan, 'hours');
        }
        return extent;
    }
    

    We just replace the function. If we needed to reuse the old implementation in our function, we could use dc.override.

    If graphSpan has been set, we add that amount to the beginning to get the end. If it's not set, we allow the user to specify the brush width - you'd need to default the graphSpan and the select widget if you wanted that part to work automatically.

    Well, let's admit it: it's very twitchy, but it works:

    EDIT: Got rid of the twitch! The problem was that dc.js was setting the brush extent asynchronously after a little while (in response to the filter event). If we also set it during extentBrush then it never shows the wrong extent:

    timeSlider.extendBrush = function() {
        var extent = timeSlider.brush().extent();
        if(graphSpan) {
          extent[1] = moment(extent[0]).add(graphSpan, 'hours');
          timeSlider.brush().extent(extent);
        }
        return extent;
    }
    

    https://jsfiddle.net/gordonwoodhull/xdo05chk/1/

    0 讨论(0)
  • 2020-12-18 04:51

    What worked for me:

    in d3:

    disable resize handles d3.selectAll('.brush>.handle').remove();

    disable crosshair d3.selectAll('.brush>.overlay').remove();

    or in css:

    disable resize handles -

    .handle {
        pointer-events: none;
    }
    

    disable crosshair -

    .overlay {
        pointer-events: none;
    }
    
    0 讨论(0)
提交回复
热议问题