中心SVG组元素

时间:2019-03-10 05:58:55

标签: javascript d3.js svg

我正尝试使用下面的代码使用ggplot(datamergedMelted, aes(x = Months, y = value, colour = factor(variable), linetype = factor(variable), size = factor(variable))) + geom_area(data = . %>% filter(variable == "data2"), color = NA, fill = "black", alpha = 0.5, show.legend = FALSE)+ geom_line()+ geom_point(data = . %>% filter(variable == "data3"), shape = 19, size = 1.5)+ scale_color_manual("", values = c("red", "blue", "black")) + scale_linetype_manual("", values = c(1, 1, 4))+ scale_size_manual("", values=c(1.2,1.3,0.5))+ ylab("Levels (mm)")+ theme(legend.position="top") g的{​​{1}}元素与text放在tspan元素的中心。

svg
d3

执行上述代码后,您可以看到group元素未正确地位于x和y坐标的中心。如何在svg中使组元素居中?

我使用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>getBoundingClientRect之后(在将任何内容重新放入svg中之前)在初始阶段获得svg的大小。

2 个答案:

答案 0 :(得分:2)

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

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

这样,您可以为alignment-baselinedominant-baselinetext-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>

答案 1 :(得分:0)

我已对svg进行了一些更改,这是最重要的:我更改了tspan的{​​{1}}的某些值。另外,我使用的是dy而不是dominant-baseline="middle"。希望对您有所帮助。

alignment-baseline="middle"
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 + ")")