Reputation: 960
I want to create a SVG element, which include a list of node, each node is a rectangle with a text inside:
<svg class="chart" width="420" height="150" aria-labelledby="title" role="img">
<ng-container *ngFor="let item of listNode">
<g viewBox="0 0 56 18">
<rect [attr.width]="item.w" [attr.height]="2*item.h" fill="white"></rect>
<text [attr.x]="item.x" [attr.y]="item.y" text-anchor="middle" font-family="Meiryo" font-size="item.h"
fill="black">{{item.label}}</text>
</g>
</ng-container>
</svg>
But I want to put the text is in center of the rectangle (both vertically and horizontally). To do this, I think I need to measure the width of text before creating the SVG element. I tried to use the below function to measure text size:
getTextWidth(text, fontSize, fontFace) {
var canvas = document.createElement('canvas');
var context = canvas.getContext('2d');
context.font = fontSize + 'px ' + fontFace;
return context.measureText(text).width;
}
But the result is not correct. So, Is there any way to measure size of SVG text element before creating the real element (like my getTextWidth function), or is there any other way to create rectangle with text is exactly in center.
Upvotes: 2
Views: 1707
Reputation: 1653
There are many ways to measure the text width and height but if you have the text itself and its font properties, you already have it.
1) Let's suppose you don't want to do the math, you can use HTMLElement properties.
<!DOCTYPE html>
<head>
<meta charset="UTF-8">
</head>
<body>
<script>
const span = document.createElement('span')
document.body.append(span)
span.style = 'font-family: Arial; font-size: 14px'
span.innerHTML = 'TEXT'
document.body.textContent =
`width: ${span.offsetWidth} height: ${span.offsetHeight}`
span.remove()
</script>
</body>
</html>
Note: don't forget to append your element.
2) Use those dimensions to set your rect dimensions (add extra if you want padding) and set your text in the middle like so:
<text
style="font-family: Arial; font-size: 14px"
x="50%"
y="50%"
dominant-baseline="middle"
text-anchor="middle">TEXT</text>
Note: use always the same style in your text.
Hope this help :)
Upvotes: 2