繁体   English   中英

d3的可穿戴和可缩放的时间轴

[英]Brushable and zoomable timeline with d3

我想制作一个时间轴,用户可以在滚动缩放或选择要缩放的区域之间进行选择。 有一些第一个例子: https//bl.ocks.org/mbostock/4015254或用刷子放大一个区域: https//bl.ocks.org/mbostock/f48fcdb929a620ed97877e4678ab15e6
但我找不到兼顾两者的例子。 我怎么能两个都做? 还是有任何我错过的例子?

这不是最直接的实现方式。 正如您将注意到的那样,基于画笔的缩放不依赖于d3.zoom ,而是通过触发事件的侦听器执行缩放,以执行缩放轴和相应移动绘图元素所需的任何操作。

相比之下,所有基于滚动的缩放示例通常依赖于d3.zoom ,其利用d3.zoom()行为来跟踪在平移/缩放时在绘图上执行的所有变换,并且单独负责更新各种图表元素。 困难在于两种方法完全不同,如果您通过刷涂手动更改图表视图,则需要找到一种方法来更新d3.zoom引用的内部缩放变换,以便它了解更改通过基于画笔的缩放事件制作。

这根本不容易做到,因为d3.zoom并非设计用于从其他地方提供信息,并且所执行的转换的内部记录不是可更新/可变的。 您可以通过selection.call(zoom.transform, d3.zoomIdentity);更新转换selection.call(zoom.transform, d3.zoomIdentity); 但遗憾的是,它还会触发与实际缩放行为相关的大量事件,这不是您想要的,因为您已经使用基于画笔的缩放处理了所有缩放行为。 我能够用来重置缩放变换的一个丑陋但有效的解决方法是改变绑定到d3.zoom行为的DOM节点的实际.__zoom字段,如下所示:

// WARNING: Ugly mutation of __zoom property of pan/scroll-zoom rect to
// reset the transform without having to fire events associated with zoom
// d3.select(".zoom").node().__zoom = {k: 1, x: 0, y: 0}; <-- Fails since __zoom contains other hidden objects
scrollZoom.node().__zoom["k"] = 1;
scrollZoom.node().__zoom["x"] = 0;
scrollZoom.node().__zoom["y"] = 0;

例如:如果您想要2D画笔进行矩形缩放,还d3.zoom基于d3.zoom的缩放进行平移和鼠标滚动,那么只要您使用2D画笔进行缩放,就可以将d3.zoom变换重置为身份变换如上。 当使用平移/鼠标滚动操作链接基于2D画笔的缩放操作时,这可以防止和消除抖动/滚动响应中的抖动,因为d3.zoom与记录中的d3.zoom不同步(由于基于2D画笔的缩放更改视图,而无需d3.zoom的知识)。

以下是值得注意的重要事项:

d3.zoom的局限性在于它目前仅支持X轴和Y轴的常用缩放比例( )。 遗憾的是,这意味着无法将基于2-D画笔的缩放映射到基于d3.zoom的方法,因为基于2D画笔的缩放会在X和Y中产生不同的缩放比例。如果您想以最小的问题做事,请使用一致的方法,我建议考虑使用d3.xyzoom 这是d3.zoom一个分支,它实现了对X和Y轴的不同比例的支持。 这将使您能够为任何2D画笔选择计算相应的X和Y缩放比例和平移值,然后您可以将其输入d3.zoom ,从而使您能够使用通用方法执行所有缩放(这也会导致最少量的代码重复)。

话虽如此,如果您只对基于1-D画笔的缩放感兴趣,您应该能够将其映射到d3.zoom方法,这样您就不必处理2个不同的路径来处理视图和缩放图表中的所有轴和其他图形元素。 这是一个很好的例子:

https://bl.ocks.org/mbostock/34f08d5e11952a80609169b7917d4172

我为这篇文章的篇幅道歉,如果它有点散漫。 我正在努力在几天内将我的工作放在一起,我会尝试回到这里,并在我开始这样做时发布一个链接。 我一周前才开始学习D3,所以我一直在学习。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM