javascript-调整组的比例以确保内部形状在d3 js中尽可能大
作者:互联网
我正在使用类似于此示例的d3树布局:http://bl.ocks.org/mbostock/4339083
我实现了一个搜索框,该搜索框在键入时将屏幕居中于所有适当节点的虚拟“平均”位置.
我想调整比例,以便将选定的节点设置为
>全部可见
>尽可能放大.
如果搜索匹配恰好为1,则模拟节点上的单击,否则以该虚拟位置为中心.
if (matches[0].length === 1) {
click(matches.datum(), 0, 0, false);
}
else {
var position = GetAveragePosition(matches);
centerToPosition(position.x, position.y, 1);
}
这就是centerToPosition函数的样子:
function centerToPosition(x0, y0, newScale) {
if (typeof newScale == "undefined") {
scale = zoomListener.scale();
}
else {
scale = newScale;
}
var x = y0 * -1; //not sure why this is.. but it is
var y = x0 * -1;
x = x * scale + viewerWidth / 2;
y = y * scale + viewerHeight / 2;
d3.select('g').transition()
.duration(duration)
.attr("transform", "translate(" + x + "," + y + ")scale(" + scale + ")");
zoomListener.scale(scale);
zoomListener.translate([x, y]);
}
那么如何计算新的比例尺呢?我通过考虑数据点的范围尝试了不同的变化
var xExtent = d3.extent(matches.data(), function (d) {
return d.x0;
});
var yExtent = d3.extent(matches.data(), function (d) {
return d.y0;
});
还尝试在将屏幕居中之前查看组的变换属性.
var components = d3.transform(svgGroup.attr("transform"));
我将尝试尽快添加js小提琴!
编辑:这是:http://jsfiddle.net/7SJqC/
解决方法:
有趣的项目.
确定合适的比例尺以适合一组点的方法相当简单,尽管我花了相当长的时间才弄清楚为什么它对我不起作用-我并没有发现以下事实:在水平方向上绘制树),树布局中的“ x”代表垂直位置,“ y”代表水平位置,因此我得到的显然是任意结果.
清除后,只需找出要显示区域的高度和宽度(以数据坐标为单位),然后将其与视口的高度和宽度(或任何原始的最大和最小尺寸是).
ScaleFactor = oldDomain / newDomain
通常,您不希望使用不同的水平和垂直比例来使图像变形,因此您要分别计算宽度和高度的比例因子并取最小值(这样整个区域将适合视口).
您可以使用d3数组函数找出每个方向上的位置范围,然后找到范围的中间,将max和min相加并除以2.
var matches = d3.selectAll(".selected");
/*...*/
if ( matches.empty() ) {
centerToPosition(0, 0, 1); //reset
}
else if (matches.size() === 1) {
click(matches.datum(), 0, 0, false);
}
else {
var xExtent = d3.extent(matches.data(), function (d) {
return d.x0;
});
var yExtent = d3.extent(matches.data(), function (d) {
return d.y0;
});
//note: the "x" values are used to set VERTICAL position,
//while the "y" values are setting the HORIZONTAL position
var potentialXZoom = viewerHeight/(xExtent[1] - xExtent[0] + 20);
var potentialYZoom = viewerWidth/(yExtent[1] - yExtent[0] + 150);
//The "20" and "150" are for height and width of the labels
//You could (should) replace with calculated values
//or values stored in variables
centerToPosition( (xExtent[0] + xExtent[1])/2,
(yExtent[0] + yExtent[1])/2,
Math.min(potentialXZoom, potentialYZoom)
);
}
标签:svg,d3-js,logic,javascript 来源: https://codeday.me/bug/20191122/2056089.html