Skip to content

Commit

Permalink
Merge pull request imaNNeo#511 from imaNNeoFighT/dev
Browse files Browse the repository at this point in the history
Dev 0.12.1
  • Loading branch information
imaNNeo authored Dec 11, 2020
2 parents 1d39257 + 1068e56 commit eff8916
Show file tree
Hide file tree
Showing 12 changed files with 173 additions and 76 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## 0.12.1
* [Bugfix] Fixed PieChart badges bug with re-implementing the solution, #507
* [Bugfix] Fix the setState issue using PieChart in the ListView, #467
* [Bugfix] Fixed formatNumber bug for negative numbers, #486.
* [Improvement] Added applyCutOffY property in [BarAreaSpotsLine](https://github.com/imaNNeoFighT/fl_chart/blob/master/repo_files/documentations/line_chart.md#barareaspotsline) to inherit cutOffY property of its parent, #478.

## 0.12.0
* [Improvement] [BREAKING] Replaced `color` property with `colors` in [BarChartRodData](https://github.com/imaNNeoFighT/fl_chart/blob/master/repo_files/documentations/bar_chart.md#barchartroddata), and [BackgroundBarChartRodData](https://github.com/imaNNeoFighT/fl_chart/blob/master/repo_files/documentations/bar_chart.md#backgroundbarchartroddata) to support gradient in BarChart, instead of solid color, #166. Check [BarChartSample3](https://github.com/imaNNeoFighT/fl_chart/blob/master/repo_files/documentations/bar_chart.md#sample-3-source-code)
* [Improvement] Improved gradient stops calculating algorithm.
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ Thank you all!

```yml
dependencies:
fl_chart: ^0.12.0
fl_chart: ^0.12.1
```
Expand Down
6 changes: 6 additions & 0 deletions lib/src/chart/base/axis_chart/axis_chart_data.dart
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,12 @@ class FlSpot with EquatableMixin {
);
}

///Prints x and y coordinates of FlSpot list
@override
String toString() {
return '(' + x.toString() + ', ' + y.toString() + ')';
}

/// Used for splitting lines, or maybe other concepts.
static FlSpot nullSpot = FlSpot(null, null);

Expand Down
3 changes: 0 additions & 3 deletions lib/src/chart/base/base_chart/base_chart_data.dart
Original file line number Diff line number Diff line change
Expand Up @@ -147,9 +147,6 @@ TextStyle defaultGetTitleTextStyle(double value) {
);
}

/// The signature for a callback that provides a map of position offsets.
typedef GetPositionOffsetsFunction = void Function(Map<int, Offset> offsetsMap);

/// This class holds the touch response details.
///
/// Specific touch details should be hold on the concrete child classes.
Expand Down
9 changes: 8 additions & 1 deletion lib/src/chart/line_chart/line_chart_data.dart
Original file line number Diff line number Diff line change
Expand Up @@ -688,23 +688,29 @@ class BarAreaSpotsLine with EquatableMixin {
/// Checks to show or hide lines on the spots.
final CheckToShowSpotLine checkToShowSpotLine;

/// Determines to inherit the cutOff properties from its parent [BarAreaData]
final bool applyCutOffY;

/// If [show] is true, [LineChart] draws some lines on above or below the spots,
/// you can customize the appearance of the lines using [flLineStyle]
/// and you can decide to show or hide the lines on each spot using [checkToShowSpotLine].
BarAreaSpotsLine({
bool show,
FlLine flLineStyle,
CheckToShowSpotLine checkToShowSpotLine,
bool applyCutOffY,
}) : show = show ?? false,
flLineStyle = flLineStyle ?? FlLine(),
checkToShowSpotLine = checkToShowSpotLine ?? showAllSpotsBelowLine;
checkToShowSpotLine = checkToShowSpotLine ?? showAllSpotsBelowLine,
applyCutOffY = applyCutOffY ?? true;

/// Lerps a [BarAreaSpotsLine] based on [t] value, check [Tween.lerp].
static BarAreaSpotsLine lerp(BarAreaSpotsLine a, BarAreaSpotsLine b, double t) {
return BarAreaSpotsLine(
show: b.show,
checkToShowSpotLine: b.checkToShowSpotLine,
flLineStyle: FlLine.lerp(a.flLineStyle, b.flLineStyle, t),
applyCutOffY: b.applyCutOffY,
);
}

Expand All @@ -714,6 +720,7 @@ class BarAreaSpotsLine with EquatableMixin {
show,
flLineStyle,
checkToShowSpotLine,
applyCutOffY,
];
}

Expand Down
36 changes: 28 additions & 8 deletions lib/src/chart/line_chart/line_chart_painter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -590,10 +590,20 @@ class LineChartPainter extends AxisChartPainter<LineChartData>
);

final double bottomPadding = getExtraNeededVerticalSpace() - getTopOffsetDrawSize();
final Offset to = Offset(
getPixelX(spot.x, chartViewSize),
viewSize.height - bottomPadding,
);
Offset to;

// Check applyCutOffY
if (barData.belowBarData.spotsLine.applyCutOffY && barData.belowBarData.applyCutOffY) {
to = Offset(
getPixelX(spot.x, chartViewSize),
getPixelY(barData.belowBarData.cutOffY, chartViewSize),
);
} else {
to = Offset(
getPixelX(spot.x, chartViewSize),
viewSize.height - bottomPadding,
);
}

_barAreaLinesPaint.color = barData.belowBarData.spotsLine.flLineStyle.color;
_barAreaLinesPaint.strokeWidth = barData.belowBarData.spotsLine.flLineStyle.strokeWidth;
Expand Down Expand Up @@ -670,10 +680,20 @@ class LineChartPainter extends AxisChartPainter<LineChartData>
getPixelY(spot.y, chartViewSize),
);

final Offset to = Offset(
getPixelX(spot.x, chartViewSize),
getTopOffsetDrawSize(),
);
Offset to;

// Check applyCutOffY
if (barData.aboveBarData.spotsLine.applyCutOffY && barData.aboveBarData.applyCutOffY) {
to = Offset(
getPixelX(spot.x, chartViewSize),
getPixelY(barData.aboveBarData.cutOffY, chartViewSize),
);
} else {
to = Offset(
getPixelX(spot.x, chartViewSize),
getTopOffsetDrawSize(),
);
}

_barAreaLinesPaint.color = barData.aboveBarData.spotsLine.flLineStyle.color;
_barAreaLinesPaint.strokeWidth = barData.aboveBarData.spotsLine.flLineStyle.strokeWidth;
Expand Down
91 changes: 53 additions & 38 deletions lib/src/chart/pie_chart/pie_chart.dart
Original file line number Diff line number Diff line change
Expand Up @@ -36,21 +36,14 @@ class _PieChartState extends AnimatedWidgetBaseState<PieChart> {
/// This is used to map the touch events to [PieTouchResponse]
TouchHandler _touchHandler;

/// For storing the badge widgets' offsets.
Map<int, Offset> _badgeWidgetsOffsets = <int, Offset>{};
/// This is used to retrieve the offsets for puting widgets upon the chart.
///
/// exposes [PieChartWidgetsPositionHandler.getBadgeOffsets] to retrieve the badge widgets position.
PieChartWidgetsPositionHandler _widgetsPositionHandler;

/// this is used to retrieve the chart size to handle the touches
final GlobalKey _chartKey = GlobalKey();

@override
void initState() {
/// Make sure that [_badgeWidgetsOffsets] is updated.
WidgetsBinding.instance.addPostFrameCallback((_) {
setState(() {});
});
super.initState();
}

@override
Widget build(BuildContext context) {
final PieChartData showingData = _getData();
Expand Down Expand Up @@ -152,39 +145,61 @@ class _PieChartState extends AnimatedWidgetBaseState<PieChart> {
});
},
textScale: MediaQuery.of(context).textScaleFactor,
badgeWidgetsOffsetsProvider: (offsetsMap) {
/// Store badge widget offsets from painter.
_badgeWidgetsOffsets = Map.from(offsetsMap);
widgetsPositionHandler: (widgetPositionHandler) {
setState(() {
_widgetsPositionHandler = widgetPositionHandler;
});
},
),
child: _badgeWidgetsOffsets.isEmpty
? null
: CustomMultiChildLayout(
delegate: BadgeWidgetsDelegate(
badgeWidgetsCount: _badgeWidgetsOffsets.length,
badgeWidgetsOffsets: _badgeWidgetsOffsets,
),
children: List.generate(
_badgeWidgetsOffsets.length,
(index) {
final int _key = _badgeWidgetsOffsets.keys.elementAt(index);
final Widget _badgeWidget = widget.data.sections[_key].badgeWidget;

if (_badgeWidget == null) {
return null;
}

return LayoutId(
id: _key,
child: _badgeWidget,
);
},
),
),
child: badgeWidgets(),
),
);
}

Widget badgeWidgets() {
final chartSize = _getChartSize();
if (chartSize != null && _widgetsPositionHandler != null) {
final offsetsMap = _widgetsPositionHandler.getBadgeOffsets(chartSize);
if (offsetsMap.isNotEmpty) {
return CustomMultiChildLayout(
delegate: BadgeWidgetsDelegate(
badgeWidgetsCount: offsetsMap.length,
badgeWidgetsOffsets: offsetsMap,
),
children: List.generate(
offsetsMap.length,
(index) {
final int _key = offsetsMap.keys.elementAt(index);

if (offsetsMap.length != _getData().sections.length) {
return LayoutId(
id: _key,
child: Container(),
);
}

final Widget _badgeWidget = _getData().sections[_key].badgeWidget;

if (_badgeWidget == null) {
return LayoutId(
id: _key,
child: Container(),
);
}

return LayoutId(
id: _key,
child: _badgeWidget,
);
},
),
);
}
}

return null;
}

bool _canHandleTouch(PieTouchResponse response, PieTouchData touchData) {
return response != null && touchData != null && touchData.touchCallback != null;
}
Expand Down
77 changes: 54 additions & 23 deletions lib/src/chart/pie_chart/pie_chart_painter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,10 @@ import 'package:flutter/widgets.dart';
import 'pie_chart_data.dart';

/// Paints [PieChartData] in the canvas, it can be used in a [CustomPainter]
class PieChartPainter extends BaseChartPainter<PieChartData> with TouchHandler<PieTouchResponse> {
class PieChartPainter extends BaseChartPainter<PieChartData>
with TouchHandler<PieTouchResponse>, PieChartWidgetsPositionHandler {
Paint _sectionPaint, _sectionsSpaceClearPaint, _centerSpacePaint;

/// A callback that provides position offsets for the badge widgets.
GetPositionOffsetsFunction _badgeWidgetsOffsetsProvider;

/// Paints [data] into canvas, it is the animating [PieChartData],
/// [targetData] is the animation's target and remains the same
/// during animation, then we should use it when we need to show
Expand All @@ -26,20 +24,18 @@ class PieChartPainter extends BaseChartPainter<PieChartData> with TouchHandler<P
/// [textScale] used for scaling texts inside the chart,
/// parent can use [MediaQuery.textScaleFactor] to respect
/// the system's font size.
PieChartPainter(
PieChartData data,
PieChartData targetData,
Function(TouchHandler) touchHandler, {
double textScale,
GetPositionOffsetsFunction badgeWidgetsOffsetsProvider,
}) : super(
PieChartPainter(PieChartData data, PieChartData targetData, Function(TouchHandler) touchHandler,
{Function(PieChartWidgetsPositionHandler) widgetsPositionHandler, double textScale})
: super(
data,
targetData,
textScale: textScale,
) {
touchHandler(this);

_badgeWidgetsOffsetsProvider = badgeWidgetsOffsetsProvider;
if (widgetsPositionHandler != null) {
widgetsPositionHandler(this);
}

_sectionPaint = Paint()..style = PaintingStyle.stroke;

Expand All @@ -65,7 +61,7 @@ class PieChartPainter extends BaseChartPainter<PieChartData> with TouchHandler<P

_drawCenterSpace(canvas, size);
_drawSections(canvas, size, sectionsAngle);
_calculateOverlays(canvas, size);
_drawTexts(canvas, size);
}

List<double> _calculateSectionsAngle(List<PieChartSectionData> sections, double sumValue) {
Expand Down Expand Up @@ -168,9 +164,8 @@ class PieChartPainter extends BaseChartPainter<PieChartData> with TouchHandler<P
/// Calculates layout of overlaying elements, includes:
/// - title text
/// - badge widget positions
void _calculateOverlays(Canvas canvas, Size viewSize) {
void _drawTexts(Canvas canvas, Size viewSize) {
final Offset center = Offset(viewSize.width / 2, viewSize.height / 2);
final Map<int, Offset> badgeWidgetsOffsets = <int, Offset>{};

double tempAngle = data.startDegreeOffset;

Expand All @@ -192,8 +187,6 @@ class PieChartPainter extends BaseChartPainter<PieChartData> with TouchHandler<P
);

final Offset sectionCenterOffsetTitle = sectionCenter(section.titlePositionPercentageOffset);
final Offset sectionCenterOffsetBadgeWidget =
sectionCenter(section.badgePositionPercentageOffset);

if (section.showTitle) {
final TextSpan span = TextSpan(
Expand All @@ -210,14 +203,8 @@ class PieChartPainter extends BaseChartPainter<PieChartData> with TouchHandler<P
tp.paint(canvas, sectionCenterOffsetTitle - Offset(tp.width / 2, tp.height / 2));
}

if (section.badgeWidget != null) {
badgeWidgetsOffsets[i] = sectionCenterOffsetBadgeWidget;
}

tempAngle += sweepAngle;
}

_badgeWidgetsOffsetsProvider(badgeWidgetsOffsets);
}

double _calculateCenterRadius(Size viewSize, double givenCenterRadius) {
Expand Down Expand Up @@ -308,10 +295,54 @@ class PieChartPainter extends BaseChartPainter<PieChartData> with TouchHandler<P
foundSectionData, foundSectionDataPosition, touchAngle, touchR, touchInput);
}

/// Exposes offset for laying out the badge widgets upon the chart.
@override
Map<int, Offset> getBadgeOffsets(Size viewSize) {
final Offset center = Offset(viewSize.width / 2, viewSize.height / 2);
final Map<int, Offset> badgeWidgetsOffsets = <int, Offset>{};

double tempAngle = data.startDegreeOffset;

for (int i = 0; i < data.sections.length; i++) {
final PieChartSectionData section = data.sections[i];
final double startAngle = tempAngle;
final double sweepAngle = 360 * (section.value / data.sumValue);
final double sectionCenterAngle = startAngle + (sweepAngle / 2);

Offset sectionCenter(double percentageOffset) =>
center +
Offset(
math.cos(radians(sectionCenterAngle)) *
(_calculateCenterRadius(viewSize, data.centerSpaceRadius) +
(section.radius * percentageOffset)),
math.sin(radians(sectionCenterAngle)) *
(_calculateCenterRadius(viewSize, data.centerSpaceRadius) +
(section.radius * percentageOffset)),
);

final Offset sectionCenterOffsetBadgeWidget =
sectionCenter(section.badgePositionPercentageOffset);

if (section.badgeWidget != null) {
badgeWidgetsOffsets[i] = sectionCenterOffsetBadgeWidget;
}

tempAngle += sweepAngle;
}

return badgeWidgetsOffsets;
}

/// Determines should it redraw the chart or not.
///
/// If there is a change in the [PieChartData],
/// [PieChartPainter] should repaint itself.
@override
bool shouldRepaint(PieChartPainter oldDelegate) => oldDelegate.data != data;
}

/// Responsible to expose offset positions for laying out the widgets upon the chart.
mixin PieChartWidgetsPositionHandler {
/// Exposes offset for laying out the badge widgets upon the chart.
Map<int, Offset> getBadgeOffsets(Size size) => throw UnsupportedError('not implemented');
}
Loading

0 comments on commit eff8916

Please sign in to comment.