这与您的其他问题类似,只是它是在正投影和缩放而不是反转。 (我在更新之前开始写这个,但必须运行,我会继续使用你的原始代码)。
与路径一样,您可以按预期附加标签:
country_labels.selectAll("text")
.data(collection.features)
.enter().append("text")
.attr("x", function(d){return path.centroid(d)[0];})
.attr("y", function(d){return path.centroid(d)[1];})
.attr("dx", -40)
.text(function(d){ return d.properties.name })
.style("fill", "#aeaeaf")
.style("font-size", "15px")
这里有一个问题,因为大多数 d3-tile 示例的投影,包括你的,使用 1/tau 的 d3-projection 比例,世界被投影在 1 个像素的空间内,所以 dx值等于 40 个世界,这在应用缩放时不起作用,所以让我们放下那部分
现在您或多或少地像路径一样附加特征,但问题在于缩放处理:
d3.selectAll(".country_labels")
.attr("transform", function(d) {return "translate(" + path.centroid(d) + ")"})
路径被给予类似的处理:
vector
.attr("transform", "translate(" + [transform.x, transform.y] + ")scale(" + transform.k + ")")
.style("stroke-width", 1 / transform.k);
但这里有几个不同之处:
与文本相比,您正在对路径应用不同的变换(缩放和平移):对于文本,没有对当前缩放变换的引用,而是仅使用锚定的投影在 0,0 处,所有特征都位于一个像素的区域内(并且锚定在 0,0 处的基线将在 y=0 处,文本将大部分不在视野范围内)。如果你检查 svg,你会看到文本,只是在错误的位置。
路径在放大时会减小笔画宽度(当我们缩放 svg 时,笔画宽度本身会增加),同样适用于文本,因此即使文本定位正确,它也会非常非常大(比浏览器的大多数屏幕都大)。
我们可以解决这个问题的一种方法是我们在文本的 x/y 坐标上应用缩放变换,而不是元素本身(这也会缩放文本大小,这样我们就不需要调整文本大小完全):
country_labels.selectAll("文本")
.attr("x", function(d){return transform.apply(path.centroid(d))[0];})
.attr("y", function(d){return transform.apply(path.centroid(d))1;})
与inversion from svg pixel to lat/long 一样,我们执行相同的动作,但顺序相反:应用投影,然后应用缩放。
这是updated fiddle。
但是,我有一个坏消息 - 标签的位置正好位于您现在告诉它们的位置。但它们不是你想要它们在的地方(俗话说,编程最好的事情是代码完全按照你说的做,编程最糟糕的事情是代码做到底是什么意思?)。
您正在使用路径质心来放置标签,这有时适用于某些功能,但并非始终有效。以美国为例,使用墨卡托投影的美国质心不在美国,因为它位于阿拉斯加和美国本土 48 个州之间(对不起,夏威夷,这里没有太大的吸引力)。加拿大的质心部分位于北冰洋,在许多数据集中(这并不令人惊讶),在使用质心作为文本锚点时,由于法属圭亚那,法国被标记在大西洋中部。
您可以使用.style("text-anchor","middle") 稍微改善视觉外观,它至少将标签居中(对于较小或公平的国家非常有用),但最终的质心位置并不理想。
我将结束:注释是制图的祸根。
但是,有希望,here's 我见过的更有希望的未来之一。