Reactのチャートライブラリ「Recharts」のLineChartで上の箇所に、任意の位置でテキストを追加したかった。
課題になったのは、Rechartsのテキストを表示したい箇所は、svgで表示する仕様になっていた点である。
要件の一つに、テキストを特定の長さ以上になったら3点リーダーで表示したいということがあった。
svgだと、CSSでテキスト省略ができず、JavaScriptで頑張ったのだが、foreignObjectを使えばSVGにHTMLタグを組み込めることができることを知った。
その整理を記載する。
目次
LineChartにそのまま表示する。
LineChartを公式に従ってそのまま表示してみる。
<text>、<tspan>はsvgの中でテキストを扱うための要素です。
そのため、ただテキストを描画するだけならこれでOK。
可変するテキストに合わせて対応するのには向かない(JavaScriptしかない。)
<LineChart data={data} margin={chartMargin}>
<text
x={15}
y={25}
fill="black"
textAnchor="left"
dominantBaseline="central"
style={{
display: "block",
whiteSpace: "nowrap",
overflow: "hidden",
textOverflow: "ellipsis",
}}
>
<tspan fontSize={16} fontWeight={700}>
{chartTitle}
</tspan>
</text>
<Line
type="linear"
dataKey="count"
stroke="#0096FA"
dot={false}
strokeWidth={2}
/>
</LineChart>
foreignObjectを使用してsvgにHTMLを組み込む
JavaScriptで書くと長くなるし、重くもなる。
CSSでかけないかな、と検討した時にforeignObjectを知る。
これを使うことで、svgの中にHTMLを埋め込むことが可能です。
foreignObjectタグの中でstyled-componentで定義したContainerとChartTitleをそのまま使用することができます。
<LineChart data={data} margin={chartMargin}>
<foreignObject y={12} width="100%" height="200">
<Container>
<ChartTitle>{chartTitle}</ChartTitle>
</Container>
</foreignObject>
<Line
type="linear"
dataKey="count"
stroke="#0096FA"
dot={false}
strokeWidth={2}
/>
</LineChart>
Summary
svgの中では制約が大きく、できることも工夫しながらが多かったのですが、foreignObjectを知ってからは、できることの幅が広がったと思います。
分からないことがあったら、調べる、人に聞く、これはとても大切ですね。