flet-charts 0.2.0.dev524__py3-none-any.whl → 0.70.0.dev6293__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 +23 -1
- flet_charts/bar_chart.py +4 -5
- flet_charts/bar_chart_group.py +0 -1
- flet_charts/bar_chart_rod.py +0 -1
- flet_charts/candlestick_chart.py +266 -0
- flet_charts/candlestick_chart_spot.py +98 -0
- flet_charts/line_chart.py +4 -5
- flet_charts/line_chart_data.py +0 -1
- flet_charts/line_chart_data_point.py +0 -1
- flet_charts/matplotlib_backends/backend_flet_agg.py +16 -0
- flet_charts/matplotlib_chart.py +348 -31
- flet_charts/matplotlib_chart_with_toolbar.py +110 -0
- flet_charts/pie_chart.py +0 -1
- flet_charts/plotly_chart.py +1 -1
- flet_charts/scatter_chart.py +4 -5
- flet_charts/scatter_chart_spot.py +0 -1
- {flet_charts-0.2.0.dev524.dist-info → flet_charts-0.70.0.dev6293.dist-info}/METADATA +19 -11
- flet_charts-0.70.0.dev6293.dist-info/RECORD +42 -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/candlestick_chart.dart +136 -0
- flutter/flet_charts/lib/src/extension.dart +3 -0
- flutter/flet_charts/lib/src/utils/bar_chart.dart +136 -83
- flutter/flet_charts/lib/src/utils/candlestick_chart.dart +117 -0
- flutter/flet_charts/pubspec.yaml +10 -9
- flet_charts-0.2.0.dev524.dist-info/RECORD +0 -38
- flutter/flet_charts/README.md +0 -3
- flutter/flet_charts/pubspec.lock +0 -792
- {flet_charts-0.2.0.dev524.dist-info → flet_charts-0.70.0.dev6293.dist-info}/WHEEL +0 -0
- {flet_charts-0.2.0.dev524.dist-info → flet_charts-0.70.0.dev6293.dist-info}/licenses/LICENSE +0 -0
- {flet_charts-0.2.0.dev524.dist-info → flet_charts-0.70.0.dev6293.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
flet_charts/__init__.py,sha256=1rbVlnYcFmtrT8_X2IQSFLmmAWl6dsFWJhpWy-_ZCLE,2824
|
|
2
|
+
flet_charts/bar_chart.py,sha256=NxxbK9HrVmkNPGbP7OtpoGf6aLsQ2htbdrawZbxWkWU,7641
|
|
3
|
+
flet_charts/bar_chart_group.py,sha256=g8JGjaxQMDFGozE1BTQXBaiCynFYTTOVlB1kTzGvB8I,701
|
|
4
|
+
flet_charts/bar_chart_rod.py,sha256=hBMPwprgJWZhryKTFHaOwbHIiKq2uQzPyCKG7-mS8go,3574
|
|
5
|
+
flet_charts/bar_chart_rod_stack_item.py,sha256=XPLRpHdScmdde2UAau47OLSSL-AuQUbLpT1g7pNS9kI,623
|
|
6
|
+
flet_charts/candlestick_chart.py,sha256=ApxX1gnQDryIsRB5FJu90P4jRn-xzUfwQl9FqJOg-yQ,7448
|
|
7
|
+
flet_charts/candlestick_chart_spot.py,sha256=ti4R_IgQb2zyU64aeHx3s2uADI-INl0_J7sGohZaIPY,2749
|
|
8
|
+
flet_charts/chart_axis.py,sha256=jKX1bxQqxW3piNmyJUQShGATwnI1sKjXtKP425iDRhg,1869
|
|
9
|
+
flet_charts/line_chart.py,sha256=A7Y0LqHFw-iLiFtATZLIGXOpvvueiGFiSdf3fLfHtIA,7979
|
|
10
|
+
flet_charts/line_chart_data.py,sha256=KDE8GZ-Q08usKoHjMCkwG7wl-twcXvq6hBnM2IrtWv0,4161
|
|
11
|
+
flet_charts/line_chart_data_point.py,sha256=4GH2MU81IbIisapxupQRoiOd768pj4ixp4ml8AdIyKA,3252
|
|
12
|
+
flet_charts/matplotlib_chart.py,sha256=ZvKopbELoQEXhj0fGEjq4eybccpqpwCP9yL6yiaGyXE,13020
|
|
13
|
+
flet_charts/matplotlib_chart_with_toolbar.py,sha256=XJ_Ucj2F7yLImEEB6H-oGWn_6vp1VvJ4K9GB2Smi7qY,3407
|
|
14
|
+
flet_charts/pie_chart.py,sha256=boJ01MiDN1lWYFQIW497P5MNdih53ZdWcB7ce734dvQ,1963
|
|
15
|
+
flet_charts/pie_chart_section.py,sha256=KdUF91BYAhY63U3NxMuY9Go56Ss0w-dmT8hLdxgP-tQ,2482
|
|
16
|
+
flet_charts/plotly_chart.py,sha256=AqRRaamjYeuT1YHAWtEP_49zxjjXIEoNKkDuMeYICww,1675
|
|
17
|
+
flet_charts/scatter_chart.py,sha256=q_YY0AZwI_xXQye53HWEmedjTI33kSfITf-6xsC4XXQ,7040
|
|
18
|
+
flet_charts/scatter_chart_spot.py,sha256=oFUGHxK9q6pehcHxzY9v-dcJAqc7Sef0sbR-2E5x7nw,3662
|
|
19
|
+
flet_charts/types.py,sha256=0VNeobnKFjM5F164yqH81qGJVbtewhJEGAygMWy7SCs,11121
|
|
20
|
+
flet_charts/matplotlib_backends/backend_flet_agg.py,sha256=1imjpVpAexu02v96_jWlTPHhXdHMztPllTvHjnxDT78,483
|
|
21
|
+
flet_charts-0.70.0.dev6293.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
22
|
+
flutter/flet_charts/CHANGELOG.md,sha256=tLc4Pl32-dWgzs4OPKaUerLsnLo1u3yVWKU9qjyazf0,41
|
|
23
|
+
flutter/flet_charts/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
24
|
+
flutter/flet_charts/analysis_options.yaml,sha256=x4UkoVEHV7h6exoZk7csc1_nfwEhkWpL7L8itHPuwLY,155
|
|
25
|
+
flutter/flet_charts/pubspec.yaml,sha256=N5gRkctY8H17u1ZLU8i0IkUnLC4GkodZ8Bdw5hnG6xM,419
|
|
26
|
+
flutter/flet_charts/lib/flet_charts.dart,sha256=66hr4Shizat1MIyu957NiJI_xXYOSeOJbFI489qw7ok,70
|
|
27
|
+
flutter/flet_charts/lib/src/bar_chart.dart,sha256=6K_WPR4NzI_C9dor0eblESZi5hdf6PpKGD6xTml9KDI,3683
|
|
28
|
+
flutter/flet_charts/lib/src/candlestick_chart.dart,sha256=g-mFGNw4Q2F_NKB8igT9ex_KsjFRSUZNLFMdtguBtJ4,4964
|
|
29
|
+
flutter/flet_charts/lib/src/extension.dart,sha256=eHGoSpVHN-Qat-gO6o7yfd8LCY8HW5_Gp0NZtptpNs0,834
|
|
30
|
+
flutter/flet_charts/lib/src/line_chart.dart,sha256=iij6QsZG0PgSCnZoK9YHQTwH7nJnM1_pNrb2zt-Mtk8,8733
|
|
31
|
+
flutter/flet_charts/lib/src/pie_chart.dart,sha256=WQWrUcPjTj2ywUtA2ZwAwRmzv1mouS17Hj-uSOJtD-c,2384
|
|
32
|
+
flutter/flet_charts/lib/src/scatter_chart.dart,sha256=CVdnTNlXmQZxonjs2e0jXAGGMs1LT1e4iujTEkopTII,5541
|
|
33
|
+
flutter/flet_charts/lib/src/utils/bar_chart.dart,sha256=7Z7izbK_JUzAE4i5lHvEInq7K7-pdyiZOZH3ulD0u7A,7178
|
|
34
|
+
flutter/flet_charts/lib/src/utils/candlestick_chart.dart,sha256=AlPCNkA-c8lXD3paK59KmYRKhIH8lMEmFNZ70Ylbz6o,3667
|
|
35
|
+
flutter/flet_charts/lib/src/utils/charts.dart,sha256=5Umt7NIzHp9UBDdIQ_8YQCxn8vQs8nC1NtpKzJ7aC64,6479
|
|
36
|
+
flutter/flet_charts/lib/src/utils/line_chart.dart,sha256=s_9iokaUFHNipu_YVw6OSJcmD8JctWCoImrIyuxB688,8633
|
|
37
|
+
flutter/flet_charts/lib/src/utils/pie_chart.dart,sha256=GbxCrhx_SXtJFH_94raOd_m_u7r37NRc6IExi-Qcumw,1850
|
|
38
|
+
flutter/flet_charts/lib/src/utils/scatter_chart.dart,sha256=KqJxvpl8jIZkQw132Ab4x4nhHTyiUw8M2NExgRCXf1k,3323
|
|
39
|
+
flet_charts-0.70.0.dev6293.dist-info/METADATA,sha256=jO3QermOGinwvqj99wIEwd0diGuOHMMxMhLY4G7cdgo,2057
|
|
40
|
+
flet_charts-0.70.0.dev6293.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
41
|
+
flet_charts-0.70.0.dev6293.dist-info/top_level.txt,sha256=CVHmtljbPFTyfCiru5bxX1vvWL8L6rtUbV9bqqkSxFE,20
|
|
42
|
+
flet_charts-0.70.0.dev6293.dist-info/RECORD,,
|
flutter/flet_charts/CHANGELOG.md
CHANGED
flutter/flet_charts/LICENSE
CHANGED
|
@@ -198,4 +198,4 @@
|
|
|
198
198
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
199
199
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
200
200
|
See the License for the specific language governing permissions and
|
|
201
|
-
limitations under the License.
|
|
201
|
+
limitations under the License.
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import 'package:fl_chart/fl_chart.dart';
|
|
2
|
+
import 'package:flet/flet.dart';
|
|
3
|
+
import 'package:flutter/material.dart';
|
|
4
|
+
|
|
5
|
+
import 'utils/candlestick_chart.dart';
|
|
6
|
+
import 'utils/charts.dart';
|
|
7
|
+
|
|
8
|
+
class CandlestickChartControl extends StatefulWidget {
|
|
9
|
+
final Control control;
|
|
10
|
+
|
|
11
|
+
CandlestickChartControl({Key? key, required this.control})
|
|
12
|
+
: super(key: ValueKey("control_${control.id}"));
|
|
13
|
+
|
|
14
|
+
@override
|
|
15
|
+
State<CandlestickChartControl> createState() =>
|
|
16
|
+
_CandlestickChartControlState();
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
class _CandlestickChartControlState extends State<CandlestickChartControl> {
|
|
20
|
+
CandlestickChartEventData? _eventData;
|
|
21
|
+
|
|
22
|
+
@override
|
|
23
|
+
Widget build(BuildContext context) {
|
|
24
|
+
debugPrint("CandlestickChart build: ${widget.control.id}");
|
|
25
|
+
|
|
26
|
+
final theme = Theme.of(context);
|
|
27
|
+
final animation = widget.control.getAnimation(
|
|
28
|
+
"animation",
|
|
29
|
+
ImplicitAnimationDetails(
|
|
30
|
+
duration: const Duration(milliseconds: 150),
|
|
31
|
+
curve: Curves.linear))!;
|
|
32
|
+
final border = widget.control.getBorder("border", theme);
|
|
33
|
+
|
|
34
|
+
final leftTitles = parseAxisTitles(widget.control.child("left_axis"));
|
|
35
|
+
final topTitles = parseAxisTitles(widget.control.child("top_axis"));
|
|
36
|
+
final rightTitles = parseAxisTitles(widget.control.child("right_axis"));
|
|
37
|
+
final bottomTitles = parseAxisTitles(widget.control.child("bottom_axis"));
|
|
38
|
+
|
|
39
|
+
final interactive = widget.control.getBool("interactive", true)!;
|
|
40
|
+
final handleBuiltInTouches =
|
|
41
|
+
widget.control.getBool("handle_built_in_touches", true)!;
|
|
42
|
+
final touchSpotThreshold = widget.control.getDouble("touch_spot_threshold");
|
|
43
|
+
|
|
44
|
+
final spotControls = widget.control.children("spots");
|
|
45
|
+
final candlestickSpots = spotControls.map((spot) {
|
|
46
|
+
spot.notifyParent = true;
|
|
47
|
+
return CandlestickSpot(
|
|
48
|
+
x: spot.getDouble("x", 0)!,
|
|
49
|
+
open: spot.getDouble("open", 0)!,
|
|
50
|
+
high: spot.getDouble("high", 0)!,
|
|
51
|
+
low: spot.getDouble("low", 0)!,
|
|
52
|
+
close: spot.getDouble("close", 0)!,
|
|
53
|
+
show: spot.visible,
|
|
54
|
+
);
|
|
55
|
+
}).toList();
|
|
56
|
+
|
|
57
|
+
final selectedIndicators = spotControls
|
|
58
|
+
.asMap()
|
|
59
|
+
.entries
|
|
60
|
+
.where((entry) => entry.value.getBool("selected", false)!)
|
|
61
|
+
.map((entry) => entry.key)
|
|
62
|
+
.toList();
|
|
63
|
+
|
|
64
|
+
final showingIndicators =
|
|
65
|
+
(!interactive || !handleBuiltInTouches) ? selectedIndicators : <int>[];
|
|
66
|
+
|
|
67
|
+
final candlestickTouchData = CandlestickTouchData(
|
|
68
|
+
enabled: interactive && !widget.control.disabled,
|
|
69
|
+
handleBuiltInTouches: handleBuiltInTouches,
|
|
70
|
+
longPressDuration: widget.control.getDuration("long_press_duration"),
|
|
71
|
+
touchSpotThreshold: touchSpotThreshold,
|
|
72
|
+
touchTooltipData: parseCandlestickTouchTooltipData(
|
|
73
|
+
context,
|
|
74
|
+
widget.control,
|
|
75
|
+
spotControls,
|
|
76
|
+
),
|
|
77
|
+
touchCallback: widget.control.getBool("on_event", false)!
|
|
78
|
+
? (event, response) {
|
|
79
|
+
final eventData =
|
|
80
|
+
CandlestickChartEventData.fromDetails(event, response);
|
|
81
|
+
if (eventData != _eventData) {
|
|
82
|
+
_eventData = eventData;
|
|
83
|
+
widget.control.triggerEvent("event", eventData.toMap());
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
: null,
|
|
87
|
+
);
|
|
88
|
+
|
|
89
|
+
final chart = CandlestickChart(
|
|
90
|
+
CandlestickChartData(
|
|
91
|
+
candlestickSpots: candlestickSpots,
|
|
92
|
+
backgroundColor: widget.control.getColor("bgcolor", context),
|
|
93
|
+
minX: widget.control.getDouble("min_x"),
|
|
94
|
+
maxX: widget.control.getDouble("max_x"),
|
|
95
|
+
baselineX: widget.control.getDouble("baseline_x"),
|
|
96
|
+
minY: widget.control.getDouble("min_y"),
|
|
97
|
+
maxY: widget.control.getDouble("max_y"),
|
|
98
|
+
baselineY: widget.control.getDouble("baseline_y"),
|
|
99
|
+
titlesData: FlTitlesData(
|
|
100
|
+
show: (leftTitles.sideTitles.showTitles ||
|
|
101
|
+
topTitles.sideTitles.showTitles ||
|
|
102
|
+
rightTitles.sideTitles.showTitles ||
|
|
103
|
+
bottomTitles.sideTitles.showTitles),
|
|
104
|
+
leftTitles: leftTitles,
|
|
105
|
+
topTitles: topTitles,
|
|
106
|
+
rightTitles: rightTitles,
|
|
107
|
+
bottomTitles: bottomTitles,
|
|
108
|
+
),
|
|
109
|
+
borderData: FlBorderData(show: border != null, border: border),
|
|
110
|
+
gridData: parseChartGridData(
|
|
111
|
+
widget.control.get("horizontal_grid_lines"),
|
|
112
|
+
widget.control.get("vertical_grid_lines"),
|
|
113
|
+
theme),
|
|
114
|
+
candlestickTouchData: candlestickTouchData,
|
|
115
|
+
showingTooltipIndicators: showingIndicators,
|
|
116
|
+
rotationQuarterTurns:
|
|
117
|
+
widget.control.getInt("rotation_quarter_turns", 0)!,
|
|
118
|
+
),
|
|
119
|
+
duration: animation.duration,
|
|
120
|
+
curve: animation.curve,
|
|
121
|
+
);
|
|
122
|
+
|
|
123
|
+
return ConstrainedControl(
|
|
124
|
+
control: widget.control,
|
|
125
|
+
child: LayoutBuilder(
|
|
126
|
+
builder: (BuildContext context, BoxConstraints constraints) {
|
|
127
|
+
return (constraints.maxHeight == double.infinity)
|
|
128
|
+
? ConstrainedBox(
|
|
129
|
+
constraints: const BoxConstraints(maxHeight: 300),
|
|
130
|
+
child: chart,
|
|
131
|
+
)
|
|
132
|
+
: chart;
|
|
133
|
+
}),
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
@@ -2,6 +2,7 @@ import 'package:flet/flet.dart';
|
|
|
2
2
|
import 'package:flutter/material.dart';
|
|
3
3
|
|
|
4
4
|
import 'bar_chart.dart';
|
|
5
|
+
import 'candlestick_chart.dart';
|
|
5
6
|
import 'line_chart.dart';
|
|
6
7
|
import 'pie_chart.dart';
|
|
7
8
|
import 'scatter_chart.dart';
|
|
@@ -12,6 +13,8 @@ class Extension extends FletExtension {
|
|
|
12
13
|
switch (control.type) {
|
|
13
14
|
case "BarChart":
|
|
14
15
|
return BarChartControl(key: key, control: control);
|
|
16
|
+
case "CandlestickChart":
|
|
17
|
+
return CandlestickChartControl(key: key, control: control);
|
|
15
18
|
case "LineChart":
|
|
16
19
|
return LineChartControl(key: key, control: control);
|
|
17
20
|
case "PieChart":
|
|
@@ -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
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
41
|
+
'type': eventType,
|
|
42
|
+
'group_index': groupIndex,
|
|
43
|
+
'rod_index': rodIndex,
|
|
44
|
+
'stack_item_index': stackItemIndex,
|
|
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
|
|
|
@@ -65,22 +74,31 @@ BarTouchTooltipData? parseBarTouchTooltipData(
|
|
|
65
74
|
parseColor(tooltip["bgcolor"], theme, theme.colorScheme.secondary)!,
|
|
66
75
|
tooltipBorderRadius: parseBorderRadius(tooltip["border_radius"]),
|
|
67
76
|
tooltipMargin: parseDouble(tooltip["margin"], 16)!,
|
|
68
|
-
tooltipPadding: parsePadding(
|
|
69
|
-
|
|
77
|
+
tooltipPadding: parsePadding(
|
|
78
|
+
tooltip["padding"],
|
|
79
|
+
const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
|
|
80
|
+
)!,
|
|
70
81
|
maxContentWidth: parseDouble(tooltip["max_width"]),
|
|
71
82
|
rotateAngle: parseDouble(tooltip["rotation"], 0.0)!,
|
|
72
83
|
tooltipHorizontalOffset: parseDouble(tooltip["horizontal_offset"], 0)!,
|
|
73
84
|
tooltipBorder: parseBorderSide(tooltip["border_side"], theme),
|
|
74
|
-
fitInsideHorizontally:
|
|
75
|
-
|
|
85
|
+
fitInsideHorizontally: parseBool(
|
|
86
|
+
tooltip["fit_inside_horizontally"],
|
|
87
|
+
false,
|
|
88
|
+
)!,
|
|
76
89
|
fitInsideVertically: parseBool(tooltip["fit_inside_vertically"], false)!,
|
|
77
|
-
direction:
|
|
78
|
-
|
|
90
|
+
direction: parseTooltipDirection(
|
|
91
|
+
tooltip["direction"],
|
|
92
|
+
TooltipDirection.auto,
|
|
93
|
+
)!,
|
|
79
94
|
tooltipHorizontalAlignment: parseFLHorizontalAlignment(
|
|
80
|
-
|
|
95
|
+
tooltip["horizontal_alignment"],
|
|
96
|
+
FLHorizontalAlignment.center,
|
|
97
|
+
)!,
|
|
81
98
|
getTooltipItem: (group, groupIndex, rod, rodIndex) {
|
|
82
|
-
var rod =
|
|
83
|
-
|
|
99
|
+
var rod = control
|
|
100
|
+
.children("groups")[groupIndex]
|
|
101
|
+
.children("rods")[rodIndex];
|
|
84
102
|
return parseBarTooltipItem(rod, context);
|
|
85
103
|
},
|
|
86
104
|
);
|
|
@@ -93,29 +111,42 @@ BarTooltipItem? parseBarTooltipItem(Control rod, BuildContext context) {
|
|
|
93
111
|
if (tooltip == null) return null;
|
|
94
112
|
|
|
95
113
|
final theme = Theme.of(context);
|
|
96
|
-
var tooltipTextStyle =
|
|
97
|
-
|
|
114
|
+
var tooltipTextStyle = parseTextStyle(
|
|
115
|
+
tooltip["text_style"],
|
|
116
|
+
theme,
|
|
117
|
+
const TextStyle(),
|
|
118
|
+
)!;
|
|
98
119
|
if (tooltipTextStyle.color == null) {
|
|
99
120
|
tooltipTextStyle = tooltipTextStyle.copyWith(
|
|
100
|
-
|
|
101
|
-
|
|
121
|
+
color:
|
|
122
|
+
rod.getGradient("gradient", theme)?.colors.first ??
|
|
123
|
+
rod.getColor("color", context, Colors.blueGrey)!,
|
|
124
|
+
);
|
|
102
125
|
}
|
|
103
126
|
return BarTooltipItem(
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
127
|
+
tooltip["text"] ?? rod.getDouble("to_y", 0)!.toString(),
|
|
128
|
+
tooltipTextStyle,
|
|
129
|
+
textAlign: parseTextAlign(tooltip["text_align"], TextAlign.center)!,
|
|
130
|
+
textDirection: parseBool(tooltip["rtl"], false)!
|
|
131
|
+
? TextDirection.rtl
|
|
132
|
+
: TextDirection.ltr,
|
|
133
|
+
children: tooltip["text_spans"] != null
|
|
134
|
+
? parseTextSpans(tooltip["text_spans"], theme, (
|
|
135
|
+
s,
|
|
136
|
+
eventName, [
|
|
137
|
+
eventData,
|
|
138
|
+
]) {
|
|
139
|
+
s.triggerEvent(eventName, eventData);
|
|
140
|
+
})
|
|
141
|
+
: null,
|
|
142
|
+
);
|
|
115
143
|
}
|
|
116
144
|
|
|
117
145
|
BarChartGroupData parseBarChartGroupData(
|
|
118
|
-
|
|
146
|
+
Control group,
|
|
147
|
+
bool interactiveChart,
|
|
148
|
+
BuildContext context,
|
|
149
|
+
) {
|
|
119
150
|
group.notifyParent = true;
|
|
120
151
|
return BarChartGroupData(
|
|
121
152
|
x: group.getInt("x", 0)!,
|
|
@@ -126,7 +157,8 @@ BarChartGroupData parseBarChartGroupData(
|
|
|
126
157
|
.asMap()
|
|
127
158
|
.entries
|
|
128
159
|
.where(
|
|
129
|
-
|
|
160
|
+
(rod) => !interactiveChart && rod.value.getBool("selected", false)!,
|
|
161
|
+
)
|
|
130
162
|
.map((rod) => rod.key)
|
|
131
163
|
.toList(),
|
|
132
164
|
barRods: group
|
|
@@ -137,7 +169,10 @@ BarChartGroupData parseBarChartGroupData(
|
|
|
137
169
|
}
|
|
138
170
|
|
|
139
171
|
BarChartRodData parseBarChartRodData(
|
|
140
|
-
|
|
172
|
+
Control rod,
|
|
173
|
+
bool interactiveChart,
|
|
174
|
+
BuildContext context,
|
|
175
|
+
) {
|
|
141
176
|
rod.notifyParent = true;
|
|
142
177
|
|
|
143
178
|
final theme = Theme.of(context);
|
|
@@ -147,28 +182,39 @@ BarChartRodData parseBarChartRodData(
|
|
|
147
182
|
var backgroundGradient = rod.getGradient("background_gradient", theme);
|
|
148
183
|
|
|
149
184
|
return BarChartRodData(
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
185
|
+
fromY: rod.getDouble("from_y"),
|
|
186
|
+
toY: rod.getDouble("to_y", 0)!,
|
|
187
|
+
width: rod.getDouble("width"),
|
|
188
|
+
color: rod.getColor("color", context),
|
|
189
|
+
gradient: rod.getGradient("gradient", theme),
|
|
190
|
+
borderRadius: rod.getBorderRadius("border_radius"),
|
|
191
|
+
borderSide: rod.getBorderSide(
|
|
192
|
+
"border_side",
|
|
193
|
+
theme,
|
|
194
|
+
defaultValue: BorderSide.none,
|
|
195
|
+
),
|
|
196
|
+
backDrawRodData: BackgroundBarChartRodData(
|
|
197
|
+
show:
|
|
198
|
+
(bgFromY != null ||
|
|
199
|
+
bgToY != null ||
|
|
200
|
+
bgcolor != null ||
|
|
201
|
+
backgroundGradient != null),
|
|
202
|
+
fromY: bgFromY,
|
|
203
|
+
toY: bgToY,
|
|
204
|
+
color: bgcolor,
|
|
205
|
+
gradient: backgroundGradient,
|
|
206
|
+
),
|
|
207
|
+
rodStackItems: rod
|
|
208
|
+
.children("stack_items")
|
|
209
|
+
.map(
|
|
210
|
+
(rodStackItem) => parseBarChartRodStackItem(
|
|
211
|
+
rodStackItem,
|
|
212
|
+
interactiveChart,
|
|
213
|
+
context,
|
|
214
|
+
),
|
|
215
|
+
)
|
|
216
|
+
.toList(),
|
|
217
|
+
);
|
|
172
218
|
}
|
|
173
219
|
|
|
174
220
|
BarChartRodStackItem parseBarChartRodStackItem(
|
|
@@ -178,17 +224,24 @@ BarChartRodStackItem parseBarChartRodStackItem(
|
|
|
178
224
|
) {
|
|
179
225
|
rodStackItem.notifyParent = true;
|
|
180
226
|
return BarChartRodStackItem(
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
227
|
+
rodStackItem.getDouble("from_y")!,
|
|
228
|
+
rodStackItem.getDouble("to_y", 0)!,
|
|
229
|
+
rodStackItem.getColor("color", context)!,
|
|
230
|
+
borderSide: rodStackItem.getBorderSide(
|
|
231
|
+
"border_side",
|
|
232
|
+
Theme.of(context),
|
|
233
|
+
defaultValue: BorderSide.none,
|
|
234
|
+
)!,
|
|
235
|
+
);
|
|
186
236
|
}
|
|
187
237
|
|
|
188
|
-
BarChartAlignment? parseBarChartAlignment(
|
|
189
|
-
|
|
238
|
+
BarChartAlignment? parseBarChartAlignment(
|
|
239
|
+
String? value, [
|
|
240
|
+
BarChartAlignment? defaultValue,
|
|
241
|
+
]) {
|
|
190
242
|
if (value == null) return defaultValue;
|
|
191
243
|
return BarChartAlignment.values.firstWhereOrNull(
|
|
192
|
-
|
|
244
|
+
(e) => e.name.toLowerCase() == value.toLowerCase(),
|
|
245
|
+
) ??
|
|
193
246
|
defaultValue;
|
|
194
247
|
}
|
|
@@ -0,0 +1,117 @@
|
|
|
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:
|
|
43
|
+
parseBorderSide(tooltip["border_side"], theme, defaultValue: BorderSide.none)!,
|
|
44
|
+
rotateAngle: parseDouble(tooltip["rotation"], 0.0)!,
|
|
45
|
+
tooltipBorderRadius: parseBorderRadius(tooltip["border_radius"]),
|
|
46
|
+
tooltipPadding: parsePadding(
|
|
47
|
+
tooltip["padding"], const EdgeInsets.symmetric(horizontal: 16, vertical: 8))!,
|
|
48
|
+
tooltipHorizontalAlignment: parseFLHorizontalAlignment(
|
|
49
|
+
tooltip["horizontal_alignment"], FLHorizontalAlignment.center)!,
|
|
50
|
+
tooltipHorizontalOffset: parseDouble(tooltip["horizontal_offset"], 0)!,
|
|
51
|
+
maxContentWidth: parseDouble(tooltip["max_width"], 120)!,
|
|
52
|
+
fitInsideHorizontally:
|
|
53
|
+
parseBool(tooltip["fit_inside_horizontally"], false)!,
|
|
54
|
+
fitInsideVertically:
|
|
55
|
+
parseBool(tooltip["fit_inside_vertically"], false)!,
|
|
56
|
+
showOnTopOfTheChartBoxArea:
|
|
57
|
+
parseBool(tooltip["show_on_top_of_chart_box_area"], false)!,
|
|
58
|
+
getTooltipColor: (spot) => parseColor(
|
|
59
|
+
tooltip["bgcolor"], theme, const Color.fromRGBO(96, 125, 139, 1))!,
|
|
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:
|
|
109
|
+
parseBool(tooltip["rtl"], false)! ? TextDirection.rtl : TextDirection.ltr,
|
|
110
|
+
children: tooltip["text_spans"] != null
|
|
111
|
+
? parseTextSpans(tooltip["text_spans"], theme, (s, eventName,
|
|
112
|
+
[eventData]) {
|
|
113
|
+
s.triggerEvent(eventName, eventData);
|
|
114
|
+
})
|
|
115
|
+
: null,
|
|
116
|
+
);
|
|
117
|
+
}
|
flutter/flet_charts/pubspec.yaml
CHANGED
|
@@ -1,23 +1,24 @@
|
|
|
1
1
|
name: flet_charts
|
|
2
2
|
description: A Flet extension for creating interactive charts and graphs.
|
|
3
|
-
|
|
4
|
-
repository: https://github.com/flet-dev/flet-charts/src/flutter/flet_charts
|
|
5
|
-
version: 0.2.0
|
|
3
|
+
version: 0.1.0
|
|
6
4
|
publish_to: none
|
|
5
|
+
|
|
7
6
|
environment:
|
|
8
7
|
sdk: '>=3.2.3 <4.0.0'
|
|
9
|
-
flutter:
|
|
8
|
+
flutter: ">=1.17.0"
|
|
9
|
+
|
|
10
10
|
dependencies:
|
|
11
11
|
flutter:
|
|
12
12
|
sdk: flutter
|
|
13
|
+
|
|
14
|
+
|
|
13
15
|
collection: ^1.16.0
|
|
14
16
|
equatable: ^2.0.3
|
|
15
|
-
fl_chart: 1.
|
|
17
|
+
fl_chart: 1.1.1
|
|
18
|
+
|
|
16
19
|
flet:
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
path: packages/flet
|
|
20
|
-
ref: main
|
|
20
|
+
path: ../../../../../../../packages/flet
|
|
21
|
+
|
|
21
22
|
dev_dependencies:
|
|
22
23
|
flutter_test:
|
|
23
24
|
sdk: flutter
|