flet-charts 0.2.0.dev35__py3-none-any.whl → 0.70.0.dev6555__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of flet-charts might be problematic. Click here for more details.

Files changed (46) hide show
  1. flet_charts/__init__.py +59 -17
  2. flet_charts/bar_chart.py +87 -30
  3. flet_charts/bar_chart_group.py +1 -2
  4. flet_charts/bar_chart_rod.py +36 -5
  5. flet_charts/candlestick_chart.py +269 -0
  6. flet_charts/candlestick_chart_spot.py +98 -0
  7. flet_charts/chart_axis.py +29 -9
  8. flet_charts/line_chart.py +76 -14
  9. flet_charts/line_chart_data.py +30 -5
  10. flet_charts/line_chart_data_point.py +33 -4
  11. flet_charts/matplotlib_backends/backend_flet_agg.py +16 -0
  12. flet_charts/matplotlib_chart.py +396 -36
  13. flet_charts/matplotlib_chart_with_toolbar.py +125 -0
  14. flet_charts/pie_chart.py +3 -6
  15. flet_charts/pie_chart_section.py +29 -18
  16. flet_charts/plotly_chart.py +17 -6
  17. flet_charts/radar_chart.py +214 -0
  18. flet_charts/radar_data_set.py +66 -0
  19. flet_charts/scatter_chart.py +75 -29
  20. flet_charts/scatter_chart_spot.py +44 -6
  21. flet_charts/types.py +159 -16
  22. flet_charts-0.70.0.dev6555.dist-info/METADATA +67 -0
  23. flet_charts-0.70.0.dev6555.dist-info/RECORD +47 -0
  24. flutter/flet_charts/CHANGELOG.md +1 -1
  25. flutter/flet_charts/LICENSE +1 -1
  26. flutter/flet_charts/analysis_options.yaml +1 -1
  27. flutter/flet_charts/lib/src/bar_chart.dart +2 -0
  28. flutter/flet_charts/lib/src/candlestick_chart.dart +129 -0
  29. flutter/flet_charts/lib/src/extension.dart +6 -0
  30. flutter/flet_charts/lib/src/radar_chart.dart +104 -0
  31. flutter/flet_charts/lib/src/scatter_chart.dart +22 -21
  32. flutter/flet_charts/lib/src/utils/bar_chart.dart +137 -73
  33. flutter/flet_charts/lib/src/utils/candlestick_chart.dart +118 -0
  34. flutter/flet_charts/lib/src/utils/charts.dart +12 -0
  35. flutter/flet_charts/lib/src/utils/line_chart.dart +15 -3
  36. flutter/flet_charts/lib/src/utils/pie_chart.dart +2 -1
  37. flutter/flet_charts/lib/src/utils/radar_chart.dart +90 -0
  38. flutter/flet_charts/lib/src/utils/scatter_chart.dart +22 -21
  39. flutter/flet_charts/pubspec.lock +85 -71
  40. flutter/flet_charts/pubspec.yaml +10 -9
  41. flet_charts-0.2.0.dev35.dist-info/METADATA +0 -69
  42. flet_charts-0.2.0.dev35.dist-info/RECORD +0 -38
  43. flutter/flet_charts/README.md +0 -3
  44. {flet_charts-0.2.0.dev35.dist-info → flet_charts-0.70.0.dev6555.dist-info}/WHEEL +0 -0
  45. {flet_charts-0.2.0.dev35.dist-info → flet_charts-0.70.0.dev6555.dist-info}/licenses/LICENSE +0 -0
  46. {flet_charts-0.2.0.dev35.dist-info → flet_charts-0.70.0.dev6555.dist-info}/top_level.txt +0 -0
@@ -18,6 +18,8 @@ class ScatterChartControl extends StatefulWidget {
18
18
  class _ScatterChartControlState extends State<ScatterChartControl> {
19
19
  @override
20
20
  Widget build(BuildContext context) {
21
+ debugPrint("ScatterChart build: ${widget.control.id}");
22
+
21
23
  final theme = Theme.of(context);
22
24
  var animation = widget.control.getAnimation(
23
25
  "animation",
@@ -34,11 +36,12 @@ class _ScatterChartControlState extends State<ScatterChartControl> {
34
36
  var interactive = widget.control.getBool("interactive", true)!;
35
37
 
36
38
  // Build list of ScatterSpotData
37
- final spots = widget.control.children('spots').map((spot) {
39
+ final spotsAsControls = widget.control.children('spots');
40
+ final spots = spotsAsControls.map((spot) {
38
41
  var x = spot.getDouble('x', 0)!;
39
42
  var y = spot.getDouble('y', 0)!;
40
43
  return ScatterSpot(x, y,
41
- show: spot.getBool('visible', true)!,
44
+ show: spot.visible,
42
45
  renderPriority: spot.getInt('render_priority', 0)!,
43
46
  xError: spot.get('x_error'),
44
47
  yError: spot.get('y_error'),
@@ -80,30 +83,29 @@ class _ScatterChartControlState extends State<ScatterChartControl> {
80
83
  widget.control.get("vertical_grid_lines"),
81
84
  theme),
82
85
  scatterTouchData: ScatterTouchData(
83
- enabled: interactive,
84
- touchCallback: widget.control.getBool("on_event", false)!
85
- ? (evt, resp) {
86
- var eventData =
87
- ScatterChartEventData.fromDetails(evt, resp);
88
- widget.control.triggerEvent("event", eventData.toMap());
89
- }
90
- : null,
91
- longPressDuration:
92
- widget.control.getDuration("long_press_duration"),
93
- handleBuiltInTouches:
94
- widget.control.getBool("handle_built_in_touches", true)!,
95
- touchTooltipData:
96
- parseScatterTouchTooltipData(context, widget.control, spots)),
86
+ enabled: interactive && !widget.control.disabled,
87
+ touchCallback: widget.control.getBool("on_event", false)!
88
+ ? (evt, resp) {
89
+ var eventData = ScatterChartEventData.fromDetails(evt, resp);
90
+ widget.control.triggerEvent("event", eventData.toMap());
91
+ }
92
+ : null,
93
+ longPressDuration: widget.control.getDuration("long_press_duration"),
94
+ handleBuiltInTouches: !widget.control
95
+ .getBool("show_tooltips_for_selected_spots_only", false)!,
96
+ touchTooltipData:
97
+ parseScatterTouchTooltipData(context, widget.control, spots),
98
+ ),
97
99
  scatterLabelSettings: ScatterLabelSettings(
98
100
  showLabel: true,
99
101
  getLabelFunction: (spotIndex, spot) {
100
- var dp = widget.control.children("spots")[spotIndex];
102
+ var dp = spotsAsControls[spotIndex];
101
103
  return dp.getString("label_text", "")!;
102
104
  },
103
105
  getLabelTextStyleFunction: (spotIndex, spot) {
104
- var dp = widget.control.children("spots")[spotIndex];
106
+ var dp = spotsAsControls[spotIndex];
105
107
  var labelStyle =
106
- dp.getTextStyle("label_style", theme, const TextStyle())!;
108
+ dp.getTextStyle("label_text_style", theme, const TextStyle())!;
107
109
  if (labelStyle.color == null) {
108
110
  labelStyle =
109
111
  labelStyle.copyWith(color: spot.dotPainter.mainColor);
@@ -111,8 +113,7 @@ class _ScatterChartControlState extends State<ScatterChartControl> {
111
113
  return labelStyle;
112
114
  },
113
115
  ),
114
- showingTooltipIndicators: widget.control
115
- .children('spots')
116
+ showingTooltipIndicators: spotsAsControls
116
117
  .asMap()
117
118
  .entries
118
119
  .where((e) => e.value.getBool("selected", false)!)
@@ -12,49 +12,58 @@ class BarChartEventData extends Equatable {
12
12
  final int? rodIndex;
13
13
  final int? stackItemIndex;
14
14
 
15
- const BarChartEventData(
16
- {required this.eventType,
17
- required this.groupIndex,
18
- required this.rodIndex,
19
- required this.stackItemIndex});
15
+ const BarChartEventData({
16
+ required this.eventType,
17
+ required this.groupIndex,
18
+ required this.rodIndex,
19
+ required this.stackItemIndex,
20
+ });
20
21
 
21
22
  factory BarChartEventData.fromDetails(
22
- FlTouchEvent event, BarTouchResponse? response) {
23
+ FlTouchEvent event,
24
+ BarTouchResponse? response,
25
+ ) {
23
26
  return BarChartEventData(
24
- eventType: eventMap[event.runtimeType.toString()] ?? "undefined",
25
- groupIndex: response != null && response.spot != null
26
- ? response.spot!.touchedBarGroupIndex
27
- : null,
28
- rodIndex: response != null && response.spot != null
29
- ? response.spot!.touchedRodDataIndex
30
- : null,
31
- stackItemIndex: response != null && response.spot != null
32
- ? response.spot!.touchedStackItemIndex
33
- : null);
27
+ eventType: eventMap[event.runtimeType.toString()] ?? "undefined",
28
+ groupIndex: response != null && response.spot != null
29
+ ? response.spot!.touchedBarGroupIndex
30
+ : null,
31
+ rodIndex: response != null && response.spot != null
32
+ ? response.spot!.touchedRodDataIndex
33
+ : null,
34
+ stackItemIndex: response != null && response.spot != null
35
+ ? response.spot!.touchedStackItemIndex
36
+ : null,
37
+ );
34
38
  }
35
39
 
36
40
  Map<String, dynamic> toMap() => <String, dynamic>{
37
41
  'type': eventType,
38
42
  'group_index': groupIndex,
39
43
  'rod_index': rodIndex,
40
- 'stack_item_index': stackItemIndex
44
+ 'stack_item_index': stackItemIndex,
41
45
  };
42
46
 
43
47
  @override
44
48
  List<Object?> get props => [eventType, groupIndex, rodIndex, stackItemIndex];
45
49
  }
46
50
 
47
- TooltipDirection? parseTooltipDirection(String? value,
48
- [TooltipDirection? defaultValue]) {
51
+ TooltipDirection? parseTooltipDirection(
52
+ String? value, [
53
+ TooltipDirection? defaultValue,
54
+ ]) {
49
55
  if (value == null) return defaultValue;
50
56
  return TooltipDirection.values.firstWhereOrNull(
51
- (e) => e.name.toLowerCase() == value.toLowerCase()) ??
57
+ (e) => e.name.toLowerCase() == value.toLowerCase(),
58
+ ) ??
52
59
  defaultValue;
53
60
  }
54
61
 
55
62
  BarTouchTooltipData? parseBarTouchTooltipData(
56
- BuildContext context, Control control,
57
- [BarTouchTooltipData? defaultValue]) {
63
+ BuildContext context,
64
+ Control control, [
65
+ BarTouchTooltipData? defaultValue,
66
+ ]) {
58
67
  var tooltip = control.get("tooltip");
59
68
  if (tooltip == null) return defaultValue;
60
69
 
@@ -64,15 +73,28 @@ BarTouchTooltipData? parseBarTouchTooltipData(
64
73
  getTooltipColor: (BarChartGroupData group) =>
65
74
  parseColor(tooltip["bgcolor"], theme, theme.colorScheme.secondary)!,
66
75
  tooltipBorderRadius: parseBorderRadius(tooltip["border_radius"]),
67
- tooltipMargin: parseDouble(tooltip["margin"]),
68
- tooltipPadding: parsePadding(tooltip["padding"]),
76
+ tooltipMargin: parseDouble(tooltip["margin"], 16)!,
77
+ tooltipPadding: parsePadding(
78
+ tooltip["padding"],
79
+ const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
80
+ )!,
69
81
  maxContentWidth: parseDouble(tooltip["max_width"]),
70
- rotateAngle: parseDouble(tooltip["rotate_angle"]),
71
- tooltipHorizontalOffset: parseDouble(tooltip["horizontal_offset"]),
82
+ rotateAngle: parseDouble(tooltip["rotation"], 0.0)!,
83
+ tooltipHorizontalOffset: parseDouble(tooltip["horizontal_offset"], 0)!,
72
84
  tooltipBorder: parseBorderSide(tooltip["border_side"], theme),
73
- fitInsideHorizontally: parseBool(tooltip["fit_inside_horizontally"]),
74
- fitInsideVertically: parseBool(tooltip["fit_inside_vertically"]),
75
- direction: parseTooltipDirection(tooltip["direction"]),
85
+ fitInsideHorizontally: parseBool(
86
+ tooltip["fit_inside_horizontally"],
87
+ false,
88
+ )!,
89
+ fitInsideVertically: parseBool(tooltip["fit_inside_vertically"], false)!,
90
+ direction: parseTooltipDirection(
91
+ tooltip["direction"],
92
+ TooltipDirection.auto,
93
+ )!,
94
+ tooltipHorizontalAlignment: parseFLHorizontalAlignment(
95
+ tooltip["horizontal_alignment"],
96
+ FLHorizontalAlignment.center,
97
+ )!,
76
98
  getTooltipItem: (group, groupIndex, rod, rodIndex) {
77
99
  var rod =
78
100
  control.children("groups")[groupIndex].children("rods")[rodIndex];
@@ -84,29 +106,45 @@ BarTouchTooltipData? parseBarTouchTooltipData(
84
106
  BarTooltipItem? parseBarTooltipItem(Control rod, BuildContext context) {
85
107
  if (!rod.getBool("show_tooltip", true)!) return null;
86
108
 
87
- final theme = Theme.of(context);
109
+ var tooltip = rod.internals?["tooltip"];
110
+ if (tooltip == null) return null;
88
111
 
89
- var tooltip = rod.get("tooltip");
90
- var tooltipTextStyle =
91
- parseTextStyle(tooltip["text_style"], theme, const TextStyle())!;
112
+ final theme = Theme.of(context);
113
+ var tooltipTextStyle = parseTextStyle(
114
+ tooltip["text_style"],
115
+ theme,
116
+ const TextStyle(),
117
+ )!;
92
118
  if (tooltipTextStyle.color == null) {
93
119
  tooltipTextStyle = tooltipTextStyle.copyWith(
94
- color: rod.getGradient("gradient", theme)?.colors.first ??
95
- rod.getColor("color", context, Colors.blueGrey)!);
120
+ color: rod.getGradient("gradient", theme)?.colors.first ??
121
+ rod.getColor("color", context, Colors.blueGrey)!,
122
+ );
96
123
  }
97
124
  return BarTooltipItem(
98
- tooltip["text"] ?? rod.getDouble("to_y", 0)!.toString(), tooltipTextStyle,
99
- textAlign: parseTextAlign(tooltip["text_align"], TextAlign.center)!,
100
- children: tooltip["text_spans"] != null
101
- ? parseTextSpans(tooltip["text_spans"], theme, (s, eventName,
102
- [eventData]) {
103
- s.triggerEvent(eventName, eventData);
104
- })
105
- : null);
125
+ tooltip["text"] ?? rod.getDouble("to_y", 0)!.toString(),
126
+ tooltipTextStyle,
127
+ textAlign: parseTextAlign(tooltip["text_align"], TextAlign.center)!,
128
+ textDirection: parseBool(tooltip["rtl"], false)!
129
+ ? TextDirection.rtl
130
+ : TextDirection.ltr,
131
+ children: tooltip["text_spans"] != null
132
+ ? parseTextSpans(tooltip["text_spans"], theme, (
133
+ s,
134
+ eventName, [
135
+ eventData,
136
+ ]) {
137
+ s.triggerEvent(eventName, eventData);
138
+ })
139
+ : null,
140
+ );
106
141
  }
107
142
 
108
143
  BarChartGroupData parseBarChartGroupData(
109
- Control group, bool interactiveChart, BuildContext context) {
144
+ Control group,
145
+ bool interactiveChart,
146
+ BuildContext context,
147
+ ) {
110
148
  group.notifyParent = true;
111
149
  return BarChartGroupData(
112
150
  x: group.getInt("x", 0)!,
@@ -117,7 +155,8 @@ BarChartGroupData parseBarChartGroupData(
117
155
  .asMap()
118
156
  .entries
119
157
  .where(
120
- (rod) => !interactiveChart && rod.value.getBool("selected", false)!)
158
+ (rod) => !interactiveChart && rod.value.getBool("selected", false)!,
159
+ )
121
160
  .map((rod) => rod.key)
122
161
  .toList(),
123
162
  barRods: group
@@ -128,7 +167,10 @@ BarChartGroupData parseBarChartGroupData(
128
167
  }
129
168
 
130
169
  BarChartRodData parseBarChartRodData(
131
- Control rod, bool interactiveChart, BuildContext context) {
170
+ Control rod,
171
+ bool interactiveChart,
172
+ BuildContext context,
173
+ ) {
132
174
  rod.notifyParent = true;
133
175
 
134
176
  final theme = Theme.of(context);
@@ -138,28 +180,38 @@ BarChartRodData parseBarChartRodData(
138
180
  var backgroundGradient = rod.getGradient("background_gradient", theme);
139
181
 
140
182
  return BarChartRodData(
141
- fromY: rod.getDouble("from_y"),
142
- toY: rod.getDouble("to_y", 0)!,
143
- width: rod.getDouble("width"),
144
- color: rod.getColor("color", context),
145
- gradient: rod.getGradient("gradient", theme),
146
- borderRadius: rod.getBorderRadius("border_radius"),
147
- borderSide: rod.getBorderSide("border_side", theme,
148
- defaultValue: BorderSide.none),
149
- backDrawRodData: BackgroundBarChartRodData(
150
- show: (bgFromY != null ||
151
- bgToY != null ||
152
- bgcolor != null ||
153
- backgroundGradient != null),
154
- fromY: bgFromY,
155
- toY: bgToY,
156
- color: bgcolor,
157
- gradient: backgroundGradient),
158
- rodStackItems: rod
159
- .children("stack_items")
160
- .map((rodStackItem) => parseBarChartRodStackItem(
161
- rodStackItem, interactiveChart, context))
162
- .toList());
183
+ fromY: rod.getDouble("from_y"),
184
+ toY: rod.getDouble("to_y", 0)!,
185
+ width: rod.getDouble("width"),
186
+ color: rod.getColor("color", context),
187
+ gradient: rod.getGradient("gradient", theme),
188
+ borderRadius: rod.getBorderRadius("border_radius"),
189
+ borderSide: rod.getBorderSide(
190
+ "border_side",
191
+ theme,
192
+ defaultValue: BorderSide.none,
193
+ ),
194
+ backDrawRodData: BackgroundBarChartRodData(
195
+ show: (bgFromY != null ||
196
+ bgToY != null ||
197
+ bgcolor != null ||
198
+ backgroundGradient != null),
199
+ fromY: bgFromY,
200
+ toY: bgToY,
201
+ color: bgcolor,
202
+ gradient: backgroundGradient,
203
+ ),
204
+ rodStackItems: rod
205
+ .children("stack_items")
206
+ .map(
207
+ (rodStackItem) => parseBarChartRodStackItem(
208
+ rodStackItem,
209
+ interactiveChart,
210
+ context,
211
+ ),
212
+ )
213
+ .toList(),
214
+ );
163
215
  }
164
216
 
165
217
  BarChartRodStackItem parseBarChartRodStackItem(
@@ -169,9 +221,21 @@ BarChartRodStackItem parseBarChartRodStackItem(
169
221
  ) {
170
222
  rodStackItem.notifyParent = true;
171
223
  return BarChartRodStackItem(
172
- rodStackItem.getDouble("from_y")!,
173
- rodStackItem.getDouble("to_y", 0)!,
174
- rodStackItem.getColor("color", context)!,
175
- rodStackItem.getBorderSide("border_side", Theme.of(context),
176
- defaultValue: BorderSide.none)!);
224
+ rodStackItem.getDouble("from_y")!,
225
+ rodStackItem.getDouble("to_y", 0)!,
226
+ rodStackItem.getColor("color", context)!,
227
+ borderSide: rodStackItem.getBorderSide(
228
+ "border_side",
229
+ Theme.of(context),
230
+ defaultValue: BorderSide.none,
231
+ )!,
232
+ );
233
+ }
234
+
235
+ BarChartAlignment? parseBarChartAlignment(String? value,
236
+ [BarChartAlignment? defaultValue]) {
237
+ if (value == null) return defaultValue;
238
+ return BarChartAlignment.values.firstWhereOrNull(
239
+ (e) => e.name.toLowerCase() == value.toLowerCase()) ??
240
+ defaultValue;
177
241
  }
@@ -0,0 +1,118 @@
1
+ import 'package:equatable/equatable.dart';
2
+ import 'package:fl_chart/fl_chart.dart';
3
+ import 'package:flet/flet.dart';
4
+ import 'package:flutter/material.dart';
5
+
6
+ import 'charts.dart';
7
+
8
+ class CandlestickChartEventData extends Equatable {
9
+ final String eventType;
10
+ final int? spotIndex;
11
+
12
+ const CandlestickChartEventData({
13
+ required this.eventType,
14
+ required this.spotIndex,
15
+ });
16
+
17
+ factory CandlestickChartEventData.fromDetails(
18
+ FlTouchEvent event,
19
+ CandlestickTouchResponse? response,
20
+ ) {
21
+ return CandlestickChartEventData(
22
+ eventType: eventMap[event.runtimeType.toString()] ?? "undefined",
23
+ spotIndex: response?.touchedSpot?.spotIndex,
24
+ );
25
+ }
26
+
27
+ Map<String, dynamic> toMap() => {
28
+ "type": eventType,
29
+ "spot_index": spotIndex,
30
+ };
31
+
32
+ @override
33
+ List<Object?> get props => [eventType, spotIndex];
34
+ }
35
+
36
+ CandlestickTouchTooltipData parseCandlestickTouchTooltipData(
37
+ BuildContext context, Control control, List<Control> spotControls) {
38
+ final tooltip = control.get("tooltip") ?? {};
39
+ final theme = Theme.of(context);
40
+
41
+ return CandlestickTouchTooltipData(
42
+ tooltipBorder: parseBorderSide(tooltip["border_side"], theme,
43
+ defaultValue: BorderSide.none)!,
44
+ rotateAngle: parseDouble(tooltip["rotation"], 0.0)!,
45
+ tooltipBorderRadius:
46
+ parseBorderRadius(tooltip["border_radius"], BorderRadius.circular(4))!,
47
+ tooltipPadding: parsePadding(tooltip["padding"],
48
+ const EdgeInsets.symmetric(horizontal: 16, vertical: 8))!,
49
+ tooltipHorizontalAlignment: parseFLHorizontalAlignment(
50
+ tooltip["horizontal_alignment"], FLHorizontalAlignment.center)!,
51
+ tooltipHorizontalOffset: parseDouble(tooltip["horizontal_offset"], 0)!,
52
+ maxContentWidth: parseDouble(tooltip["max_width"], 120)!,
53
+ fitInsideHorizontally:
54
+ parseBool(tooltip["fit_inside_horizontally"], false)!,
55
+ fitInsideVertically: parseBool(tooltip["fit_inside_vertically"], false)!,
56
+ showOnTopOfTheChartBoxArea:
57
+ parseBool(tooltip["show_on_top_of_chart_box_area"], false)!,
58
+ getTooltipColor: (spot) =>
59
+ parseColor(tooltip["bgcolor"], theme, const Color(0xFFFFECEF))!,
60
+ getTooltipItems: (painter, touchedSpot, spotIndex) {
61
+ if (spotIndex < 0 || spotIndex >= spotControls.length) {
62
+ return null;
63
+ }
64
+ return parseCandlestickTooltipItem(
65
+ spotControls[spotIndex],
66
+ painter,
67
+ touchedSpot,
68
+ spotIndex,
69
+ context,
70
+ );
71
+ },
72
+ );
73
+ }
74
+
75
+ CandlestickTooltipItem? parseCandlestickTooltipItem(
76
+ Control spotControl,
77
+ FlCandlestickPainter painter,
78
+ CandlestickSpot touchedSpot,
79
+ int spotIndex,
80
+ BuildContext context,
81
+ ) {
82
+ if (!spotControl.getBool("show_tooltip", true)!) {
83
+ return null;
84
+ }
85
+
86
+ final tooltip = spotControl.internals?["tooltip"];
87
+ if (tooltip == null) {
88
+ return null;
89
+ }
90
+
91
+ final theme = Theme.of(context);
92
+ var textStyle =
93
+ parseTextStyle(tooltip["text_style"], theme, const TextStyle())!;
94
+ if (textStyle.color == null) {
95
+ textStyle = textStyle.copyWith(
96
+ color: painter.getMainColor(
97
+ spot: touchedSpot,
98
+ spotIndex: spotIndex,
99
+ ),
100
+ );
101
+ }
102
+
103
+ return CandlestickTooltipItem(
104
+ tooltip["text"] ?? "",
105
+ textStyle: textStyle,
106
+ bottomMargin: parseDouble(tooltip["bottom_margin"], 8)!,
107
+ textAlign: parseTextAlign(tooltip["text_align"], TextAlign.center)!,
108
+ textDirection: parseBool(tooltip["rtl"], false)!
109
+ ? TextDirection.rtl
110
+ : TextDirection.ltr,
111
+ children: tooltip["text_spans"] != null
112
+ ? parseTextSpans(tooltip["text_spans"], theme, (s, eventName,
113
+ [eventData]) {
114
+ s.triggerEvent(eventName, eventData);
115
+ })
116
+ : null,
117
+ );
118
+ }
@@ -34,6 +34,7 @@ FlLine? parseFlLine(dynamic value, ThemeData theme, [FlLine? defaultValue]) {
34
34
  if (value == null ||
35
35
  (value['color'] == null &&
36
36
  value['width'] == null &&
37
+ value['gradient'] == null &&
37
38
  value['dash_pattern'] == null)) {
38
39
  return defaultValue;
39
40
  }
@@ -41,6 +42,7 @@ FlLine? parseFlLine(dynamic value, ThemeData theme, [FlLine? defaultValue]) {
41
42
  return FlLine(
42
43
  color: parseColor(value['color'], theme, Colors.black)!,
43
44
  strokeWidth: parseDouble(value['width'], 2)!,
45
+ gradient: parseGradient(value['gradient'], theme),
44
46
  dashArray: (value['dash_pattern'] as List?)
45
47
  ?.map((e) => parseInt(e))
46
48
  .nonNulls
@@ -143,6 +145,8 @@ AxisTitles parseAxisTitles(Control? control) {
143
145
  showTitles: control.getBool("show_labels", true)!,
144
146
  reservedSize: control.getDouble("label_size", 22)!,
145
147
  interval: control.getDouble("label_spacing"),
148
+ minIncluded: control.getBool("show_min", true)!,
149
+ maxIncluded: control.getBool("show_max", true)!,
146
150
  getTitlesWidget: control.children("labels").isEmpty
147
151
  ? defaultGetTitle
148
152
  : (double value, TitleMeta meta) {
@@ -155,6 +159,14 @@ AxisTitles parseAxisTitles(Control? control) {
155
159
  ));
156
160
  }
157
161
 
162
+ FLHorizontalAlignment? parseFLHorizontalAlignment(String? value,
163
+ [FLHorizontalAlignment? defaultValue]) {
164
+ if (value == null) return defaultValue;
165
+ return FLHorizontalAlignment.values.firstWhereOrNull(
166
+ (e) => e.name.toLowerCase() == value.toLowerCase()) ??
167
+ defaultValue;
168
+ }
169
+
158
170
  const eventMap = {
159
171
  "FlPointerEnterEvent": "pointerEnter",
160
172
  "FlPointerExitEvent": "pointerExit",
@@ -52,9 +52,10 @@ LineTooltipItem? parseLineTooltipItem(
52
52
  Control dataPoint, LineBarSpot spot, BuildContext context) {
53
53
  if (!dataPoint.getBool("show_tooltip", true)!) return null;
54
54
 
55
- final theme = Theme.of(context);
55
+ var tooltip = dataPoint.internals?["tooltip"];
56
+ if (tooltip == null) return null;
56
57
 
57
- var tooltip = dataPoint.get("tooltip");
58
+ final theme = Theme.of(context);
58
59
  var style = parseTextStyle(tooltip["text_style"], theme, const TextStyle())!;
59
60
  if (style.color == null) {
60
61
  style = style.copyWith(
@@ -65,6 +66,9 @@ LineTooltipItem? parseLineTooltipItem(
65
66
  return LineTooltipItem(
66
67
  tooltip["text"] ?? dataPoint.getDouble("y", 0)!.toString(), style,
67
68
  textAlign: parseTextAlign(tooltip["text_align"], TextAlign.center)!,
69
+ textDirection: parseBool(tooltip["rtl"], false)!
70
+ ? TextDirection.rtl
71
+ : TextDirection.ltr,
68
72
  children: tooltip["text_spans"] != null
69
73
  ? parseTextSpans(tooltip["text_spans"], theme, (s, eventName,
70
74
  [eventData]) {
@@ -89,7 +93,7 @@ LineTouchTooltipData? parseLineTouchTooltipData(
89
93
  tooltipPadding: parsePadding(tooltip["padding"],
90
94
  const EdgeInsets.symmetric(horizontal: 16, vertical: 8))!,
91
95
  maxContentWidth: parseDouble(tooltip["max_width"], 120)!,
92
- rotateAngle: parseDouble(tooltip["rotate_angle"], 0.0)!,
96
+ rotateAngle: parseDouble(tooltip["rotation"], 0.0)!,
93
97
  tooltipHorizontalOffset: parseDouble(tooltip["horizontal_offset"], 0)!,
94
98
  tooltipBorder: parseBorderSide(tooltip["border_side"], theme,
95
99
  defaultValue: BorderSide.none)!,
@@ -98,6 +102,8 @@ LineTouchTooltipData? parseLineTouchTooltipData(
98
102
  fitInsideVertically: parseBool(tooltip["fit_inside_vertically"], false)!,
99
103
  showOnTopOfTheChartBoxArea:
100
104
  parseBool(tooltip["show_on_top_of_chart_box_area"], false)!,
105
+ tooltipHorizontalAlignment: parseFLHorizontalAlignment(
106
+ tooltip["horizontal_alignment"], FLHorizontalAlignment.center)!,
101
107
  getTooltipItems: (List<LineBarSpot> touchedSpots) {
102
108
  return touchedSpots
103
109
  .map((LineBarSpot spot) => parseLineTooltipItem(
@@ -131,6 +137,7 @@ LineChartBarData parseLineChartBarData(
131
137
  var belowLine = parseFlLine(chartData.get("below_line"), Theme.of(context));
132
138
  var aboveLineCutoffY = chartData.getDouble("above_line_cutoff_y");
133
139
  var belowLineCutoffY = chartData.getDouble("below_line_cutoff_y");
140
+ var stepDirection = chartData.getDouble("step_direction");
134
141
 
135
142
  Map<FlSpot, Control> spots = {
136
143
  for (var e in chartData.children("points"))
@@ -142,6 +149,10 @@ LineChartBarData parseLineChartBarData(
142
149
  preventCurveOvershootingThreshold:
143
150
  chartData.getDouble("prevent_curve_over_shooting_threshold", 10.0)!,
144
151
  spots: barSpots[chartData.id] ?? [],
152
+ curveSmoothness: chartData.getDouble("curve_smoothness", 0.35)!,
153
+ show: chartData.visible,
154
+ isStepLineChart: stepDirection != null,
155
+ lineChartStepData: LineChartStepData(stepDirection: stepDirection ?? 0.5),
145
156
  showingIndicators: chartData
146
157
  .children("points")
147
158
  .asMap()
@@ -152,6 +163,7 @@ LineChartBarData parseLineChartBarData(
152
163
  .toList(),
153
164
  isCurved: chartData.getBool("curved", false)!,
154
165
  isStrokeCapRound: chartData.getBool("rounded_stroke_cap", false)!,
166
+ isStrokeJoinRound: chartData.getBool("rounded_stroke_join", false)!,
155
167
  barWidth: chartData.getDouble("stroke_width", 2.0)!,
156
168
  dashArray: dashPattern != null
157
169
  ? (dashPattern as List).map((e) => parseInt(e)).nonNulls.toList()
@@ -46,11 +46,12 @@ PieChartSectionData parsePieChartSectionData(
46
46
  radius: section.getDouble("radius"),
47
47
  showTitle: title != null,
48
48
  title: title,
49
+ gradient: section.getGradient("gradient", theme),
49
50
  titleStyle: section.getTextStyle("title_style", theme),
50
51
  borderSide: section.getBorderSide("border_side", theme,
51
52
  defaultValue: BorderSide.none)!,
52
53
  titlePositionPercentageOffset: section.getDouble("title_position"),
53
- badgeWidget: section.buildWidget("badge_content"),
54
+ badgeWidget: section.buildWidget("badge"),
54
55
  badgePositionPercentageOffset: section.getDouble("badge_position"),
55
56
  );
56
57
  }