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.
- flet_charts/__init__.py +59 -17
- flet_charts/bar_chart.py +87 -30
- flet_charts/bar_chart_group.py +1 -2
- flet_charts/bar_chart_rod.py +36 -5
- flet_charts/candlestick_chart.py +269 -0
- flet_charts/candlestick_chart_spot.py +98 -0
- flet_charts/chart_axis.py +29 -9
- flet_charts/line_chart.py +76 -14
- flet_charts/line_chart_data.py +30 -5
- flet_charts/line_chart_data_point.py +33 -4
- flet_charts/matplotlib_backends/backend_flet_agg.py +16 -0
- flet_charts/matplotlib_chart.py +396 -36
- flet_charts/matplotlib_chart_with_toolbar.py +125 -0
- flet_charts/pie_chart.py +3 -6
- flet_charts/pie_chart_section.py +29 -18
- flet_charts/plotly_chart.py +17 -6
- flet_charts/radar_chart.py +214 -0
- flet_charts/radar_data_set.py +66 -0
- flet_charts/scatter_chart.py +75 -29
- flet_charts/scatter_chart_spot.py +44 -6
- flet_charts/types.py +159 -16
- flet_charts-0.70.0.dev6555.dist-info/METADATA +67 -0
- flet_charts-0.70.0.dev6555.dist-info/RECORD +47 -0
- flutter/flet_charts/CHANGELOG.md +1 -1
- flutter/flet_charts/LICENSE +1 -1
- flutter/flet_charts/analysis_options.yaml +1 -1
- flutter/flet_charts/lib/src/bar_chart.dart +2 -0
- flutter/flet_charts/lib/src/candlestick_chart.dart +129 -0
- flutter/flet_charts/lib/src/extension.dart +6 -0
- flutter/flet_charts/lib/src/radar_chart.dart +104 -0
- flutter/flet_charts/lib/src/scatter_chart.dart +22 -21
- flutter/flet_charts/lib/src/utils/bar_chart.dart +137 -73
- flutter/flet_charts/lib/src/utils/candlestick_chart.dart +118 -0
- flutter/flet_charts/lib/src/utils/charts.dart +12 -0
- flutter/flet_charts/lib/src/utils/line_chart.dart +15 -3
- flutter/flet_charts/lib/src/utils/pie_chart.dart +2 -1
- flutter/flet_charts/lib/src/utils/radar_chart.dart +90 -0
- flutter/flet_charts/lib/src/utils/scatter_chart.dart +22 -21
- flutter/flet_charts/pubspec.lock +85 -71
- flutter/flet_charts/pubspec.yaml +10 -9
- flet_charts-0.2.0.dev35.dist-info/METADATA +0 -69
- flet_charts-0.2.0.dev35.dist-info/RECORD +0 -38
- flutter/flet_charts/README.md +0 -3
- {flet_charts-0.2.0.dev35.dist-info → flet_charts-0.70.0.dev6555.dist-info}/WHEEL +0 -0
- {flet_charts-0.2.0.dev35.dist-info → flet_charts-0.70.0.dev6555.dist-info}/licenses/LICENSE +0 -0
- {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
|
|
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.
|
|
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
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
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 =
|
|
102
|
+
var dp = spotsAsControls[spotIndex];
|
|
101
103
|
return dp.getString("label_text", "")!;
|
|
102
104
|
},
|
|
103
105
|
getLabelTextStyleFunction: (spotIndex, spot) {
|
|
104
|
-
var dp =
|
|
106
|
+
var dp = spotsAsControls[spotIndex];
|
|
105
107
|
var labelStyle =
|
|
106
|
-
dp.getTextStyle("
|
|
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:
|
|
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
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
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
|
-
|
|
23
|
+
FlTouchEvent event,
|
|
24
|
+
BarTouchResponse? response,
|
|
25
|
+
) {
|
|
23
26
|
return BarChartEventData(
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
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(
|
|
48
|
-
|
|
51
|
+
TooltipDirection? parseTooltipDirection(
|
|
52
|
+
String? value, [
|
|
53
|
+
TooltipDirection? defaultValue,
|
|
54
|
+
]) {
|
|
49
55
|
if (value == null) return defaultValue;
|
|
50
56
|
return TooltipDirection.values.firstWhereOrNull(
|
|
51
|
-
|
|
57
|
+
(e) => e.name.toLowerCase() == value.toLowerCase(),
|
|
58
|
+
) ??
|
|
52
59
|
defaultValue;
|
|
53
60
|
}
|
|
54
61
|
|
|
55
62
|
BarTouchTooltipData? parseBarTouchTooltipData(
|
|
56
|
-
|
|
57
|
-
|
|
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(
|
|
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["
|
|
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(
|
|
74
|
-
|
|
75
|
-
|
|
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
|
-
|
|
109
|
+
var tooltip = rod.internals?["tooltip"];
|
|
110
|
+
if (tooltip == null) return null;
|
|
88
111
|
|
|
89
|
-
|
|
90
|
-
var tooltipTextStyle =
|
|
91
|
-
|
|
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
|
-
|
|
95
|
-
|
|
120
|
+
color: rod.getGradient("gradient", theme)?.colors.first ??
|
|
121
|
+
rod.getColor("color", context, Colors.blueGrey)!,
|
|
122
|
+
);
|
|
96
123
|
}
|
|
97
124
|
return BarTooltipItem(
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
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
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
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
|
-
|
|
55
|
+
var tooltip = dataPoint.internals?["tooltip"];
|
|
56
|
+
if (tooltip == null) return null;
|
|
56
57
|
|
|
57
|
-
|
|
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["
|
|
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("
|
|
54
|
+
badgeWidget: section.buildWidget("badge"),
|
|
54
55
|
badgePositionPercentageOffset: section.getDouble("badge_position"),
|
|
55
56
|
);
|
|
56
57
|
}
|