d4 v4中的缩放功能问题

Ver*_*tor 5 javascript svg json d3.js

我在使用v4时遇到D3中缩放功能的问题.它会抛出错误,指出未定义zoom.translate.我主要使用以下代码从这个答案d3专注于点击节点,这对v3非常有效.但是,因为我对v3有问题,因为它对数据有限制,其中源和节点是字符串(而不是索引)D3 JSON文件,源和索引作为字符串而不是索引,我切换到v4.

<!DOCTYPE html>
<meta charset="utf-8">
<style>

.links line {
  stroke: #999;
  stroke-opacity: 0.6;
}

.nodes circle {
  stroke: #fff;
  stroke-width: 1.5px;
}

</style>
<svg width="960" height="600"></svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>


var svg = d3.select("svg"),
    width = +svg.attr("width"),
    height = +svg.attr("height")
    active = d3.select(null);

var zoom = d3.zoom()
    .scaleExtent([1, 8])
    .on("zoom", zoomed);     

var color = d3.scaleOrdinal(d3.schemeCategory20);

var simulation = d3.forceSimulation()
    .force("link", d3.forceLink().id(function(d) { return d.id; }))
    .force("charge", d3.forceManyBody())
    .force("center", d3.forceCenter(width / 2, height / 2));

d3.json("graph.json", function(error, graph) {
  if (error) throw error;

  var link = svg.append("g")
      .attr("class", "links")
    .selectAll("line")
    .data(graph.links)
    .enter().append("line")
      .attr("stroke-width", function(d) { return Math.sqrt(d.value); });

  var node = svg.append("g")
      .attr("class", "nodes")
    .selectAll("circle")
    .data(graph.nodes)
    .enter().append("circle")
      .attr("r", 5)
      .attr("fill", function(d) { return color(d.group); })
      .call(d3.drag()
          .on("start", dragstarted)
          .on("drag", dragged)
          .on("end", dragended))
            .on("click", clicked);

  node.append("title")
      .text(function(d) { return d.id; });

  simulation
      .nodes(graph.nodes)
      .on("tick", ticked);

  simulation.force("link")
      .links(graph.links);

  function ticked() {
    link
        .attr("x1", function(d) { return d.source.x; })
        .attr("y1", function(d) { return d.source.y; })
        .attr("x2", function(d) { return d.target.x; })
        .attr("y2", function(d) { return d.target.y; });

    node
        .attr("cx", function(d) { return d.x; })
        .attr("cy", function(d) { return d.y; });
  }
});

function dragstarted(d) {
  if (!d3.event.active) simulation.alphaTarget(0.3).restart();
  d.fx = d.x;
  d.fy = d.y;
}

function dragged(d) {
  d.fx = d3.event.x;
  d.fy = d3.event.y;
}

function dragended(d) {
  if (!d3.event.active) simulation.alphaTarget(0);
  d.fx = null;
  d.fy = null;
}

function clicked(d){
  if (active.node() === this) return reset();
  active.classed("active", false);
  active = d3.select(this).classed("active", true);

  var bbox = active.node().getBBox(),
      bounds = [[bbox.x, bbox.y],[bbox.x + bbox.width, bbox.y + bbox.height]];

  var dx = bounds[1][0] - bounds[0][0],
      dy = bounds[1][1] - bounds[0][1],
      x = (bounds[0][0] + bounds[1][0]) / 2,
      y = (bounds[0][1] + bounds[1][1]) / 2,
      scale = Math.max(1, Math.min(8, 0.9 / Math.max(dx / width, dy / height))),
      translate = [width / 2 - scale * x, height / 2 - scale * y];

  svg.transition()
      .duration(750)
      .call(zoom.translate(translate).scale(scale).event);
} 

function reset() {
  active.classed("active", false);
  active = d3.select(null);

  svg.transition()
      .duration(750)
      .call(zoom.translate([0, 0]).scale(1).event);
} 

function zoomed() {
  console.log(d3.event)
  g.style("stroke-width", 1.5 / d3.event.scale + "px");
  g.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
}        

</script>
Run Code Online (Sandbox Code Playgroud)

我改变d3.behaviour.zoom()d3.zoom()甚至改变了

.call(zoom.translate(translate).scale(scale).event);
Run Code Online (Sandbox Code Playgroud)

.call(d3.zoom().on("zoom", function () {
        svg.attr("transform", d3.event.transform)
}));
Run Code Online (Sandbox Code Playgroud)

这引发了一个奇怪的错误,错误:未知类型:wheel

克服这种情况最好的方法是什么?

Mar*_*ark 5

d3版本4中,正确的方法是:

function clicked(d) {

    if (active.node() === this){
      active.classed("active", false);
      return reset();
    }

    active = d3.select(this).classed("active", true);

    svg.transition()
      .duration(750)
      .call(zoom.transform,
        d3.zoomIdentity
        .translate(width / 2, height / 2)
        .scale(8)
        .translate(-(+active.attr('cx')), -(+active.attr('cy')))
      );
  }
Run Code Online (Sandbox Code Playgroud)

缩放处理程序在哪里:

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

注意,我简化了先前答案中的转换计算。边界计算实际上并没有必要。


完整代码:

function clicked(d) {

    if (active.node() === this){
      active.classed("active", false);
      return reset();
    }

    active = d3.select(this).classed("active", true);

    svg.transition()
      .duration(750)
      .call(zoom.transform,
        d3.zoomIdentity
        .translate(width / 2, height / 2)
        .scale(8)
        .translate(-(+active.attr('cx')), -(+active.attr('cy')))
      );
  }
Run Code Online (Sandbox Code Playgroud)