如何修复集群束图中的缩放和平移?
How do I fix zooming and panning in my cluster bundle graph?
我用一些数据创建了一个分层边缘捆绑图,在尝试对图进行缩放和拖动后,我 运行 遇到了一些问题。
这是我目前拥有的一个类似的工作 jsfiddle:https://jsfiddle.net/hnjvxd48/1/
及相关代码:
var zoom = d3.behavior.zoom()
.scaleExtent([0,8])
.on("zoom", zoomhandler);
var drag = d3.behavior.drag()
.origin(function(d) { return d; })
.on("dragstart", dragstarted)
.on("drag", dragged)
.on("dragend", dragended);
var svg = d3.select(".container").append("svg")
.attr("width", diameter)
.attr("height", diameter)
.append("g")
.attr("transform", "translate(" + radius + "," + radius + ")")
.call(zoom)
.call(drag);
function zoomhandler(){
svg.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
}
function dragstarted(d) {
d3.event.sourceEvent.stopPropagation();
d3.select(this).classed("dragging", true);
}
function dragged(d) {
d3.select(this).attr("cx", d.x = d3.event.x).attr("cy", d.y = d3.event.y);
}
function dragended(d) {
d3.select(this).classed("dragging", false);
}
你会注意到:
1) 拖动和缩放只发生在图形的外边缘,而不发生在图形的内部。
2) 左右拖动图表会导致图表的闪烁和居中发生变化并被截断。
3) 缩放(通过鼠标滚轮完成)也会错误地将图形居中并将其放置在不可预测的位置,部分超出视口。
4) 缩小后尝试拖动图形会导致图形闪烁并消失。
是什么导致了这些问题,我该如何解决?我怎样才能给我的图表(比我提供的示例大得多)初始 "zoomed out" 状态,并可能使用按钮单击事件而不是本机滚轮实现来触发缩放功能?
这里要注意的一件大事是拖动功能实际上是多余的。在此 (http://bl.ocks.org/mbostock/6123708) d3 拖动 + 缩放示例中,它们用于移动单个 'dots'。您想要一次移动整个图形,这由您包含的 'zoomhandler' 函数的 'translate' 部分处理。
这是一个有效的 fiddle:https://jsfiddle.net/14f9f4k3/1/
关键代码修改在评论中:
var zoom = d3.behavior.zoom()
.scaleExtent([0,8])
.on("zoom", zoomhandler);
//added another group as a child of the group having zoom called on it w/ id 'draggroup' to append nodes and links to
var svg = d3.select(".container").append("svg")
.attr("width", diameter)
.attr("height", diameter)
.append("g")
.attr("transform", "translate(" + radius + "," + radius + ")")
.call(zoom)
.append('g')
.attr('id','draggroup');
//added a rect behind the other elements to make an easy target for the pointer
d3.select('#draggroup')
.append('rect')
.attr("transform", "translate(" + -radius + "," + -radius + ")")
.attr('width',diameter)
.attr('height',diameter)
.attr('fill','#fff');
//no need for separate drag functions, translate and scale here do what you want
function zoomhandler(){
svg.attr("transform", "translate(" + d3.event.translate + ") scale(" + d3.event.scale + ")");
}
//append the links and nodes to the group we created above instead of the base svg
var link = d3.select('#draggroup').append("g").selectAll(".link"),
node = d3.select('#draggroup').append("g").selectAll(".node");
我用一些数据创建了一个分层边缘捆绑图,在尝试对图进行缩放和拖动后,我 运行 遇到了一些问题。
这是我目前拥有的一个类似的工作 jsfiddle:https://jsfiddle.net/hnjvxd48/1/
及相关代码:
var zoom = d3.behavior.zoom()
.scaleExtent([0,8])
.on("zoom", zoomhandler);
var drag = d3.behavior.drag()
.origin(function(d) { return d; })
.on("dragstart", dragstarted)
.on("drag", dragged)
.on("dragend", dragended);
var svg = d3.select(".container").append("svg")
.attr("width", diameter)
.attr("height", diameter)
.append("g")
.attr("transform", "translate(" + radius + "," + radius + ")")
.call(zoom)
.call(drag);
function zoomhandler(){
svg.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
}
function dragstarted(d) {
d3.event.sourceEvent.stopPropagation();
d3.select(this).classed("dragging", true);
}
function dragged(d) {
d3.select(this).attr("cx", d.x = d3.event.x).attr("cy", d.y = d3.event.y);
}
function dragended(d) {
d3.select(this).classed("dragging", false);
}
你会注意到:
1) 拖动和缩放只发生在图形的外边缘,而不发生在图形的内部。
2) 左右拖动图表会导致图表的闪烁和居中发生变化并被截断。
3) 缩放(通过鼠标滚轮完成)也会错误地将图形居中并将其放置在不可预测的位置,部分超出视口。
4) 缩小后尝试拖动图形会导致图形闪烁并消失。
是什么导致了这些问题,我该如何解决?我怎样才能给我的图表(比我提供的示例大得多)初始 "zoomed out" 状态,并可能使用按钮单击事件而不是本机滚轮实现来触发缩放功能?
这里要注意的一件大事是拖动功能实际上是多余的。在此 (http://bl.ocks.org/mbostock/6123708) d3 拖动 + 缩放示例中,它们用于移动单个 'dots'。您想要一次移动整个图形,这由您包含的 'zoomhandler' 函数的 'translate' 部分处理。
这是一个有效的 fiddle:https://jsfiddle.net/14f9f4k3/1/
关键代码修改在评论中:
var zoom = d3.behavior.zoom()
.scaleExtent([0,8])
.on("zoom", zoomhandler);
//added another group as a child of the group having zoom called on it w/ id 'draggroup' to append nodes and links to
var svg = d3.select(".container").append("svg")
.attr("width", diameter)
.attr("height", diameter)
.append("g")
.attr("transform", "translate(" + radius + "," + radius + ")")
.call(zoom)
.append('g')
.attr('id','draggroup');
//added a rect behind the other elements to make an easy target for the pointer
d3.select('#draggroup')
.append('rect')
.attr("transform", "translate(" + -radius + "," + -radius + ")")
.attr('width',diameter)
.attr('height',diameter)
.attr('fill','#fff');
//no need for separate drag functions, translate and scale here do what you want
function zoomhandler(){
svg.attr("transform", "translate(" + d3.event.translate + ") scale(" + d3.event.scale + ")");
}
//append the links and nodes to the group we created above instead of the base svg
var link = d3.select('#draggroup').append("g").selectAll(".link"),
node = d3.select('#draggroup').append("g").selectAll(".node");