将静态代码转换为可重用的D3.js饼状动画

Converting static code into reusable D3.js pie animation

本文关键字:D3 js 动画 代码 静态 转换      更新时间:2023-09-26

我正试图重新制作一支笔(http://codepen.io/anon/pen/JgyCz)由特拉维斯帕尔默,这样我就可以在多个元素上使用它。我们试图在一页上放置几个<div class="donut" data-donut="x">

所以它看起来像下面的html:

////// HTML 
<div class="donut" data-donut="22"></div>
<div class="donut" data-donut="48"></div>
<div class="donut" data-donut="75></div>

D3.js/jQuery的例子,我试图转换为一个可重用的组件如下。(要查看完整的工作示例,请访问此链接- http://codepen.io/anon/pen/JgyCz)

////// D3.js
var duration   = 500,
    transition = 200;
drawDonutChart(
  '.donut',
  $('.donut').data('donut'),
  290,
  290,
  ".35em"
);
function drawDonutChart(element, percent, width, height, text_y) {
  width = typeof width !== 'undefined' ? width : 290;
  height = typeof height !== 'undefined' ? height : 290;
  text_y = typeof text_y !== 'undefined' ? text_y : "-.10em";
  var dataset = {
        lower: calcPercent(0),
        upper: calcPercent(percent)
      },
      radius = Math.min(width, height) / 2,
      pie = d3.layout.pie().sort(null),
      format = d3.format(".0%");
  var arc = d3.svg.arc()
        .innerRadius(radius - 20)
        .outerRadius(radius);
  var svg = d3.select(element).append("svg")
        .attr("width", width)
        .attr("height", height)
        .append("g")
        .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
  var path = svg.selectAll("path")
        .data(pie(dataset.lower))
        .enter().append("path")
        .attr("class", function(d, i) { return "color" + i })
        .attr("d", arc)
        .each(function(d) { this._current = d; }); // store the initial values
  var text = svg.append("text")
        .attr("text-anchor", "middle")
        .attr("dy", text_y);
  if (typeof(percent) === "string") {
    text.text(percent);
  }
  else {
    var progress = 0;
    var timeout = setTimeout(function () {
      clearTimeout(timeout);
      path = path.data(pie(dataset.upper)); // update the data
      path.transition().duration(duration).attrTween("d", function (a) {
        // Store the displayed angles in _current.
        // Then, interpolate from _current to the new angles.
        // During the transition, _current is updated in-place by d3.interpolate.
        var i  = d3.interpolate(this._current, a);
        var i2 = d3.interpolate(progress, percent)
        this._current = i(0);
        return function(t) {
          text.text( format(i2(t) / 100) );
          return arc(i(t));
        };
      }); // redraw the arcs
    }, 200);
  }
};
function calcPercent(percent) {
  return [percent, 100-percent];
};

最好的方法是使用angular指令。angular指令基本上把html封装在一个自定义标签中,让你在多个页面上反复标记指令,或者在一个页面上多次标记指令。请看这个视频:http://www.youtube.com/watch?v=aqHBLS_6gF8

还有一个名为nvd3.js的库,它包含了可以重用的预构建angular指令:http://nvd3.org/

好了,我明白了。事后回想起来,我觉得自己有点笨,但我能说什么呢,我是一个js呆子。您所要做的就是再调用几个drawDonutChart()方法。简而言之:

drawDonutChart(
  '#donut1',
  $('#donut1').data('donut'),
  220,
  220,
  ".35em"
);
drawDonutChart(
  '#donut2',
  $('#donut2').data('donut'),
  120,
  120,
  ".35em"
);
drawDonutChart(
  '#donut3',
  $('#donut3').data('donut'),
  150,
  150,
  ".2em"
);