ウェブサイトにグラフやチャートを導入したいとき、様々な方法があります。
画像で配置したり、HTMLとCSSを使用したり、またはjsのプラグインでグラフを作成することができます。
ですが、画像で配置した場合はアニメーションを付けることはできませんし、jsのプラグインでグラフを作成する場合はデザイン通りの形にすることが難しい場合があります。
特に円グラフは、デザインのバリエーションが多いので実装が難しいものもあると思います。
今回は、項目ごとに隙間の空いた円グラフをHTMLとCSSを使用して作成する方法をご紹介します。
完成イメージ
今回、以下のような円グラフを作成していきます。
実際のデモはこちらです。
完成の円グラフ
基本の記述
まず、円グラフを作成する基本の記述です。
HTML
HTML構造は以下です。
1 2 3 4 5 6 7 8 9 10 | <div class="graph-wrap"> <svg class="circle" viewBox = "0 0 64 64"> <circle cx="50%" cy="50%" r="15.9154"></circle> ← 一つ目の項目 <circle cx="50%" cy="50%" r="15.9154"></circle> ← 二つ目の項目 <circle cx="50%" cy="50%" r="15.9154"></circle> ← 三つ目の項目 <circle cx="50%" cy="50%" r="15.9154"></circle> ← 四つ目の項目 </svg> </div> |
<svg>タグ
XMLベースのフォーマットで2次元グラフィックを描画するために使用されます。
基本の書き方は以下です。
1 2 3 | <svg width="幅" height="高さ" viewBox="min-x min-y width height"></svg> |
属性については以下の通りです。
viewBox | SVGの描画範囲と座標系を定義します。 例: viewBox=”0 0 100 100″は、(0, 0)から幅100、高さ100の座標系を定義します。 |
---|
viewBox属性の内訳は以下です。
min-x | 描画開始位置のx座標(左上のx位置) |
---|---|
min-y | 描画開始位置のy座標(左上のy位置) |
width | 描画範囲の幅 |
height | 描画範囲の高さ |
min-xとmin-yは基本0でOKです。
<circle>タグ
基本の書き方は以下です。
1 2 3 | <circle cx="50%" cy="50%" r="20"></circle> |
属性については以下の通りです。
cx | 円の中心のx座標を指定します。 デフォルト値:0 |
---|---|
cy | 円の中心のy座標を指定します。 デフォルト値:0 |
r | 円の半径を指定します。 デフォルト値を指定しないと円が描画されません。 |
CSS
まず、共通のCSSは以下です。
1 2 3 4 5 6 | .circle circle { fill: none; stroke-width: 14px; } |
fill
今回は線を使って円グラフを作成するので、 fillの指定は不要なので無くしておきます。
stroke-width
円グラフの太さを決めます。
数値を増やせば、太くなりますが中央の穴が小さくなります。
また大きすぎると崩れるため、適宜サイトにあったサイズを指定してください。
次に項目を表示させるCSSです。
1 2 3 4 5 6 7 | .circle circle:nth-child(1) { stroke: #f46060; stroke-dasharray: 40,100; stroke-dashoffset: 0; } |
stroke
項目の色を設定します。
stroke-dasharray
破線の長さを設定します。
破線の長さと円周が同じ長さの場合、1つの破線が円を一周します。
100にすると一周します。
カンマ区切りで数値を設定すると、円グラフの項目が実装出来ます。
これで項目が一つ表示されます。
しかし、パスの始点が右側から開始されるので、こちらはsvgごと回転させます。
1 2 3 4 5 | .circle { transform:rotate(-90deg); } |
上から始まるようになりました。
同じように二つ目の項目を作成します。
項目の数値は30%なので、stroke-dashoffsetは30にします。
1 2 3 4 5 6 | .circle circle:nth-child(2) { stroke: #54cccc; stroke-dasharray: 30,100; } |
これで表示されると思いきや、一つ目の項目の上に重なってしまっています。
なぜかというと、開始位置はどの項目も同じ位置から始まっているからです。
なので、開始位置をずらす必要があります。
以下のコードを追加します。
1 2 3 4 5 6 7 | .circle circle:nth-child(2) { stroke: #54cccc; stroke-dasharray: 30,100; stroke-dashoffset: 90; ← 追加したコード } |
stroke-dashoffset
線の始まりの位置を指定します。
作成するグラフに合わせて設定してください。
二つ目の項目が表示されるようになりました。
同じように三つ目と四つ目の項目も追加します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | // 三つ目の項目 .circle circle:nth-child(3) { stroke: #f2cc61; stroke-dasharray: 20,100; stroke-dashoffset: 50; } // 四つ目の項目 .circle circle:nth-child(4) { stroke: #a7d860; stroke-dasharray: 10,100; stroke-dashoffset: 20; } |
これで円グラフが完成します。
項目ごとに隙間の空いた円グラフ
円グラフは完成しましたが、今回は項目ごとにすき間の開いたグラフにするので数値を少し変更します。
すき間を開けるためには各項目ごとのstroke-dasharrayとstroke-dashoffsetの数値を変える必要があります。
stroke-dasharrayの項目の数値を全て足して100にしているので、すき間を開けるため、数値を下げる必要があります。
また、数値を減らしたことでstroke-dashoffsetの位置もずれるので同じ数だけ減らす必要があります。
各項目から、1ずつ数値を減らします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | .circle circle:nth-child(1) { stroke: #f46060; stroke-dasharray: 39,100; ← 40から39 stroke-dashoffset: 0; ← 始まりなので変える必要なし } .circle circle:nth-child(2) { stroke: #54cccc; stroke-dasharray: 29,100; ← 30から29 stroke-dashoffset: 89; ← 90から89 } .circle circle:nth-child(3) { stroke: #f2cc61; stroke-dasharray: 19,100; ← 20から19 stroke-dashoffset: 49; ← 50から49 } .circle circle:nth-child(4) { stroke: #a7d860; stroke-dasharray: 9,100; ← 10から9 stroke-dashoffset: 19; ← 20から19 } |
これですき間の空いた円グラフの完成です!
円グラフアニメーション
このままでも十分ですが、アニメーションをつけることでさらにワンランクアップした円グラフが作成できます。
CSS
動きとしては、アニメーション0%の時は項目の数値を0にし、100%になった時、希望の形に伸びていくような形です。
まず、一つ目の項目をアニメーションさせます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | .circle circle:nth-child(1) { stroke: #f46060; stroke-dashoffset: 0; animation: anime01 1.5s 0s forwards ease-in-out; ← アニメーションの記述 } // アニメーションの記述 @keyframes anime01 { 0% { stroke-dasharray: 0,100; ← 最初は非表示 } 50%, 100% { stroke-dasharray: 39,100; ← 表示した際の数値 } } |
これでアニメーションが付きました。
同じように二つ目にもアニメーションをつけていきます。
コードは以下になります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | .circle circle:nth-child(2) { stroke-dashoffset: 60; ←数値を変更 animation: anime02 1.5s 0.7s forwards ease-in-out; } @keyframes anime02 { 0% { stroke-dasharray: 0,100; } 50%, 100% { stroke-dasharray: 29,71; } } |
一つ目の項目で50%,100%のキーフレームに設定したstroke-dasharrayの円周は100を設定しましたが、二つ目の項目では、項目分を減らした数値にします。
二つ目の場合、100から29を引いた71を設定いたします。
元の数値のままアニメーションを走らせると一つ目の項目に続くように伸びていかず、一つ目の項目と重なってアニメーションが始まってしまうためです。
stroke-dasharrayの数値を変えたことによって、最終的に表示される位置もずれてしまうのでstroke-dashoffsetの数値も合わせて変更します。
数値はサイトに合わせて微調整してください。
また、一つ目の項目のアニメーションが完了されてからからアニメーションが始まるように、animation-delayの数値を調整します。
一つ目の項目に続いて二つ目の項目が伸びていくアニメーションの完成です。
同じように三つ目と四つ目の項目も設定していきます。
※変更した部分だけを記載しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | .circle circle:nth-child(3) { stroke-dasharray: 0,100; stroke-dashoffset: 30; animation: anime03 1.5s 1.4s forwards ease-in-out; } .circle circle:nth-child(4) { stroke-dasharray: 0,100; stroke-dashoffset: 10; animation: anime04 1.5s 2.1s forwards ease-in-out; } @keyframes anime03 { 0% { stroke-dasharray: 0,100; } 50%, 100% { stroke-dasharray: 19,81; } } @keyframes anime04 { 0% { stroke-dasharray: 0,100; } 50%, 100% { stroke-dasharray: 9,91; } } |
これで一つずつ項目が伸びて表示する円グラフの完成です。
完成した円グラフ
微調整
円グラフは完成しましたが、このままでは完成イメージと比べた時、余白が等間隔ではなく扇形に空いてしまっていますよね。
そこで、背景と同色の要素を重ねて余白を調整します。
.graph-wrapの中に、以下のコードを追加します。
1 2 3 4 5 6 7 8 | <div class="gap-area"> <div class="gap"></div> <div class="gap"></div> <div class="gap"></div> <div class="gap"></div> </div> |
CSSは以下です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | .gap-area { position: absolute; top: -65px; left: 0; right: 0; bottom: 0; margin: auto; width: 325px; height: 325px; } .gap-area .gap { background: #fff; height: 162px; width: 10px; position: absolute; top: 0; left: -8px; right: 0; margin: auto; transform: rotate(-1deg); } .gap-area .gap:nth-child(2) { transform: rotate(-37deg); bottom: -185px; right: -143px; left: inherit; } .gap-area .gap:nth-child(3) { transform: rotate(70deg); bottom: -60px; right: inherit; left: -168px; } .gap-area .gap:nth-child(4) { transform: rotate(-38deg); top: 1px; right: inherit; left: -128px; } |
.gap-areaを円グラフと同じサイズにし、各.gapを余白部分に重なるように調整すれば、等間隔に余白が空いた円グラフの完成です。
まとめ
いかがでしょうか?
今回、HTMLとCSSを使ってドーナツ型複数項目のある円グラフの実装方法をご紹介いたしました。
自作するのは少し手間がかかりますが、デザイン通りに作成することが可能になります。
デザイン通りに作成したいのに、jsのプラグインだとデザイン通りにできない…などと悩んでいる方のお役に少しでも立てたら幸いです。
また、他の円グラフ・棒グラフ・レーダーチャートをHTMLとCSSで作成する方法を紹介しているブログもありますので、こちらもよかったら見てみてください。
HTMLとCSSで作るインフォグラフィック(円/棒グラフ・レーダーチャート)【アニメーションつき】