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( this.rank, this.radius, this.width, this.startAngle, this.segments, ); final int rank; final double radius; final double width; final double startAngle; final List segments; factory CircularChartStack.fromData( int stackRank, List entries, Map 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 segments = new List.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, []); @override bool operator <(CircularChartStack other) => rank < other.rank; @override Tween tweenTo(CircularChartStack other) => new CircularChartStackTween(this, other); } class CircularChartStackTween extends Tween { CircularChartStackTween(CircularChartStack begin, CircularChartStack end) : _circularSegmentsTween = new MergeTween(begin.segments, end.segments), super(begin: begin, end: end) { assert(begin.rank == end.rank); } final MergeTween _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), ); }