flutter_circular_chart/lib/src/stack.dart

91 lines
2.6 KiB
Dart
Raw Normal View History

2017-11-02 23:48:58 +00:00
import 'dart:ui' show lerpDouble;
import 'package:flutter/material.dart';
import 'package:flutter_circular_chart/src/entry.dart';
import 'package:flutter_circular_chart/src/segment.dart';
import 'package:flutter_circular_chart/src/tween.dart';
const double _kMaxAngle = 360.0;
class CircularChartStack implements MergeTweenable<CircularChartStack> {
CircularChartStack(
2018-03-21 00:38:05 +00:00
this.rank,
this.radius,
this.width,
this.startAngle,
this.segments,
);
2017-11-02 23:48:58 +00:00
final int rank;
final double radius;
final double width;
final double startAngle;
final List<CircularChartSegment> segments;
factory CircularChartStack.fromData(
int stackRank,
List<CircularSegmentEntry> entries,
Map<String, int> entryRanks,
bool percentageValues,
double startRadius,
double stackWidth,
double startAngle,
) {
final double valueSum = percentageValues
? 100.0
: entries.fold(
0.0,
2018-03-21 00:38:05 +00:00
(double prev, CircularSegmentEntry element) => prev + element.value,
);
2017-11-02 23:48:58 +00:00
double previousSweepAngle = 0.0;
List<CircularChartSegment> segments =
new List<CircularChartSegment>.generate(entries.length, (i) {
double sweepAngle =
(entries[i].value / valueSum * _kMaxAngle) + previousSweepAngle;
previousSweepAngle = sweepAngle;
int rank = entryRanks[entries[i].rankKey] ?? i;
return new CircularChartSegment(rank, sweepAngle, entries[i].color);
});
return new CircularChartStack(
stackRank,
startRadius,
stackWidth,
startAngle,
segments.reversed.toList(),
);
}
@override
CircularChartStack get empty => new CircularChartStack(
rank, radius, 0.0, startAngle, <CircularChartSegment>[]);
@override
bool operator <(CircularChartStack other) => rank < other.rank;
@override
Tween<CircularChartStack> tweenTo(CircularChartStack other) =>
new CircularChartStackTween(this, other);
}
class CircularChartStackTween extends Tween<CircularChartStack> {
CircularChartStackTween(CircularChartStack begin, CircularChartStack end)
: _circularSegmentsTween =
new MergeTween<CircularChartSegment>(begin.segments, end.segments),
super(begin: begin, end: end) {
assert(begin.rank == end.rank);
}
final MergeTween<CircularChartSegment> _circularSegmentsTween;
@override
CircularChartStack lerp(double t) => new CircularChartStack(
begin.rank,
lerpDouble(begin.radius, end.radius, t),
lerpDouble(begin.width, end.width, t),
lerpDouble(begin.startAngle, end.startAngle, t),
_circularSegmentsTween.lerp(t),
);
}