我正在使用d3库并且已经成功使用了chloropleth示例,并且获得了单击操作以放大到特定状态(有关详细信息,请参阅this question)。特别是,这是我用于点击状态缩放事件的代码:
// Since height is smaller than width,
var baseWidth = 564;
var baseHeight = 400;
d3.selectAll('#states path')
.on('click', function(d) {
// getBBox() is a native SVG element method
var bbox = this.getBBox(),
centroid = [bbox.x + bbox.width/2, bbox.y + bbox.height/2],
// since height is smaller than width, I scale based off of it.
zoomScaleFactor = baseHeight / bbox.height,
zoomX = -centroid[0],
zoomY = -centroid[1];
// set a transform on the parent group element
d3.select('#states')
.attr("transform", "scale(" + scaleFactor + ")" +
"translate(" + zoomX + "," + zoomY + ")");
});
然而,当我点击查看状态时,我的变换不在我的视口的中心,而是在左上角,并且它可能也没有适当的比例。如果我手动对scaleFactor或zoomX / zoomY参数进行微调,我会完全丢失该项目。我熟悉这样一个概念,即一起进行缩放和变换会产生明显不同的结果,所以我不确定如何调整。
我唯一能想到的是原始的氯色素图像设置为960 x 500图像。为了适应这一点。我创建了一个albersUSA投影并使用我的d3.geo.path进行此投影,并继续相应地添加我的路径。
我的变换是否受到投影的影响?如果是的话,我将如何适应它呢?
答案 0 :(得分:2)
缩放变换需要像旋转变换一样处理(没有可选的cx,cy参数),也就是说,首先必须将要变换的对象移动到原点。
d3.select('#states')
.attr("transform",
"translate(" + (-zoomX) + "," + (-zoomY) + ")" +
"scale(" + scaleFactor + ")" +
"translate(" + zoomX + "," + zoomY + ")");
答案 1 :(得分:2)
供进一步参考,
我发现this article你应该找到如何使用矩阵变换来实现变焦和平移效果非常简单。
例外:
<script type="text/ecmascript">
<![CDATA[
var transMatrix = [1,0,0,1,0,0];
function init(evt)
{
if ( window.svgDocument == null )
{
svgDoc = evt.target.ownerDocument;
}
mapMatrix = svgDoc.getElementById("map-matrix");
width = evt.target.getAttributeNS(null, "width");
height = evt.target.getAttributeNS(null, "height");
}
]]>
</script>
function pan(dx, dy)
{
transMatrix[4] += dx;
transMatrix[5] += dy;
newMatrix = "matrix(" + transMatrix.join(' ') + ")";
mapMatrix.setAttributeNS(null, "transform", newMatrix);
}
function zoom(scale)
{
for (var i=0; i<transMatrix.length; i++)
{
transMatrix[i] *= scale;
}
transMatrix[4] += (1-scale)*width/2;
transMatrix[5] += (1-scale)*height/2;
newMatrix = "matrix(" + transMatrix.join(' ') + ")";
mapMatrix.setAttributeNS(null, "transform", newMatrix);
}