Javascript d3.js:限制刷子的大小

Javascript d3.js:限制刷子的大小,javascript,range,scale,d3.js,brush,Javascript,Range,Scale,D3.js,Brush,有没有办法限制画笔的大小,即使画笔的范围更大 我组装了一个只有x刻度的画笔,可以移动和调整大小。我希望能够限制用户可以调整大小的范围(基本上只能调整到某一点) 在下面的示例中,当笔刷大于最大范围的一半时,笔刷函数停止更新。不过,画笔本身仍然可以延伸。有没有办法防止这种情况发生?还是有更好的处理方法 非常感谢 请在此处查看此代码:(编辑:此演示现在可以工作了) bar=功能(范围){ var x_range=d3.scale.linear() .domain([0,range.length]) .

有没有办法限制画笔的大小,即使画笔的范围更大

我组装了一个只有x刻度的画笔,可以移动和调整大小。我希望能够限制用户可以调整大小的范围(基本上只能调整到某一点)

在下面的示例中,当笔刷大于最大范围的一半时,笔刷函数停止更新。不过,画笔本身仍然可以延伸。有没有办法防止这种情况发生?还是有更好的处理方法

非常感谢

请在此处查看此代码:(编辑:此演示现在可以工作了)

bar=功能(范围){
var x_range=d3.scale.linear()
.domain([0,range.length])
.范围([0,宽度]);
selectAll(“rect.items”).remove();
svg.selectAll(“rect.items”)
.数据(范围)
.enter().append(“svg:rect”)
.attr(“类别”、“项目”)
.attr(“x”,函数(d,i){返回x_范围(i);})
.attr(“y”,0)
.attr(“宽度”,宽度/范围.length-2)
.attr(“高度”,100)
.attr(“fill”,函数(d){return d})
.attr(“标题”,函数(d){return d});
}
var start=21;
条(data.slice(0,start),true);
var control_x_range=d3.scale.linear()
.domain([0,data.length])
.范围([0,宽度]);
controlBar=svg.selectAll(“rect.itemsControl”)
.数据(数据)
.enter().append(“svg:rect”)
.attr(“类”、“项控件”)
.attr(“x”,函数(d,i){return control_x_range(i);})
.attr(“y”,110)
.attr(“宽度”,宽度/数据长度-2)
.attr(“高度”,20)
.attr(“fill”,函数(d){return d});
svg.append(“g”)
.attr(“类”、“刷”)
.call(d3.svg.brush().x(d3.scale.linear().range([0,width]))
.extent([0,1*起始/数据.length])
.on(“刷子”,刷子))
.selectAll(“rect”)
.attr(“y”,110)
.attr(“高度”,20);
函数刷(){
var s=d3.event.target.extent();
如果(s[1]-s[0]<0.5){
var start=数学四舍五入((数据长度-1)*s[0]);
var end=数学四舍五入((数据长度-1)*s[1]);
条(data.slice(开始,结束));
};
}

我最终解决了这个问题,当画笔的大小超过允许的最大值时,我将画笔重新绘制到允许的最大值:

function brush() {
    var s = d3.event.target.extent();
    if (s[1]-s[0] < 0.5) {
        var start = Math.round((data.length-1)*s[0]);
        var end = Math.round((data.length-1)*s[1]);

        bar(data.slice(start,end));
    }
    else {d3.event.target.extent([s[0],s[0]+0.5]); d3.event.target(d3.select(this));}
} 
函数刷(){
var s=d3.event.target.extent();
如果(s[1]-s[0]<0.5){
var start=数学四舍五入((数据长度-1)*s[0]);
var end=数学四舍五入((数据长度-1)*s[1]);
条(data.slice(开始,结束));
}
else{d3.event.target.extent([s[0],s[0]+0.5]);d3.event.target(d3.select(this));}
} 
演示:


我仍然对阅读更好的解决方案感兴趣。

这段代码不错,但我发现了一个小错误。 无论何时
s[1]-s[0]<0.5
,它都会锁定你的画笔,但如果你一直按resize并将所有画笔移到oposite方向,它会开始“移动”画笔而不做任何动作(即,它的行为不正常)

我很肯定我能想出一个合理的解决办法。如果是的话,我会在这里重新发布


(很抱歉将其作为答案发布在这里,但由于您已经回答了一次,我想我无法将其作为评论发布)。

以下是使用d3.v4和ES6的另一个策略:

brush.on('end', () => {
    if (d3.event.selection[1] - d3.event.selection[0] > maxSelectionSize) {
        // selection is too large; animate back down to a more reasonable size
        let brushCenter = d3.event.selection[0] + 0.5 * (d3.event.selection[1] - d3.event.selection[0]);
        brushSel.transition()
            .duration(400)
        .call(brush.move, [
            brushCenter - 0.49 * maxSelectionSize,
            brushCenter + 0.49 * maxSelectionSize
        ]);
    } else {
        // valid selection, do stuff
    }
});
如果用户放开笔刷选择时,笔刷选择大小过大,则会将其动画设置回指定的最大大小(
maxSelectionSize
)。此时,
'end'
事件将以可接受的选择大小再次触发


请注意
0.49
标量:这是为了防止浮点/舍入错误,如果画笔
move()
d的大小仍然太大,则可能会导致无限循环。

以下是限制画笔最小宽度为100px,最大宽度为200ps的示例。我在d3.v4.js中添加了几行,用于设置笔刷宽度的限制

为设置限制添加了笔刷限制([min,max]):

var _limit = null;
brush.limit = function (l) {
  _limit = l;
}
move()函数中的断开鼠标移动事件:

if (_limit && e1 - w1 < _limit[0]) {
  return;
}
if(&u-limit&&e1-w1<\u-limit[0]){
返回;
}

()

这是Bostock关于如何强制执行特定笔刷大小的一个很好的例子:他不强制执行最大大小,但可以通过检查笔刷域
d1.map(x)
轻松添加,如所示
if (_limit && e1 - w1 < _limit[0]) {
  return;
}