【 D3.js 进阶系列 — 6.1 】 缩放的应用(Zoom)

缩放(Zoom)是另一种重要的可视化操作,主要是使用鼠标的滚轮进行。

1. zoom 的定义

缩放是由 d3.behavior.zoom() 定义的。

第 2 行:scaleExtent 用于设置最小和最大的缩放比例

第 3 行:当 zoom 事件发生时,调用 zoomed 函数

第 5 – 8 行:zoomed 函数,用于更改需要缩放的元素的属性,d3.event.translate 是平移的坐标值,d3.event.scale 是缩放的值。

2. 绘制圆

与【进阶 – 第 6.0 章】一样,绘制两个圆用于测试。只是将圆 circle 元素添加到一个组 g 里,g 元素调用 call(zoom),zoom 为刚才定义的缩放行为。

3. 结果

结果如下,在圆上滑动鼠标滚轮试试:

源代码单击以下链接后查看:

http://www.ourd3js.com/demo/J-6.1/zoom.html
谢谢阅读。

文档信息

【 D3.js 进阶系列 — 6.1 】 缩放的应用(Zoom)》上有28条评论

  1. 老师,您好。
    我现在在用zoom in/out来做一个scatter plot,但是在zoom in的过程,坐标轴如何能保持在原来的位置并且也跟着一起zoom in/out呢?
    我现在能做到整个图一起zoom in/out,但是坐标轴由于zoom in的扩大作用就消失在界面里面了。
    谢谢。

  2. 购买了你的书,写的非常好,值得学习。
    我现在有个问题是 力导图 如何实现 整体缩放呢

  3. 老师能不能详细解释下这句的执行意思
    .attr(“transform”,
    “translate(” + d3.event.translate + “)scale(” + d3.event.scale + “)”);

    • d3.event 是一个对象,其中的 translate 和 scale 分别是平移和缩放量,都是一个数组。将它们分贝作为 transform 中的 translate 和 scale 参数即可实现平移和缩放。

      • 但是调用zoom的代码是:
        var zoom = d3.behavior.zoom()
        .scaleExtent([1, 10])
        .on(“zoom”, zoomed);
        可是并没有传入任何的参数,那怎么知道要实现多少的平移和缩放呢?

        • d3 的设计是,当任何事件发生后,都写到一个对象 d3.event 里,缩放和平移了多少都在里面。

  4. 版主好,我问一下zoom事件可以通过放大缩小按钮来控制吗?而不是鼠标的滚动,如果可以的怎么实现呢???

  5. 请问,地图缩放移动的时候怎样实现上面的图标大小不变但是移动?

  6. 怎么用按钮控制缩放呀 急 求帮忙

  7. 博主您好!近两天很受您的文章的帮助。我有一个项目,是有坐标轴和拆线图,X轴是时间,Y轴是价格,需求是在wheel时,X轴要改变,拆线图也要相应显示X轴改变之后的时间段的部分。由于不能直接放大缩小拆线图本身,(因为线条粗细是不让改变的,直接缩放会改变粗细),您有什么好的解决办法吗?多谢!

    • 在SVG区域内蒙一块透明的矩形,用于捕捉鼠标事件。
      当事件发生时,改变坐标轴的domain和range,同时折线的位置也改变。

      其实改变什么内容是可以由开发者自己定的,你不让它变粗,它就不会变粗,关键看你修改了什么属性。

      • Hi, 博主,我找到想要的答案了,用vector-effect属性可以解决。参见:http://www.w3.org/TR/SVGTiny12/painting.html#NonScalingStroke。谢过~~~

  8. 楼主你好,我在一个div中放置一个svg, div的overflow设置成scoll,当svg超过div时,会出现滚动条。这时如果滚动鼠标,滚动条会跟着移动。之后我给svg加上了缩放事件,这时滚动鼠标会svg会产生缩放的效果。但是之后我想取消缩放事件,让鼠标的滚动重新控制滚动条,该怎么办呢?多谢指导。

    • 您好。
      我也不知该如何处理。应该与事件的优先级有关,一时半会儿还没找到解决办法。需要查几天。

      如果你已经找到解决办法,请在此处留言。谢谢

  9. 版主好,我问一下zoom事件可以通过放大缩小按钮来控制吗?而不是鼠标的滚动,如果可以的怎么实现呢?

    • 这就不需要使用 d3.behavior.zoom() 了,自己做两个按钮,自己设定缩放参数吧。

  10. 版主好, 我试了下,可以实现单个节点的缩放,也能实现所有节点的共同缩放,但有几个问题,对于力导向图的单个节点,缩放完一个,对另一个节点缩放的同时,会出现节点错位的现象,还有就是,既然能做到节点缩放,能不能对整个图进行缩放呢,有时候图像太大,svg容器显示不完全,能否整个图像进行缩放,达到全局预览的效果

    • 缩放行为是 d3.behavior.zoom() 定义的,其中,当缩放发生(zoom事件触发)时,调用
      function zoomed() {
      d3.select(this).attr(“transform”,
      “translate(” + d3.event.translate + “)scale(” + d3.event.scale + “)”);
      }

      请注意,当缩放事件发生时,我们做了什么?
      选择this,更改其transform属性。
      那么,能不能选择其他的图形元素,更改transform属性呢?当然也可以。其实缩放哪一个元素,是可以由自己决定的。

      另外,要捕捉哪一个元素的zoom事件,是由
      selection.call(zoom);
      决定的。

      因此,你可以在SVG上绘制一个与SVG画板大小相同的透明矩形,专门用于捕捉事件,代码形如:
      .overlay {
      fill: none;
      pointer-events: all;
      }

      svg.append(“rect”)
      .attr(“class”,”overlay”)
      .attr(“x”,0)
      .attr(“y”, 0)
      .attr(“width”,width)
      .attr(“height”,height)
      .call(zoom);

      该透明矩形专门用于捕捉缩放事件。当zoom事件发生时,对其他元素进行缩放:

      function zoomed() {
      myelements //你希望进行操作的元素
      .attr(“transform”,
      “translate(” + d3.event.translate + “)scale(” + d3.event.scale + “)”);
      }

      此思路应该能实现你希望的功能。

      谢谢。

  11. 请问地图能不能缩放 我在地图上写了缩放的代码好像不太好用

    • 可以的,类似谷歌地图那样的缩放拖移功能完全可以实现。不过,可不像这篇文章说的那么简单。

      • 你那个旋转地球仪的例子,我想在那个基础之上加上缩放,貌似不管用啊。要怎么做啊?

  12. 这个是能拖拽图形的,请问怎么能取消拖拽效果呢?

    • 下面这个函数,改成

      function zoomed() {
      d3.select(this).attr(“transform”,
      “scale(” + d3.event.scale + “)”);
      }

      即可。祝好

      • 试了下,改了之后缩放中心就变左上角了,设置坐标值也没用。

        自己又查了查,
        .call(zoom)
        .on(“mousedown.zoom”, null);
        这样就行了

评论已关闭。