call method

List<PieArc> call(
  1. Iterable<T> data, [
  2. List<Object?>? args
])

Generates a pie for the given list of data, returning an list of maps representing each datum’s arc angles.

For example, given a set of numbers, here is how to compute the angles for a pie chart:

final data = [1, 1, 2, 3, 5, 8, 13, 21];
final pie = Pie((d, i, data) => d);
final arcs = pie(data);

The resulting arcs is an list of maps:

[
  {"value":  1, "index": 6, "startAngle": 6.050474740247008, "endAngle": 6.166830023713296, "padAngle": 0},
  {"value":  1, "index": 7, "startAngle": 6.166830023713296, "endAngle": 6.283185307179584, "padAngle": 0},
  {"value":  2, "index": 5, "startAngle": 5.817764173314431, "endAngle": 6.050474740247008, "padAngle": 0},
  {"value":  3, "index": 4, "startAngle": 5.468698322915565, "endAngle": 5.817764173314431, "padAngle": 0},
  {"value":  5, "index": 3, "startAngle": 4.886921905584122, "endAngle": 5.468698322915565, "padAngle": 0},
  {"value":  8, "index": 2, "startAngle": 3.956079637853813, "endAngle": 4.886921905584122, "padAngle": 0},
  {"value": 13, "index": 1, "startAngle": 2.443460952792061, "endAngle": 3.956079637853813, "padAngle": 0},
  {"value": 21, "index": 0, "startAngle": 0.000000000000000, "endAngle": 2.443460952792061, "padAngle": 0}
]

Each map in the returned list has the following properties:

  • value - the numeric value of the arc.
  • index - the zero-based sorted index of the arc.
  • startAngle - the startAngle of the arc.
  • endAngle - the endAngle of the arc.
  • padAngle - the padAngle of the arc.

This representation is designed to work with the arc generator’s default Arc.startAngle, Arc.endAngle and Arc.padAngle accessors. Angles are in radians, with 0 at -y (12 o’clock) and positive angles proceeding clockwise.

The length of the returned list is the same as data, and each element i in the returned array corresponds to the element i in the input data. The returned list of arcs is in the same order as the data, even when the pie chart is sorted (see sortValues).

Any additional args are arbitrary; they are propagated to the pie generator’s accessor functions along with the this object.

Implementation

List<PieArc> call(Iterable<T> data, [List<Object?>? args]) {
  int i, n = (data = data.toList()).length, j;
  var index = List.filled(n, 0), arcs = List<num>.filled(n, 0);
  num k,
      sum = 0,
      a0 = startAngle(this, args),
      da = min(tau, max(-tau, endAngle(this, args) - a0)),
      a1,
      p = min(da.abs() / n, padAngle(this, args)),
      pa = p * (da < 0 ? -1 : 1),
      v;
  List<PieArc?> arcs0 = List.filled(n, null);

  for (i = 0; i < n; ++i) {
    if ((v = arcs[index[i] = i] = value((data as List<T>)[i], i, data)) > 0) {
      sum += v;
    }
  }

  // Optionally sort the arcs by previously-computed values or by data.
  if (_sortValues != null) {
    index.sort((i, j) {
      return _sortValues!(arcs[i], arcs[j]);
    });
  } else if (_sort != null) {
    index.sort((i, j) {
      return _sort!((data as List<T>)[i], data[j]);
    });
  }

  // Compute the arcs! They are stored in the original data's order.
  k = sum != 0 ? (da - n * pa) / sum : 0;
  for (i = 0; i < n; ++i, a0 = a1) {
    j = index[i];
    v = arcs[j];
    a1 = a0 + (v > 0 ? v * k : 0) + pa;
    arcs0[j] = PieArc<T>({
      "index": i,
      "value": v,
      "startAngle": a0,
      "endAngle": a1,
      "padAngle": p
    }, (data as List<T>)[j]);
  }

  return arcs0.cast();
}