如何在d3.js

时间:2016-10-12 12:34:09

标签: javascript d3.js d3.js-v4

我使用d3.js V 4.0在SVG中提供缩放和平移。我正在实现一个重置按钮,让我回到图像的中心。它正在工作,但它使用默认的d3.interpolateZoom,因此图像在过渡期间缩小。我只是希望缩放进行标准插值,但我无法弄清楚如何更改缩放行为的插补器。 这是代码的缩写版本:



var map = document.querySelector('#map');
var everything = d3.select('#everything');
var zoomBehavior = d3.zoom();
zoomBehavior.scaleExtent([0.5, 10])
  .on('zoom', zoomed);
d3.select(map).call(zoomBehavior);

function zoomed() {
  everything.attr('transform', d3.event.transform);
}

function reset() {
  d3.select(this.map)
    .transition()
    .duration(1000)
    .call(zoomBehavior.transform, d3.zoomIdentity);
}

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.1.0/d3.min.js"></script>
<svg id="map" version="1.1" xmlns="http://www.w3.org/2000/svg">
  <g id="everything">
    <circle r="5" cx="50" cy="15"></circle>
  </g>
</svg>
<button onclick="reset()">reset</button>
&#13;
&#13;
&#13;

不幸的是,这并没有表现出我所看到的行为。 (在我的真实版本中,缩放k使用van Wijk smooth zooming插入0但是问题仍然有效。如果我要为这种缩放行为更改插补器,我将如何以及在哪里这样做?我试过调用文档似乎建议的zoomBehavior.interpolate(d3.interpolate),但是我收到一条错误,指出zoomBehavior.interpolate不是函数。

3 个答案:

答案 0 :(得分:1)

如果不看到你试图避免的行为,很难回答这个问题。上面的示例代码按预期工作。也就是说,这是一个完整控制插值器并因此完成转换的例子。在这里,我将圈子缩放回scale: 1,但{s}向右下方xy

&#13;
&#13;
<!DOCTYPE html>
<html>

<head>
  <script data-require="d3@4.0.0" data-semver="4.0.0" src="https://d3js.org/d3.v4.js"></script>
</head>

<body>
  <svg id="map" version="1.1" xmlns="http://www.w3.org/2000/svg">
    <g id="everything">
      <circle r="5" cx="50" cy="15"></circle>
    </g>
  </svg>
  <button onclick="reset()">reset</button>
  <script>
    var map = d3.select('#map'),
        everything = d3.select('#everything');

    var zoomBehavior = d3.zoom();
    zoomBehavior.scaleExtent([0.5, 10])
      .on('zoom', zoomed);

    map.call(zoomBehavior);

    function zoomed() {
      everything.attr('transform', d3.event.transform);
    }

    function reset() {
      d3.select(this.map)
        .transition()
        .duration(1000)
        .tween("custom", function() {
          var curZoom = d3.zoomTransform(map.node()),
            kInter = d3.interpolate(curZoom.k, 1),
            xInter = d3.interpolate(curZoom.x, 240),
            yInter = d3.interpolate(curZoom.y, 99);
          return function(t) {
            var ts = d3.zoomIdentity
              .translate(xInter(t), yInter(t))
              .scale(kInter(t));
            map.call(zoomBehavior.transform, ts);
          };
        });
    }
  </script>
</body>

</html>
&#13;
&#13;
&#13;

答案 1 :(得分:1)

我们遇到了同样的问题,并使用post2 方法解决了。应用于您的代码,它看起来像这样:

interpolate

根据http://devdocs.io/d3~4/d3-zoom#zoom_interpolatezoomBehavior.interpolate(d3.interpolate).scaleExtent([0.5, 10]) .on('zoom', zoomed); 应用“两个视图之间的直接插值”,而默认值为d3.interpolate,应用我们都不想要的“平滑缩放”。

答案 2 :(得分:0)

请注意,您现在可以使用d3.interpolateZoom(v2.0.1)中的.rho来定制缩放和平移时获得的曲率。默认值为Math.sqrt(2),而rho(0)则为线性插值。

这是设置方法:

let zoomBehavior = d3.zoom()
    .interpolate(d3.interpolateZoom.rho(0.9)) // 0.9 for less curvature
    .scaleExtent([0.5, 10])
    .on('zoom', zoomed);