iamcootis
iamcootis

Reputation: 2313

Positioning svg text

So I have a gauge chart with some text in the middle. The main group is translated in relation to its parent so it will be centered. I can't figure out how to get the .center and .onlineText to line up correctly like the image. Code snippet is below.

enter image description here

<svg _ngcontent-c30="" class="gauge" id="gauge-AgentStatus" width="100%" height="100%" viewBox="0 20 424 250" preserveAspectRatio="xMidYMid meet"><defs _ngcontent-c30=""><linearGradient _ngcontent-c30="" id="mainGradient" x1="0%" x2="100%" y1="0%" y2="100%"><stop _ngcontent-c30="" class="start" offset="0%" stop-color="white" stop-opacity="1"></stop><stop _ngcontent-c30="" class="end" offset="100%" stop-color="blue" stop-opacity="1"></stop></linearGradient></defs><g transform="translate(212,125)"><g class="backPath"><path class="backPathArc" d="M103.55887361070263,47.394500828980114A113.88888888888889,113.88888888888889,0,1,1,-103.55887361070263,-47.394500828980114A113.88888888888889,113.88888888888889,0,1,1,103.55887361070263,47.394500828980114M34.57216181750291,76.4337053025479A83.88888888888889,83.88888888888889,0,1,0,-34.57216181750291,-76.4337053025479A83.88888888888889,83.88888888888889,0,1,0,34.57216181750291,76.4337053025479Z" fill="gray"></path></g><g class="frontPath"><path class="frontPathArc" d="M11.36991689588878,-113.31991882333071A113.88888888888889,113.88888888888889,0,1,1,-11.36991689588878,113.31991882333071A113.88888888888889,113.88888888888889,0,1,1,11.36991689588878,-113.31991882333071M9.777183295791342,-83.31717929582616A83.88888888888889,83.88888888888889,0,1,0,-9.777183295791342,83.31717929582616A83.88888888888889,83.88888888888889,0,1,0,9.777183295791342,-83.31717929582616Z" fill="url(#mainGradient)"></path></g><g class="center"><text class="centerText" alignment-baseline="hanging" text-anchor="end" fill="#4d4d4d" style="font-size: 80px;">100</text><text class="percentText" alignment-baseline="hanging" text-anchor="start" fill="#4d4d4d" style="font-size: 30px;">%</text></g><g class="onlineText"><text class="percentText" alignment-baseline="baseline" fill="#4d4d4d" dy=".35em" style="font-size: 20px;">ONLINE</text></g></g></svg>

Upvotes: 0

Views: 132

Answers (2)

iamcootis
iamcootis

Reputation: 2313

A coworker came up with this solution:

svg{
  background: yellow;
}
.text1 {
  dominant-baseline: hanging;
  text-anchor: middle;
}
.value {
  font-size: 50px;
}
.percent {
  font-size: 20px;
}
.text2 {
  dominant-baseline: baseline;
  text-anchor: middle;
}
<svg height=200 width=200>
    <g id="svgFont" stroke-width="1" transform="translate(100, 100)">
        <text class="text1" x="0" y="-35"><tspan class=value>100</tspan><tspan class="percent">%</tspan></text>
        <text class="text2" x="0" y="20">Online</text>
    </g>
</svg>

Upvotes: 0

enxaneta
enxaneta

Reputation: 33024

I've removed the transform and changed the viewBox to viewBox="-114 -114 228 228". The center of the svg canvas is now 0,0. Since the text has no x or y attributes the value by default for x and y is 0. Next you need to center the text around the 0,0 point. You can do it using dominant-baseline="middle" and text-anchor="middle". Now all 3 text elements of text are overlaping. In order to offset the text you can use the dy attribute

Observation: the width:300px is just for the demo. An SVG element with a viewBox but without a width attribute will take the all the width available.

Observation 2: you could have used <circle> with a whide stroke instead of those paths

svg{width:300px; border:1px solid; display:block;margin:0 auto;}
<svg _ngcontent-c30="" class="gauge" id="gauge-AgentStatus" viewBox="-114 -114 228 228" preserveAspectRatio="xMidYMid meet">
<defs _ngcontent-c30="">
<linearGradient _ngcontent-c30="" id="mainGradient" x1="0%" x2="100%" y1="0%" y2="100%">
<stop _ngcontent-c30="" class="start" offset="0%" stop-color="white" stop-opacity="1"></stop>
<stop _ngcontent-c30="" class="end" offset="100%" stop-color="blue" stop-opacity="1"></stop>
</linearGradient></defs>
<g>
<g class="backPath" >
<path class="backPathArc" d="M103.55887361070263,47.394500828980114A113.88888888888889,113.88888888888889,0,1,1,-103.55887361070263,-47.394500828980114A113.88888888888889,113.88888888888889,0,1,1,103.55887361070263,47.394500828980114M34.57216181750291,76.4337053025479A83.88888888888889,83.88888888888889,0,1,0,-34.57216181750291,-76.4337053025479A83.88888888888889,83.88888888888889,0,1,0,34.57216181750291,76.4337053025479Z" fill="gray"></path>
</g>
<g class="frontPath">
<path class="frontPathArc" d="M11.36991689588878,-113.31991882333071A113.88888888888889,113.88888888888889,0,1,1,-11.36991689588878,113.31991882333071A113.88888888888889,113.88888888888889,0,1,1,11.36991689588878,-113.31991882333071M9.777183295791342,-83.31717929582616A83.88888888888889,83.88888888888889,0,1,0,-9.777183295791342,83.31717929582616A83.88888888888889,83.88888888888889,0,1,0,9.777183295791342,-83.31717929582616Z" fill="url(#mainGradient)"></path>
</g>
<g class="center">
<text class="centerText" dominant-baseline="middle" text-anchor="middle" dy="-40" fill="#4d4d4d" style="font-size: 80px;">100</text>
<text class="percentText" dominant-baseline="middle" text-anchor="middle" fill="#4d4d4d" style="font-size: 30px;">%</text>
</g>
<g class="onlineText">
<text class="percentText" dominant-baseline="middle" text-anchor="middle" dy="40" fill="#4d4d4d" dy=".35em" style="font-size: 20px;">ONLINE</text></g></g>
</svg>

Upvotes: 1

Related Questions