您的位置:首页 > Web前端 > Node.js

d3力导向图,Zoom后brush画刷选取node节点不正常

2017-03-30 00:00 176 查看
摘要: d3 brush circle

在用brush画刷批量选取力学导图的node节点时,页面初始化时是一切正常的。 但是点击zoom事件放大缩小后,brush画刷选取开始出现明显的不正常,有时候可以选取到,有时候选取不到。

正常情况:



zoom后:



这是我初始化brush的代码:



这是zoom的代码

//set zoom
function setZoom() {
$('#zoomOut').click(function () {
if (scale < 5) {
scale = scale + 0.1; //增加比例尺
gTranslateAndScale(scale);
zoomType = "out";
}
$(this).blur();
});

$('#zoomIn').click(function () {
if (scale >= 0.2) {
scale = scale - 0.1;
gTranslateAndScale(scale);
zoomType = "in";
}
$(this).blur();
});
}

//translate and scale
function gTranslateAndScale(scale) {
g.attr("transform", "translate(" + (width * (1 - scale)) / 2 + "," + ($("svg").height() * (1 - scale)) / 2 + ")scale(" + scale + ")");
}


原因是:zoom之后元素坐标系发生变化,brush的坐标系和zoom对不上了。

brush的坐标和zoom的坐标是不在一个平面内的。

transform="translate(-57.45000000000005,-20.10000000000002)scale(1.1)"

translate(x,y)    //  定义 2D 转换。 向左移动57,向上移动27
scale            // 放大1.1

解决办法:zoom 之后他们在两套坐标系统内,那么只能把一个坐标转化到另一个系统中 相同坐标系下做对比。zoom后,在brush的extent判断落点里把extent的x,y也相对的放大,判断当前node的落点
是否在extent区域内

重点是:在一个坐标系变换后,要统计两个坐标系的判断标准。



最终解决代码如下:

zoom代码:

//translate and scale
/*
* transform="translate(-57.45000000000005,-20.10000000000002)scale(1.1)"
* translate(x,y)   定义 2D 转换。 向左移动57,向上移动27
* scale  放大1.1
* */
function gTranslateAndScale(scale) {
translate_a =  (width * (1 - scale)) / 2;
translate_b =  ($("svg").height() * (1 - scale)) / 2;
g.attr("transform", "translate(" + (width * (1 - scale)) / 2 + "," + ($("svg").height() * (1 - scale)) / 2 + ")scale(" + scale + ")");
}

brush代码:

var brush = svg.append("g")
.datum(function() { return {selected: false, previouslySelected: false}; })
.attr("class", "brush")
.call(d3.svg.brush()
.x(d3.scale.identity().domain([0, width]))
.y(d3.scale.identity().domain([0, height]))
.on("brushstart", function(d) {
nodes.each(function(d) { d.previouslySelected = shiftKey && d.selected; });
})
.on("brush", function() {

var extent = d3.event.target.extent();

nodes.classed("selected", function(d) {

if( zoomType == "out" || zoomType == "in"){
console.log("重新设置了brush的extent");
/*
警告zoom放大或者缩小后,<g class="nodes" transform="translate(170.29999999999995,76.29999999999998)scale(0.8)"
nodes的坐标系发生了变化。由于nodes和brush不在一个坐标系
nodes坐标系变化,brush的extent[画刷的点击框选范围]也要随之变化,这样才能正确判断node是否在extent范围内
* */
return d.selected = d.previouslySelected ^
(((extent[0][0]-translate_a)/scale) <= d.x && d.x < ((extent[1][0]-translate_a)/scale)
&& ((extent[0][1]-translate_b)/scale)  <= d.y && d.y < ((extent[1][1]-translate_b)/scale) );
}
else{
console.log("没有重新设置extent");
return d.selected = d.previouslySelected ^
(extent[0][0] <= d.x && d.x < extent[1][0]
&& extent[0][1] <= d.y && d.y < extent[1][1]);

}

});
})
.on("brushend", function() {
d3.event.target.clear();
d3.select(this).call(d3.event.target);
}));
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: