patorashのブログ

方向性はまだない

c3.jsでスタックバーチャートのラベルを縦中央揃えにする

c3.jsでスタックバーチャートを描画するのは、比較的簡単です。dataのところでgroupsに含めてしまえばいいです。 しかし、値のラベルがバーの上に表示されてしまいます。これでもいいケースは多いと思いますが、ラベルの色がバーの色になるため、合わない色の上になる可能性があり、見づらくなりそうです。

f:id:patorash:20200608013519p:plain
スタックバーチャートのラベルがバーの上に表示される

そこで、今回はバーの中央に表示してみようと思います。

コード

まず、CodePenで書いたコードを載せておきます。プレビューを見てもらえばわかるかと思いますが、縦中央ぞろえになっています。

See the Pen c3-stacked-bar-chart-label-middle by patorash (@patorash) on CodePen.

解説

c3.jsには、バーの中央に値を表示するような設定はありません。そのため、なにかしらの方法で描画位置を変えなければなりません。

onrenderedを使う

onrenderedイベントで、レンダリング後に操作を行うことができます。

d3のselectAllメソッドを使って、バーのNodeを取得し、それぞれの高さを2で割った値を取得します。 そして、ラベルのノードを取得し、その高さに移動するようにtransformを使って移動させます。

onrendered: () => {
  centers = d3.selectAll("#chart .c3-chart-bars .c3-bar").nodes().map((el) => el.getBBox().height/2);
  d3.selectAll("#chart .c3-chart-texts text.c3-text").nodes().forEach((el, i) => {
        d3.select(el)
          .attr('transform', `translate(0, ${centers[i]})`)      
  });
}

cssで微調整する

これだけだと、ラベルの色とバーの色が同色のため、何も見えなくなります。そこで、cssで文字の色を強制的に白にします。 また、デフォルトのbaselineだと微妙にずれるので、dominant-baselinemathmaticalに指定することで本当の中央になるようにしました。

.c3 .c3-chart-texts text.c3-text {
  font-size: 14px;
  fill: white !important;
  dominant-baseline: mathematical;
}

dominant-baselineの値の説明は、以下の記事を参考にしました。

qiita.com

これで、ラベルがスタックバーの上に、縦中央揃えで表示されるようになりました😀

f:id:patorash:20200608021859p:plain
縦中央揃えにラベルが表示された状態