d3 v4 - 使用与缩放行为冲突的按钮进行缩放

nki*_*int 6 javascript zoom pan d3.js d3.js-v4

我已经用我的问题创造了一个要点.

我从这个例子开始.

所以我的问题是我需要一些放大和缩小按钮以及鼠标控件.

使用zoom()行为实现鼠标控件(通过拖动缩放轮和平移).它工作得很好.

然后我添加了两个用于放大和缩小的按钮:

var _zoom = d3.zoom()
    .scaleExtent([1 / 2, 8])
    .on("zoom", zoomed);
var gui = d3.select("#gui")
gui.append("span")
  .classed("zoom in", true)
  .text("+")
  .on("click", function() { _zoom.scaleBy(container, 2); })
gui.append("span")
  .classed("zoom out", true)
  .text("-")
  .on("click", function(){ _zoom.scaleBy(container, 0.5); })
Run Code Online (Sandbox Code Playgroud)

它们与鼠标行为发生冲突.要重现您必须缩放和拖动的错误(使用鼠标控件),然后单击+跨度:当前转换将被覆盖.

怎么解决?

And*_*rew 18

需要记住的重要一点是,缩放变换存储在node,不是_zoom对象.

在您的情况下,您在svg节点上设置鼠标侦听器,

svg.call(_zoom);
Run Code Online (Sandbox Code Playgroud)

当在svg元素上触发缩放事件时,您可以获取svg节点的更新缩放变换并将其应用于g节点,

g.attr("transform", d3.event.transform);
Run Code Online (Sandbox Code Playgroud)

在按钮单击时更新g元素的缩放时,您需要做的就是获取正确的变换,在您的情况下,获取svg节点的变换,

 _zoom.scaleBy(svg, 0.5);
Run Code Online (Sandbox Code Playgroud)

这将svg正确触发节点上的缩放事件,下面全部更新,

var svg = d3.select("svg"),
  width = +svg.attr("width"),
  height = +svg.attr("height");
svg.style("border", "solid 1px black");
var points = d3.range(2000).map(phyllotaxis(10));
var g = svg.append("g");

var _zoom = d3.zoom()
  .scaleExtent([1 / 2, 8])
  .on("zoom", function() {
    g.attr("transform", d3.event.transform);
  });
svg.call(_zoom);

var container = g.selectAll("circle")
  .data(points)
  .enter().append("circle")
  .attr("cx", function(d) {
    return d.x;
  })
  .attr("cy", function(d) {
    return d.y;
  })
  .attr("r", 2.5)

function phyllotaxis(radius) {
  var theta = Math.PI * (3 - Math.sqrt(5));
  return function(i) {
    var r = radius * Math.sqrt(i),
      a = theta * i;
    return {
      x: width / 2 + r * Math.cos(a),
      y: height / 2 + r * Math.sin(a)
    };
  };
}
var gui = d3.select("#gui");
gui.append("span")
  .classed("zoom in", true)
  .text("+")
  .on("click", function() {
    _zoom.scaleBy(svg, 2);
  });
gui.append("span")
  .classed("zoom out", true)
  .text("-")
  .on("click", function() {
    _zoom.scaleBy(svg, 0.5);
  })
Run Code Online (Sandbox Code Playgroud)
<svg width="960" height="500"></svg>
<div id="gui"></div>
<script src="https://d3js.org/d3.v4.min.js"></script>
Run Code Online (Sandbox Code Playgroud)