Reputation: 411
I has this clock and I need to put the numbers above as you can see:
I know the position of each line but if I create a text with x, y and angle like:
<text *ngFor="let line of lines; let index = i" [attr.rotate]="line.angle"
[attr.x]="line.x1" [attr.y]="line.y1" [id]="'text'+index">
<tspan class="number">20</tspan>
</text>
How could I put the text exactly in middle of line and has circle text instead of this?
Upvotes: 1
Views: 104
Reputation: 13110
In this example each <text>
is the child of a <g>
and all the <g>
s are children of a container <g>
. The container is translated to the center and each <text>
has a negative value of -44 that moves the text out to the circle. All the <g>
s are then rotated. The container is also rotated (-20) to rotate the entire thing in place.
const container = document.getElementById('container');
Object.keys([...Array(13)]).forEach(i => {
let t = document.createElementNS('http://www.w3.org/2000/svg', 'text');
t.setAttribute('y', '-44');
t.textContent = i*5;
let g = document.createElementNS('http://www.w3.org/2000/svg', 'g');
g.setAttribute('transform', `rotate(${i*20})`);
g.append(t);
container.append(g);
});
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" width="250">
<circle cx="50" cy="50" r="40" fill="none" stroke="black" stroke-width="1" />
<g id="container" transform="translate(50 50) rotate(-20)"
font-size="8" text-anchor="middle" dominant-baseline="text-bottom">
</g>
</svg>
The <text>
s can also be horizontal by rotating them "back" after rotating the parent <g>
(but you can see that they are more difficult to place with an equal distance from the circle):
const container = document.getElementById('container');
Object.keys([...Array(13)]).forEach(i => {
let t = document.createElementNS('http://www.w3.org/2000/svg', 'text');
t.setAttribute('transform', `translate(0 -46) rotate(${-i*20+20})`);
t.textContent = i*5;
let g2 = document.createElementNS('http://www.w3.org/2000/svg', 'g');
g2.setAttribute('transform', `rotate(${i*20-20})`);
g2.append(t);
container.append(g2);
});
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" width="250">
<circle cx="50" cy="50" r="40" fill="none" stroke="black" stroke-width="1" />
<g id="container" transform="translate(50 50)"
font-size="8" text-anchor="middle" dominant-baseline="middle">
</g>
</svg>
Upvotes: 1
Reputation: 7210
For each <text>
set x = 0
, y = -radius
and transform='rotate(index * angle)'
:
const SECTORS = 16;
const RADIUS = 70;
const g = d3.select('g');
for (let i = 0; i < SECTORS; i++) {
g.append('text')
.text('20')
.attr('x', 0)
.attr('y', -RADIUS)
.attr('transform', `rotate(${i * 360 / SECTORS})`)
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg width="200" height="200">
<g transform="translate(100,100)"/>
</svg>
Upvotes: 1