Setting x.domain with setInterval

老子叫甜甜 提交于 2019-12-04 18:53:45

If you change the scale's domain programmatically, you need to reassign the scale to the zoom behaviour. This is because the zoom behaviour stores a clone of the scale internally for computing the new domain for new scale and translate offsets. So if you don't reassign the scale, it continues to use the (old) cloned scale.

I've updated the documentation to include a note about this.

There is an additional complication, which is that the zoom's x- and y-scales should represent the domains at zoom scale=1. So you actually need to keep your own clone of the current scale(s) at zoom scale=1 and apply the offset to both the clones and the current scales.

Then, you may also need to invert the current zoom translate and scale, depending on the exact behaviour that you need.

So it should look something like:

var x0 = d3.scale.linear().domain(…).range(…), // initial scale
    x = x0.copy(); // copy to use for axes and zoom behaviour

setInterval(function() {
  var translate = zoom.translate(),
      scale = zoom.scale(),
      xd = x0.domain(),
      dx = 1;

  // Set a new x-domain: offset by dx.
  x0.domain([xd[0] += dx, xd[1] += dx]);

  // Set the zoom x-domain (this resets the domain at zoom scale=1).
  zoom.x(x.domain(xd));

  // Reset the domain relative to the current zoom offsets.
  x.domain(x0.range().map(function(x) {
    return (x - translate[0]) / scale;
  }).map(x0.invert));
}, 1e3);

Example of this in action.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!