gpt4 book ai didi

javascript - d3 如何在缩放和平移时将文本绑定(bind)到视口(viewport)的右上角

转载 作者:行者123 更新时间:2023-11-29 20:51:41 25 4
gpt4 key购买 nike

我正在 d3 中创建一个 map 应用程序,并希望将一些文本绑定(bind)到我的视口(viewport)的右上角。此外,我希望在缩放和平移应用程序时文本保留在右上角。我想我可以通过弄清楚如何获取 View 右上角的坐标来解决我的问题。了解此信息后,我便可以设置文本元素的坐标。我已经尝试手动设置包含 svg 元素的尺寸,然后将文本移动到该位置,但有趣的是这没有用。我希望能够以编程方式找到坐标,而不是手动设置坐标。我如何在 d3/javascript 中执行此操作?

编辑:我的代码是 Andy Barefoot 对这段代码的修改:https://codepen.io/nb123456/pen/zLdqvM

我自己的缩放和平移代码基本上与上面的示例保持相同:

function zoomed() {
t = d3
.event
.transform
;
countriesGroup
.attr("transform","translate(" + [t.x, t.y] + ")scale(" + t.k + ")")
;
}

我试图在代码的最底部附加文本:

countriesGroup.append("text")
.attr("transform", "translate(" How do I get top right coordinates? ")")
.style("fill", "#ff0000")
.attr("font-size", "50px")
.text("This is a test");

我的想法是能够通过代码获取视口(viewport)的右上角坐标,而不是手动设置,然后在用户缩放或平移时更新文本的坐标。

最佳答案

要在缩放和平移时保持原位,您可以反转缩放:

point == invertZoom(applyZoom(point))

这不是特别有效,因为我们使用两个操作来获得原始数字。此处应用缩放:

countriesGroup
.attr("transform","translate(" + [t.x, t.y] + ")scale(" + t.k + ")");

虽然反转需要看起来像:

text.attr("x", d3.zoom.transform.invert(point)[0])
.attr("y", d3.zoom.transform.invert(point)[1])
.attr("font-size", baseFontSize / d3.zoom.transform.k);

其中point和base font size是原来的 anchor 和字体大小。这意味着将该数据存储在某处。在下面的示例中,我将其作为数据分配给文本元素:

var width = 500;
var height = 200;

var data = d3.range(100).map(function() {
return {x:Math.random()*width,y:Math.random()*height}
})

var zoom = d3.zoom()
.on("zoom",zoomed);

var svg = d3.select("body")
.append("svg")
.attr("width",width)
.attr("height",height)
.call(zoom);

var g = svg.append("g")

var circles = g.selectAll()
.data(data)
.enter()
.append("circle")
.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; })
.attr("r", 5)
.attr("fill","steelblue")


var text = g.append("text")
.datum({x: width-10, y: 20, fontSize: 12})
.attr("x", function(d) { return d.x; })
.attr("y", function(d) { return d.y; })
.style("text-anchor","end")
.attr("font-size",function(d) { return d.fontSize; })
.text("This is a test");


function zoomed() {
g.attr("transform", d3.event.transform);

var d = text.datum();
var p = d3.event.transform.invert([d.x,d.y]);
var x1 = p[0];
var y1 = p[1];

text.attr("x",x1)
.attr("y",y1)
.attr("font-size", d.fontSize / d3.event.transform.k)

}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.min.js"></script>

更好的解决方案

以上是您似乎正在寻找的方法的解决方案。但最终结果最好通过不同的方法来实现。正如我在评论中提到的,上述方法经过了可以避免的额外步骤。 使用上述方法(快速)缩放时,文本中的大小/清晰度也会发生一些变化

如上所述,您正在此处应用缩放:

countriesGroup
.attr("transform","translate(" + [t.x, t.y] + ")scale(" + t.k + ")")

缩放转换应用于countriesGroup,如果您的标签恰好位于不同的g(而不是countriesGroup),它不会被缩放或平移。

我们不需要应用和反转缩放,我们根本不需要更新文本的位置或字体大小。

var width = 500;
var height = 200;

var data = d3.range(100).map(function() {
return {x:Math.random()*width,y:Math.random()*height}
})

var zoom = d3.zoom()
.on("zoom",zoomed);

var svg = d3.select("body")
.append("svg")
.attr("width",width)
.attr("height",height)
.call(zoom);

var g = svg.append("g");
var g2 = svg.append("g"); // order does matter in layering

var circles = g.selectAll()
.data(data)
.enter()
.append("circle")
.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; })
.attr("r", 5)
.attr("fill","steelblue")

// position once and leave it alone:
var text = g2.append("text")
.attr("x", width - 10)
.attr("y", 20 )
.style("text-anchor","end")
.attr("font-size", 12)
.text("This is a test");


function zoomed() {
// apply the zoom to the g that has zoomable content:
g.attr("transform", d3.event.transform);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.min.js"></script>

关于javascript - d3 如何在缩放和平移时将文本绑定(bind)到视口(viewport)的右上角,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51528040/

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