首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >D3.js语义缩放行为不当

D3.js语义缩放行为不当
EN

Stack Overflow用户
提问于 2013-11-23 07:06:12
回答 2查看 1.9K关注 0票数 3

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

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

这是我的密码:

代码语言:javascript
复制
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);

小提琴的实时版本。

这应该很简单。我正在创建网格的圆圈,应该准确地触摸时,没有缩放应用(距离是50 px,直径是50 px)。当我放大时,我希望圆圈会散开,鼠标下面的点保持静止。我期望变焦是平滑和线性的应用鼠标轮。但是,圆圈应该保持相同的大小,这样当我放大时,它们就不再接触;当我放大时,它们应该重叠。

相反,最初,圆圈的分布距离应该是原来的两倍。当我放大和缩小,中心点不是在鼠标下面(并移动取决于我如何平移)。变焦是高度非线性的,渐变接近1(圆圈接触)的比例,当我放大,并迅速加速我放大。

这看起来真的很奇怪,而且我找不到我的代码和语义缩放示例之间的显著差异,而语义缩放示例就像预期的那样工作。我的结论是,我实际上不明白D3变焦应该如何工作。有人能帮我整理一下吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-11-23 21:54:14

问题是在翻译过程中堆叠的圆圈的初始位置。

活码指出并修正了问题,并做了一些其他的修改:

代码语言:javascript
复制
var size = 600
var scale = 100

circles = []
for (var j = 0; j<6; j++) {
    for (var i = 0; i<6; i++) {
        circles.push({x: i*scale, y: j*scale })
    }
}

var X = d3.scale.linear()
    .domain([0,6*scale])
    .range([0,size])
var Y = d3.scale.linear()
    .domain([0,6*scale])
    .range([0,size])

function transform(d) {
    return "translate("+X(d.x)+", "+Y(d.y)+")"
}

var circle  /*fwd declaration*/

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

var svg = d3.select("body").append("svg")
    .attr("width", size).attr("height", size)
    .call(zoom)
    .append("g")

circle = svg.selectAll("circle")
    .data(circles)
    .enter().append("circle")
    .attr("r", 20)
/*the problem was this initial offset interfering with the
translation we were applying, resulting in very strange behavior*/
/*    .attr("cx", function (d) {return d.x})
    .attr("cy", function (d) {return d.y})*/
    .attr("transform", transform)

"scale“参数不应该做任何事情,但是如果添加那些注释行,它会影响初始位置并导致非直观的效果。

最初的问题是:

  • 最初的规模似乎比它应该放大的更大。
  • 放大变变量产生了明显的非线性渐近效应。
  • 放大,然后在周围滚动,然后放大回来一点也不像预期的那样,图在鼠标下面滑动,而不是被固定住。

所有这些都是最初立场的直接后果:

  • 初始距离似乎更大,因为我们应用了它们的原始位置加上缩放转换。
  • 非线性渐近效应是变焦平移距离渐近于零(如预期的),但最初施加的距离不为零,从而使非零变焦渐近化。
  • 在放大时,D3认为它比用户放大的要多(因为圆圈之间有额外的距离),这意味着当应用pan时,D3跟踪的图像中心与用户期望的不同,这会导致缩放中心不处于鼠标下面的效果。

您可以使用这些效果来理解它们,方法是取消对初始位置线的注释,并使用不同的scale参数进行相同的缩放操作。注释它们会导致圆圈最初都位于屏幕空间0,0,所以只应用缩放距离转换,这就是我们想要的。

支持me _ut的答案,因为它提出了更小的世界空间坐标尺度,这不应该有任何不同,但确实如此,这帮助我发现了问题。

票数 4
EN

Stack Overflow用户

发布于 2013-11-23 08:08:17

您的代码非常接近正确:工作演示

使用缩尺来映射对象的位置()

与其保存对象在其中的确切位置,然后使用rangedomain设置为[0, 1]的缩放,不如使用刻度来为您进行映射:

代码语言:javascript
复制
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]);

这里的变化是,现在D3知道您的视口的纵横比,以及它应该以何种比例转换比例,以便将svg下的点保持在鼠标下的静态状态。否则,它会试图放大和缩小一个正方形,造成一种令人不快的体验。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20159644

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档