Javascript 更改SVG内容时是否保留d3缩放状态?

Javascript 更改SVG内容时是否保留d3缩放状态?,javascript,d3.js,dagre-d3,dagre,Javascript,D3.js,Dagre D3,Dagre,我使用d3渲染一些东西,并使用d3.zoom用鼠标缩放。它可以工作,但我还需要定期更改svg的内容(执行完整的$('svg').html($('svg').html())调用,因为我的svg包含html) 问题是,当我这样做时,我会失去缩放状态。我试图通过存储缩放变换并在更新后重新应用来跟踪它,但它不起作用 通过我的尝试,使用dagre-d3示例图 简而言之,我正在做的是: let transform; function dag(){ // ... set up stuff here

我使用d3渲染一些东西,并使用
d3.zoom
用鼠标缩放。它可以工作,但我还需要定期更改svg的内容(执行完整的
$('svg').html($('svg').html())
调用,因为我的svg包含html)

问题是,当我这样做时,我会失去缩放状态。我试图通过存储缩放变换并在更新后重新应用来跟踪它,但它不起作用

通过我的尝试,使用dagre-d3示例图

简而言之,我正在做的是:

let transform;

function dag(){
  // ... set up stuff here

  var svg = d3.select("svg"),
      inner = svg.select("g");

  // Set up zoom support
  var zoom = d3.zoom().on("zoom", function() {
        //store transform
        transform = d3.event.transform
        inner.attr("transform", d3.event.transform);
      });
  svg.call(zoom);

  // render graph
  new dagreD3.render()(inner, g);

  // Center the graph
  var initialScale = 0.75;
  svg.call(zoom.transform, d3.zoomIdentity.translate((svg.attr("width") - g.graph().width * initialScale) / 2, 20).scale(initialScale));

  svg.attr('height', g.graph().height * initialScale + 40);
}

setInterval(() => {
  // simulate reloading content
  dag()
  console.log('render again')
  //try and apply saved transform state
  transform && inner.attr("transform", transform);
}, 2000)

在zoom func中设置转换后,使用'initialScale'变量再次设置svg比例,可以在此处看到问题:

  // Center the graph
  var initialScale = 0.75;
  svg.call(zoom.transform, d3.zoomIdentity.translate((svg.attr("width") - g.graph().width * initialScale) / 2, 20).scale(initialScale));
  // Center the graph
  var initialScale = (typeof transform != 'undefined') ? transform.k : 0.75;
  svg.call(zoom.transform, d3.zoomIdentity.translate((svg.attr("width") - g.graph().width * initialScale) / 2, 20).scale(initialScale));
要解决这个问题,您需要根据svg的当前缩放变换更改“initialScale”变量中的值。如图所示:

  // Center the graph
  var initialScale = 0.75;
  svg.call(zoom.transform, d3.zoomIdentity.translate((svg.attr("width") - g.graph().width * initialScale) / 2, 20).scale(initialScale));
  // Center the graph
  var initialScale = (typeof transform != 'undefined') ? transform.k : 0.75;
  svg.call(zoom.transform, d3.zoomIdentity.translate((svg.attr("width") - g.graph().width * initialScale) / 2, 20).scale(initialScale));

一个带有补丁的代码笔:

这就是你想要的吗?(每次在间隔上绘制时,它仍然居中,但我猜您希望这样做吗?)如果这是您想要的,那是因为您使用默认的“initialScale”重新缩放,您需要更新它。检查第63行。@REEE我不想让它居中,但删除该代码会使它排序。谢谢你的帮助,你能写一个答案让我接受吗?太棒了,很高兴我能帮上忙。我在写答案时多了一点解释,以防其他人遇到类似的问题。祝您项目的其余部分好运:)。