javascript - 防止在 d3v5 中平移到 map 边界之外

标签 javascript d3.js

在 d3 v3 中,我使用了 this example以防止在 SVG 之外平移。这是相关代码:

.on("zoom", function() {
    // the "zoom" event populates d3.event with an object that has
    // a "translate" property (a 2-element Array in the form [x, y])
    // and a numeric "scale" property
    var e = d3.event,

    // now, constrain the x and y components of the translation by the
    // dimensions of the viewport
    tx = Math.min(0, Math.max(e.translate[0], width - width * e.scale)),
    ty = Math.min(0, Math.max(e.translate[1], height - height * e.scale));

    // then, update the zoom behavior's internal translation, so that
    // it knows how to properly manipulate it on the next movement
    zoom.translate([tx, ty]);

    // and finally, update the <g> element's transform attribute with the
    // correct translation and scale (in reverse order)
    g.attr("transform", ["translate(" + [tx, ty] + ")","scale(" + e.scale + ")"].join(" "));
}

在 d3 v5 中,它不再起作用。所有示例都允许 map 在屏幕外平移可笑的数量。我的目标是 map 的最右边永远不会比 div 的最右边更靠左,等等。我怎样才能做到这一点?有没有更近的例子?

最佳答案

对于您链接的示例,这些是 zoom 函数中的必要更改,以便与 D3 v5 一起使用:

var e = d3.event.transform,
tx = Math.min(0, Math.max(e.x, width - width * e.k)),
ty = Math.min(0, Math.max(e.y, height - height * e.k));

除此之外,更改组翻译功能并删除 zoom.translate([tx, ty]);

下面是修改后的原始代码:

<html>

<head>
  <title>Restricted zoom behavior in d3</title>
  <meta charset="utf-8">
  <script src="https://d3js.org/d3.v5.min.js"></script>
  <style>

  </style>
</head>

<body>
  <script>
    // first, define your viewport dimensions
    var width = 960,
      height = 500;

    // then, create your svg element and a <g> container
    // for all of the transformed content
    var svg = d3.select("body").append("svg")
      .attr("width", width)
      .attr("height", height)
      .style("background-color", randomColor),
      g = svg.append("g");

    // then, create the zoom behvavior
    var zoom = d3.zoom()
      // only scale up, e.g. between 1x and 50x
      .scaleExtent([1, 50])
      .on("zoom", function() {
        // the "zoom" event populates d3.event with an object that has
        // a "translate" property (a 2-element Array in the form [x, y])
        // and a numeric "scale" property
        var e = d3.event.transform,
          // now, constrain the x and y components of the translation by the
          // dimensions of the viewport
          tx = Math.min(0, Math.max(e.x, width - width * e.k)),
          ty = Math.min(0, Math.max(e.y, height - height * e.k));
        // then, update the zoom behavior's internal translation, so that
        // it knows how to properly manipulate it on the next movement
        // and finally, update the <g> element's transform attribute with the
        // correct translation and scale (in reverse order)
        g.attr("transform", [
          "translate(" + [tx, ty] + ")",
          "scale(" + e.k + ")"
        ].join(" "));
      });

    // then, call the zoom behavior on the svg element, which will add
    // all of the necessary mouse and touch event handlers.
    // remember that if you call this on the <g> element, the even handlers
    // will only trigger when the mouse or touch cursor intersects with the
    // <g> elements' children!
    svg.call(zoom);

    // then, let's add some circles
    var circle = g.selectAll("circle")
      .data(d3.range(300).map(function(i) {
        return {
          x: Math.random() * width,
          y: Math.random() * height,
          r: .01 + Math.random() * 50,
          color: randomColor()
        };
      }).sort(function(a, b) {
        return d3.descending(a.r, b.r);
      }))
      .enter()
      .append("circle")
      .attr("fill", function(d) {
        return d.color;
      })
      .attr("cx", function(d) {
        return d.x;
      })
      .attr("cy", function(d) {
        return d.y;
      })
      .attr("r", function(d) {
        return d.r;
      });

    function randomColor() {
      return "hsl(" + ~~(60 + Math.random() * 180) + ",80%,60%)";
    }
  </script>
</body>

</html>

关于javascript - 防止在 d3v5 中平移到 map 边界之外,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55987499/

相关文章:

javascript - 等待一个在一系列 promise 中返回真值的 promise

javascript - Promise.all 中的索引

javascript - 图表中一致的条宽

javascript - 正在为所有文章加载相同的 disqus 线程

javascript - d3.js 创建和输入元素的意外行为

javascript - D3 JS - 时间轴上的刻度间距被月份边界弄乱了

javascript - 如何在不重置刻度文本属性的情况下转换 D3 轴?

javascript - 如何将一个/一个完全定义但自治的 GUI 元素追溯附加到另一个(DOM 附加)元素

javascript - 编辑饼图中的数据而不是创建新饼图

javascript - 从数组中的值范围与 javaScript 中的给定值获取关联值