flet-charts 0.2.0.dev524__py3-none-any.whl → 0.2.0.dev534__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 CHANGED
@@ -19,7 +19,12 @@ from flet_charts.line_chart_data_point import (
19
19
  LineChartDataPoint,
20
20
  LineChartDataPointTooltip,
21
21
  )
22
- from flet_charts.matplotlib_chart import MatplotlibChart
22
+ from flet_charts.matplotlib_chart import (
23
+ MatplotlibChart,
24
+ MatplotlibChartMessageEvent,
25
+ MatplotlibChartToolbarButtonsUpdateEvent,
26
+ )
27
+ from flet_charts.matplotlib_chart_with_toolbar import MatplotlibChartWithToolbar
23
28
  from flet_charts.pie_chart import PieChart, PieChartEvent
24
29
  from flet_charts.pie_chart_section import PieChartSection
25
30
  from flet_charts.plotly_chart import PlotlyChart
@@ -78,4 +83,7 @@ __all__ = [
78
83
  "ScatterChartSpot",
79
84
  "ScatterChartSpotTooltip",
80
85
  "ScatterChartTooltip",
86
+ "MatplotlibChartMessageEvent",
87
+ "MatplotlibChartToolbarButtonsUpdateEvent",
88
+ "MatplotlibChartWithToolbar",
81
89
  ]
@@ -0,0 +1,16 @@
1
+ from matplotlib import _api
2
+ from matplotlib.backends import backend_webagg_core
3
+
4
+
5
+ class FigureCanvasFletAgg(backend_webagg_core.FigureCanvasWebAggCore):
6
+ manager_class = _api.classproperty(lambda cls: FigureManagerFletAgg)
7
+ supports_blit = False
8
+
9
+
10
+ class FigureManagerFletAgg(backend_webagg_core.FigureManagerWebAgg):
11
+ _toolbar2_class = backend_webagg_core.NavigationToolbar2WebAgg
12
+
13
+
14
+ FigureCanvas = FigureCanvasFletAgg
15
+ FigureManager = FigureManagerFletAgg
16
+ interactive = True
@@ -1,22 +1,63 @@
1
- import io
2
- import re
3
- import xml.etree.ElementTree as ET
4
- from dataclasses import field
1
+ import asyncio
2
+ import logging
3
+ from dataclasses import dataclass, field
4
+ from io import BytesIO
5
+ from typing import Optional
5
6
 
6
7
  import flet as ft
8
+ import flet.canvas as fc
7
9
 
8
10
  try:
11
+ import matplotlib
9
12
  from matplotlib.figure import Figure
10
13
  except ImportError as e:
11
14
  raise Exception(
12
15
  'Install "matplotlib" Python package to use MatplotlibChart control.'
13
16
  ) from e
14
17
 
15
- __all__ = ["MatplotlibChart"]
18
+ __all__ = [
19
+ "MatplotlibChart",
20
+ "MatplotlibChartMessageEvent",
21
+ "MatplotlibChartToolbarButtonsUpdateEvent",
22
+ ]
16
23
 
24
+ logger = logging.getLogger("flet-charts.matplotlib")
17
25
 
18
- @ft.control(kw_only=True)
19
- class MatplotlibChart(ft.Container):
26
+ matplotlib.use("module://flet_charts.matplotlib_backends.backend_flet_agg")
27
+
28
+ figure_cursors = {
29
+ "default": None,
30
+ "pointer": ft.MouseCursor.CLICK,
31
+ "crosshair": ft.MouseCursor.PRECISE,
32
+ "move": ft.MouseCursor.MOVE,
33
+ "wait": ft.MouseCursor.WAIT,
34
+ "ew-resize": ft.MouseCursor.RESIZE_LEFT_RIGHT,
35
+ "ns-resize": ft.MouseCursor.RESIZE_UP_DOWN,
36
+ }
37
+
38
+
39
+ @dataclass
40
+ class MatplotlibChartMessageEvent(ft.Event["MatplotlibChart"]):
41
+ message: str
42
+ """
43
+ Message text.
44
+ """
45
+
46
+
47
+ @dataclass
48
+ class MatplotlibChartToolbarButtonsUpdateEvent(ft.Event["MatplotlibChart"]):
49
+ back_enabled: bool
50
+ """
51
+ Whether Back button is enabled or not.
52
+ """
53
+ forward_enabled: bool
54
+ """
55
+ Whether Forward button is enabled or not.
56
+ """
57
+
58
+
59
+ @ft.control(kw_only=True, isolated=True)
60
+ class MatplotlibChart(ft.GestureDetector):
20
61
  """
21
62
  Displays a [Matplotlib](https://matplotlib.org/) chart.
22
63
 
@@ -33,33 +74,309 @@ class MatplotlibChart(ft.Container):
33
74
  [`matplotlib.figure.Figure`](https://matplotlib.org/stable/api/_as_gen/matplotlib.figure.Figure.html#matplotlib.figure.Figure).
34
75
  """
35
76
 
36
- original_size: bool = False
77
+ on_message: Optional[ft.EventHandler[MatplotlibChartMessageEvent]] = None
37
78
  """
38
- Whether to display chart in original size.
39
-
40
- Set to `False` to display a chart that fits configured bounds.
79
+ The event is triggered on figure message update.
41
80
  """
42
81
 
43
- transparent: bool = False
82
+ on_toolbar_buttons_update: Optional[
83
+ ft.EventHandler[MatplotlibChartToolbarButtonsUpdateEvent]
84
+ ] = None
44
85
  """
45
- Whether to remove the background from the chart.
86
+ Triggers when toolbar buttons status is updated.
46
87
  """
47
88
 
48
- def init(self):
49
- self.alignment = ft.Alignment.CENTER
50
- self.__img = ft.Image(fit=ft.BoxFit.FILL)
51
- self.content = self.__img
52
-
53
- def before_update(self):
54
- super().before_update()
55
- if self.figure is not None:
56
- s = io.StringIO()
57
- self.figure.savefig(s, format="svg", transparent=self.transparent)
58
- svg = s.getvalue()
59
-
60
- if not self.original_size:
61
- root = ET.fromstring(svg)
62
- w = float(re.findall(r"\d+", root.attrib["width"])[0])
63
- h = float(re.findall(r"\d+", root.attrib["height"])[0])
64
- self.__img.aspect_ratio = w / h
65
- self.__img.src = svg
89
+ def build(self):
90
+ self.mouse_cursor = ft.MouseCursor.WAIT
91
+ self.__started = False
92
+ self.__dpr = self.page.media.device_pixel_ratio
93
+ logger.debug(f"DPR: {self.__dpr}")
94
+ self.__image_mode = "full"
95
+
96
+ self.canvas = fc.Canvas(
97
+ # resize_interval=10,
98
+ on_resize=self.on_canvas_resize,
99
+ expand=True,
100
+ )
101
+ self.keyboard_listener = ft.KeyboardListener(
102
+ self.canvas,
103
+ autofocus=True,
104
+ on_key_down=self._on_key_down,
105
+ on_key_up=self._on_key_up,
106
+ )
107
+ self.content = self.keyboard_listener
108
+ self.on_enter = self._on_enter
109
+ self.on_hover = self._on_hover
110
+ self.on_exit = self._on_exit
111
+ self.on_pan_start = self._pan_start
112
+ self.on_pan_update = self._pan_update
113
+ self.on_pan_end = self._pan_end
114
+ self.on_right_pan_start = self._right_pan_start
115
+ self.on_right_pan_update = self._right_pan_update
116
+ self.on_right_pan_end = self._right_pan_end
117
+ self.img_count = 1
118
+ self._receive_queue = asyncio.Queue()
119
+ self._main_loop = asyncio.get_event_loop()
120
+ self._width = 0
121
+ self._height = 0
122
+ self._waiting = False
123
+
124
+ def _on_key_down(self, e):
125
+ logger.debug(f"ON KEY DOWN: {e}")
126
+
127
+ def _on_key_up(self, e):
128
+ logger.debug(f"ON KEY UP: {e}")
129
+
130
+ def _on_enter(self, e: ft.HoverEvent):
131
+ logger.debug(f"_on_enter: {e.local_position.x}, {e.local_position.y}")
132
+ self.send_message(
133
+ {
134
+ "type": "figure_enter",
135
+ "x": e.local_position.x * self.__dpr,
136
+ "y": e.local_position.y * self.__dpr,
137
+ "button": 0,
138
+ "buttons": 0,
139
+ "modifiers": [],
140
+ }
141
+ )
142
+
143
+ def _on_hover(self, e: ft.HoverEvent):
144
+ logger.debug(f"_on_hover: {e.local_position.x}, {e.local_position.y}")
145
+ self.send_message(
146
+ {
147
+ "type": "motion_notify",
148
+ "x": e.local_position.x * self.__dpr,
149
+ "y": e.local_position.y * self.__dpr,
150
+ "button": 0,
151
+ "buttons": 0,
152
+ "modifiers": [],
153
+ }
154
+ )
155
+
156
+ def _on_exit(self, e: ft.HoverEvent):
157
+ logger.debug(f"_on_exit: {e.local_position.x}, {e.local_position.y}")
158
+ self.send_message(
159
+ {
160
+ "type": "figure_leave",
161
+ "x": e.local_position.x * self.__dpr,
162
+ "y": e.local_position.y * self.__dpr,
163
+ "button": 0,
164
+ "buttons": 0,
165
+ "modifiers": [],
166
+ }
167
+ )
168
+
169
+ def _pan_start(self, e: ft.DragStartEvent):
170
+ logger.debug(f"_pan_start: {e.local_position.x}, {e.local_position.y}")
171
+ asyncio.create_task(self.keyboard_listener.focus())
172
+ self.send_message(
173
+ {
174
+ "type": "button_press",
175
+ "x": e.local_position.x * self.__dpr,
176
+ "y": e.local_position.y * self.__dpr,
177
+ "button": 0,
178
+ "buttons": 1,
179
+ "modifiers": [],
180
+ }
181
+ )
182
+
183
+ def _pan_update(self, e: ft.DragUpdateEvent):
184
+ logger.debug(f"_pan_update: {e.local_position.x}, {e.local_position.y}")
185
+ self.send_message(
186
+ {
187
+ "type": "motion_notify",
188
+ "x": e.local_position.x * self.__dpr,
189
+ "y": e.local_position.y * self.__dpr,
190
+ "button": 0,
191
+ "buttons": 1,
192
+ "modifiers": [],
193
+ }
194
+ )
195
+
196
+ def _pan_end(self, e: ft.DragEndEvent):
197
+ logger.debug(f"_pan_end: {e.local_position.x}, {e.local_position.y}")
198
+ self.send_message(
199
+ {
200
+ "type": "button_release",
201
+ "x": e.local_position.x * self.__dpr,
202
+ "y": e.local_position.y * self.__dpr,
203
+ "button": 0,
204
+ "buttons": 0,
205
+ "modifiers": [],
206
+ }
207
+ )
208
+
209
+ def _right_pan_start(self, e: ft.PointerEvent):
210
+ logger.debug(f"_pan_start: {e.local_position.x}, {e.local_position.y}")
211
+ self.send_message(
212
+ {
213
+ "type": "button_press",
214
+ "x": e.local_position.x * self.__dpr,
215
+ "y": e.local_position.y * self.__dpr,
216
+ "button": 2,
217
+ "buttons": 2,
218
+ "modifiers": [],
219
+ }
220
+ )
221
+
222
+ def _right_pan_update(self, e: ft.PointerEvent):
223
+ logger.debug(f"_pan_update: {e.local_position.x}, {e.local_position.y}")
224
+ self.send_message(
225
+ {
226
+ "type": "motion_notify",
227
+ "x": e.local_position.x * self.__dpr,
228
+ "y": e.local_position.y * self.__dpr,
229
+ "button": 0,
230
+ "buttons": 2,
231
+ "modifiers": [],
232
+ }
233
+ )
234
+
235
+ def _right_pan_end(self, e: ft.PointerEvent):
236
+ logger.debug(f"_pan_end: {e.local_position.x}, {e.local_position.y}")
237
+ self.send_message(
238
+ {
239
+ "type": "button_release",
240
+ "x": e.local_position.x * self.__dpr,
241
+ "y": e.local_position.y * self.__dpr,
242
+ "button": 2,
243
+ "buttons": 0,
244
+ "modifiers": [],
245
+ }
246
+ )
247
+
248
+ def will_unmount(self):
249
+ self.figure.canvas.manager.remove_web_socket(self)
250
+
251
+ def home(self):
252
+ logger.debug("home)")
253
+ self.send_message({"type": "toolbar_button", "name": "home"})
254
+
255
+ def back(self):
256
+ logger.debug("back()")
257
+ self.send_message({"type": "toolbar_button", "name": "back"})
258
+
259
+ def forward(self):
260
+ logger.debug("forward)")
261
+ self.send_message({"type": "toolbar_button", "name": "forward"})
262
+
263
+ def pan(self):
264
+ logger.debug("pan()")
265
+ self.send_message({"type": "toolbar_button", "name": "pan"})
266
+
267
+ def zoom(self):
268
+ logger.debug("zoom()")
269
+ self.send_message({"type": "toolbar_button", "name": "zoom"})
270
+
271
+ def download(self, format):
272
+ logger.debug(f"Download in format: {format}")
273
+ buff = BytesIO()
274
+ self.figure.savefig(buff, format=format, dpi=self.figure.dpi * self.__dpr)
275
+ return buff.getvalue()
276
+
277
+ async def _receive_loop(self):
278
+ while True:
279
+ is_binary, content = await self._receive_queue.get()
280
+ if is_binary:
281
+ logger.debug(f"receive_binary({len(content)})")
282
+ if self.__image_mode == "full":
283
+ await self.canvas.clear_capture()
284
+
285
+ self.canvas.shapes = [
286
+ fc.Image(
287
+ src_bytes=content,
288
+ x=0,
289
+ y=0,
290
+ width=self.figure.bbox.size[0] / self.__dpr,
291
+ height=self.figure.bbox.size[1] / self.__dpr,
292
+ )
293
+ ]
294
+ ft.context.disable_auto_update()
295
+ self.canvas.update()
296
+ await self.canvas.capture()
297
+ self.img_count += 1
298
+ self._waiting = False
299
+ else:
300
+ logger.debug(f"receive_json({content})")
301
+ if content["type"] == "image_mode":
302
+ self.__image_mode = content["mode"]
303
+ elif content["type"] == "cursor":
304
+ self.mouse_cursor = figure_cursors[content["cursor"]]
305
+ self.update()
306
+ elif content["type"] == "draw" and not self._waiting:
307
+ self._waiting = True
308
+ self.send_message({"type": "draw"})
309
+ elif content["type"] == "rubberband":
310
+ if len(self.canvas.shapes) == 2:
311
+ self.canvas.shapes.pop()
312
+ if (
313
+ content["x0"] != -1
314
+ and content["y0"] != -1
315
+ and content["x1"] != -1
316
+ and content["y1"] != -1
317
+ ):
318
+ x0 = content["x0"] / self.__dpr
319
+ y0 = self._height - content["y0"] / self.__dpr
320
+ x1 = content["x1"] / self.__dpr
321
+ y1 = self._height - content["y1"] / self.__dpr
322
+ self.canvas.shapes.append(
323
+ fc.Rect(
324
+ x=x0,
325
+ y=y0,
326
+ width=x1 - x0,
327
+ height=y1 - y0,
328
+ paint=ft.Paint(
329
+ stroke_width=1, style=ft.PaintingStyle.STROKE
330
+ ),
331
+ )
332
+ )
333
+ self.canvas.update()
334
+ elif content["type"] == "resize":
335
+ self.send_message({"type": "refresh"})
336
+ elif content["type"] == "message":
337
+ await self._trigger_event(
338
+ "message", {"message": content["message"]}
339
+ )
340
+ elif content["type"] == "history_buttons":
341
+ await self._trigger_event(
342
+ "toolbar_buttons_update",
343
+ {
344
+ "back_enabled": content["Back"],
345
+ "forward_enabled": content["Forward"],
346
+ },
347
+ )
348
+
349
+ def send_message(self, message):
350
+ logger.debug(f"send_message({message})")
351
+ manager = self.figure.canvas.manager
352
+ if manager is not None:
353
+ manager.handle_json(message)
354
+
355
+ def send_json(self, content):
356
+ logger.debug(f"send_json: {content}")
357
+ self._main_loop.call_soon_threadsafe(
358
+ lambda: self._receive_queue.put_nowait((False, content))
359
+ )
360
+
361
+ def send_binary(self, blob):
362
+ self._main_loop.call_soon_threadsafe(
363
+ lambda: self._receive_queue.put_nowait((True, blob))
364
+ )
365
+
366
+ async def on_canvas_resize(self, e: fc.CanvasResizeEvent):
367
+ logger.debug(f"on_canvas_resize: {e.width}, {e.height}")
368
+
369
+ if not self.__started:
370
+ self.__started = True
371
+ asyncio.create_task(self._receive_loop())
372
+ self.figure.canvas.manager.add_web_socket(self)
373
+ self.send_message({"type": "send_image_mode"})
374
+ self.send_message(
375
+ {"type": "set_device_pixel_ratio", "device_pixel_ratio": self.__dpr}
376
+ )
377
+ self.send_message({"type": "refresh"})
378
+ self._width = e.width
379
+ self._height = e.height
380
+ self.send_message(
381
+ {"type": "resize", "width": self._width, "height": self._height}
382
+ )
@@ -0,0 +1,110 @@
1
+ from dataclasses import field
2
+
3
+ import flet as ft
4
+ from matplotlib.figure import Figure
5
+
6
+ import flet_charts
7
+
8
+ _download_formats = [
9
+ "eps",
10
+ "jpeg",
11
+ "pgf",
12
+ "pdf",
13
+ "png",
14
+ "ps",
15
+ "raw",
16
+ "svg",
17
+ "tif",
18
+ "webp",
19
+ ]
20
+
21
+
22
+ @ft.control(kw_only=True, isolated=True)
23
+ class MatplotlibChartWithToolbar(ft.Column):
24
+ figure: Figure = field(metadata={"skip": True})
25
+ """
26
+ Matplotlib figure to draw - an instance of
27
+ [`matplotlib.figure.Figure`](https://matplotlib.org/stable/api/_as_gen/matplotlib.figure.Figure.html#matplotlib.figure.Figure).
28
+ """
29
+
30
+ def build(self):
31
+ self.mpl = flet_charts.MatplotlibChart(
32
+ figure=self.figure,
33
+ expand=True,
34
+ on_message=self.on_message,
35
+ on_toolbar_buttons_update=self.on_toolbar_update,
36
+ )
37
+ self.home_btn = ft.IconButton(ft.Icons.HOME, on_click=lambda: self.mpl.home())
38
+ self.back_btn = ft.IconButton(
39
+ ft.Icons.ARROW_BACK_ROUNDED, on_click=lambda: self.mpl.back()
40
+ )
41
+ self.fwd_btn = ft.IconButton(
42
+ ft.Icons.ARROW_FORWARD_ROUNDED, on_click=lambda: self.mpl.forward()
43
+ )
44
+ self.pan_btn = ft.IconButton(
45
+ ft.Icons.OPEN_WITH,
46
+ selected_icon=ft.Icons.OPEN_WITH,
47
+ selected_icon_color=ft.Colors.AMBER_800,
48
+ on_click=self.pan_click,
49
+ )
50
+ self.zoom_btn = ft.IconButton(
51
+ ft.Icons.ZOOM_IN,
52
+ selected_icon=ft.Icons.ZOOM_IN,
53
+ selected_icon_color=ft.Colors.AMBER_800,
54
+ on_click=self.zoom_click,
55
+ )
56
+ self.download_btn = ft.IconButton(
57
+ ft.Icons.DOWNLOAD, on_click=self.download_click
58
+ )
59
+ self.download_fmt = ft.Dropdown(
60
+ value="png",
61
+ options=[ft.DropdownOption(fmt) for fmt in _download_formats],
62
+ )
63
+ self.msg = ft.Text()
64
+ self.controls = [
65
+ ft.Row(
66
+ [
67
+ self.home_btn,
68
+ self.back_btn,
69
+ self.fwd_btn,
70
+ self.pan_btn,
71
+ self.zoom_btn,
72
+ self.download_btn,
73
+ self.download_fmt,
74
+ self.msg,
75
+ ]
76
+ ),
77
+ self.mpl,
78
+ ]
79
+ if not self.expand:
80
+ if not self.height:
81
+ self.height = self.figure.bbox.height
82
+ if not self.width:
83
+ self.width = self.figure.bbox.width
84
+
85
+ def on_message(self, e: flet_charts.MatplotlibChartMessageEvent):
86
+ self.msg.value = e.message
87
+ self.msg.update()
88
+
89
+ def on_toolbar_update(
90
+ self, e: flet_charts.MatplotlibChartToolbarButtonsUpdateEvent
91
+ ):
92
+ self.back_btn.disabled = not e.back_enabled
93
+ self.fwd_btn.disabled = not e.forward_enabled
94
+ self.update()
95
+
96
+ def pan_click(self):
97
+ self.mpl.pan()
98
+ self.pan_btn.selected = not self.pan_btn.selected
99
+ self.zoom_btn.selected = False
100
+
101
+ def zoom_click(self):
102
+ self.mpl.zoom()
103
+ self.pan_btn.selected = False
104
+ self.zoom_btn.selected = not self.zoom_btn.selected
105
+
106
+ async def download_click(self):
107
+ fmt = self.download_fmt.value
108
+ buffer = self.mpl.download(fmt)
109
+ title = self.figure.canvas.manager.get_window_title()
110
+ await ft.FilePicker().save_file(file_name=f"{title}.{fmt}", src_bytes=buffer)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: flet-charts
3
- Version: 0.2.0.dev524
3
+ Version: 0.2.0.dev534
4
4
  Summary: A Flet extension for creating interactive charts and graphs.
5
5
  Author-email: Flet contributors <hello@flet.dev>
6
6
  License-Expression: Apache-2.0
@@ -11,7 +11,7 @@ Project-URL: Issues, https://github.com/flet-dev/flet-charts/issues
11
11
  Requires-Python: >=3.10
12
12
  Description-Content-Type: text/markdown
13
13
  License-File: LICENSE
14
- Requires-Dist: flet>=0.70.0.dev0
14
+ Requires-Dist: flet
15
15
  Dynamic: license-file
16
16
 
17
17
  # flet-charts
@@ -1,4 +1,4 @@
1
- flet_charts/__init__.py,sha256=nDRlnDCu1302gO75mgX2dEiKXMeL_okH8GShCFfZYkg,2157
1
+ flet_charts/__init__.py,sha256=otIOAmorZ5XajhO-3wi-qz0xwAgWa-kHCeu0sDpzyzE,2443
2
2
  flet_charts/bar_chart.py,sha256=YSgwdmSoHqJOusC6fR27p-v8OBj7HqBBvxvjEn96B7U,7806
3
3
  flet_charts/bar_chart_group.py,sha256=O9-jSiCgO28mq0-DDUJznfcGLJbWvLmnGrzf9BLjH1I,702
4
4
  flet_charts/bar_chart_rod.py,sha256=66BdckFGr-YUNXNIQb4NzvGGy8HIXGCzTOfHFOZhRi8,3575
@@ -7,19 +7,21 @@ flet_charts/chart_axis.py,sha256=jKX1bxQqxW3piNmyJUQShGATwnI1sKjXtKP425iDRhg,186
7
7
  flet_charts/line_chart.py,sha256=bgKrqyzXDj_49UDB8edy8-rArhuEKDuzy8qFBb_CEYw,8144
8
8
  flet_charts/line_chart_data.py,sha256=Q9A3UlZ8zp8wpcTdqjgh0mAfO9GhlUpeWXljGY3bFrk,4162
9
9
  flet_charts/line_chart_data_point.py,sha256=3OrM19H3hDJppiGmE2CTm_K3dWf83Rr-wELPC3Ak_OA,3253
10
- flet_charts/matplotlib_chart.py,sha256=cWDqMSuUxfXYb-DjU6sp7fcHWh1DV2Ig7w62aYS6Fag,1878
10
+ flet_charts/matplotlib_chart.py,sha256=ZvKopbELoQEXhj0fGEjq4eybccpqpwCP9yL6yiaGyXE,13020
11
+ flet_charts/matplotlib_chart_with_toolbar.py,sha256=mliwIo_Yt9MgSii0_y3BHDEtPxQp79cf54n8M3WdDMQ,3407
11
12
  flet_charts/pie_chart.py,sha256=YOFJXKfgc192iu9Icp8VsTsTmbepp-hvQpM6_tPyTIE,1964
12
13
  flet_charts/pie_chart_section.py,sha256=KdUF91BYAhY63U3NxMuY9Go56Ss0w-dmT8hLdxgP-tQ,2482
13
14
  flet_charts/plotly_chart.py,sha256=ZpmO4TXVHDmeLoAXySx3iieBNPTRy36xptmGzvDP71s,1679
14
15
  flet_charts/scatter_chart.py,sha256=7NFlZNKk4FPRozMwyVKQSsgxLV9s5EyCJsomC4S9VIE,7153
15
16
  flet_charts/scatter_chart_spot.py,sha256=VcEta4HYkU_EmwbRNifQXao4o6wNNNZ81YdKRcrxN28,3663
16
17
  flet_charts/types.py,sha256=0VNeobnKFjM5F164yqH81qGJVbtewhJEGAygMWy7SCs,11121
17
- flet_charts-0.2.0.dev524.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
18
+ flet_charts/matplotlib_backends/backend_flet_agg.py,sha256=1imjpVpAexu02v96_jWlTPHhXdHMztPllTvHjnxDT78,483
19
+ flet_charts-0.2.0.dev534.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
18
20
  flutter/flet_charts/CHANGELOG.md,sha256=JbP72D9_B4ipiQh7Ezg1O6gSCUi9GA8CseA31Wg2oWw,40
19
21
  flutter/flet_charts/LICENSE,sha256=QwcOLU5TJoTeUhuIXzhdCEEDDvorGiC6-3YTOl4TecE,11356
20
22
  flutter/flet_charts/README.md,sha256=rIiq6cSepxf6Rhq2bZGK0PcMAlkz8iTfruGf2hbKFHQ,75
21
23
  flutter/flet_charts/analysis_options.yaml,sha256=tNXU6s4EJ4KmXROObwPetH5vkzRTVG4AH4gpMw85_EY,154
22
- flutter/flet_charts/pubspec.lock,sha256=yoNzzi7MSl0GcdKO9fzOJyy7xq1_TXPZPosmpmDADlI,23516
24
+ flutter/flet_charts/pubspec.lock,sha256=GYe3TrOjzPEC8z1TXlqE77F9WUugHMwiEiBMC64zpCA,23516
23
25
  flutter/flet_charts/pubspec.yaml,sha256=RB9sfjlNztvDASX0kAJGmXIaV_NamD7U_dVEhS5FMJ8,570
24
26
  flutter/flet_charts/lib/flet_charts.dart,sha256=66hr4Shizat1MIyu957NiJI_xXYOSeOJbFI489qw7ok,70
25
27
  flutter/flet_charts/lib/src/bar_chart.dart,sha256=6K_WPR4NzI_C9dor0eblESZi5hdf6PpKGD6xTml9KDI,3683
@@ -32,7 +34,7 @@ flutter/flet_charts/lib/src/utils/charts.dart,sha256=5Umt7NIzHp9UBDdIQ_8YQCxn8vQ
32
34
  flutter/flet_charts/lib/src/utils/line_chart.dart,sha256=s_9iokaUFHNipu_YVw6OSJcmD8JctWCoImrIyuxB688,8633
33
35
  flutter/flet_charts/lib/src/utils/pie_chart.dart,sha256=GbxCrhx_SXtJFH_94raOd_m_u7r37NRc6IExi-Qcumw,1850
34
36
  flutter/flet_charts/lib/src/utils/scatter_chart.dart,sha256=KqJxvpl8jIZkQw132Ab4x4nhHTyiUw8M2NExgRCXf1k,3323
35
- flet_charts-0.2.0.dev524.dist-info/METADATA,sha256=95i62GDOLre3OgoiQ9Oga48-Yjyinz8Tat9aMGOeOs8,1883
36
- flet_charts-0.2.0.dev524.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
37
- flet_charts-0.2.0.dev524.dist-info/top_level.txt,sha256=CVHmtljbPFTyfCiru5bxX1vvWL8L6rtUbV9bqqkSxFE,20
38
- flet_charts-0.2.0.dev524.dist-info/RECORD,,
37
+ flet_charts-0.2.0.dev534.dist-info/METADATA,sha256=0KIJ9m964rp8jD2ZmWMEvfmn-NbESiw-9CQPUV3A-24,1870
38
+ flet_charts-0.2.0.dev534.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
39
+ flet_charts-0.2.0.dev534.dist-info/top_level.txt,sha256=CVHmtljbPFTyfCiru5bxX1vvWL8L6rtUbV9bqqkSxFE,20
40
+ flet_charts-0.2.0.dev534.dist-info/RECORD,,
@@ -142,7 +142,7 @@ packages:
142
142
  description:
143
143
  path: "packages/flet"
144
144
  ref: main
145
- resolved-ref: cbdae3a51670e2a124bbe5883280302efffcb3e0
145
+ resolved-ref: b51db65cd3ccdc47fe4915f9b6a9413c86a4f903
146
146
  url: "https://github.com/flet-dev/flet.git"
147
147
  source: git
148
148
  version: "0.70.0"