HTML5テクニカルノート
D3.js入門 04: グラフにアニメーションを加える
- ID: FN1702001
- Technique: HTML5 / JavaScript
- Library: D3.js 4.4.0
「D3.js入門 03: 立て棒グラフに軸の記載を加える」(以下「D3.js入門 03」)で数値軸と項目軸のついた縦棒グラフをつくりました。グラフにするデータを差し替えて手直ししたうえで、アニメーションも加えてみましょう。今回は先にでき上がりのサンプル001をお見せします。
サンプル001■D3.js: Vertical SVG Bar Chart with Transition
>>画像をクリックでjsdo.itへ
01 棒グラフのデータを差し替える
まずは、TSV(タブ区切り)ファイルを、つぎのデータで差し替えましょう。これは、アルファベット26文字が英語に使われる割合で、Robert Lewand『Cryptological Mathematics』による統計です(Googleスプレッドシート)[*1]。「D3.js入門 03」で書いたコード002は、読み込んだTSVのデータにもとづいて、グラフの棒の長さと幅だけでなく、数値や項目の軸も差し替えるようにしました。ですから、これだけで新しいグラフができてしまうのです(図001)。
data.tsvname value A .08167 B .01492 C .02782 D .04253 E .12702 F .02288 G .02015 H .06094 I .06966 J .00153 K .00772 L .04025 M .02406 N .06749 O .07507 P .01929 Q .00095 R .05987 S .06327 T .09056 U .02758 V .00978 W .02360 X .00150 Y .01974 Z .00074
図001■グラフの棒だけでなく数値と項目の軸も変わった
02 数値軸の書式を変える
数値軸の書式を変えましょう。データの値からは、パーセンテージの方が適しているからです(図002)。axis.ticks()
メソッドで、軸のメモリ間隔と単位が定められます。第1引数は、軸をメモリでいくつに分けるかです。大まかな数値でかまいません(値を少し増減しても調整されて、メモリは変わらなかったりします)。第2引数には'%'を渡します。また、項目数が多いので、左右マージンは値を少し減らしました。
// var margin = {top: 20, right: 30, bottom: 30, left: 40}; var margin = {top: 20, right: 20, bottom: 30, left: 30}; d3.tsv('data.tsv', type, function(error, data) { elements.append('g') // .call(d3.axisLeft(y)); .call(d3.axisLeft(y).ticks(10, '%')); }); });
図002■グラフの数値軸の単位が%になった
03 グラフの棒をアニメーションで伸ばす
selection.transition()
メソッドを使うと、CSSのtransition
プロパティと同じようなやり方でアニメーションが加えられます。戻り値のオブジェクトに対して、つぎのようにメソッドtransition.duration()
でアニメーションの時間、
transition.delay()
は始まるまでのタメ(遅れ)、
transition.attr()
に変化させる属性と値をそれぞれ与えます。これで、ページを読み込んだとき、グラフの棒が伸びながら表れます。
もっとも、アニメーションの動きは期待と大きく異なるでしょう(図003)。
d3.tsv('data.tsv', type, function(error, data) { elements.selectAll('.bar') .attr('y', function(d) { return getY(d); }) .attr('width', x.bandwidth()) .transition() .duration(500) .delay(function(d, i) { return i * 50; }) .attr('height', function(d) { return height - getY(d); }); });
図003■グラフの棒が上端から項目軸に向かって伸びる
画面の垂直軸は下が正の方向です。したがって、グラフの棒は上端を決めて、下に向けて長さが定められています。そのため、映画『The Matrix』の有名な映像のような、下に向かうさみだれのアニメーションになってしまったのです。しかし、下端から上に向けて長方形は描けませんでした。ではどうしたらよいかといいますと、垂直座標(y
属性)を、つぎのように項目軸の位置から、棒の伸びに合わせて上端に動かしてゆくのです。なお、transition.ease()
メソッドで、アニメーションの動きに変化を与えました。引数のイージング関数d3.easeElasticOut()
で、アニメーションの終わりがバネのように弾みます。
d3.tsv('data.tsv', type, function(error, data) { elements.selectAll('.bar') .attr('y', height) /* function(d) { return getY(d); }) */ .transition() .duration(500) .delay(function(d, i) { return i * 50; }) .ease(d3.easeElasticOut) .attr('y', function(d) { return getY(d); }) .attr('height', function(d) { return height - getY(d); }); });
これで、前掲サンプル1の伸びる動きで表れる棒グラフができ上がりました。スクリプトは以下のコード001にまとめたとおりです。つぎのCSSを加えて、棒にポインタが重なったときの色を変えました。
.bar:hover { fill: brown; }
コード001■棒グラフを伸びる動きで表示する
var chart = d3.select('.chart');
var margin = {top: 20, right: 20, bottom: 30, left: 30};
var width = +chart.attr('width') - margin.left - margin.right;
var height = +chart.attr('height') - margin.top - margin.bottom;
var x = d3.scaleBand()
.rangeRound([0, width]).padding(0.1);
var y = d3.scaleLinear()
.rangeRound([height, 0]);
var elements = chart.append('g')
.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
d3.tsv('data.tsv', type, function(error, data) {
x.domain(data.map(getName));
y.domain([0, d3.max(data, getValue)]);
elements.append('g')
.attr('class', 'axis axis--x')
.attr('transform', 'translate(0,' + height + ')')
.call(d3.axisBottom(x));
elements.append('g')
.attr('class', 'axis axis--y')
.call(d3.axisLeft(y).ticks(10, '%'));
elements.selectAll('.bar')
.data(data)
.enter().append('rect')
.attr('class', 'bar')
.attr('x', function(d) {
return getX(d);
})
.attr('y', height)
.attr('width', x.bandwidth())
.transition()
.duration(500)
.delay(function(d, i) {
return i * 50;
})
.ease(d3.easeElasticOut)
.attr('y', function(d) {
return getY(d);
})
.attr('height', function(d) {
return height - getY(d);
});
});
function type(d) {
d.value = +d.value;
return d;
}
function getName(d) {
return d.name;
}
function getValue(d) {
return d.value;
}
function getX(d) {
return x(d.name);
}
function getY(d) {
return y(d.value);
}
- D3.jsを使う
- D3.js入門 01: 棒グラフを描く
- D3.js入門 02: 外部ファイルのデータからSVGで棒グラフを描く
- D3.js入門 03: 立て棒グラフに軸の記載を加える
- D3.js入門 05: グラフの棒にラベルを加える
作成者: 野中文雄
更新日: 2017年3月4日 スクリプトの無駄を1箇所修正。
作成日: 2017年2月4日
Copyright © 2001-2017 Fumio Nonaka. All rights reserved.