Skip to content

Commit 6aa528c

Browse files
committed
feat: add segments to PieChart
Signed-off-by: Jonas Klock <[email protected]>
1 parent 32e75f5 commit 6aa528c

File tree

6 files changed

+392
-129
lines changed

6 files changed

+392
-129
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
## newVersion
2+
* **FEATURE** (by @jay-k98) Add `segments` property to `PieChartSectionData` for drawing Stacked Pie Charts with segmented sections
3+
14
## newVersion
25
* **BUGFIX** (by @imaNNeo) Consider the `enabled` property in [LineTouchData](https://github.com/imaNNeo/fl_chart/blob/main/repo_files/documentations/line_chart.md#linetouchdata-read-about-touch-handling), [BarTouchData](https://github.com/imaNNeo/fl_chart/blob/main/repo_files/documentations/bar_chart.md#bartouchdata-read-about-touch-handling), [PieTouchData](https://github.com/imaNNeo/fl_chart/blob/main/repo_files/documentations/pie_chart.md#pietouchdata-read-about-touch-handling), [ScatterTouchData](https://github.com/imaNNeo/fl_chart/blob/main/repo_files/documentations/scatter_chart.md#scattertouchdata-read-about-touch-handling), [RadarTouchData](https://github.com/imaNNeo/fl_chart/blob/main/repo_files/documentations/radar_chart.md#radartouchdata-read-about-touch-handling) and [CandlestickTouchData](https://github.com/imaNNeo/fl_chart/blob/main/repo_files/documentations/candlestick_chart.md#candlesticktouchdata-read-about-touch-handling), #1676
36

lib/src/chart/pie_chart/pie_chart_data.dart

Lines changed: 112 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,8 @@ class PieChartData extends BaseChartData with EquatableMixin {
6767
final bool titleSunbeamLayout;
6868

6969
/// We hold this value to determine weight of each [PieChartSectionData.value].
70-
double get sumValue => sections
71-
.map((data) => data.value)
72-
.reduce((first, second) => first + second);
70+
double get sumValue =>
71+
sections.fold<double>(0, (sumVal, second) => sumVal + second.value);
7372

7473
/// Copies current [PieChartData] to a new [PieChartData],
7574
/// and replaces provided values.
@@ -165,14 +164,18 @@ class PieChartSectionData with EquatableMixin {
165164
this.badgeWidget,
166165
double? titlePositionPercentageOffset,
167166
double? badgePositionPercentageOffset,
167+
List<PieChartStackSegmentData>? segments,
168+
double? segmentsSpace,
168169
}) : value = value ?? 10,
169170
color = color ?? Colors.cyan,
170171
radius = radius ?? 40,
171172
showTitle = showTitle ?? true,
172173
title = title ?? (value == null ? '' : value.toString()),
173174
borderSide = borderSide ?? const BorderSide(width: 0),
174175
titlePositionPercentageOffset = titlePositionPercentageOffset ?? 0.5,
175-
badgePositionPercentageOffset = badgePositionPercentageOffset ?? 0.5;
176+
badgePositionPercentageOffset = badgePositionPercentageOffset ?? 0.5,
177+
segments = segments ?? const [],
178+
segmentsSpace = segmentsSpace ?? 0.0;
176179

177180
/// It determines how much space it should occupy around the circle.
178181
///
@@ -223,6 +226,30 @@ class PieChartSectionData with EquatableMixin {
223226
/// 1.0 means near the outside of the [PieChart].
224227
final double badgePositionPercentageOffset;
225228

229+
/// Fill up the [segments] to add stacked segments to a pie chart section.
230+
final List<PieChartStackSegmentData> segments;
231+
232+
/// Defines the spacing between [segments].
233+
final double segmentsSpace;
234+
235+
/// Transform section to a segment to help while rendering
236+
PieChartStackSegmentData get asSegment => PieChartStackSegmentData(
237+
radius: radius,
238+
color: color,
239+
gradient: gradient,
240+
);
241+
242+
/// Total radius including the section radius, segments radii and segment spaces.
243+
double get totalRadius {
244+
if (segments.isEmpty) return radius;
245+
final segmentsRadius = segments.fold<double>(
246+
0,
247+
(sum, segment) => sum + segment.radius,
248+
);
249+
final spaces = (segments.where((s) => s.radius > 0).length) * segmentsSpace;
250+
return radius + segmentsRadius + spaces;
251+
}
252+
226253
/// Copies current [PieChartSectionData] to a new [PieChartSectionData],
227254
/// and replaces provided values.
228255
PieChartSectionData copyWith({
@@ -237,6 +264,8 @@ class PieChartSectionData with EquatableMixin {
237264
Widget? badgeWidget,
238265
double? titlePositionPercentageOffset,
239266
double? badgePositionPercentageOffset,
267+
List<PieChartStackSegmentData>? segments,
268+
double? segmentsSpace,
240269
}) =>
241270
PieChartSectionData(
242271
value: value ?? this.value,
@@ -252,6 +281,8 @@ class PieChartSectionData with EquatableMixin {
252281
titlePositionPercentageOffset ?? this.titlePositionPercentageOffset,
253282
badgePositionPercentageOffset:
254283
badgePositionPercentageOffset ?? this.badgePositionPercentageOffset,
284+
segments: segments ?? this.segments,
285+
segmentsSpace: segmentsSpace ?? this.segmentsSpace,
255286
);
256287

257288
/// Lerps a [PieChartSectionData] based on [t] value, check [Tween.lerp].
@@ -280,6 +311,12 @@ class PieChartSectionData with EquatableMixin {
280311
b.badgePositionPercentageOffset,
281312
t,
282313
),
314+
segments: lerpPieChartStackSegmentDataList(
315+
a.segments,
316+
b.segments,
317+
t,
318+
),
319+
segmentsSpace: lerpDouble(a.segmentsSpace, b.segmentsSpace, t),
283320
);
284321

285322
/// Used for equality check, see [EquatableMixin].
@@ -296,6 +333,77 @@ class PieChartSectionData with EquatableMixin {
296333
badgeWidget,
297334
titlePositionPercentageOffset,
298335
badgePositionPercentageOffset,
336+
segments,
337+
segmentsSpace,
338+
];
339+
}
340+
341+
/// A stylized segment of Stacked Pie Chart section item
342+
///
343+
/// Each [PieChartSectionData] can have a list of [PieChartStackSegmentData] (with different radius, color
344+
/// and gradient) to represent a Stacked Pie Chart section,
345+
class PieChartStackSegmentData with EquatableMixin {
346+
/// Renders a segment of Stacked Pie Chart with given [radius] and [color] or [gradient]
347+
/// for example if you want to have a Stacked Pie Chart with three colors:
348+
///
349+
/// ```dart
350+
/// PieChartSectionData(
351+
/// color: Colors.red,
352+
/// radius: 10,
353+
/// segments: [
354+
/// PieChartStackSegmentData(radius: 20, color: Colors.green),
355+
/// PieChartStackSegmentData(radius: 30, color: Colors.blue),
356+
/// ]
357+
/// )
358+
/// ```
359+
/// To use the [gradient], set [color] to null
360+
PieChartStackSegmentData({
361+
double? radius,
362+
Color? color,
363+
this.gradient,
364+
}) : radius = radius ?? 10,
365+
color = color ?? Colors.purple;
366+
367+
/// The radius that defines the "thickness" of a segment
368+
final double radius;
369+
370+
/// Defines the color of section.
371+
final Color color;
372+
373+
/// Defines the gradient of section. If specified, overrides the color setting.
374+
final Gradient? gradient;
375+
376+
/// Copies current [PieChartStackSegmentData] to a new [PieChartStackSegmentData],
377+
/// and replaces provided values.
378+
PieChartStackSegmentData copyWith({
379+
double? radius,
380+
Color? color,
381+
Gradient? gradient,
382+
}) =>
383+
PieChartStackSegmentData(
384+
radius: radius ?? this.radius,
385+
color: color ?? this.color,
386+
gradient: gradient ?? this.gradient,
387+
);
388+
389+
/// Lerps a [PieChartStackSegmentData] based on [t] value, check [Tween.lerp].
390+
static PieChartStackSegmentData lerp(
391+
PieChartStackSegmentData a,
392+
PieChartStackSegmentData b,
393+
double t,
394+
) =>
395+
PieChartStackSegmentData(
396+
radius: lerpDouble(a.radius, b.radius, t),
397+
color: lerpColor(a.color, b.color, t),
398+
gradient: Gradient.lerp(a.gradient, b.gradient, t),
399+
);
400+
401+
/// Used for equality check, see [EquatableMixin].
402+
@override
403+
List<Object?> get props => [
404+
radius,
405+
color,
406+
gradient,
299407
];
300408
}
301409

0 commit comments

Comments
 (0)