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 >20</tspan>
</text>
How could I put the text exactly in middle of line and has circle text instead of this?
CodePudding user response:
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>
CodePudding user response:
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>


