d3.brush() 区域选择:
作用:Brush 的功能是用来选取图表上的某一个区间,我们对此区间段内的元素做 (变色、移位、放大缩小等等),类似于放大镜功能,适用于图表的某一块区域特殊处理之类的需求
常见的一些操作方法
d3.brush( )、d3.brushX( )、d3.brushY( )
当我们使用 d3.brush( )时,它会建立一个二维 brush 并自动带入svg的鼠标跟触控事件,我们就能用鼠标或手指触控来进行操作。
除了使用d3.brush( ) 之外,如果你只想建立一维X轴向的brush,可以用 d3.brushX( ) 这个API;反之如果想建立一维Y轴向的brush,则是使用d3.brushY( )。
建立好brush之后,我们接著使用 selection.call( )的方法把建立好的 brush 绑定到选定的DOM元素上,然后就可以使用 brush.on(事件,方法) 来监听 brush 事件
brush.on(事件, 方法 ) 分为三种
1.strat 移动开始时
2.brush 移动中
3.end 动作结束时
<script>
svg.append("g")
.call(d3.brush()
.on("start brush", brushed)
.on('end' brushEnd)
)
</script>
一旦我们开始监听 brush event 之后,每个 event 就会包含以下几种属性;
brushFn回调的函数参数是event,需要调用该参数获取到相关的参数;
target - 触发brush 行为的元素
type -目前的事件状态,例如 start、brush、end
selection - 目前绑定node节点的 brush 选取集合。这个集合一般是一个数组,如果brush是二维,此集合的是[[x0, y0], [x1, y1]]。使用 event.selection 來判断DOM元素是否在brush范围内。
sourceEvent - 原生事件,例如 mousemove 或 touchmove
mode - brush当前的状态,例如 drag、space、handle、center 等等。
brush.extent([[x0, y0], [x1, y1]])
这个方法是用来设定可以框选的范围,[x0, y0] 是设定左上角位置,[x1, y1]则是设定右下角位置。一般来说会设定的跟svg一样大或是稍微大一点。
brush.handleSize([size])
这个方法则是用来设置 brush 尺寸的大小。没有特别设定的话,其预设尺寸为6。这个方法必须要在用selection.call( ) 使用并绑定brush 之前就使用。
示例:
<body>
<svg style="width: 600px; height:500px; border:1px blue solid" xmlns="http://www.w3.org/2000/svg">
</svg>
</body>
<script>
const dataCircle = [
{ cx: 100, cy: 150, r: 10 },
{ cx: 200, cy: 250, r: 15 },
]
const svg = d3.select("svg");
const circles = svg.selectAll("circle")
.data(dataCircle)
.join("circle")
.attr("cx", d => d.cx)
.attr("cy", d => d.cy)
.attr("r", d => d.r)
.attr("fill", "pink")
// 设置brush事件,效果是选中区域内的圆fill填充色变红
const brush = svg.append('g')
.attr("class", 'test')
.call(
d3.brush().extent([[0, 0], [600, 600]]) // 设置鼠标刷取范围,一般比svg要大
.on("end", brushend))
// 设定brush回调函数
function brushend(event) {
console.log(event); // 可以看到打印出来的是对应的相关参数
const extent = event.selection // 是一个数组
circles.classed('selected', d => { // .classed("className", boolearn)方法是动态给选定的元素添加类名,依据布尔值进行判断是否添加
console.log(d); // 对应元素的坐标和大小属性
return isBrushed(extent, d.cx, d.cy)
})
}
// 判断是否在划取的区间之内
function isBrushed(params, x, y) {
let x0 = params[0][0],
y0 = params[0][1],
x1 = params[1][0],
y1 = params[1][1];
console.log(x0, y0); // 划取区域开始点的坐标
console.log(x1, y1); // 划取区域结束点的坐标
// 判断范围
return x0 <= x && y0 <= y && x1 >= x && y1 >= y
}
</script>
