86 lines
2.6 KiB
Dart
86 lines
2.6 KiB
Dart
|
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(
|
||
|
this.rank, this.radius, this.width, this.startAngle, this.segments);
|
||
|
|
||
|
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,
|
||
|
(double prev, CircularSegmentEntry element) =>
|
||
|
prev + element.value);
|
||
|
|
||
|
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),
|
||
|
);
|
||
|
}
|