d3.js:刷的极限尺寸(d3.js: limit size of brush)

2019-09-22 06:35发布

有没有办法来限制画笔的大小,尽管程度更大?

我放在一起刷,只有一个X级,可移动和调整大小。 我想能够限制到其中它可以通过用户调整的程度(基本上只达到一定点)。

在下面的示例中,当刷变得大于一半的最大程度上的刷子功能停止更新。 刷本身,但是,仍然可以延长。 有没有一种方法,以防止这种情况发生? 还是有处理这更好的办法?

非常感谢!

看到这里的代码在行动: http://bl.ocks.org/3691274 ( 编辑 :这个演示现在工作)

bar = function(range) {

      var x_range = d3.scale.linear()
          .domain([0, range.length])
          .range([0, width]); 

      svg.selectAll("rect.items").remove();

      svg.selectAll("rect.items")
          .data(range)
        .enter().append("svg:rect")
          .attr("class", "items")
          .attr("x", function(d, i) {return x_range(i);})
          .attr("y", 0)
          .attr("width",  width/range.length-2)
          .attr("height", 100)
          .attr("fill", function(d) {return d})
          .attr("title", function(d) {return d});
}

var start = 21;
bar(data.slice(0, start), true);

var control_x_range = d3.scale.linear()
    .domain([0, data.length])
    .range([0, width]); 

controlBar = svg.selectAll("rect.itemsControl")
    .data(data)
  .enter().append("svg:rect")
    .attr("class", "itemsControl")
    .attr("x", function(d, i) {return control_x_range(i);})
    .attr("y", 110)
    .attr("width",  width/data.length-2)
    .attr("height", 20)
    .attr("fill", function(d) {return d});

svg.append("g")
    .attr("class", "brush")
    .call(d3.svg.brush().x(d3.scale.linear().range([0, width]))
    .extent([0,1*start/data.length])
    .on("brush", brush))
  .selectAll("rect")
    .attr("y", 110)
    .attr("height", 20);

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));
    };

}

Answer 1:

我终于解决了它由超过大小时重画刷其允许的最大尺寸:

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));}
} 

演示: http://bl.ocks.org/3691274

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



Answer 2:

下面是使用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的大小仍然过大。



Answer 3:

这里是限制性的画笔的最小宽度为100像素和最大宽度为200ps的的一个例子。 我添加几行到d3.v4.js,用于设定刷宽度的限制。

加入brush.limit为设定的限制([最小值,最大值]):

var _limit = null;
brush.limit = function (l) {
  _limit = l;
}

在此举打破鼠标移动事件()函数:

if (_limit && e1 - w1 < _limit[0]) {
  return;
}

( 演示 )( 源代码 )



Answer 4:

尼斯一段代码,但我发现了一个小错误。 它锁定你刷每当s[1]-s[0] < 0.5 ,但如果你按住调整大小,并把所有的刷到oposite方向,它开始“移动”刷无任何动作(即它不”牛逼的行为,因为它应该)。

我敢肯定我能拿出一个合理的解决方案。 如果是的话,我会在这里重新发布。

(对不起它张贴在这里作为一个答案,但你已经回答过一次,我不能作为一个评论,我想POST)。



文章来源: d3.js: limit size of brush