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

时间:2017-01-09 16:01:19

标签: javascript d3.js zoom zooming brush

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

1 个答案:

答案 0 :(得分:0)

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

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

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

d3.zoom

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

以下是其他值得注意的事项:

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

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

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

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