d3.behavior.zoom() 将图形移动到角落而不是中心
d3.behavior.zoom() moves graph to corner instead of center
我想为我的朝阳效果添加鼠标滚轮缩放功能:
我所做的是编辑了这段代码:
var zoom = d3.behavior.zoom()
.scaleExtent([1, 10])
.on("zoom", zoomed);
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width/2 + "," + height * .52 + ")")
.call(zoom);
function zoomed() {
svg.attr('transform', 'translate(' + d3.event.transform.x + ',' + d3.event.transform.y + ') scale(' + d3.event.scale + ')');
//svg.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
}
问题是,当页面加载时一切似乎都正常,但是当使用鼠标滚轮滚动时,朝阳最终出现在左上角:
我能够通过更改此代码来解决此问题:
function zoomed() {
svg.attr("transform", "translate(" + width/2 + "," + height * .52 + ")scale(" + d3.event.scale + ")");
}
旭日纹现在停留在中间,但是这不会缩放到光标所在的位置,也不允许用户进一步缩小。
有什么建议可以缩放到光标位置(如第一个代码示例中所示)而左上角的朝阳不消失吗?
完整代码参见 JSfiddle,它在这里不起作用,但是 运行 它在本地确实有效。
d3.event.translate
returns 一个数组。因此,如果您想添加这些值(width/2
和 height/2
),您必须单独添加它们:
function zoomed() {
svg.attr('transform', 'translate(' + (d3.event.translate[0] + width / 2) +
',' + (d3.event.translate[1] + height / 2) + ') scale(' + d3.event.scale + ')');
}
或者,如果您想使用原来的缩放功能...
function zoomed() {
svg.attr("transform", "translate(" + d3.event.translate +
")scale(" + d3.event.scale + ")");
}
...只是打破 svg 选择,为组分配另一个名称:
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
var foo = svg.append("g")
.attr("transform", "translate(" + width / 2 + "," + height * .52 + ")")
.call(zoom);
我在 Zoomed 函数中使用标准 d3.event.translate 和 d3.event.scale,如下所示:
function zoomed() {
svg.attr("transform", "translate(" + d3.event.translate + ")" + " scale(" + d3.event.scale + ")");
}
一切正常,除了当我第一次滚动时整个旭日跳到左上角。我把它拖回中间后它自己纠正了,但是很烦人。
我为此苦苦挣扎了几个小时。最终我通过更改 svg 上的 viewBox 属性解决了这个问题:
.attr({viewBox: "" + (-width / 2) + " " + (-height / 2) + " " + width + " " + height})
我从这个例子中得到了灵感:Basic Sunburst
我想为我的朝阳效果添加鼠标滚轮缩放功能:
我所做的是编辑了这段代码:
var zoom = d3.behavior.zoom()
.scaleExtent([1, 10])
.on("zoom", zoomed);
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width/2 + "," + height * .52 + ")")
.call(zoom);
function zoomed() {
svg.attr('transform', 'translate(' + d3.event.transform.x + ',' + d3.event.transform.y + ') scale(' + d3.event.scale + ')');
//svg.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
}
问题是,当页面加载时一切似乎都正常,但是当使用鼠标滚轮滚动时,朝阳最终出现在左上角:
我能够通过更改此代码来解决此问题:
function zoomed() {
svg.attr("transform", "translate(" + width/2 + "," + height * .52 + ")scale(" + d3.event.scale + ")");
}
旭日纹现在停留在中间,但是这不会缩放到光标所在的位置,也不允许用户进一步缩小。
有什么建议可以缩放到光标位置(如第一个代码示例中所示)而左上角的朝阳不消失吗?
完整代码参见 JSfiddle,它在这里不起作用,但是 运行 它在本地确实有效。
d3.event.translate
returns 一个数组。因此,如果您想添加这些值(width/2
和 height/2
),您必须单独添加它们:
function zoomed() {
svg.attr('transform', 'translate(' + (d3.event.translate[0] + width / 2) +
',' + (d3.event.translate[1] + height / 2) + ') scale(' + d3.event.scale + ')');
}
或者,如果您想使用原来的缩放功能...
function zoomed() {
svg.attr("transform", "translate(" + d3.event.translate +
")scale(" + d3.event.scale + ")");
}
...只是打破 svg 选择,为组分配另一个名称:
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
var foo = svg.append("g")
.attr("transform", "translate(" + width / 2 + "," + height * .52 + ")")
.call(zoom);
我在 Zoomed 函数中使用标准 d3.event.translate 和 d3.event.scale,如下所示:
function zoomed() {
svg.attr("transform", "translate(" + d3.event.translate + ")" + " scale(" + d3.event.scale + ")");
}
一切正常,除了当我第一次滚动时整个旭日跳到左上角。我把它拖回中间后它自己纠正了,但是很烦人。
我为此苦苦挣扎了几个小时。最终我通过更改 svg 上的 viewBox 属性解决了这个问题:
.attr({viewBox: "" + (-width / 2) + " " + (-height / 2) + " " + width + " " + height})
我从这个例子中得到了灵感:Basic Sunburst