I'm writing a legend for d3. Ten rectangles plotted from left to right. The outcome I would like is to position the text above its relevant cell, positioned vertically, but at a slight angle to the right. I have applied the rotation, but there's something about this that I'm missing, as it treats them as a group and rotates them all in a line, instead of rotating them relative to their sibling cell.
Can someone recommend some attributes or style tips or perhaps a different manner of grouping the elements so that the text elements rotate individually around their own centers, and not as a single line?
Here's the current state of my code:
<svg preserveAspectRatio="xMinYMin meet" viewBox={`0 0 800 70`}>
<g transform={`translate(${[dms.marginTop, dms.marginLeft].join(',')})`}>
<g>
{range(10).map((d) => (
<>
<rect
key={`${d}_legendCell`}
width={cellSize - 1.5}
height={cellSize - 1.5}
fill={colorScale(Number(legendBands(String(d))) interval)}
x={d * cellSize}
></rect>
<text
key={`${d}_legendLabel`}
fontWeight="300"
fontSize="12"
width="100"
y={cellSize * d}
transform="rotate(290)"
dy=".85rem"
>
{Number(legendBands(String(d))).toFixed(1)}
</text>
</>
))}
</g>
</g>
</svg>
TIA!
CodePudding user response:
If I read your code correctly you're currently aligning your <text>
elements vertically and rotate them - better use horizontal offsets
You could instead place your label elements with specific x
coordinates relative to your current rect's center.
Example 2nd cell
<rect x="10" y="0" width="10" height="10" fill="magenta"/>
<text x="15" y="5" width="10" dominant-baseline="central" text-anchor="middle" transform="rotate(-45, 15, 5)">02</text>
The text element's x-value (15) is the center point of the current cell/rect.
dominant-baseline="central"
and text-anchor="middle"
just simplify the horizontal and vertical alignment relative to the preceding <rect>
.
We copy this x-value to the transformation:
transform="rotate(-45, 15, 5)"
This way we ensure the label is rotated around the rect's center.
Also, this method is quite robust, considering that some browsers still have problems with transform-origin
and transform-box
(especially some versions of Safari)
Static svg example
svg {
display: block;
border: 1px solid #ccc;
}
text {
font-size: 5px
}
<svg width="50%" viewBox="0 0 30 10">
<rect x="0" y="0" width="10" height="10" fill="green"/>
<text x="5" y="5" width="10" dominant-baseline="central" text-anchor="middle" transform="rotate(-45, 5, 5)">01</text>
<rect x="10" y="0" width="10" height="10" fill="magenta"/>
<text x="15" y="5" width="10" dominant-baseline="central" text-anchor="middle" transform="rotate(-45, 15, 5)">02</text>
<rect x="20" y="0" width="10" height="10" fill="cyan"/>
<text x="25" y="5" width="10" dominant-baseline="central" text-anchor="middle" transform="rotate(-45, 25, 5)">03</text>
</svg>
<p>Add gaps</p>
<svg width="50%" viewBox="0 0 32 10">
<rect x="0" y="0" width="10" height="10" fill="green"/>
<text x="5" y="5" width="10" dominant-baseline="central" text-anchor="middle" transform="rotate(-45, 5, 5)">01</text>
<rect x="11" y="0" width="10" height="10" fill="magenta"/>
<text x="16" y="5" width="10" dominant-baseline="central" text-anchor="middle" transform="rotate(-45, 16, 5)">02</text>
<rect x="22" y="0" width="10" height="10" fill="cyan"/>
<text x="27" y="5" width="10" dominant-baseline="central" text-anchor="middle" transform="rotate(-45, 27, 5)">03</text>
</svg>