Преобразование статического кода в многоразовый D3.js круговая анимация

#javascript #jquery #html #css #d3.js

#javascript #jquery #HTML #css #d3.js

Вопрос:

Я пытаюсь переработать перо (http://codepen.io/anon/pen/JgyCz ) Трэвиса Палмера, чтобы я мог использовать его на нескольких элементах. Мы пытаемся разместить несколько <div class="donut" data-donut="x"> ‘s на странице.

Таким образом, это будет выглядеть аналогично приведенному ниже html:

 ////// HTML 

<div class="donut" data-donut="22"></div>

<div class="donut" data-donut="48"></div>

<div class="donut" data-donut="75></div>
  

The 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];
};
  

Ответ №1:

Лучший способ сделать это — использовать угловые директивы. Директива angular в основном оборачивает html внутри пользовательского тега и позволяет вам снова и снова повторять директиву на нескольких страницах или несколько раз на странице. Смотрите это видео: http://www.youtube.com/watch?v=aqHBLS_6gF8

Существует также библиотека, которая называется nvd3.js который содержит готовые угловые директивы, которые можно использовать повторно: http://nvd3.org /

Надеюсь, это поможет.

Комментарии:

1. Я ценю ваш ответ, но как Angular, так и nvd3 многоваты для моих целей. Мы и так полагаемся на слишком много фреймворков и т.д. В худшем случае я мог бы просто клонировать код и просто изменить имена.

Ответ №2:

хорошо, я понял это. Оглядываясь назад, я чувствую себя немного глупо, но что я могу сказать, я js n00b. Все, что вам нужно сделать, это сделать еще несколько вызовов метода 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"
);