グラフ画像をただ置いておいても、円グラフはただの丸、棒グラフもただの棒の並びのように見えてしまい、なかなか注目されないものです。
そこでグラフを動かすchart.jsで、グラフをニョキニョキっと動かし、視認性UPに繋がるようにしてみました。
しかし単純にサンプルコードから引っ張って来ても動かなかったり、参考ページを見て追加したことなど、カスタマイズした項目もありますので、合わせてご紹介したいと思います。
公式サイトからDL
上記からGit hubへアクセスして、chart.jsをDLし、任意のjsディレクトリにUPしておきます。コードを記述
HTMLファイルのscriptタグまたは外部jsファイルの中身に、以下を記述します。
デモコードよりもさらに記述を追加していますが後に紹介します。
//スクロールしたとき、画面中央で発火して動くようにする
var chartEl1 = document.getElementById("circleChart");
var chartEl2 = document.getElementById("barChart");
var chartFlag1 = false;
var chartFlag2 = false;
// 1つ目のグラフ
var chartFunc1 = function() {
var ctx = chartEl1.getContext('2d');
chart = new Chart(ctx, {
type: 'pie',
options: {
maintainAspectRatio: false, //アスペクト比維持解除
tooltips: [{
enabled: false
}]
},
layout: { //レイアウト
padding: { //余白設定
left: 0,
right: 0,
top: 0,
bottom: 0
}
},
data: {
datasets: [{
label: 'label',
data: [3, 18, 6, 10, 12],
backgroundColor: ["#000","#333","#666","#999","#aaa"]
}]
}
});
};
//------------------グラフ2の設定 中略------------------
//スクロール処理
var graphAnim = function() {
var wy = window.pageYOffset,
wb = wy + window.innerHeight,
chartElPos1 = wy + chartEl1.getBoundingClientRect().top + ( screen.height / 2 ),
chartElPos2 = wy + chartEl2.getBoundingClientRect().top + ( screen.height / 2 );
if ( wb > chartElPos1 && chartFlag1 == false ) {
chartFunc1();
chartFlag1 = true;
}
if ( wb > chartElPos2 && chartFlag2 == false ) {
chartFunc2();
chartFlag2 = true;
}
};
window.addEventListener('load', graphAnim);
window.addEventListener('scroll', graphAnim);
上記は2つ目のグラフ設定を省略しています。
設定についての詳細は以下のページにて紹介されていましたので、そちらをぜひ参考にしてみてください。
画面中央で発火させるようにする
公式のデモコードをそのまま引用するだけでは、ページロード時に読み込まれてしまい、ファーストビュー外にアニメーションをつけたグラフがあってもそのアニメーションを確認することはできません。
そこでスクロールをして画面中央あたりで発火、アニメーションが始まるようにしています。
//スクロールしたとき、画面中央で発火して動くようにする
var chartEl1 = document.getElementById("circleChart");
var chartEl2 = document.getElementById("barChart");
var chartFlag1 = false;
var chartFlag2 = false;
//------------------グラフの設定 中略------------------
//以下からスクロール処理
var graphAnim = function() {
var wy = window.pageYOffset,
wb = wy + window.innerHeight,
chartElPos1 = wy + chartEl1.getBoundingClientRect().top + ( screen.height / 2 ),
chartElPos2 = wy + chartEl2.getBoundingClientRect().top + ( screen.height / 2 ); //ブラウザ中央に来るくらいで出て来るようにする
if ( wb > chartElPos1 && chartFlag1 == false ) {
chartFunc1();
chartFlag1 = true;
}
if ( wb > chartElPos2 && chartFlag2 == false ) {
chartFunc2();
chartFlag2 = true;
}
};
window.addEventListener('load', graphAnim);
window.addEventListener('scroll', graphAnim);
このコードはこちらを参考にさせていただきました。ありがとうございます。
chartElPos1 = wy + chartEl1.getBoundingClientRect().top + ( screen.height / 2 ),
chartElPos2 = wy + chartEl2.getBoundingClientRect().top + ( screen.height / 2 ); //ブラウザ中央に来るくらいで出て来るようにする
”( screen.height / 2 )” については、画面中央を想定しての計算式になります。 適宜変更してみてください。
スマホ対応
スマホではグラフ部分だけが表示されるようにします。
何も設定しないままだと、たとえ円グラフであっても左右に余白ができてしまい、グラフそのものが縮んでしまいます。
スマホだけではなく、親要素の幅に合わせたい時などにも便利ですね。
options: {
maintainAspectRatio: false, //アスペクト比維持解除
tooltips: [{
enabled: false
}]
},
layout: { //レイアウト
padding: { //余白設定
left: 0,
right: 0,
top: 0,
bottom: 0
}
},
まずmaintainAspectRatioをfalseにしてアスペクト比維持を解除します。 また、余白の設定も全て0にします。
HTML記述の注意点
私はここで一度ハマってしまったのですが、HTMLでは親要素に特定の記述をする必要があります。
<div class="wrap">
<section> <!--なるべく親をつけて内包する-->
<canvas id="circleChart"></canvas>
</section>
<section> <!--なるべく親をつけて内包する-->
<canvas id="barChart"></canvas>
</section>
</div>
テスト段階の時、何にも挟まずにcanvasを直置きしていましたが、高さを設定しない限り全く動きませんでした。
なるべく上記のようにsectionタグなどで挟んでください。
cssの注意点
上記で説明したとおり、chart.jsは親要素に高さの指定が無いと動来ません。
そこで親要素に内包し、その親要素に高さを指定します。
以下略していますが必要な箇所だけ抜粋します。
body, html {
/*height: 100%*/ /*親要素無しに直置きする場合はbody,htmlに高さ指定*/
}
.wrap {
width : 100%;
}
section {
width:80vw;
height:50vh; /*高さ指定をする*/
margin : 100px auto 800px;
position : relative;
}
もし表示されずに困っているようでしたら、上記の通り、親要素に高さ指定をしてみてください。