見出し画像

Chart.jsで”100%超え”のドーナツグラフを実装してみた

こんにちは!
クリーヴァ株式会社のエンジニア ふじの です。

もうすっかり冬の寒さが身にしみる季節になり、夏の暑さが少し懐かしく感じられるようになりました。インフルエンザも流行しているので、みなさんも体調には気をつけてお過ごしくださいね。

さて今回は、Chart.js をテーマに書いてみようと思います!
ある案件で「管理画面のダッシュボードにグラフを表示したい」という要望をいただき、その対応の中で私自身も初めて Chart.js を触りました。

その中でも特に悩んだのが、ドーナツグラフで “達成率が100%を超えたとき” のデザインをどう表現するか という点。意外とハマりどころが多かったので、今回はその工夫を共有してみたいと思います!


100%を超えるドーナツグラフ、実装してみたら意外とむずかしい

今回の案件では、管理画面のダッシュボードに表示する ドーナツグラフのデザインはデザイナーさんがしっかり作ってくれていました
しかし、デザインをいただいた時正直「これ実装できるかな、、」という不安が大きかったです。

いざ実装を始めてみると、やはり
“100%を超えた時の表現” を Chart.js でどう再現するか が意外と難しく、試行錯誤することになりました。

デザインを見ると、

  • 100%までは通常色

  • 100%を超えたら濃い色で「オーバー」を表現

  • でもリングは一周以上しない

  • 真ん中には実際の達成率(100%超え)を表示する

…という、とても綺麗でわかりやすい仕様。

ただ、Chart.js の素直な実装だと「100%超過=一周以上描く」という動きになってしまい、これを 見た目通りに再現するためのロジック作り に結構頭を使いました。

通常の100%以下のドーナツグラフ

グラフの “見た目” と “実データ” を分けて考える

考え方としてはとてもシンプルで、

  1. グラフとして描く割合は常に 0〜100% に収める

  2. 100%を超えたら色を切り替えて“超えた感”を表現

  3. 真ん中の数字は実際の達成率をそのまま表示

というように、
「リングの見た目」と「実際の数値」を切り離す ことで解決しました。

デザインの意図を守りつつ、Chart.js 的にも破綻させず再現する…という感じです。


実際の処理はこんなイメージ

100%超えを表現するために、
まずは メインのリングに表示する割合を調整 します。

const displayRate = isOver100
    ? Math.min(achievementRate - 100, 100)
    : achievementRate;

const remainingRate = isOver100
    ? Math.max(0, 100 - (achievementRate - 100))
    : (100 - achievementRate);

ここがポイントで、

  • 100%以下 → そのまま達成率を描く

  • 100%超え → 見た目の円は一周のままにし、色だけ変える

という動作になります。

背景色も状態によって切り替えて、

backgroundColor: [
    isOver100 ? '#fa1b1b' : '#ff7d7d',
    isOver100 ? '#ffe6e6' : '#faf7f7'
]

これで 「100%までは通常色、超えると明るい赤」 という分かりやすい UI になります。

※今回、200%以上の場合は通常のドーナツグラフと同様に単色表示とする仕様となったため、実装はひとまずここまでとしています。

画面イメージはこちらになります👇


実装してみて感じたこと

今回はChart.jsの仕様とデザインの仕様の擦り合わせをしっかり行わなくてはいけませんでした。

このロジックにしたことで、

  • どれだけ数値が大きくてもグラフは破綻しない

  • デザイン通りの “自然なオーバー表現” ができる

  • 中央の数字で正確な達成率も分かる

という、運用面でも見た目でも納得の仕上がりになりました。


クリーヴァ株式会社では様々な企業様のDX開発・新規開発を支援しております!
お気軽なご相談から承っておりますので、DXでお悩みの方は以下よりご相談ください!
https://creava.co.jp/contact/