D3.js缩放后选择功能异常,d3.event.selection值始终不变求助
解决D3缩放后Brush选区坐标错位问题
我来帮你搞定这个问题——你遇到的是D3中Zoom和Brush配合时非常典型的坐标转换错位问题,原因很简单:缩放后画布应用了变换,但Brush的选区坐标没有经过逆变换处理,导致你拿到的还是原始画布坐标系下的区域,而非缩放后的实际可视区域对应的原始数据范围。
问题核心原因
当你通过d3.zoom对画布进行缩放/平移后,画布上的所有元素都应用了transform(包含缩放倍数k和平移量x/y)。但d3.brush获取到的d3.event.selection是基于当前屏幕坐标系的坐标,直接用这个坐标去匹配原始数据的位置,就会出现错位——相当于你在放大后的画布上选了一块区域,但代码还是按照没放大前的位置去筛选数据。
具体解决步骤
你只需要在brudhtest函数中,对Brush获取到的选区坐标做逆变换,把屏幕坐标转换回原始画布/数据坐标系下的坐标即可。修改你的brudhtest函数如下:
brudhtest(test, test2, dataSel, transform) { let extent = d3.event.selection console.log(extent) console.log(transform.k) if (!extent) return; // 关键:对选区的两个角点应用逆变换,得到原始坐标系下的范围 const [topLeft, bottomRight] = extent; const originalTopLeft = transform.invert(topLeft); const originalBottomRight = transform.invert(bottomRight); // 使用逆变换后的坐标进行数据筛选 var x0 = originalTopLeft[0], x1 = originalBottomRight[0], y0 = originalTopLeft[1], y1 = originalBottomRight[1]; let elementsOfInterest = test.filter(element => { return x0 <= this.x(element[a]) && this.x(element[a]) <= x1 && y0 <= this.y(element[b]) && this.y(element[b]) <= y1; }); // 这里可以添加筛选后的数据处理逻辑 }
额外注意事项
- 确保你传入的
transform是当前最新的缩放变换对象(也就是zoom事件中拿到的d3.event.transform),你的代码里已经在调用brudhtest时传入了this.t,这部分是没问题的。 - 未缩放时正常的原因:此时
transform.k = 1,平移量x/y为0,逆变换后的坐标和原始屏幕坐标完全一致,所以筛选逻辑正常。
这样修改后,缩放后的Brush选区就能正确对应到原始数据的范围,筛选功能就可以正常工作了。
内容的提问来源于stack exchange,提问作者thouraya
相关产品推荐
相关产品推荐

