gpt4 book ai didi

javascript - 将文本元素添加到路径元素的中心

转载 作者:行者123 更新时间:2023-12-05 02:25:37 24 4
gpt4 key购买 nike

我正在创建 Choropleth map 。我需要为 hover effect 制作每个 svg 路径和标题的 group。现在我坚持定位 textpath

请检查代码片段。如何在其 Path 中心位置添加每个 Text?目前文字已置顶。

注意:我只用路径,不是坐标!
Note2: Mute/Unmute console.log 查看 map 。

document.addEventListener("DOMContentLoaded", function () {
const h = 400;
const w = 400;

var svg = d3
.select(".map")
.append("svg")
.attr("width", w)
.attr("height", h)
.attr("viewBox", "0 0 400 400")

var groups = svg
.selectAll(".groups")
.data(map)
.enter()
.append("g")
.attr("class", "region");

groups
.append("path")
.attr("d", (m) => m.path)
.attr("stroke-width", "1")
.attr("stroke", "#fff")
.attr("fill","#333")

groups
.append("text")
.text((m) => m.title)
.style("font-weight", "bold")
.style("font-family", "Jersey")
.attr("fill","#6D6E71")
.attr("text-anchor", "middle")
.style("text-transform", "uppercase")
.attr("x", (m, i, nodes) => {
let bbox = d3.select(nodes[i]).node().getBBox();
let centreX = bbox.width + bbox.x;
//console.log(d3.select(nodes[i]).node().getBBox());
// console.log("X", centreX);
return centreX;
})
.attr("y", (m, i, nodes) => {
let bbox = d3.select(nodes[i]).node().getBBox();
let centreY = bbox.height + bbox.y;
// console.log(d3.select(nodes[i]).node().getBBox());
// console.log("Y", centreY);
return centreY;
});
});

const map=[{
id: 0,
title: "A",
path: "M 45.25 34.96 l -0.97 -3.35 l -0.97 -2.39 l 2.43 -3.35 l 1.94 -4.31 l 1.94 -5.74 l 3.89 -5.74 l 0.97 6.22 l 0.49 3.35 l 3.89 3.83 l 3.89 -0.96 l 0.97 3.35 l 3.89 0.96 l 0.49 2.87 l 3.89 1.44 l 0.49 1.91 L 76.36 34 l 2.43 -2.87 l 1.46 3.83 l 1.94 2.39 l 2.92 1.91 l 0.97 1.91 l 2.43 -0.96 l 1.46 1.44 l -1.46 3.35 l 1.46 1.44 l 1.94 1.44 v 0.96 l 3.89 -0.48 v 1.91 l 0.97 1.91 v 2.39 l 2.43 1.91 l -0.49 4.31 l 1.94 3.35 l 2.43 3.35 l -0.97 3.35 v 4.79 v 4.31 l -1.46 3.83 l 0.97 4.79 l -2.43 3.35 l -3.4 4.79 l -3.89 -0.96 l -5.35 -0.48 l -1.94 -3.83 l -2.43 -1.91 l 2.92 -5.26 l -1.94 -3.83 l -2.43 -2.87 l -3.89 -1.44 l -1.94 -1.91 l -1.46 -2.87 l -2.43 0.96 c 0 0 -0.61 -0.48 -1.94 -0.96 s -3.4 -0.96 -3.4 -0.96 l -2.43 -0.96 l -2.43 1.91 l -3.89 -0.96 l -3.4 -1.44 l -2.92 1.91 l -0.49 2.39 c 0 0 -1.58 -0.24 -3.4 -0.96 c -1.82 -0.72 -3.89 -1.91 -3.89 -1.91 l -0.97 -1.44 l 3.4 -1.91 l 1.94 -2.39 l -1.46 -2.87 v -6.7 l 5.35 -0.48 l 1.94 -1.91 l 1.94 -2.87 l 4.37 -1.44 l 0.97 -3.35 l 2.43 3.83 l 2.43 -1.44 l 1.94 -3.35 l -1.94 -2.39 l -1.94 -2.87 v -3.35 l -3.4 -2.87 l -4.37 0.96 l -2.43 -3.83 l -2.43 1.91 l -2.92 -0.48 L 45.25 34.96 Z",
},
{
id: 1,
title: "B",
path: "M 19.49 126.38 l -2.43 -4.31 l -2.92 -3.83 l 1.94 -4.31 l -4.86 -0.96 l 1.46 -7.66 l 3.4 -2.39 l -0.49 -2.87 l 1.94 -3.83 l 5.83 -3.83 l 1.94 -5.26 l -4.37 -2.39 l 2.43 -4.31 l 0.97 -4.31 l 5.35 -1.91 v -4.79 l 7.29 0.96 l 5.35 -1.44 l 7.29 4.79 l 1.46 -3.83 l 4.96 -1.03 l 4.27 1.51 l 3.89 -0.48 l 9.72 2.39 l 3.89 4.31 l 3.4 1.44 l 4.86 5.74 l -3.4 4.79 l 0.97 3.35 l -2.43 2.39 l -0.97 3.83 h -3.4 l -2.43 -3.83 l -1.46 2.87 h -2.92 l -1.46 5.27 l 1.94 1.91 l -2.43 0.48 l -2.92 4.79 l -0.97 2.87 l -1.46 2.87 l 1.94 2.39 l -2.92 0.48 h -1.94 v -2.39 l -6.32 0.48 v 3.83 h -2.43 l -0.49 4.79 l 2.92 1.44 l -1.94 1.91 v 4.31 l 2.43 1.44 l 2.92 2.39 l -0.49 3.35 l -3.4 0.48 l -2.92 -2.87 l -2.43 -1.44 v -1.92 l -3.4 -3.35 h -2.92 l -0.97 -3.35 l -5.35 -2.87 l 0.49 -2.39 l -0.49 -1.44 l -4.37 1.44 l -2.92 2.39 l -2.43 -2.87 L 19.49 126.38 Z",
},
{
id: 2,
title: "C",
path: "M 98.24 55.54 l 2.43 -2.39 l 2.43 0.48 l 2.43 1.91 l -1.94 5.26 l 2.92 0.96 l 2.43 2.87 l 2.92 -0.48 l -0.49 -3.35 l -2.43 -1.44 l 2.92 -3.35 l 5.35 0.48 l 2.43 3.35 l 1.94 2.39 l 1.46 2.39 L 124 63.2 h 4.37 l 0.97 0.96 l 2.92 -1.44 v 3.35 l 0.49 5.74 l 3.4 2.39 l 3.4 1.91 l 0.97 2.39 l -0.49 2.87 l -0.97 7.18 l 1.46 4.79 l 0.97 5.26 l 3.89 3.35 l 4.37 2.87 l 3.4 2.87 l -1.46 3.83 l -1.46 3.35 l -1.46 1.91 l -2.92 -3.35 l -4.86 4.31 l 0.49 5.27 l -3.89 -3.83 l -2.43 4.79 l -7.78 -1.91 l -5.35 1.44 l 1.94 4.79 l -2.43 2.87 l -1.46 2.39 l -4.37 -0.48 l -3.89 -3.35 h -2.43 v -5.26 l -3.89 -0.96 v -11.49 l -1.94 -2.39 l -1.94 -3.35 l -5.35 -1.44 l 0.49 -2.39 l -1.46 -0.96 v -3.83 l -0.49 -1.44 l 1.94 -2.39 l -1.46 2.39 l 2.92 -4.31 l 2.92 -1.44 v -8.14 l 1.46 -2.87 v -1.91 l -0.49 -6.7 l 1.46 -2.87 l -5.35 -5.74 L 98.24 55.54 L 98.24 55.54 L 98.24 55.54 Z",
}]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta
name="viewport"
content="width=device-width, initial-scale=1.0, shrink-to-fit=no"
/>
<title>Choropleth Map</title>
<style>
.region:hover path {
cursor: pointer;
fill: #ccc;
}
.region:hover text {
fill: #fff;
}
</style>
</head>

<body>
<div class="map m-auto"></div>

<!-- Script Section -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="https://d3js.org/d3.v7.min.js"></script>
</body>
</html>

最佳答案

如果您想遵循当前的方法,您应该根据添加到 x 或 y 位置的宽度或高度的一半来计算中心。

另外,请注意 d3.select(nodes[i]).node() 是不必要的,这与 nodes[i] 相同。

这是您的代码,其中包含更改:

document.addEventListener("DOMContentLoaded", function() {
const h = 400;
const w = 400;

var svg = d3
.select(".map")
.append("svg")
.attr("width", w)
.attr("height", h)
.attr("viewBox", "0 0 400 400")

var groups = svg
.selectAll(".groups")
.data(map)
.enter()
.append("g")
.attr("class", "region");

groups
.append("path")
.attr("d", (m) => m.path)
.attr("stroke-width", "1")
.attr("stroke", "#fff")
.attr("fill", "#333")

groups
.append("text")
.text((m) => m.title)
.style("font-weight", "bold")
.style("font-family", "Jersey")
.attr("fill", "#6D6E71")
.attr("text-anchor", "middle")
.style("text-transform", "uppercase")
.attr("x", (m, i, nodes) => {
let bbox = nodes[i].previousSibling.getBBox();
let centreX = bbox.width / 2 + bbox.x;
return centreX;
})
.attr("y", (m, i, nodes) => {
let bbox = nodes[i].previousSibling.getBBox();
let centreY = bbox.height / 2 + bbox.y;
return centreY;
});
});

const map = [{
id: 0,
title: "A",
path: "M 45.25 34.96 l -0.97 -3.35 l -0.97 -2.39 l 2.43 -3.35 l 1.94 -4.31 l 1.94 -5.74 l 3.89 -5.74 l 0.97 6.22 l 0.49 3.35 l 3.89 3.83 l 3.89 -0.96 l 0.97 3.35 l 3.89 0.96 l 0.49 2.87 l 3.89 1.44 l 0.49 1.91 L 76.36 34 l 2.43 -2.87 l 1.46 3.83 l 1.94 2.39 l 2.92 1.91 l 0.97 1.91 l 2.43 -0.96 l 1.46 1.44 l -1.46 3.35 l 1.46 1.44 l 1.94 1.44 v 0.96 l 3.89 -0.48 v 1.91 l 0.97 1.91 v 2.39 l 2.43 1.91 l -0.49 4.31 l 1.94 3.35 l 2.43 3.35 l -0.97 3.35 v 4.79 v 4.31 l -1.46 3.83 l 0.97 4.79 l -2.43 3.35 l -3.4 4.79 l -3.89 -0.96 l -5.35 -0.48 l -1.94 -3.83 l -2.43 -1.91 l 2.92 -5.26 l -1.94 -3.83 l -2.43 -2.87 l -3.89 -1.44 l -1.94 -1.91 l -1.46 -2.87 l -2.43 0.96 c 0 0 -0.61 -0.48 -1.94 -0.96 s -3.4 -0.96 -3.4 -0.96 l -2.43 -0.96 l -2.43 1.91 l -3.89 -0.96 l -3.4 -1.44 l -2.92 1.91 l -0.49 2.39 c 0 0 -1.58 -0.24 -3.4 -0.96 c -1.82 -0.72 -3.89 -1.91 -3.89 -1.91 l -0.97 -1.44 l 3.4 -1.91 l 1.94 -2.39 l -1.46 -2.87 v -6.7 l 5.35 -0.48 l 1.94 -1.91 l 1.94 -2.87 l 4.37 -1.44 l 0.97 -3.35 l 2.43 3.83 l 2.43 -1.44 l 1.94 -3.35 l -1.94 -2.39 l -1.94 -2.87 v -3.35 l -3.4 -2.87 l -4.37 0.96 l -2.43 -3.83 l -2.43 1.91 l -2.92 -0.48 L 45.25 34.96 Z",
},
{
id: 1,
title: "B",
path: "M 19.49 126.38 l -2.43 -4.31 l -2.92 -3.83 l 1.94 -4.31 l -4.86 -0.96 l 1.46 -7.66 l 3.4 -2.39 l -0.49 -2.87 l 1.94 -3.83 l 5.83 -3.83 l 1.94 -5.26 l -4.37 -2.39 l 2.43 -4.31 l 0.97 -4.31 l 5.35 -1.91 v -4.79 l 7.29 0.96 l 5.35 -1.44 l 7.29 4.79 l 1.46 -3.83 l 4.96 -1.03 l 4.27 1.51 l 3.89 -0.48 l 9.72 2.39 l 3.89 4.31 l 3.4 1.44 l 4.86 5.74 l -3.4 4.79 l 0.97 3.35 l -2.43 2.39 l -0.97 3.83 h -3.4 l -2.43 -3.83 l -1.46 2.87 h -2.92 l -1.46 5.27 l 1.94 1.91 l -2.43 0.48 l -2.92 4.79 l -0.97 2.87 l -1.46 2.87 l 1.94 2.39 l -2.92 0.48 h -1.94 v -2.39 l -6.32 0.48 v 3.83 h -2.43 l -0.49 4.79 l 2.92 1.44 l -1.94 1.91 v 4.31 l 2.43 1.44 l 2.92 2.39 l -0.49 3.35 l -3.4 0.48 l -2.92 -2.87 l -2.43 -1.44 v -1.92 l -3.4 -3.35 h -2.92 l -0.97 -3.35 l -5.35 -2.87 l 0.49 -2.39 l -0.49 -1.44 l -4.37 1.44 l -2.92 2.39 l -2.43 -2.87 L 19.49 126.38 Z",
},
{
id: 2,
title: "C",
path: "M 98.24 55.54 l 2.43 -2.39 l 2.43 0.48 l 2.43 1.91 l -1.94 5.26 l 2.92 0.96 l 2.43 2.87 l 2.92 -0.48 l -0.49 -3.35 l -2.43 -1.44 l 2.92 -3.35 l 5.35 0.48 l 2.43 3.35 l 1.94 2.39 l 1.46 2.39 L 124 63.2 h 4.37 l 0.97 0.96 l 2.92 -1.44 v 3.35 l 0.49 5.74 l 3.4 2.39 l 3.4 1.91 l 0.97 2.39 l -0.49 2.87 l -0.97 7.18 l 1.46 4.79 l 0.97 5.26 l 3.89 3.35 l 4.37 2.87 l 3.4 2.87 l -1.46 3.83 l -1.46 3.35 l -1.46 1.91 l -2.92 -3.35 l -4.86 4.31 l 0.49 5.27 l -3.89 -3.83 l -2.43 4.79 l -7.78 -1.91 l -5.35 1.44 l 1.94 4.79 l -2.43 2.87 l -1.46 2.39 l -4.37 -0.48 l -3.89 -3.35 h -2.43 v -5.26 l -3.89 -0.96 v -11.49 l -1.94 -2.39 l -1.94 -3.35 l -5.35 -1.44 l 0.49 -2.39 l -1.46 -0.96 v -3.83 l -0.49 -1.44 l 1.94 -2.39 l -1.46 2.39 l 2.92 -4.31 l 2.92 -1.44 v -8.14 l 1.46 -2.87 v -1.91 l -0.49 -6.7 l 1.46 -2.87 l -5.35 -5.74 L 98.24 55.54 L 98.24 55.54 L 98.24 55.54 Z",
}
]
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no" />
<title>Choropleth Map</title>
<style>
.region:hover path {
cursor: pointer;
fill: #ccc;
}

.region:hover text {
fill: #fff;
}
</style>
</head>

<body>
<div class="map m-auto"></div>

<!-- Script Section -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="https://d3js.org/d3.v7.min.js"></script>
</body>

</html>

但是,基于this answer of mine ,即使您只有路径的 d 属性,我也会对地理路径使用质心方法。这只是改造它们的问题。

这是使用该方法的代码:

document.addEventListener("DOMContentLoaded", function() {
const h = 400;
const w = 400;
const geoPath = d3.geoPath()
.projection(d3.geoIdentity());
const precision = 4;

var svg = d3
.select(".map")
.append("svg")
.attr("width", w)
.attr("height", h)
.attr("viewBox", "0 0 400 400")

var groups = svg
.selectAll(".groups")
.data(map)
.enter()
.append("g")
.attr("class", "region");

groups
.append("path")
.attr("d", (m) => m.path)
.each((d, i, n) => {
const pathLength = n[i].getTotalLength();
let index = 0;
const geoJSONObject = {
"type": "Polygon",
"coordinates": [
[]
]
};
while (index < pathLength) {
const point = n[i].getPointAtLength(index);
geoJSONObject.coordinates[0].push([point.x, point.y]);
index += precision;
};
const centroid = geoPath.centroid(geoJSONObject);
d.centroid = centroid;
})
.attr("stroke-width", "1")
.attr("stroke", "#fff")
.attr("fill", "#333")

groups
.append("text")
.text((m) => m.title)
.style("font-weight", "bold")
.style("font-family", "Jersey")
.attr("fill", "#6D6E71")
.attr("text-anchor", "middle")
.style("text-transform", "uppercase")
.attr("x", d => d.centroid[0])
.attr("y", d => d.centroid[1])
});

const map = [{
id: 0,
title: "A",
path: "M 45.25 34.96 l -0.97 -3.35 l -0.97 -2.39 l 2.43 -3.35 l 1.94 -4.31 l 1.94 -5.74 l 3.89 -5.74 l 0.97 6.22 l 0.49 3.35 l 3.89 3.83 l 3.89 -0.96 l 0.97 3.35 l 3.89 0.96 l 0.49 2.87 l 3.89 1.44 l 0.49 1.91 L 76.36 34 l 2.43 -2.87 l 1.46 3.83 l 1.94 2.39 l 2.92 1.91 l 0.97 1.91 l 2.43 -0.96 l 1.46 1.44 l -1.46 3.35 l 1.46 1.44 l 1.94 1.44 v 0.96 l 3.89 -0.48 v 1.91 l 0.97 1.91 v 2.39 l 2.43 1.91 l -0.49 4.31 l 1.94 3.35 l 2.43 3.35 l -0.97 3.35 v 4.79 v 4.31 l -1.46 3.83 l 0.97 4.79 l -2.43 3.35 l -3.4 4.79 l -3.89 -0.96 l -5.35 -0.48 l -1.94 -3.83 l -2.43 -1.91 l 2.92 -5.26 l -1.94 -3.83 l -2.43 -2.87 l -3.89 -1.44 l -1.94 -1.91 l -1.46 -2.87 l -2.43 0.96 c 0 0 -0.61 -0.48 -1.94 -0.96 s -3.4 -0.96 -3.4 -0.96 l -2.43 -0.96 l -2.43 1.91 l -3.89 -0.96 l -3.4 -1.44 l -2.92 1.91 l -0.49 2.39 c 0 0 -1.58 -0.24 -3.4 -0.96 c -1.82 -0.72 -3.89 -1.91 -3.89 -1.91 l -0.97 -1.44 l 3.4 -1.91 l 1.94 -2.39 l -1.46 -2.87 v -6.7 l 5.35 -0.48 l 1.94 -1.91 l 1.94 -2.87 l 4.37 -1.44 l 0.97 -3.35 l 2.43 3.83 l 2.43 -1.44 l 1.94 -3.35 l -1.94 -2.39 l -1.94 -2.87 v -3.35 l -3.4 -2.87 l -4.37 0.96 l -2.43 -3.83 l -2.43 1.91 l -2.92 -0.48 L 45.25 34.96 Z",
},
{
id: 1,
title: "B",
path: "M 19.49 126.38 l -2.43 -4.31 l -2.92 -3.83 l 1.94 -4.31 l -4.86 -0.96 l 1.46 -7.66 l 3.4 -2.39 l -0.49 -2.87 l 1.94 -3.83 l 5.83 -3.83 l 1.94 -5.26 l -4.37 -2.39 l 2.43 -4.31 l 0.97 -4.31 l 5.35 -1.91 v -4.79 l 7.29 0.96 l 5.35 -1.44 l 7.29 4.79 l 1.46 -3.83 l 4.96 -1.03 l 4.27 1.51 l 3.89 -0.48 l 9.72 2.39 l 3.89 4.31 l 3.4 1.44 l 4.86 5.74 l -3.4 4.79 l 0.97 3.35 l -2.43 2.39 l -0.97 3.83 h -3.4 l -2.43 -3.83 l -1.46 2.87 h -2.92 l -1.46 5.27 l 1.94 1.91 l -2.43 0.48 l -2.92 4.79 l -0.97 2.87 l -1.46 2.87 l 1.94 2.39 l -2.92 0.48 h -1.94 v -2.39 l -6.32 0.48 v 3.83 h -2.43 l -0.49 4.79 l 2.92 1.44 l -1.94 1.91 v 4.31 l 2.43 1.44 l 2.92 2.39 l -0.49 3.35 l -3.4 0.48 l -2.92 -2.87 l -2.43 -1.44 v -1.92 l -3.4 -3.35 h -2.92 l -0.97 -3.35 l -5.35 -2.87 l 0.49 -2.39 l -0.49 -1.44 l -4.37 1.44 l -2.92 2.39 l -2.43 -2.87 L 19.49 126.38 Z",
},
{
id: 2,
title: "C",
path: "M 98.24 55.54 l 2.43 -2.39 l 2.43 0.48 l 2.43 1.91 l -1.94 5.26 l 2.92 0.96 l 2.43 2.87 l 2.92 -0.48 l -0.49 -3.35 l -2.43 -1.44 l 2.92 -3.35 l 5.35 0.48 l 2.43 3.35 l 1.94 2.39 l 1.46 2.39 L 124 63.2 h 4.37 l 0.97 0.96 l 2.92 -1.44 v 3.35 l 0.49 5.74 l 3.4 2.39 l 3.4 1.91 l 0.97 2.39 l -0.49 2.87 l -0.97 7.18 l 1.46 4.79 l 0.97 5.26 l 3.89 3.35 l 4.37 2.87 l 3.4 2.87 l -1.46 3.83 l -1.46 3.35 l -1.46 1.91 l -2.92 -3.35 l -4.86 4.31 l 0.49 5.27 l -3.89 -3.83 l -2.43 4.79 l -7.78 -1.91 l -5.35 1.44 l 1.94 4.79 l -2.43 2.87 l -1.46 2.39 l -4.37 -0.48 l -3.89 -3.35 h -2.43 v -5.26 l -3.89 -0.96 v -11.49 l -1.94 -2.39 l -1.94 -3.35 l -5.35 -1.44 l 0.49 -2.39 l -1.46 -0.96 v -3.83 l -0.49 -1.44 l 1.94 -2.39 l -1.46 2.39 l 2.92 -4.31 l 2.92 -1.44 v -8.14 l 1.46 -2.87 v -1.91 l -0.49 -6.7 l 1.46 -2.87 l -5.35 -5.74 L 98.24 55.54 L 98.24 55.54 L 98.24 55.54 Z",
}
]
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no" />
<title>Choropleth Map</title>
<style>
.region:hover path {
cursor: pointer;
fill: #ccc;
}

.region:hover text {
fill: #fff;
}
</style>
</head>

<body>
<div class="map m-auto"></div>

<!-- Script Section -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="https://d3js.org/d3.v7.min.js"></script>
</body>

</html>

关于javascript - 将文本元素添加到路径元素的中心,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74419109/

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