|
|
|
@ -10,7 +10,7 @@ enum LegendPosition { top, bottom, left, right }
|
|
|
|
enum ChartType { disc, ring }
|
|
|
|
enum ChartType { disc, ring }
|
|
|
|
|
|
|
|
|
|
|
|
class PieChart extends StatefulWidget {
|
|
|
|
class PieChart extends StatefulWidget {
|
|
|
|
PieChart({
|
|
|
|
const PieChart({
|
|
|
|
@required this.dataMap,
|
|
|
|
@required this.dataMap,
|
|
|
|
this.chartType = ChartType.disc,
|
|
|
|
this.chartType = ChartType.disc,
|
|
|
|
this.chartRadius,
|
|
|
|
this.chartRadius,
|
|
|
|
@ -55,11 +55,11 @@ class _PieChartState extends State<PieChart> with SingleTickerProviderStateMixin
|
|
|
|
List<double> legendValues;
|
|
|
|
List<double> legendValues;
|
|
|
|
|
|
|
|
|
|
|
|
void initLegends() {
|
|
|
|
void initLegends() {
|
|
|
|
this.legendTitles = widget.dataMap.keys.toList(growable: false);
|
|
|
|
legendTitles = widget.dataMap.keys.toList(growable: false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void initValues() {
|
|
|
|
void initValues() {
|
|
|
|
this.legendValues = widget.dataMap.values.toList(growable: false);
|
|
|
|
legendValues = widget.dataMap.values.toList(growable: false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void initData() {
|
|
|
|
void initData() {
|
|
|
|
@ -76,7 +76,7 @@ class _PieChartState extends State<PieChart> with SingleTickerProviderStateMixin
|
|
|
|
super.initState();
|
|
|
|
super.initState();
|
|
|
|
initData();
|
|
|
|
initData();
|
|
|
|
controller = AnimationController(
|
|
|
|
controller = AnimationController(
|
|
|
|
duration: widget.animationDuration ?? Duration(milliseconds: 800),
|
|
|
|
duration: widget.animationDuration ?? const Duration(milliseconds: 800),
|
|
|
|
vsync: this,
|
|
|
|
vsync: this,
|
|
|
|
);
|
|
|
|
);
|
|
|
|
final Animation curve = CurvedAnimation(
|
|
|
|
final Animation curve = CurvedAnimation(
|
|
|
|
@ -85,9 +85,8 @@ class _PieChartState extends State<PieChart> with SingleTickerProviderStateMixin
|
|
|
|
);
|
|
|
|
);
|
|
|
|
animation = Tween<double>(begin: 0, end: 1).animate(curve)
|
|
|
|
animation = Tween<double>(begin: 0, end: 1).animate(curve)
|
|
|
|
..addListener(() {
|
|
|
|
..addListener(() {
|
|
|
|
setState(() {
|
|
|
|
_animFraction = animation.value;
|
|
|
|
_animFraction = animation.value;
|
|
|
|
setState(() {});
|
|
|
|
});
|
|
|
|
|
|
|
|
});
|
|
|
|
});
|
|
|
|
controller.forward();
|
|
|
|
controller.forward();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -98,39 +97,64 @@ class _PieChartState extends State<PieChart> with SingleTickerProviderStateMixin
|
|
|
|
alignment: Alignment.center,
|
|
|
|
alignment: Alignment.center,
|
|
|
|
children: [
|
|
|
|
children: [
|
|
|
|
LayoutBuilder(
|
|
|
|
LayoutBuilder(
|
|
|
|
builder: (_, c) => Container(
|
|
|
|
builder: (_, c) => SizedBox(
|
|
|
|
height: widget.chartRadius != null
|
|
|
|
height: widget.chartRadius != null
|
|
|
|
? c.maxWidth < widget.chartRadius
|
|
|
|
? c.maxWidth < widget.chartRadius
|
|
|
|
? c.maxWidth
|
|
|
|
? c.maxWidth
|
|
|
|
: widget.chartRadius
|
|
|
|
: widget.chartRadius
|
|
|
|
: null,
|
|
|
|
: null,
|
|
|
|
child: InkWell(
|
|
|
|
child: GestureDetector(
|
|
|
|
onTap: () {
|
|
|
|
onTapDown: (details) {
|
|
|
|
setState(() {
|
|
|
|
_selected = !_selected;
|
|
|
|
_selected = !_selected;
|
|
|
|
setState(() {});
|
|
|
|
});
|
|
|
|
|
|
|
|
},
|
|
|
|
},
|
|
|
|
child: CustomPaint(
|
|
|
|
child: Stack(
|
|
|
|
painter: PieChartPainter(
|
|
|
|
children: [
|
|
|
|
_animFraction,
|
|
|
|
if (_selected)
|
|
|
|
widget.chartValuesOptions.showChartValues,
|
|
|
|
CustomPaint(
|
|
|
|
widget.chartValuesOptions.showChartValuesOutside,
|
|
|
|
painter: PieChartPainter(
|
|
|
|
widget.colorList,
|
|
|
|
_animFraction,
|
|
|
|
chartValueStyle: widget.chartValuesOptions.chartValueStyle,
|
|
|
|
widget.chartValuesOptions.showChartValues,
|
|
|
|
chartValueBackgroundColor: widget.chartValuesOptions.chartValueBackgroundColor,
|
|
|
|
widget.chartValuesOptions.showChartValuesOutside,
|
|
|
|
values: legendValues,
|
|
|
|
widget.colorList.map((e) => e.withOpacity(0.4)).toList(),
|
|
|
|
titles: legendTitles,
|
|
|
|
chartValueStyle: widget.chartValuesOptions.chartValueStyle,
|
|
|
|
initialAngle: widget.initialAngleInDegree,
|
|
|
|
chartValueBackgroundColor: widget.chartValuesOptions.chartValueBackgroundColor,
|
|
|
|
showValuesInPercentage: widget.chartValuesOptions.showChartValuesInPercentage,
|
|
|
|
values: legendValues,
|
|
|
|
decimalPlaces: widget.chartValuesOptions.decimalPlaces,
|
|
|
|
titles: legendTitles,
|
|
|
|
showChartValueLabel: widget.chartValuesOptions.showChartValueBackground,
|
|
|
|
initialAngle: widget.initialAngleInDegree,
|
|
|
|
chartType: widget.chartType,
|
|
|
|
showValuesInPercentage: widget.chartValuesOptions.showChartValuesInPercentage,
|
|
|
|
formatChartValues: widget.formatChartValues,
|
|
|
|
decimalPlaces: widget.chartValuesOptions.decimalPlaces,
|
|
|
|
strokeWidth: widget.ringStrokeWidth,
|
|
|
|
showChartValueLabel: widget.chartValuesOptions.showChartValueBackground,
|
|
|
|
selected: _selected,
|
|
|
|
chartType: widget.chartType,
|
|
|
|
sideTextStyle: widget.sideTextStyle,
|
|
|
|
formatChartValues: widget.formatChartValues,
|
|
|
|
),
|
|
|
|
strokeWidth: widget.ringStrokeWidth + 10,
|
|
|
|
child: AspectRatio(aspectRatio: 1),
|
|
|
|
sideTextStyle: widget.sideTextStyle,
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
child: const AspectRatio(aspectRatio: 1),
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
CustomPaint(
|
|
|
|
|
|
|
|
painter: PieChartPainter(
|
|
|
|
|
|
|
|
_animFraction,
|
|
|
|
|
|
|
|
widget.chartValuesOptions.showChartValues,
|
|
|
|
|
|
|
|
widget.chartValuesOptions.showChartValuesOutside,
|
|
|
|
|
|
|
|
widget.colorList,
|
|
|
|
|
|
|
|
chartValueStyle: widget.chartValuesOptions.chartValueStyle,
|
|
|
|
|
|
|
|
chartValueBackgroundColor: widget.chartValuesOptions.chartValueBackgroundColor,
|
|
|
|
|
|
|
|
values: legendValues,
|
|
|
|
|
|
|
|
titles: legendTitles,
|
|
|
|
|
|
|
|
initialAngle: widget.initialAngleInDegree,
|
|
|
|
|
|
|
|
showValuesInPercentage: widget.chartValuesOptions.showChartValuesInPercentage,
|
|
|
|
|
|
|
|
decimalPlaces: widget.chartValuesOptions.decimalPlaces,
|
|
|
|
|
|
|
|
showChartValueLabel: widget.chartValuesOptions.showChartValueBackground,
|
|
|
|
|
|
|
|
chartType: widget.chartType,
|
|
|
|
|
|
|
|
formatChartValues: widget.formatChartValues,
|
|
|
|
|
|
|
|
strokeWidth: widget.ringStrokeWidth,
|
|
|
|
|
|
|
|
selected: _selected,
|
|
|
|
|
|
|
|
sideTextStyle: widget.sideTextStyle,
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
child: const AspectRatio(aspectRatio: 1),
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
],
|
|
|
|
),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
@ -147,11 +171,7 @@ class _PieChartState extends State<PieChart> with SingleTickerProviderStateMixin
|
|
|
|
return Column(
|
|
|
|
return Column(
|
|
|
|
mainAxisSize: MainAxisSize.min,
|
|
|
|
mainAxisSize: MainAxisSize.min,
|
|
|
|
children: <Widget>[
|
|
|
|
children: <Widget>[
|
|
|
|
_getLegend(
|
|
|
|
_getLegend(padding: EdgeInsets.only(bottom: widget.chartLegendSpacing)),
|
|
|
|
padding: EdgeInsets.only(
|
|
|
|
|
|
|
|
bottom: widget.chartLegendSpacing,
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
_getChart(),
|
|
|
|
_getChart(),
|
|
|
|
],
|
|
|
|
],
|
|
|
|
);
|
|
|
|
);
|
|
|
|
@ -161,22 +181,14 @@ class _PieChartState extends State<PieChart> with SingleTickerProviderStateMixin
|
|
|
|
mainAxisSize: MainAxisSize.min,
|
|
|
|
mainAxisSize: MainAxisSize.min,
|
|
|
|
children: <Widget>[
|
|
|
|
children: <Widget>[
|
|
|
|
_getChart(),
|
|
|
|
_getChart(),
|
|
|
|
_getLegend(
|
|
|
|
_getLegend(padding: EdgeInsets.only(top: widget.chartLegendSpacing)),
|
|
|
|
padding: EdgeInsets.only(
|
|
|
|
|
|
|
|
top: widget.chartLegendSpacing,
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
],
|
|
|
|
],
|
|
|
|
);
|
|
|
|
);
|
|
|
|
case LegendPosition.left:
|
|
|
|
case LegendPosition.left:
|
|
|
|
return Row(
|
|
|
|
return Row(
|
|
|
|
mainAxisSize: MainAxisSize.min,
|
|
|
|
mainAxisSize: MainAxisSize.min,
|
|
|
|
children: <Widget>[
|
|
|
|
children: <Widget>[
|
|
|
|
_getLegend(
|
|
|
|
_getLegend(padding: EdgeInsets.only(right: widget.chartLegendSpacing)),
|
|
|
|
padding: EdgeInsets.only(
|
|
|
|
|
|
|
|
right: widget.chartLegendSpacing,
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
_getChart(),
|
|
|
|
_getChart(),
|
|
|
|
],
|
|
|
|
],
|
|
|
|
);
|
|
|
|
);
|
|
|
|
@ -185,11 +197,7 @@ class _PieChartState extends State<PieChart> with SingleTickerProviderStateMixin
|
|
|
|
mainAxisSize: MainAxisSize.min,
|
|
|
|
mainAxisSize: MainAxisSize.min,
|
|
|
|
children: <Widget>[
|
|
|
|
children: <Widget>[
|
|
|
|
_getChart(),
|
|
|
|
_getChart(),
|
|
|
|
_getLegend(
|
|
|
|
_getLegend(padding: EdgeInsets.only(left: widget.chartLegendSpacing)),
|
|
|
|
padding: EdgeInsets.only(
|
|
|
|
|
|
|
|
left: widget.chartLegendSpacing,
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
],
|
|
|
|
],
|
|
|
|
);
|
|
|
|
);
|
|
|
|
default:
|
|
|
|
default:
|
|
|
|
@ -230,18 +238,16 @@ class _PieChartState extends State<PieChart> with SingleTickerProviderStateMixin
|
|
|
|
.toList(),
|
|
|
|
.toList(),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
);
|
|
|
|
);
|
|
|
|
} else
|
|
|
|
} else {
|
|
|
|
return SizedBox(
|
|
|
|
return const SizedBox(height: 0, width: 0);
|
|
|
|
height: 0,
|
|
|
|
}
|
|
|
|
width: 0,
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
@override
|
|
|
|
Widget build(BuildContext context) {
|
|
|
|
Widget build(BuildContext context) {
|
|
|
|
return Container(
|
|
|
|
return Container(
|
|
|
|
alignment: Alignment.center,
|
|
|
|
alignment: Alignment.center,
|
|
|
|
padding: EdgeInsets.all(8.0),
|
|
|
|
padding: const EdgeInsets.all(8.0),
|
|
|
|
child: _getPieChart(),
|
|
|
|
child: _getPieChart(),
|
|
|
|
);
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|