アニメーションに必要なメソッドの追加

前回前々回の続き。最後にアニメーションを追加します。path要素に設定を行います。

// Path Setting
pieElement.append("path")
  .style("fill", function(d, i) {
    return colorSet(i);
  })
  .transition()
  .duration(settings.duration)
  .delay(function(d, i){
    return settings.delay * i;
  })
  .attr("d", arc);

transitionメソッド

6行目のpath要素の属性値(attr)の設定後に動作させます。要はtransitionメソッドを境に、transitionメソッドの前の設定値が初期値で、その後に設定した値がアニメーションの最終値ということになります。まずはこの設定が必要です。

durationメソッド

7行目のdurationメソッドは、アニメーションを全体で何ミリ秒で終了させるかを設定します。jQueryのプラグインパラメータとして、setting.durationを準備して値を変更できるようにします。

delayメソッド

8〜10行目のdelayメソッドは、円グラフの要素ごとのアニメーションの開始時間になります。こちらもjQueryのプラグインパラメータとして、setting.delayを準備して値を変更できるようにします。9行目にsetting.delay * iとあるのが、iは要素ごとの添字になるので、初期値×0、初期値×1、初期値×2……と増やすことで順番に表示されるようになります。

初期パラメータ設定

durationやdelayメソッドの初期値をjQueryのパラメータとして設定しておきます。

$.fn.D3PieChart = function(options) {
  var defaults = {
    "data": [],
    "color": d3.schemeCategory10,
    "height": 250,
    "width": 250,
    "innerRadisu": 0,
    "outerRadisu": 100,
    "duration": 500,
    "delay": 500
  };

アニメーションを滑らかに動作させる

とりあえず円グラフの要素が時間に応じて順番に表示されるようになったのですが、滑らかに表示されるわけではありません。

滑らかでない円グラフの動き

これを滑らかに動作させるために、円グラフの座標の補間処理をさせる必要があります。

attrTweenメソッド

path要素で円グラフの要素設定をしている箇所、.attr("d", arc);をattrTweenメソッドに置き換えます。

// Path Setting
pieElement.append("path")
  .style("fill", function(d, i) {
    return colorSet(i);
  })
  .transition()
  .duration(settings.duration)
  .delay(function(d, i){
    return settings.delay * i;
  })
  .attrTween("d", function (d) {
    var interpolate = d3.interpolate(
      {startAngle: d.startAngle, endAngle: d.startAngle},
      {startAngle: d.startAngle, endAngle: d.endAngle}
    );
    return function (t) {
      return arc(interpolate(t));
    }
  });
d3のinterpolate(補間する)メソッドを使用します。attrTweenメソッドの引数として、扇形の座標それぞれを開始角度・終了角度を渡してもとめます。便利。これで

アニメーションの種類

d3.jsのversion4では、アニメーションの指定がversion3と異なります。こちらのサイトを参考にアニメーションの種類を設定します。

// Path Setting
pieElement.append("path")
  .style("fill", function(d, i) {
    return colorSet(i);
  })
  .transition()
  .duration(settings.duration)
  .delay(function(d, i){
    return settings.delay * i;
  })
  .ease(settings.ease)
  .attrTween("d", function (d) {
    var interpolate = d3.interpolate(
      {startAngle: d.startAngle, endAngle: d.startAngle},
      {startAngle: d.startAngle, endAngle: d.endAngle}
    );
    return function (t) {
      return arc(interpolate(t));
    }
  });

jQueryのパラメータ初期値設定は以下のようにセット。

$.fn.D3PieChart = function(options) {
  var defaults = {
    "data": [],
    "color": d3.schemeCategory10,
    "height": 250,
    "width": 250,
    "innerRadisu": 0,
    "outerRadisu": 100,
    "duration": 500,
    "delay": 500,
    "ease": d3.easeLinear
  };

easeパラメータにd3.easeLinearを初期値として設定しました。他のアニメーションの種類もあるので、アニメーションのオブジェクトを配列で管理して引数は数値を渡すようにしてみました。

var easing = [
  d3.easeElastic,
  d3.easeBounce,
  d3.easeLinear,
  d3.easeSin,
  d3.easeQuad,
  d3.easeCubic,
  d3.easePoly,
  d3.easeCircle,
  d3.easeExp,
  d3.easeBack
];

jQueryのパラメータ初期値も書き換え。

"ease": 2

最後にeaseメソッドの引数も変更。

.ease(easing[settings.ease])

これで動かすと……

円グラフを滑らかに動作

できた!\(^o^)/
gifアニメなのでカクカクしてますが、実際は滑らかに動いてくれます。

関連記事

GitHub
※D3-sample/basic_charts/pie_chart/内のファイル