gpt4 book ai didi

map - 为什么我的 D3 缩放变换没有正确居中?

转载 作者:行者123 更新时间:2023-12-05 01:35:04 27 4
gpt4 key购买 nike

我正在将我的 map 升级到 D3 的 v3,并使用找到的 D3 示例代码中概述的单击缩放转换 here .

我的代码几乎相同,只是我的 map 尺寸稍小(564 x 300 而不是 960 x 500)。此外,我的 map 嵌套在一个 div 中并位于页面的左上角(尽管我认为这并不重要)

我的 map 加载的初始加载很好(目前使用黑色背景进行区分)

// Clear existing map in case there is remnant data.
$("#map").html(null);

var mapWidth = 564;
var mapHeight = 300;

var projection = d3.geo.albersUsa()
.scale(mapWidth)
.translate([0, 0]);

var path = d3.geo.path()
.projection(projection);

var svg = d3.select("#map")
.append("svg")
.attr("id", "map-svg")
.attr("width", mapWidth)
.attr("height", mapHeight);

svg.append("rect")
.attr("id", "map-background")
.attr("class", "background")
.attr("width", mapWidth)
.attr("height", mapHeight)
.on("click", click);

// Create placeholders for shapes and labels
var states = svg.append("g")
.attr("transform", "translate(" + mapWidth / 2 + "," + mapHeight / 2 + ")")
.attr("id", "states");

enter image description here

但是,当单击状态并运行单击功能时,我的转换似乎已关闭。在我的例子中,点击了阿肯色州(用蓝色阴影表示)

function click(d)
{
var x = 0,
y = 0,
k = 1;

if (d && centered !== d)
{
var centroid = path.centroid(d);
x = -centroid[0];
y = -centroid[1];
k = 4;
centered = d;
}
else
{
centered = null;
}

d3.select("#states").selectAll("path")
.classed("active", centered && function (d) { return d === centered; });

d3.select("#states").transition()
.duration(1000)
.attr("transform", "scale(" + k + ")translate(" + x + "," + y + ")")
.style("stroke-width", 1.5 / k + "px");
}

enter image description here

我唯一的想法是我的质心计算需要针对 map 的较小尺寸或不同位置稍微调整,但这似乎也不正确。

如何进行适当的调整?

编辑:我发现如果我在变换结束时添加“负平移” (translate("+ -x + ","+ -y + ")) ,它会更接近正确地以缩放为中心,但并不完美

最佳答案

您缺少来自 the example 的两个转换之一;但请继续阅读以获得更简单的解决方案。

您使用的示例有两个嵌套变换。首先,对外部 G 元素进行静态变换:

var g = svg.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")")
.append("g")
.attr("id", "states");

此转换的目的与 projection.translate 相同。通常会这样做,但该示例使用的是 translate([0, 0])。 (正如我所说,会有一个更简单的解决方案......)

第二个变换是动态设置在inner G(id为“states”)上放大的:

g.transition()
.attr("transform", "scale(" + k + ")translate(" + x + "," + y + ")");

请注意 var g这里指的是内部G元素,因为当g已定义,有一个 append("g")与第二个 append("g") 链接在一起;因此,变量被定义为第二个内部 G,而不是第一个外部 G。

生成的 SVG 如下所示:

<g transform="translate(480,250)">
<g id="states" transform="translate(75.746,-439.514)scale(4,4)">

</g>
</g>

您的派生缺少嵌套的内部 G。因此,当您在 #states G 元素上设置“transform”属性时,您将覆盖外部转换,从而为您提供:

<g id="states" transform="scale(4)translate(18.936679862557288,-109.8787070159044)">

</g>

因此,您缺少静态转换“translate(480,250)”。

我建议将这些转换组合在一起。那你就不需要外G了,你可以:

g.transition()
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")"
+ "scale(" + k + ")"
+ "translate(" + x + "," + y + ")");

这也消除了将投影的平移设置为 [0, 0] 的需要,因此您可以使用标准平移 [width/2, height/2] 来代替。我有 updated the example就这样做!

关于map - 为什么我的 D3 缩放变换没有正确居中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15532405/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com