D3 - 使用嵌套画笔

时间:2018-02-07 14:16:55

标签: javascript d3.js

我正在使用d3创建2个嵌套画笔。内刷由外刷约束。我还使用filter函数限制画笔的行为。以下是整个代码:

(我已经离开了日志以帮助识别流程 - 我发现运行代码和使用" Full Page"以下更好)



<!DOCTYPE html>

<style>
.handle--w, .selection, .overlay {
  cursor: auto;
}

.brush2>.handle--n {
  cursor: auto;
}

.brush2>.selection {
  fill: red;
}

</style>
<svg width=1200 height=500></svg>

<script src="https://d3js.org/d3.v4.min.js" charset="utf-8"></script>
<script type="text/javascript">
var rectHeight = 80, rectWidth = 180,
  svg = d3.select("svg"),
  mainGroup = svg.append("g");

var xScale = d3.scaleLinear()
    .domain([0,1])
    .range([0,rectWidth]);

// function for outer brush
var brush1 = d3.brushX()
    .extent([[0, 0], [rectWidth-10, rectHeight]])
    .handleSize([4])
    .filter(function(){
      // keep only the right side expansion/contraction
      return !d3.event.button
        && !d3.select(d3.event.target).classed("handle--w")
        && !d3.select(d3.event.target).classed("overlay")
        && !d3.select(d3.event.target).classed("selection")
        ;
    })
    .on("brush", brushed1)
    ;

// when brush1 is "move"d
function brushed1() {
  var w = d3.select(this).select(".selection").attr("width")-3;
  console.log("in brushed1 -- "+w);
  if(!d3.select(this.nextSibling).empty()){
    // handle the inner brush, if present
    console.log("found inner brush");
    var innerBrush = d3.select(this.nextSibling);
    brush2.extent([[0,0],[w,rectHeight]]);
    innerBrush.call(brush2);
    if (w < innerBrush.select(".selection").attr("width")){
      var innerHeight = innerBrush.select(".selection").attr("height");
      innerBrush.call(brush2.move, [[0,0],[w,innerHeight]]);
    }
  }
}

// function for inner brush
var brush2 = d3.brush()
  .handleSize([4])
  .filter(function(){
    return !d3.event.button
      && !d3.select(d3.event.target).classed("overlay")
      && !d3.select(d3.event.target).classed("selection")
      ;
  });

// create outer brush
mainGroup.append("g")
  .attr("class", "brush1")
  .call(brush1)
  .call(brush1.move, [0,0.65].map(xScale));

// add function for outer brush selection click
mainGroup.selectAll("rect.selection")
  .on("mousedown touchstart", function() {
    var w = d3.select(this).attr("width")-3;
    console.log("Selection clicked  -- " + w);
    var p = d3.select(this.parentNode.parentNode);

    // Create inner brush if one doesn't exist
    if (d3.select(this.parentNode.nextSibling).empty()) {
      console.log("creating element");
      console.log(`w ${w} rectHeight ${rectHeight}`);
      brush2.extent([[0,0], [w,rectHeight]]);
      var innerBrush = p.append("g")
        .attr("class", "brush2")
        .call(brush2)
        .call(brush2.move, [[0,0],[w/2,rectHeight/2]])
        ;

      // remove inner brush if double clicked
      innerBrush.select("rect.selection")
        .on("dblclick touchstart", function(){
          console.log("removing element");
          d3.select(this.parentNode).remove();
        })
    }
  });
</script>
&#13;
&#13;
&#13;

单击外部画笔选择会创建内部画笔,双击内部画笔的选择将删除它。

我看到除了一个实例之外,所有画笔都表现得很完美。

如果我将外刷挤入内刷,然后尝试改变内刷的高度,d3不尊重内刷的范围,我看到如下所示。

在: Before Image

在: After Image

我注意到d3似乎是将高度乘以10,这似乎是造成这种情况。

我在这里做错了吗?

0 个答案:

没有答案