我正在使用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;
单击外部画笔选择会创建内部画笔,双击内部画笔的选择将删除它。
我看到除了一个实例之外,所有画笔都表现得很完美。
如果我将外刷挤入内刷,然后尝试改变内刷的高度,d3不尊重内刷的范围,我看到如下所示。
我注意到d3似乎是将高度乘以10,这似乎是造成这种情况。
我在这里做错了吗?