我一直在教自己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);小提琴的实时版本。
这应该很简单。我正在创建网格的圆圈,应该准确地触摸时,没有缩放应用(距离是50 px,直径是50 px)。当我放大时,我希望圆圈会散开,鼠标下面的点保持静止。我期望变焦是平滑和线性的应用鼠标轮。但是,圆圈应该保持相同的大小,这样当我放大时,它们就不再接触;当我放大时,它们应该重叠。
相反,最初,圆圈的分布距离应该是原来的两倍。当我放大和缩小,中心点不是在鼠标下面(并移动取决于我如何平移)。变焦是高度非线性的,渐变接近1(圆圈接触)的比例,当我放大,并迅速加速我放大。
这看起来真的很奇怪,而且我找不到我的代码和语义缩放示例之间的显著差异,而语义缩放示例就像预期的那样工作。我的结论是,我实际上不明白D3变焦应该如何工作。有人能帮我整理一下吗?
发布于 2013-11-23 21:54:14
问题是在翻译过程中堆叠的圆圈的初始位置。
活码指出并修正了问题,并做了一些其他的修改:
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“参数不应该做任何事情,但是如果添加那些注释行,它会影响初始位置并导致非直观的效果。
最初的问题是:
所有这些都是最初立场的直接后果:
您可以使用这些效果来理解它们,方法是取消对初始位置线的注释,并使用不同的scale参数进行相同的缩放操作。注释它们会导致圆圈最初都位于屏幕空间0,0,所以只应用缩放距离转换,这就是我们想要的。
支持me _ut的答案,因为它提出了更小的世界空间坐标尺度,这不应该有任何不同,但确实如此,这帮助我发现了问题。
发布于 2013-11-23 08:08:17
您的代码非常接近正确:工作演示。
使用缩尺来映射对象的位置()
与其保存对象在其中的确切位置,然后使用range和domain设置为[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]);这里的变化是,现在D3知道您的视口的纵横比,以及它应该以何种比例转换比例,以便将svg下的点保持在鼠标下的静态状态。否则,它会试图放大和缩小一个正方形,造成一种令人不快的体验。
https://stackoverflow.com/questions/20159644
复制相似问题