首页 > 解决方案 > 中心 SVG 组元素

问题描述

我正在尝试使用以下代码g将具有内部元素text的元素居中。tspansvgd3

var rootSVGSize = d3.select("svg.root-svg").node().getBoundingClientRect()
var dataLabelSize = d3.select("g.data-label").node().getBoundingClientRect()

var x = rootSVGSize.width / 2;
var y = rootSVGSize.height / 2;

d3.select("g.data-label").attr("transform", "translate(" + x + "," + y + ")")
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>

<svg class="root-svg" width="180" height="200" style="border: black;border-style: solid;border-width: 1px;">
   <g class="data-label">
      <text alignment-baseline="middle" style="font-family: Arial; font-size: 36px; font-style: normal; font-weight: normal; fill: rgb(242, 200, 15);" text-anchor="middle">
         <tspan x="0" dy="0">1/1/2018</tspan>
         <tspan x="0" dy="41">3:00:00</tspan>
         <tspan x="0" dy="41">AM</tspan>
      </text>
      <title>1/1/2018 3:00:00 AM</title>
   </g>
</svg>

正如您在执行上述代码后所看到的,组元素没有正确地以 x 和 y 坐标为中心。如何使组元素在 svg 中居中?

我正在使用,getBoundingClientRect因为我想svg在分配后的初始阶段获得大小widthheight也就是在 svg 中渲染任何内容之前。

标签: javascriptd3.jssvg

解决方案


您必须考虑SVG 容器和组的位置x和位置:y

var x = (rootSVGSize.x - dataLabelSize.x) + (rootSVGSize.width - dataLabelSize.width) / 2;
var y = (rootSVGSize.y - dataLabelSize.y) + (rootSVGSize.height - dataLabelSize.height) / 2;

这样,您就可以拥有任何您想要的价值alignment-baselinedominant-baseline而且text-anchor,没关系,该组将始终居中。

这是您进行更改的代码:

var rootSVGSize = d3.select("svg.root-svg").node().getBoundingClientRect()
var dataLabelSize = d3.select("g.data-label").node().getBoundingClientRect()

var x = (rootSVGSize.x - dataLabelSize.x) + (rootSVGSize.width - dataLabelSize.width) / 2;
var y = (rootSVGSize.y - dataLabelSize.y) + (rootSVGSize.height - dataLabelSize.height) / 2;

d3.select("g.data-label").attr("transform", "translate(" + x + "," + y + ")")
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>

<svg class="root-svg" width="180" height="200" style="border: black;border-style: solid;border-width: 1px;">
   <g class="data-label">
      <text alignment-baseline="middle" style="font-family: Arial; font-size: 36px; font-style: normal; font-weight: normal; fill: rgb(242, 200, 15);" text-anchor="middle">
         <tspan x="0" dy="0">1/1/2018</tspan>
         <tspan x="0" dy="41">3:00:00</tspan>
         <tspan x="0" dy="41">AM</tspan>
      </text>
      <title>1/1/2018 3:00:00 AM</title>
   </g>
</svg>


推荐阅读