[Recharts]svgにHTMLタグを組み込む

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を知ってからは、できることの幅が広がったと思います。

分からないことがあったら、調べる、人に聞く、これはとても大切ですね。

よかったらシェアしてね!
目次