如何在D3.js的SVG Path中心添加标题文本?
如何在SVG Path中心添加标题(仅使用Path,不依赖预设坐标)
我正在创建SVG路径,需要将标题设置在path的中心位置,尝试了多个示例但均失败。以下是我的代码片段,请问如何为每个path在其中心位置添加对应的Title?
<!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" /> <link rel="stylesheet" href="assets/scss/style.css" /> </head> <body> <script src="https://d3js.org/d3.v7.min.js"></script> <script src="./assets/js/main.js"></script> </body> </html>
document.addEventListener("DOMContentLoaded", function () { const h = 300; const w = 300; const svg = d3 .select("body") .append("svg") .attr("height", h) .attr("width", w); svg .selectAll("path") .data(map) .enter() .append("path") .attr("d", (m) => m.path) .attr("stroke-width", "1") .attr("stroke", "#000") .attr('fill','#fff') svg .selectAll("text") .data(map) .enter() .append("text") .attr("fill", "#fff") .text((m) =>m.title) .attr("x", (m) => m.id) .attr("y", (m) => m.id) .attr("transform", (m) => "translate(" + m.id + "," + m.id + ")"); }); const map=[ { id: 0, title: "Title 1", 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: "Title 2", 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", }]
解决方案
核心思路是利用SVG路径的**边界框(Bounding Box)**自动计算中心坐标,无需手动预设位置。修改后的代码如下:
document.addEventListener("DOMContentLoaded", function () { const h = 300; const w = 300; const svg = d3 .select("body") .append("svg") .attr("height", h) .attr("width", w); // 绘制路径并保存选择集,方便后续获取边界框 const paths = svg .selectAll("path") .data(map) .enter() .append("path") .attr("d", (m) => m.path) .attr("stroke-width", "1") .attr("stroke", "#000") .attr('fill','#fff') // 添加标题文本,基于路径边界框计算中心位置 svg .selectAll("text") .data(map) .enter() .append("text") .attr("fill", "#000") // 改为黑色,避免在白色填充路径上不可见 .text((m) => m.title) // 获取对应路径的边界框,计算中心坐标 .attr("x", (d, i) => { const bbox = paths.nodes()[i].getBBox(); return bbox.x + bbox.width / 2; }) .attr("y", (d, i) => { const bbox = paths.nodes()[i].getBBox(); return bbox.y + bbox.height / 2; }) // 设置文本居中对齐 .attr("text-anchor", "middle") .attr("dominant-baseline", "middle"); }); const map=[ { id: 0, title: "Title 1", 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: "Title 2", 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
相关产品推荐
相关产品推荐

