我正在尝试在d3(v4)图表中同时实现缩放和刷涂。
我使它们都可以单独工作,但是当我尝试在同一张图表上同时实现这两个功能时,就会出现问题。
我的情况如下:1.用户使用画笔显示图表的特定区域。2.然后进行缩放/平移,但这会导致视图跳回到旧位置,因为存储的缩放变换无法识别刷涂所做的更改。
我的理解是,当前的缩放变换(缩放+平移)存储在DOM元素内部的内部__zoom
属性中。每当您与元素互动时(例如,通过滚动鼠标滚轮),zoom插件都会自动调整此设置。
我看到您可以使用d3.zoomTransform来获取元素的当前缩放变换。
如何重置/删除存储的缩放变换(例如,在平移之后,以便从笔刷停止处继续进行任何后续缩放)?
注意:我不想更改缩放比例,而只是更新存储的缩放比例转换以将该新比例视为“标识”。这很重要,因为我希望能够在刷等时从一个刻度平滑过渡到另一个刻度。
我最终解决这个问题的方法是:
transform.rescaleX()
获取新的转换比例这里的关键是,在缩放比例已更新之后,始终将DOM元素上存储的转换放回身份(即,scale = 1,translate = 0,0)。
这意味着我们不必担心刷涂/缩放或在不同元素上对缩放比例进行任何编程更改都不会冲突或彼此具有不同的值。我们实际上只是对元素应用很小的比例因子。
就代码示例而言,这是我的工作图中的相关部分:
// class contains:
// this.xScale - stored scale for x-axis
// this.xAxis - a d3 Axis
// this.xAxisElement - a d3 selection for the element on which the x-axis is drawn
// this.zoomX - a d3 ZoomBehavior
// this.chartElement - a d3 selection for the element on which the zooming is added
protected setupZooming(): void {
this.zoomX = d3.zoom().on('zoom', () => { this.onZoomX(); });
this.zoomXElement = this.xAxisElement
.append('rect')
.attr('fill', 'none')
.style('pointer-events', 'all')
.attr('width', this.width)
.attr('height', this.margin.bottom)
.call(this.zoomX);
}
onZoomX(): void {
const transform: d3.ZoomTransform = d3.event.transform;
if (transform.k === 1 && transform.x === 0 && transform.y === 0) {
return;
}
const transformedXScale = transform.rescaleX<any>(this.xScale);
const from = transformedXScale.domain()[0];
const to = transformedXScale.domain()[1];
this.zoomXTo(from, to, false);
this.chartElement.call(this.zoomX.transform, d3.zoomIdentity);
}
zoomXTo(x0: Date, x1: Date, animate: boolean): void {
const transitionSpeed = animate ? 750 : 0;
this.xScale.domain([x0, x1]);
this.xAxisElement.transition().duration(transitionSpeed).call(this.xAxis);
this.updateData(transitionSpeed);
}
updateData(transitionSpeed: number): void {
// ...
}
如果在我的其余代码上下文之外不容易理解此摘录,则表示歉意,但希望它仍然会有所帮助。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句