またまたc3.jsネタです。
c3.jsでスタックバーをするのは簡単で、そのスタックバーの軸を100%にするように表示するのも簡単です。dataのところでstack: { normalize: true }
とすればできます。
しかし、それだとチャートは%表示になるのですが、ツールチップに表示されるのは実数です😥
そこで、今回はこれを割合表示(%表示)にしてみます。
また、前回のと合わせて、ラベル中央に%表記してみます。前回の記事はこちら。
コード
まず、CodePenで書いたコードを載せておきます。プレビューを見てもらえばわかるかと思いますが、%表記になっています。
See the Pen c3-stacked-bar-chart-label-middle-percentage by patorash (@patorash) on CodePen.
解説
c3.jsでは、パイチャート等は%表示する方法があるらしいのですが、なぜかスタックバーチャートにはありません。なので、自力で実装していきます。
labelsのformatの指定を関数にして上書きする
labels:format
は通常はフォーマットを指定するだけですが、関数を取ることもできます。そこで、関数を使って割合を算出して出力させます。
labels: { format: (v, id, i, j) => { const sum = Object.values(json[i]).reduce((sum, value) => { return sum + value; }, 0); return d3.format('.1%')(v/sum); } }
関数の引数のvは実数、idはx軸のラベル(item0やitem1等だったはず)、iはループの何番目(item0ならば0, item1なら1等)か、jはiのループ内の更に何番目か(item0のdata1なら0, data2なら1等)を表します。
今回は単純に割合を知りたいので、item0, item1, ..., item4のそれぞれの合計値を取得し、それで実数を割ることで割合を出したいので、変数json
からループ番目毎に値だけの配列を取得し、reduceで合計値を求めるようにしました。
最後に、d3.format('.1%')(v/sum)
とすることで、小数点一桁までを出すようにしています。
これで、ラベルのほうを%表示にすることができました。ツールチップはまだなので、ツールチップも設定していきます。
tooltipのformat指定を関数にして上書きする
ツールチップのほうはめちゃくちゃ簡単です。なぜならば、引数に既にratio
があるからです。先ほどと同じように、d3.format('.1%')(raito)
とするだけです。labelsのほうにも最初からratioがあればいいのに!!😅
tooltip: { format: { value: (value, ratio) => d3.format('.1%')(ratio) } },
なにはともあれ、これでスタックバーチャートの表記が%表記になりました💪
検索用の文字を最後に残しておきます。
- d3.js
- stacked bar chart
- percentage