flet-charts 0.2.0.dev35__py3-none-any.whl → 0.70.0.dev6551__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 +25 -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.dev6551.dist-info/METADATA +67 -0
- flet_charts-0.70.0.dev6551.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 +1 -0
- 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.dev6551.dist-info}/WHEEL +0 -0
- {flet_charts-0.2.0.dev35.dist-info → flet_charts-0.70.0.dev6551.dist-info}/licenses/LICENSE +0 -0
- {flet_charts-0.2.0.dev35.dist-info → flet_charts-0.70.0.dev6551.dist-info}/top_level.txt +0 -0
flet_charts/plotly_chart.py
CHANGED
|
@@ -1,19 +1,28 @@
|
|
|
1
1
|
import re
|
|
2
2
|
import xml.etree.ElementTree as ET
|
|
3
3
|
from dataclasses import field
|
|
4
|
+
from typing import Any, Optional
|
|
4
5
|
|
|
5
6
|
import flet as ft
|
|
6
7
|
|
|
8
|
+
_PLOTLY_IMPORT_ERROR: Optional[ImportError] = None
|
|
9
|
+
|
|
7
10
|
try:
|
|
8
11
|
from plotly.graph_objects import Figure
|
|
9
|
-
except ImportError as e:
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
) from e
|
|
12
|
+
except ImportError as e: # pragma: no cover - depends on optional dependency
|
|
13
|
+
Figure = Any # type: ignore[assignment]
|
|
14
|
+
_PLOTLY_IMPORT_ERROR = e
|
|
13
15
|
|
|
14
16
|
__all__ = ["PlotlyChart"]
|
|
15
17
|
|
|
16
18
|
|
|
19
|
+
def _require_plotly() -> None:
|
|
20
|
+
if _PLOTLY_IMPORT_ERROR is not None:
|
|
21
|
+
raise ModuleNotFoundError(
|
|
22
|
+
'Install "plotly" Python package to use PlotlyChart control.'
|
|
23
|
+
) from _PLOTLY_IMPORT_ERROR
|
|
24
|
+
|
|
25
|
+
|
|
17
26
|
@ft.control(kw_only=True)
|
|
18
27
|
class PlotlyChart(ft.Container):
|
|
19
28
|
"""
|
|
@@ -28,8 +37,9 @@ class PlotlyChart(ft.Container):
|
|
|
28
37
|
|
|
29
38
|
figure: Figure = field(metadata={"skip": True})
|
|
30
39
|
"""
|
|
31
|
-
Plotly figure to draw
|
|
32
|
-
|
|
40
|
+
Plotly figure to draw.
|
|
41
|
+
|
|
42
|
+
The value is an instance of [`plotly.graph_objects.Figure`](https://plotly.com/python-api-reference/generated/plotly.graph_objects.Figure.html).
|
|
33
43
|
"""
|
|
34
44
|
|
|
35
45
|
original_size: bool = False
|
|
@@ -40,6 +50,7 @@ class PlotlyChart(ft.Container):
|
|
|
40
50
|
"""
|
|
41
51
|
|
|
42
52
|
def init(self):
|
|
53
|
+
_require_plotly()
|
|
43
54
|
self.alignment = ft.Alignment.CENTER
|
|
44
55
|
self.__img = ft.Image(fit=ft.BoxFit.FILL)
|
|
45
56
|
self.content = self.__img
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
from dataclasses import dataclass, field
|
|
2
|
+
from enum import Enum
|
|
3
|
+
from typing import Optional
|
|
4
|
+
|
|
5
|
+
import flet as ft
|
|
6
|
+
from flet_charts.radar_data_set import RadarDataSet
|
|
7
|
+
from flet_charts.types import ChartEventType
|
|
8
|
+
|
|
9
|
+
__all__ = ["RadarChart", "RadarChartEvent", "RadarChartTitle", "RadarShape"]
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class RadarShape(Enum):
|
|
13
|
+
"""Shape of the radar grid and data polygons."""
|
|
14
|
+
|
|
15
|
+
CIRCLE = "circle"
|
|
16
|
+
"""Draws radial circles for the grid and data outlines."""
|
|
17
|
+
|
|
18
|
+
POLYGON = "polygon"
|
|
19
|
+
"""Draws straight-edged polygons for the grid and data outlines."""
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@ft.control("RadarChartTitle")
|
|
23
|
+
class RadarChartTitle(ft.BaseControl):
|
|
24
|
+
"""
|
|
25
|
+
Custom title configuration displayed around a [`RadarChart`][(p).].
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
text: str = ""
|
|
29
|
+
"""
|
|
30
|
+
The text displayed for the title.
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
angle: ft.Number = 0
|
|
34
|
+
"""
|
|
35
|
+
Rotation angle (in degrees) applied to the title.
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
position_percentage_offset: Optional[ft.Number] = None
|
|
39
|
+
"""
|
|
40
|
+
Defines the relative distance of this title from the chart center.
|
|
41
|
+
|
|
42
|
+
- `0` draws this title near the inside edge of each section.
|
|
43
|
+
- `1` draws this title near the outside edge of each section.
|
|
44
|
+
|
|
45
|
+
Must be between `0` and `1` (inclusive), if set.
|
|
46
|
+
|
|
47
|
+
Note:
|
|
48
|
+
If set, it takes precedence over the parent
|
|
49
|
+
[`RadarChart.title_position_percentage_offset`][(p).] value.
|
|
50
|
+
"""
|
|
51
|
+
|
|
52
|
+
text_spans: Optional[list[ft.TextSpan]] = None
|
|
53
|
+
"""
|
|
54
|
+
Inline spans appended to the title.
|
|
55
|
+
"""
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
@dataclass
|
|
59
|
+
class RadarChartEvent(ft.Event["RadarChart"]):
|
|
60
|
+
"""
|
|
61
|
+
Event raised for interactions with a [`RadarChart`][(p).].
|
|
62
|
+
"""
|
|
63
|
+
|
|
64
|
+
type: ChartEventType
|
|
65
|
+
"""
|
|
66
|
+
The touch or pointer event that occurred.
|
|
67
|
+
"""
|
|
68
|
+
|
|
69
|
+
data_set_index: Optional[int] = None
|
|
70
|
+
"""
|
|
71
|
+
The index of the touched data set, if any.
|
|
72
|
+
"""
|
|
73
|
+
|
|
74
|
+
entry_index: Optional[int] = None
|
|
75
|
+
"""
|
|
76
|
+
The index of the touched radar entry, if any.
|
|
77
|
+
"""
|
|
78
|
+
|
|
79
|
+
entry_value: Optional[ft.Number] = None
|
|
80
|
+
"""
|
|
81
|
+
The value of the touched radar entry, if any.
|
|
82
|
+
"""
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
@ft.control("RadarChart")
|
|
86
|
+
class RadarChart(ft.LayoutControl):
|
|
87
|
+
"""
|
|
88
|
+
A radar chart made of multiple datasets.
|
|
89
|
+
"""
|
|
90
|
+
|
|
91
|
+
data_sets: list[RadarDataSet] = field(default_factory=list)
|
|
92
|
+
"""
|
|
93
|
+
A list of [`RadarDataSet`][(p).] controls rendered on the chart.
|
|
94
|
+
"""
|
|
95
|
+
|
|
96
|
+
titles: list[RadarChartTitle] = field(default_factory=list)
|
|
97
|
+
"""
|
|
98
|
+
The titles shown around this chart, matching the number of entries per set.
|
|
99
|
+
"""
|
|
100
|
+
|
|
101
|
+
title_text_style: Optional[ft.TextStyle] = None
|
|
102
|
+
"""
|
|
103
|
+
The text style applied to titles around this chart.
|
|
104
|
+
"""
|
|
105
|
+
|
|
106
|
+
title_position_percentage_offset: ft.Number = 0.2
|
|
107
|
+
"""
|
|
108
|
+
Defines the relative distance of titles from the chart center.
|
|
109
|
+
|
|
110
|
+
- `0` draws titles near the inside edge of each section.
|
|
111
|
+
- `1` draws titles near the outside edge of each section.
|
|
112
|
+
|
|
113
|
+
Must be between `0` and `1` (inclusive).
|
|
114
|
+
|
|
115
|
+
Raises:
|
|
116
|
+
ValueError: If set to a value less than `0` or greater than `1`.
|
|
117
|
+
"""
|
|
118
|
+
|
|
119
|
+
radar_bgcolor: ft.ColorValue = ft.Colors.TRANSPARENT
|
|
120
|
+
"""
|
|
121
|
+
The background color of the radar area.
|
|
122
|
+
"""
|
|
123
|
+
|
|
124
|
+
radar_border_side: ft.BorderSide = field(
|
|
125
|
+
default_factory=lambda: ft.BorderSide(width=2.0)
|
|
126
|
+
)
|
|
127
|
+
"""
|
|
128
|
+
The outline drawn around the radar area.
|
|
129
|
+
"""
|
|
130
|
+
|
|
131
|
+
radar_shape: RadarShape = RadarShape.POLYGON
|
|
132
|
+
"""
|
|
133
|
+
The shape of the radar area.
|
|
134
|
+
"""
|
|
135
|
+
|
|
136
|
+
border: Optional[ft.Border] = None
|
|
137
|
+
"""
|
|
138
|
+
The border drawn around this chart.
|
|
139
|
+
"""
|
|
140
|
+
|
|
141
|
+
center_min_value: bool = False
|
|
142
|
+
"""
|
|
143
|
+
Whether minimum entry values should be positioned at the center of this chart.
|
|
144
|
+
"""
|
|
145
|
+
|
|
146
|
+
tick_count: ft.Number = 1
|
|
147
|
+
"""
|
|
148
|
+
Number of tick rings drawn from the centre to the edge.
|
|
149
|
+
|
|
150
|
+
Must be greater than or equal to `1`.
|
|
151
|
+
|
|
152
|
+
Raises:
|
|
153
|
+
ValueError: If set to a value less than `1`.
|
|
154
|
+
"""
|
|
155
|
+
|
|
156
|
+
ticks_text_style: Optional[ft.TextStyle] = None
|
|
157
|
+
"""
|
|
158
|
+
The text style used to draw tick labels.
|
|
159
|
+
"""
|
|
160
|
+
|
|
161
|
+
tick_border_side: ft.BorderSide = field(
|
|
162
|
+
default_factory=lambda: ft.BorderSide(width=2.0)
|
|
163
|
+
)
|
|
164
|
+
"""
|
|
165
|
+
The style of the tick rings.
|
|
166
|
+
"""
|
|
167
|
+
|
|
168
|
+
grid_border_side: ft.BorderSide = field(
|
|
169
|
+
default_factory=lambda: ft.BorderSide(width=2.0)
|
|
170
|
+
)
|
|
171
|
+
"""
|
|
172
|
+
The style of the radar grid lines.
|
|
173
|
+
"""
|
|
174
|
+
|
|
175
|
+
animation: ft.AnimationValue = field(
|
|
176
|
+
default_factory=lambda: ft.Animation(
|
|
177
|
+
duration=ft.Duration(milliseconds=150), curve=ft.AnimationCurve.LINEAR
|
|
178
|
+
)
|
|
179
|
+
)
|
|
180
|
+
"""
|
|
181
|
+
Controls the implicit animation applied when updating this chart.
|
|
182
|
+
"""
|
|
183
|
+
|
|
184
|
+
interactive: bool = True
|
|
185
|
+
"""
|
|
186
|
+
Enables touch interactions and event notifications.
|
|
187
|
+
"""
|
|
188
|
+
|
|
189
|
+
long_press_duration: Optional[ft.DurationValue] = None
|
|
190
|
+
"""
|
|
191
|
+
The duration before a long-press event fires.
|
|
192
|
+
"""
|
|
193
|
+
|
|
194
|
+
touch_spot_threshold: ft.Number = 10
|
|
195
|
+
"""
|
|
196
|
+
The radius (in logical pixels) used to detect nearby entries for touches.
|
|
197
|
+
"""
|
|
198
|
+
|
|
199
|
+
on_event: Optional[ft.EventHandler[RadarChartEvent]] = None
|
|
200
|
+
"""
|
|
201
|
+
Called when the chart is interacted with.
|
|
202
|
+
"""
|
|
203
|
+
|
|
204
|
+
def init(self):
|
|
205
|
+
super().init()
|
|
206
|
+
entries_lengths = {len(ds.entries) for ds in self.data_sets}
|
|
207
|
+
if len(entries_lengths) > 1:
|
|
208
|
+
raise ValueError(
|
|
209
|
+
"All data sets in the data_sets list must have equal number of entries"
|
|
210
|
+
)
|
|
211
|
+
if not (0 <= self.title_position_percentage_offset <= 1):
|
|
212
|
+
raise ValueError("title_position_percentage_offset must be between 0 and 1")
|
|
213
|
+
if self.tick_count is not None and self.tick_count < 1:
|
|
214
|
+
raise ValueError("tick_count must be greater than or equal to 1")
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
from dataclasses import field
|
|
2
|
+
from typing import Optional
|
|
3
|
+
|
|
4
|
+
import flet as ft
|
|
5
|
+
|
|
6
|
+
__all__ = ["RadarDataSet", "RadarDataSetEntry"]
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@ft.control("RadarDataSetEntry")
|
|
10
|
+
class RadarDataSetEntry(ft.BaseControl):
|
|
11
|
+
"""
|
|
12
|
+
A single data point rendered on a [`RadarChart`][(p).].
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
value: ft.Number
|
|
16
|
+
"""
|
|
17
|
+
The numeric value drawn for this entry.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@ft.control("RadarDataSet")
|
|
22
|
+
class RadarDataSet(ft.BaseControl):
|
|
23
|
+
"""
|
|
24
|
+
A collection of [`RadarDataSetEntry`][(p).] drawn as a filled radar shape.
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
entries: list[RadarDataSetEntry] = field(default_factory=list)
|
|
28
|
+
"""
|
|
29
|
+
The data points that compose this set.
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
fill_color: ft.ColorValue = ft.Colors.CYAN
|
|
33
|
+
"""
|
|
34
|
+
The color used to fill this dataset.
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
fill_gradient: Optional[ft.Gradient] = None
|
|
38
|
+
"""
|
|
39
|
+
The gradient used to fill this dataset.
|
|
40
|
+
|
|
41
|
+
Takes precedence over [`fill_color`][..].
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
border_color: ft.ColorValue = ft.Colors.CYAN
|
|
45
|
+
"""
|
|
46
|
+
The color of the dataset outline.
|
|
47
|
+
"""
|
|
48
|
+
|
|
49
|
+
border_width: ft.Number = 2.0
|
|
50
|
+
"""
|
|
51
|
+
The width of the dataset outline.
|
|
52
|
+
"""
|
|
53
|
+
|
|
54
|
+
entry_radius: ft.Number = 5.0
|
|
55
|
+
"""
|
|
56
|
+
The radius of each entry.
|
|
57
|
+
"""
|
|
58
|
+
|
|
59
|
+
def init(self):
|
|
60
|
+
super().init()
|
|
61
|
+
entries_length = len(self.entries)
|
|
62
|
+
if entries_length != 0 and entries_length < 3:
|
|
63
|
+
raise ValueError(
|
|
64
|
+
f"entries can contain either 0 or at least 3 items, "
|
|
65
|
+
f"got {entries_length}"
|
|
66
|
+
)
|
flet_charts/scatter_chart.py
CHANGED
|
@@ -2,10 +2,9 @@ from dataclasses import dataclass, field
|
|
|
2
2
|
from typing import Any, Optional
|
|
3
3
|
|
|
4
4
|
import flet as ft
|
|
5
|
-
|
|
6
|
-
from .
|
|
7
|
-
from .
|
|
8
|
-
from .types import ChartEventType, ChartGridLines, ChartHorizontalAlignment
|
|
5
|
+
from flet_charts.chart_axis import ChartAxis
|
|
6
|
+
from flet_charts.scatter_chart_spot import ScatterChartSpot
|
|
7
|
+
from flet_charts.types import ChartEventType, ChartGridLines, HorizontalAlignment
|
|
9
8
|
|
|
10
9
|
__all__ = ["ScatterChart", "ScatterChartEvent", "ScatterChartTooltip"]
|
|
11
10
|
|
|
@@ -24,62 +23,104 @@ class ScatterChartTooltip:
|
|
|
24
23
|
The tooltip's border radius.
|
|
25
24
|
"""
|
|
26
25
|
|
|
27
|
-
padding:
|
|
26
|
+
padding: ft.PaddingValue = field(
|
|
27
|
+
default_factory=lambda: ft.Padding.symmetric(vertical=8, horizontal=16)
|
|
28
|
+
)
|
|
28
29
|
"""
|
|
29
30
|
Applies a padding for showing contents inside the tooltip.
|
|
30
31
|
"""
|
|
31
32
|
|
|
32
|
-
max_width:
|
|
33
|
+
max_width: ft.Number = 120
|
|
33
34
|
"""
|
|
34
35
|
Restricts the tooltip's width.
|
|
35
36
|
"""
|
|
36
37
|
|
|
37
|
-
|
|
38
|
+
rotation: ft.Number = 0.0
|
|
38
39
|
"""
|
|
39
40
|
The tooltip's rotation angle in degrees.
|
|
40
41
|
"""
|
|
41
42
|
|
|
42
|
-
horizontal_offset:
|
|
43
|
+
horizontal_offset: ft.Number = 0
|
|
43
44
|
"""
|
|
44
45
|
Applies horizontal offset for showing tooltip.
|
|
45
46
|
"""
|
|
46
47
|
|
|
47
|
-
horizontal_alignment:
|
|
48
|
+
horizontal_alignment: HorizontalAlignment = HorizontalAlignment.CENTER
|
|
48
49
|
"""
|
|
49
50
|
The tooltip's horizontal alignment.
|
|
50
51
|
"""
|
|
51
52
|
|
|
52
|
-
border_side:
|
|
53
|
+
border_side: ft.BorderSide = field(default_factory=lambda: ft.BorderSide.none())
|
|
53
54
|
"""
|
|
54
55
|
The tooltip's border side.
|
|
55
56
|
"""
|
|
56
57
|
|
|
57
|
-
fit_inside_horizontally:
|
|
58
|
+
fit_inside_horizontally: bool = False
|
|
58
59
|
"""
|
|
59
60
|
Forces the tooltip to shift horizontally inside the chart, if overflow happens.
|
|
60
61
|
"""
|
|
61
62
|
|
|
62
|
-
fit_inside_vertically:
|
|
63
|
+
fit_inside_vertically: bool = False
|
|
63
64
|
"""
|
|
64
65
|
Forces the tooltip to shift vertically inside the chart, if overflow happens.
|
|
65
66
|
"""
|
|
66
67
|
|
|
68
|
+
def copy(
|
|
69
|
+
self,
|
|
70
|
+
*,
|
|
71
|
+
bgcolor: Optional[ft.ColorValue] = None,
|
|
72
|
+
border_radius: Optional[ft.BorderRadiusValue] = None,
|
|
73
|
+
padding: Optional[ft.PaddingValue] = None,
|
|
74
|
+
max_width: Optional[ft.Number] = None,
|
|
75
|
+
rotation: Optional[ft.Number] = None,
|
|
76
|
+
horizontal_offset: Optional[ft.Number] = None,
|
|
77
|
+
horizontal_alignment: Optional[HorizontalAlignment] = None,
|
|
78
|
+
border_side: Optional[ft.BorderSide] = None,
|
|
79
|
+
fit_inside_horizontally: Optional[bool] = None,
|
|
80
|
+
fit_inside_vertically: Optional[bool] = None,
|
|
81
|
+
) -> "ScatterChartTooltip":
|
|
82
|
+
"""
|
|
83
|
+
Returns a copy of this object with the specified properties overridden.
|
|
84
|
+
"""
|
|
85
|
+
return ScatterChartTooltip(
|
|
86
|
+
bgcolor=bgcolor if bgcolor is not None else self.bgcolor,
|
|
87
|
+
border_radius=border_radius
|
|
88
|
+
if border_radius is not None
|
|
89
|
+
else self.border_radius,
|
|
90
|
+
padding=padding if padding is not None else self.padding,
|
|
91
|
+
max_width=max_width if max_width is not None else self.max_width,
|
|
92
|
+
rotation=rotation if rotation is not None else self.rotation,
|
|
93
|
+
horizontal_offset=horizontal_offset
|
|
94
|
+
if horizontal_offset is not None
|
|
95
|
+
else self.horizontal_offset,
|
|
96
|
+
horizontal_alignment=horizontal_alignment
|
|
97
|
+
if horizontal_alignment is not None
|
|
98
|
+
else self.horizontal_alignment,
|
|
99
|
+
border_side=border_side if border_side is not None else self.border_side,
|
|
100
|
+
fit_inside_horizontally=fit_inside_horizontally
|
|
101
|
+
if fit_inside_horizontally is not None
|
|
102
|
+
else self.fit_inside_horizontally,
|
|
103
|
+
fit_inside_vertically=fit_inside_vertically
|
|
104
|
+
if fit_inside_vertically is not None
|
|
105
|
+
else self.fit_inside_vertically,
|
|
106
|
+
)
|
|
107
|
+
|
|
67
108
|
|
|
68
109
|
@dataclass
|
|
69
110
|
class ScatterChartEvent(ft.Event["ScatterChart"]):
|
|
70
111
|
type: ChartEventType
|
|
71
112
|
"""
|
|
72
|
-
|
|
113
|
+
The type of the event that occurred.
|
|
73
114
|
"""
|
|
74
115
|
|
|
75
116
|
spot_index: Optional[int] = None
|
|
76
117
|
"""
|
|
77
|
-
|
|
118
|
+
The index of the touched spot, if any.
|
|
78
119
|
"""
|
|
79
120
|
|
|
80
121
|
|
|
81
122
|
@ft.control("ScatterChart")
|
|
82
|
-
class ScatterChart(ft.
|
|
123
|
+
class ScatterChart(ft.LayoutControl):
|
|
83
124
|
"""
|
|
84
125
|
A scatter chart control.
|
|
85
126
|
|
|
@@ -99,9 +140,6 @@ class ScatterChart(ft.ConstrainedControl):
|
|
|
99
140
|
)
|
|
100
141
|
"""
|
|
101
142
|
Controls chart implicit animation.
|
|
102
|
-
|
|
103
|
-
Value is of [`AnimationValue`](https://flet.dev/docs/reference/types/animationvalue)
|
|
104
|
-
type.
|
|
105
143
|
"""
|
|
106
144
|
|
|
107
145
|
interactive: bool = True
|
|
@@ -109,11 +147,6 @@ class ScatterChart(ft.ConstrainedControl):
|
|
|
109
147
|
Enables automatic tooltips when hovering chart bars.
|
|
110
148
|
"""
|
|
111
149
|
|
|
112
|
-
handle_built_in_touches: bool = True
|
|
113
|
-
"""
|
|
114
|
-
Whether to show a tooltip popup on top of the spots if a touch occurs.
|
|
115
|
-
"""
|
|
116
|
-
|
|
117
150
|
long_press_duration: Optional[ft.DurationValue] = None
|
|
118
151
|
"""
|
|
119
152
|
The duration of a long press on the chart.
|
|
@@ -139,22 +172,22 @@ class ScatterChart(ft.ConstrainedControl):
|
|
|
139
172
|
Controls drawing of chart's vertical lines.
|
|
140
173
|
"""
|
|
141
174
|
|
|
142
|
-
left_axis: ChartAxis =
|
|
175
|
+
left_axis: Optional[ChartAxis] = None
|
|
143
176
|
"""
|
|
144
177
|
Configures the appearance of the left axis, its title and labels.
|
|
145
178
|
"""
|
|
146
179
|
|
|
147
|
-
top_axis: ChartAxis =
|
|
180
|
+
top_axis: Optional[ChartAxis] = None
|
|
148
181
|
"""
|
|
149
182
|
Configures the appearance of the top axis, its title and labels.
|
|
150
183
|
"""
|
|
151
184
|
|
|
152
|
-
right_axis: ChartAxis =
|
|
185
|
+
right_axis: Optional[ChartAxis] = None
|
|
153
186
|
"""
|
|
154
187
|
Configures the appearance of the right axis, its title and labels.
|
|
155
188
|
"""
|
|
156
189
|
|
|
157
|
-
bottom_axis: ChartAxis =
|
|
190
|
+
bottom_axis: Optional[ChartAxis] = None
|
|
158
191
|
"""
|
|
159
192
|
Configures the appearance of the bottom axis, its title and labels.
|
|
160
193
|
"""
|
|
@@ -189,14 +222,27 @@ class ScatterChart(ft.ConstrainedControl):
|
|
|
189
222
|
The maximum displayed value for Y axis.
|
|
190
223
|
"""
|
|
191
224
|
|
|
192
|
-
tooltip:
|
|
225
|
+
tooltip: ScatterChartTooltip = field(default_factory=lambda: ScatterChartTooltip())
|
|
193
226
|
"""
|
|
194
227
|
The tooltip configuration for the chart.
|
|
195
228
|
"""
|
|
196
229
|
|
|
230
|
+
show_tooltips_for_selected_spots_only: bool = False
|
|
231
|
+
"""
|
|
232
|
+
Whether to permanently and only show the tooltips of spots with their
|
|
233
|
+
[`selected`][(p).ScatterChartSpot.selected] property set to `True`.
|
|
234
|
+
"""
|
|
235
|
+
|
|
236
|
+
rotation_quarter_turns: ft.Number = 0
|
|
237
|
+
"""
|
|
238
|
+
Number of quarter turns (90-degree increments) to rotate the chart.
|
|
239
|
+
Ex: `1` rotates the chart `90` degrees clockwise,
|
|
240
|
+
`2` rotates `180` degrees and `0` for no rotation.
|
|
241
|
+
"""
|
|
242
|
+
|
|
197
243
|
on_event: Optional[ft.EventHandler[ScatterChartEvent]] = None
|
|
198
244
|
"""
|
|
199
|
-
|
|
245
|
+
Called when an event occurs on this chart.
|
|
200
246
|
"""
|
|
201
247
|
|
|
202
248
|
def __post_init__(self, ref: Optional[ft.Ref[Any]]):
|
|
@@ -2,8 +2,7 @@ from dataclasses import dataclass, field
|
|
|
2
2
|
from typing import Any, Optional, Union
|
|
3
3
|
|
|
4
4
|
import flet as ft
|
|
5
|
-
|
|
6
|
-
from .types import ChartDataPointTooltip, ChartPointShape
|
|
5
|
+
from flet_charts.types import ChartDataPointTooltip, ChartPointShape
|
|
7
6
|
|
|
8
7
|
__all__ = ["ScatterChartSpot", "ScatterChartSpotTooltip"]
|
|
9
8
|
|
|
@@ -21,6 +20,37 @@ class ScatterChartSpotTooltip(ChartDataPointTooltip):
|
|
|
21
20
|
When `None`, defaults to [`ScatterChartSpot.y`][(p).].
|
|
22
21
|
"""
|
|
23
22
|
|
|
23
|
+
bottom_margin: ft.Number = 8
|
|
24
|
+
"""
|
|
25
|
+
The bottom space from the spot.
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
def copy(
|
|
29
|
+
self,
|
|
30
|
+
*,
|
|
31
|
+
text: Optional[str] = None,
|
|
32
|
+
text_style: Optional[ft.TextStyle] = None,
|
|
33
|
+
text_align: Optional[ft.TextAlign] = None,
|
|
34
|
+
text_spans: Optional[list[ft.TextSpan]] = None,
|
|
35
|
+
rtl: Optional[bool] = None,
|
|
36
|
+
bottom_margin: Optional[float] = None,
|
|
37
|
+
) -> "ScatterChartSpotTooltip":
|
|
38
|
+
"""
|
|
39
|
+
Returns a copy of this object with the specified properties overridden.
|
|
40
|
+
"""
|
|
41
|
+
return ScatterChartSpotTooltip(
|
|
42
|
+
text=text if text is not None else self.text,
|
|
43
|
+
text_style=text_style if text_style is not None else self.text_style,
|
|
44
|
+
text_align=text_align if text_align is not None else self.text_align,
|
|
45
|
+
text_spans=text_spans.copy()
|
|
46
|
+
if text_spans is not None
|
|
47
|
+
else (self.text_spans.copy() if self.text_spans is not None else None),
|
|
48
|
+
rtl=rtl if rtl is not None else self.rtl,
|
|
49
|
+
bottom_margin=bottom_margin
|
|
50
|
+
if bottom_margin is not None
|
|
51
|
+
else self.bottom_margin,
|
|
52
|
+
)
|
|
53
|
+
|
|
24
54
|
|
|
25
55
|
@ft.control("ScatterChartSpot")
|
|
26
56
|
class ScatterChartSpot(ft.BaseControl):
|
|
@@ -72,10 +102,10 @@ class ScatterChartSpot(ft.BaseControl):
|
|
|
72
102
|
|
|
73
103
|
selected: bool = False
|
|
74
104
|
"""
|
|
75
|
-
|
|
105
|
+
Whether to treat this spot as selected.
|
|
76
106
|
"""
|
|
77
107
|
|
|
78
|
-
tooltip: ScatterChartSpotTooltip = field(
|
|
108
|
+
tooltip: Union[ScatterChartSpotTooltip, str] = field(
|
|
79
109
|
default_factory=lambda: ScatterChartSpotTooltip()
|
|
80
110
|
)
|
|
81
111
|
"""
|
|
@@ -87,12 +117,12 @@ class ScatterChartSpot(ft.BaseControl):
|
|
|
87
117
|
Wether to show the tooltip.
|
|
88
118
|
"""
|
|
89
119
|
|
|
90
|
-
label_text:
|
|
120
|
+
label_text: str = ""
|
|
91
121
|
"""
|
|
92
122
|
TBD
|
|
93
123
|
"""
|
|
94
124
|
|
|
95
|
-
|
|
125
|
+
label_text_style: ft.TextStyle = field(default_factory=lambda: ft.TextStyle())
|
|
96
126
|
"""
|
|
97
127
|
TBD
|
|
98
128
|
"""
|
|
@@ -101,3 +131,11 @@ class ScatterChartSpot(ft.BaseControl):
|
|
|
101
131
|
"""
|
|
102
132
|
TBD
|
|
103
133
|
"""
|
|
134
|
+
|
|
135
|
+
def before_update(self):
|
|
136
|
+
super().before_update()
|
|
137
|
+
self._internals["tooltip"] = (
|
|
138
|
+
ScatterChartSpotTooltip(text=self.tooltip)
|
|
139
|
+
if isinstance(self.tooltip, str)
|
|
140
|
+
else self.tooltip
|
|
141
|
+
)
|