Javascript 无法转换初始d3.zoomIdentity,缩放时无抖动

Javascript 无法转换初始d3.zoomIdentity,缩放时无抖动,javascript,d3.js,svg,Javascript,D3.js,Svg,我用的是D3V4。我正在显示一个树形图,基本上如下所示: 我正在尝试实现拖动和缩放。我还对zoomIdentity应用了一个变换,以便在第一次渲染时将贴图移动固定量(margin.left和margin.top) 这似乎与我的问题最为接近,但当我试图将svg与g分开时,阻力非常大。当我拖动时,每个节点都会抖动和跳跃。使用下面给出的代码,拖动是平滑的,但最初的拖动会将所有节点向左移动(d3.event.transform x:0,y:0) 我不确定我做错了什么,也不清楚为什么svg的内容都是乱七八

我用的是D3V4。我正在显示一个树形图,基本上如下所示:

我正在尝试实现拖动和缩放。我还对zoomIdentity应用了一个变换,以便在第一次渲染时将贴图移动固定量(margin.left和margin.top)

这似乎与我的问题最为接近,但当我试图将
svg
g
分开时,阻力非常大。当我拖动时,每个节点都会抖动和跳跃。使用下面给出的代码,拖动是平滑的,但最初的拖动会将所有节点向左移动(d3.event.transform x:0,y:0)


我不确定我做错了什么,也不清楚为什么svg的内容都是乱七八糟的。

生活有时很有趣

按照Mark的建议,我创建了一个代码示例。令我惊讶的是,它成功了。所以我得出结论,这一定是其他问题(我的真实树处于模态中,等等)

在清理沙盒的代码时,我几乎随机地做了以下更改:

let transform = d3.zoomIdentity.translate(margin.left, margin.top);
let zoom = d3.zoom();
let svg = d3
    .select("#map")
    .attr("width", width + margin.right + margin.left)
    .attr("height", height + margin.top + margin.bottom)
    .call(d3.zoom()
        .on("zoom", () => {
            svg.attr("transform", d3.event.transform)
        }))
    .call(zoom.transform, transform)
    .append("g")
    .attr("class", "view")
    .attr("transform", transform)

当我把同样的代码应用到我的实际代码中时,一切都很完美。我不完全理解为什么会这样,但我认为这与再次调用
d3.zoom()
有关,而不是存储对它的引用。如果有比我更博学的人可以发表评论,我会将这一解释纳入我的答案。

生活有时很有趣

按照Mark的建议,我创建了一个代码示例。令我惊讶的是,它成功了。所以我得出结论,这一定是其他问题(我的真实树处于模态中,等等)

在清理沙盒的代码时,我几乎随机地做了以下更改:

let transform = d3.zoomIdentity.translate(margin.left, margin.top);
let zoom = d3.zoom();
let svg = d3
    .select("#map")
    .attr("width", width + margin.right + margin.left)
    .attr("height", height + margin.top + margin.bottom)
    .call(d3.zoom()
        .on("zoom", () => {
            svg.attr("transform", d3.event.transform)
        }))
    .call(zoom.transform, transform)
    .append("g")
    .attr("class", "view")
    .attr("transform", transform)

当我把同样的代码应用到我的实际代码中时,一切都很完美。我不完全理解为什么会这样,但我认为这与再次调用
d3.zoom()
有关,而不是存储对它的引用。如果有比我更了解情况的人可以发表评论,我会将这一解释纳入我的答案。

您的代码按照编写的方式工作,因为您幸运地使用了Map.js中的第43行,您手动应用了转换以防止它“跳跃”

保留对缩放的引用并不重要,因为:

缩放行为会将缩放状态存储在要将对象缩放到的元素上 应用了缩放行为,而不是缩放行为本身。这是 因为缩放行为可以应用于许多元素 同时,可以单独缩放每个元素。变焦 状态可以在用户交互时更改,也可以通过 缩放。变换

为了记录在案,我会这样编码:

let transform = d3.zoomIdentity.translate(margin.left, margin.top);

// create zoom
let zoom = d3.zoom().on("zoom", () => {
  svg.attr("transform", d3.event.transform);
});    

// create svg apply zoom to it
// svg becomes the event handler
// storing as p to avoid confusion
let p = d3
  .select("#map")
  .attr("width", width + margin.right + margin.left)
  .attr("height", height + margin.top + margin.bottom)
  .call(zoom);   

// create g, store as svg, so I don't have to refactor code later
let svg = p    
  .append("g")
  .attr("class", "view");

// apply initial transform to g by acting on svg
p.call(zoom.transform, transform);

这是一个例子。顺便说一句,这是一个很酷的网站,我不知道。你的代码是按照写的那样工作的,因为你很幸运在Map.js中有第43行,你手动应用了转换来防止它“跳跃”

保留对缩放的引用并不重要,因为:

缩放行为会将缩放状态存储在要将对象缩放到的元素上 应用了缩放行为,而不是缩放行为本身。这是 因为缩放行为可以应用于许多元素 同时,可以单独缩放每个元素。变焦 状态可以在用户交互时更改,也可以通过 缩放。变换

为了记录在案,我会这样编码:

let transform = d3.zoomIdentity.translate(margin.left, margin.top);

// create zoom
let zoom = d3.zoom().on("zoom", () => {
  svg.attr("transform", d3.event.transform);
});    

// create svg apply zoom to it
// svg becomes the event handler
// storing as p to avoid confusion
let p = d3
  .select("#map")
  .attr("width", width + margin.right + margin.left)
  .attr("height", height + margin.top + margin.bottom)
  .call(zoom);   

// create g, store as svg, so I don't have to refactor code later
let svg = p    
  .append("g")
  .attr("class", "view");

// apply initial transform to g by acting on svg
p.call(zoom.transform, transform);

这是一个例子。顺便说一句,这是一个很酷的网站,我不知道。

你应该包括一个可复制的代码示例。如果你有,我会回答这个问题的。我太忙(懒散)了,无法尝试将博斯托克先生的示例代码与您的代码合并。@Mark Hi Mark!谢谢你的评论。它实际上帮助我找到了解决办法。请看下面我的答案。如果您不介意评论我的解决方案为何有效,我们将不胜感激!我没有长篇大论,而是键入了一个关于如何编写代码的答案……您应该包括一个可复制的代码示例。如果你有,我会回答这个问题的。我太忙(懒散)了,无法尝试将博斯托克先生的示例代码与您的代码合并。@Mark Hi Mark!谢谢你的评论。它实际上帮助我找到了解决办法。请看下面我的答案。如果您不介意评论我的解决方案为何有效,我们将不胜感激!我没有长篇大论,而是键入了一个答案,说明我将如何对其进行编码。。。