以编程方式触发d3.behavior.zoom事件时,如何为translate和scale设置初始值?

时间:2014-12-19 16:59:22

标签: d3.js zoom

以下示例中的方块是具有初始平移和缩放集的SVG组的一部分。

点击正方形会启动缩放过渡。但是转换设置的初始值与我的默认值不同,正如这种转变的震撼开始所显而易见的那样。

如何在我以编程方式启动的缩放转换中设置翻译和缩放的初始值?

var svg = d3.select("#main");

svg.append("rect").attr({"x":0,"y":0,"height":100,"width":100,"fill":"red"})
svg.append("rect").attr({"x":100,"y":100,"height":100,"width":100,"fill":"blue"})
svg.append("rect").attr({"x":0,"y":100,"height":100,"width":100,"fill":"green"})
svg.append("rect").attr({"x":100,"y":0,"height":100,"width":100,"fill":"yellow"})

var zoom = d3.behavior.zoom().on("zoom",function(){
  var t = d3.event.translate;
  var s = d3.event.scale;
  console.log(s)
  
  svg.attr("transform","translate("+t[0]+","+t[1]+") scale("+s+")")
  
}).scaleExtent([1,10]).scale(1).translate([0,0])

d3.select("svg").call(zoom)

d3.selectAll("rect").on("mousedown",function(){
  var scale = Math.random()*3;
  var translate = [Math.random()*200,Math.random()*200]
  zoom.scale(scale);
  zoom.translate(translate);
  
  //new transition
  var T = svg.transition().duration(5000)
  zoom.event(T);
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

<p style="font-weight:bold">When a zoom is triggered programatically, how do you set inital values for translate and scale?</p>
<p>Click on one of the squares</p>

<svg height="600px" width="600px">
  <g id="main" transform="translate(25,25) scale(0.25)"></g>
</svg>

3 个答案:

答案 0 :(得分:1)

这是缩放功能本身的问题。我会建议缩放孩子而不是父母,如果那样可以工作

var zoom = d3.behavior.zoom().on("zoom",function(){
  var t = d3.event.translate;
  var s = d3.event.scale;
  svg.selectAll("rect").attr("transform","translate("+t[0]+","+t[1]+") scale("+s+")")  
}).scaleExtent([1,10]);

编辑

上述代码的问题是d3.js没有注册SVG的转换或初始状态。这个问题更深入。由于d3不跟踪SVG转换并仅执行它们。它只跟踪您在名为__chart__的变量中在库上运行的转换。

因此,当运行缩放功能时,它只是插入变量并给出输出。由于尚未对此运行任何函数,因此尚未设置__chart__变量并导致从(x = 0,y = 0,k = 1)开始生涩。

解决方案:

  1. 在缩放转换之前运行此代码以手动设置初始图表

    svg.transition().each(function(){
        this.__chart__={x:25,y:25,k:0.25}; //or you can pick those values using attr
     });
    
  2. 在任何其他功能之前,首先以编程方式将svg缩放到25,25,0.25。 (这就是为什么你的解决方法适用于__chart__变量设置)

答案 1 :(得分:1)

要设置缩放的初始值,请尝试以下操作:

// Init zoom
var zoom = d3.behavior.zoom().on("zoom", function () {
                svg.attr("transform", "translate(" + d3.event.translate + ")" + " scale(" + d3.event.scale + ")");
            });

// Get SVG element
var svg = d3.select("svg")
  .call(zoom)
  .append("g");

// Create circle
svg.append("circle")
  .attr("cx",0)
  .attr("cy",0)
  .attr("r", 5);

// Create init value
var scale = 5;
var translate = [50, 50];

// Set init value
zoom.scale(scale);
zoom.translate(translate);

// Call zoom event
svg.call(zoom.event); 
// or svg.transition().call(zoom.event);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

<svg height="100px" width="100px"></svg>

答案 2 :(得分:0)

我一直在寻找答案,但似乎D3已经发展了几个版本。

虽然Majklcjds的答案帮助我解决了我的问题,但我认为这将有助于留下更多最新信息,因为很难找到v5.4示例在那里,直到我至少找到Observable

&#13;
&#13;
// Applies event transformation to the Group element's attribute
const zoom_action = () => g.attr("transform", d3.event.transform)

// Create the zoom handler
const zoom = d3
        .zoom()
        .on("zoom", zoom_action)

// Get SVG element and apply zoom behaviour
var svg = d3
  .select("svg")
  .call(zoom)

// Create Group that will be zoomed
var g = svg.append("g")

// Create circle
g.append("circle")
  .attr("cx",0)
  .attr("cy",0)
  .attr("r", 5)

// Set initial scale and translation
zoom.scaleBy(svg, 5)
zoom.translateBy(svg, 50, 50)    
&#13;
<script src="https://d3js.org/d3.v5.js"></script>

<svg height="100px" width="100px"></svg>
&#13;
&#13;
&#13;