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

十年热恋 提交于 2019-12-01 06:24:50
Gordon

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:

https://jsfiddle.net/gordonwoodhull/272xrsat/5/

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/272xrsat/9/

Phil Borkenhagen

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;
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!