Javascript 在画布上放大d3js力模拟

Javascript 在画布上放大d3js力模拟,javascript,canvas,d3.js,Javascript,Canvas,D3.js,我使用svg使用d3.js建立了一个力定向图,但最终该图变得很大,并且出现了性能问题。我决定试着在画布上做这件事,因为我读到它能更好更快地渲染东西。但现在我在缩放方面遇到了问题。我已经正确地实现了缩放行为(我猜),但我只能在图形静止时进行缩放。在模拟之前,找到平衡点缩放行为不起作用。知道为什么吗?或者我该怎么做的建议 var force = d3.forceSimulation() .force("link", d3.forceLink().id(function(d,

我使用svg使用d3.js建立了一个力定向图,但最终该图变得很大,并且出现了性能问题。我决定试着在画布上做这件事,因为我读到它能更好更快地渲染东西。但现在我在缩放方面遇到了问题。我已经正确地实现了缩放行为(我猜),但我只能在图形静止时进行缩放。在模拟之前,找到平衡点缩放行为不起作用。知道为什么吗?或者我该怎么做的建议

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

force.nodes(data.nodes)
    .on("tick", ticked)

force.force("link")
    .links(data.links);

function ticked(){
  context.clearRect(0, 0, width, height);

  // Draw the links
  data.links.forEach(function(d) {
      // Draw a line from source to target.
      context.beginPath();
      context.moveTo(d.source.x, d.source.y);
      context.lineTo(d.target.x, d.target.y);
      context.stroke();
  });
  // Draw the nodes 
  data.nodes.forEach(function(d, i) {
     // Draws a complete arc for each node.
     context.beginPath();
     context.arc(d.x, d.y, d.radius, 0, 2 * Math.PI, true);
     context.fill();
  });
};

// now the zooming part
  canvas.call( d3.zoom().scaleExtent([0.2, 10]).on("zoom", zoomed) )

  function zoomed(d) {
    context.save();
    context.clearRect(0, 0, width, height);
    context.translate(d3.event.transform.x, d3.event.transform.y);
    context.scale(d3.event.transform.k, d3.event.transform.k);

    // Draw the links ...
    data.links.forEach(function(d) {
        context.beginPath();
        context.moveTo(d.source.x, d.source.y);
        context.lineTo(d.target.x, d.target.y);
        context.stroke();
    });
    // Draw the nodes ...
    data.nodes.forEach(function(d, i) {
        context.beginPath();
        context.arc(d.x, d.y, d.radius, 0, 2 * Math.PI, true);
        context.fill();
    });
    context.restore();
  }

勾选
函数不知道缩放创建的任何变换。做到这一点的最佳方法是始终在刻度中应用变换(在任何缩放之前,这是最重要的)。这允许您重复使用勾号方法来绘制所有图形

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

force.nodes(data.nodes)
  .on("tick", ticked);

force.force("link")
  .links(data.links)

var trans = d3.zoomIdentity; //<-- identity transform
function ticked() {
  context.save();
  context.clearRect(0, 0, width, height);
  context.translate(trans.x, trans.y); //<-- this always applies a transform
  context.scale(trans.k, trans.k);

  // Draw the links
  data.links.forEach(function(d) {
    // Draw a line from source to target.
    context.beginPath();
    context.moveTo(d.source.x, d.source.y);
    context.lineTo(d.target.x, d.target.y);
    context.stroke();
  });
  // Draw the nodes 
  data.nodes.forEach(function(d, i) {
    // Draws a complete arc for each node.
    context.beginPath();
    context.arc(d.x, d.y, 5, 0, 2 * Math.PI, true);
    context.fill();
  });

  context.restore();
};

// now the zooming part
canvas.call(d3.zoom().scaleExtent([0.2, 10]).on("zoom", zoomed))

function zoomed(d) {
  trans = d3.event.transform; //<-- set to current transform
  ticked(); //<-- use tick to redraw regardless of event
}
var-force=d3.forceSimulation()
.force(“link”,d3.forceLink().id(函数(d,i){
返回d.id;
}))
.力(“电荷”,d3.力人体().力(-5))
.力(“中心”,d3.力中心(宽度/2,高度/2));
force.nodes(data.nodes)
。在(勾选)上;
力。力(“链接”)
.links(data.links)

var trans=d3.zoomIdentity//这是迄今为止我发现的唯一一个d3v4画布强制图,它工作正常、简短且易于理解!:)