D3.js 语义缩放行为异常

Wol*_*ivy 3 svg zooming d3.js

我一直在尝试自学 D3.js,但我似乎无法让语义缩放(缩放位置但不是形状)为我工作。

我在这里阅读了 d3 缩放文档,并尝试在功能上复制svg 语义缩放示例代码

这是我的代码:

var X, Y, circle, circles, h, i, j, svg, transform, w, zoom, _i, _j;

w = 1200;
h = 600;

circles = [];
for (j = _i = 0; _i <= 6; j = ++_i) {
  for (i = _j = 0; _j <= 12; i = ++_j) {
    circles.push({r: 25, cx: i * 50, cy: j * 50});
  }
}

X = d3.scale.linear()
    .domain([0, 1])
    .range([0, 1]);
Y = d3.scale.linear()
    .domain([0, 1])
    .range([0, 1]);

zoom = d3.behavior.zoom()
  .x(X)
  .y(Y)
  .on("zoom", function() {
      return circle.attr("transform", transform);
  });

transform = function(d) {
  return "translate(" + (X(d.cx)) + ", " + (Y(d.cy)) + ")";
};

svg = d3.select("body")
    .append("svg")
    .attr("width", w)
    .attr("height", h)
    .call(zoom)
    .append("g");

circle = svg.selectAll("circle")
    .data(circles)
    .enter().append("circle")
    .attr("r", function(d) {
        return d.r;
    }).attr("cx", function(d) {
        return d.cx;
    }).attr("cy", function(d) {
        return d.cy;
    }).attr("transform", transform);
Run Code Online (Sandbox Code Playgroud)

jsfiddle 的实时版本。

这应该很简单。我正在创建在没有应用缩放时应该完全接触的圆圈网格(距离为 50 像素,直径为 50 像素)。当我放大时,我希望圆圈分开,鼠标下方的点保持静止。我希望通过应用鼠标滚轮可以平滑和线性地缩放。但是,圆圈​​应该保持相同的大小,以便在我放大时它们停止接触;当我缩小时它们应该重叠。

取而代之的是,最初,圆圈的展开范围恰好是它们应有的两倍。当我放大和缩小时,中心点不在鼠标下方(并根据我的平移方式四处移动)。缩放是高度非线性的,当我缩小时渐近地接近 1 的比例(圆圈接触),并在我放大时迅速加速。

这看起来很奇怪,我无法发现我的代码和语义缩放示例之间的显着差异,它按预期工作。我得出的结论是,我实际上并不了解 D3 缩放应该如何工作。有人可以帮我解决吗?

mus*_*_ut 5

您的代码非常接近正确:Working demo

使用比例来映射对象的位置

而不是保存对象的确切位置,然后使用比例rangedomain设置为[0, 1],而是使用比例为您进行映射:

for (j = _i = 0; _i <= 6; j = ++_i) {
  for (i = _j = 0; _j <= 12; i = ++_j) {
    circles.push({
      r: 25,
      cx: i,
      cy: j,
      color: "#000"
    });
  }
}

X = d3.scale.linear()
    .domain([0, 6])
    .range([0, w]);
Y = d3.scale.linear()
    .domain([0, 12])
    .range([0, h]);
Run Code Online (Sandbox Code Playgroud)

这里的变化是现在 D3知道你的视口的纵横比,以及它应该以什么比例转换比例以保持svg鼠标下的静态点。否则,它会尝试放大和缩小正方形,从而产生不和谐的体验。