flet-charts 0.2.0.dev506__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
  ]
flet_charts/bar_chart.py CHANGED
@@ -164,11 +164,9 @@ class BarChartEvent(ft.Event["BarChart"]):
164
164
 
165
165
 
166
166
  @ft.control("BarChart")
167
- class BarChart(ft.ConstrainedControl):
167
+ class BarChart(ft.LayoutControl):
168
168
  """
169
169
  Draws a bar chart.
170
-
171
- ![Overview](assets/bar-chart-diagram.svg)
172
170
  """
173
171
 
174
172
  groups: list[BarChartGroup] = field(default_factory=list)
flet_charts/line_chart.py CHANGED
@@ -165,11 +165,9 @@ class LineChartTooltip:
165
165
 
166
166
 
167
167
  @ft.control("LineChart")
168
- class LineChart(ft.ConstrainedControl):
168
+ class LineChart(ft.LayoutControl):
169
169
  """
170
170
  Draws a line chart.
171
-
172
- ![Overview](assets/line-chart-diagram.svg)
173
171
  """
174
172
 
175
173
  data_series: list[LineChartData] = field(default_factory=list)
@@ -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)
flet_charts/pie_chart.py CHANGED
@@ -33,11 +33,9 @@ class PieChartEvent(ft.Event["PieChart"]):
33
33
 
34
34
 
35
35
  @ft.control("PieChart")
36
- class PieChart(ft.ConstrainedControl):
36
+ class PieChart(ft.LayoutControl):
37
37
  """
38
38
  A pie chart control displaying multiple sections as slices of a circle.
39
-
40
- ![Overview](assets/pie-chart-diagram.svg)
41
39
  """
42
40
 
43
41
  sections: list[PieChartSection] = field(default_factory=list)
@@ -28,8 +28,9 @@ class PlotlyChart(ft.Container):
28
28
 
29
29
  figure: Figure = field(metadata={"skip": True})
30
30
  """
31
- Plotly figure to draw -
32
- an instance of [`plotly.graph_objects.Figure`](https://plotly.com/python-api-reference/generated/plotly.graph_objects.Figure.html).
31
+ Plotly figure to draw.
32
+
33
+ The value is an instance of [`plotly.graph_objects.Figure`](https://plotly.com/python-api-reference/generated/plotly.graph_objects.Figure.html).
33
34
  """
34
35
 
35
36
  original_size: bool = False
@@ -121,7 +121,7 @@ class ScatterChartEvent(ft.Event["ScatterChart"]):
121
121
 
122
122
 
123
123
  @ft.control("ScatterChart")
124
- class ScatterChart(ft.ConstrainedControl):
124
+ class ScatterChart(ft.LayoutControl):
125
125
  """
126
126
  A scatter chart control.
127
127
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: flet-charts
3
- Version: 0.2.0.dev506
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
@@ -26,20 +26,15 @@ It is based on the [fl_chart](https://pub.dev/packages/fl_chart) Flutter package
26
26
 
27
27
  ## Documentation
28
28
 
29
- Detailed documentation to this package can be found [here](https://flet-dev.github.io/flet-charts/).
29
+ Detailed documentation to this package can be found [here](https://flet-charts.docs.flet.dev/).
30
30
 
31
31
  ## Platform Support
32
32
 
33
33
  This package supports the following platforms:
34
34
 
35
- | Platform | Supported |
36
- |----------|:---------:|
37
- | Windows | |
38
- | macOS | ✅ |
39
- | Linux | ✅ |
40
- | iOS | ✅ |
41
- | Android | ✅ |
42
- | Web | ✅ |
35
+ | Platform | Windows | macOS | Linux | iOS | Android | Web |
36
+ |----------|---------|-------|-------|-----|---------|-----|
37
+ | Supported| ✅ | ✅ | ✅ | | | ✅ |
43
38
 
44
39
  ## Usage
45
40
 
@@ -58,11 +53,6 @@ To install the `flet-charts` package and add it to your project dependencies:
58
53
  ```
59
54
  After this, you will have to manually add this package to your `requirements.txt` or `pyproject.toml`.
60
55
 
61
- - Using `poetry`:
62
- ```bash
63
- poetry add flet-charts
64
- ```
65
-
66
56
  ### Examples
67
57
 
68
58
  For examples, see [these](./examples).
@@ -1,25 +1,27 @@
1
- flet_charts/__init__.py,sha256=nDRlnDCu1302gO75mgX2dEiKXMeL_okH8GShCFfZYkg,2157
2
- flet_charts/bar_chart.py,sha256=SB4QDcHautFPvQoz-8QQjlQGVRcbA215m-eYbZb46go,7858
1
+ flet_charts/__init__.py,sha256=otIOAmorZ5XajhO-3wi-qz0xwAgWa-kHCeu0sDpzyzE,2443
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
5
5
  flet_charts/bar_chart_rod_stack_item.py,sha256=XPLRpHdScmdde2UAau47OLSSL-AuQUbLpT1g7pNS9kI,623
6
6
  flet_charts/chart_axis.py,sha256=jKX1bxQqxW3piNmyJUQShGATwnI1sKjXtKP425iDRhg,1869
7
- flet_charts/line_chart.py,sha256=v7bcCFwYKIGwRCopQG4piWLY5mXn1Qu0Y-ozcbACL-g,8197
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
11
- flet_charts/pie_chart.py,sha256=z7S3jzlndxMzJtevVMohakPAV8CvNt_wKg_Z9d8w3ac,2016
10
+ flet_charts/matplotlib_chart.py,sha256=ZvKopbELoQEXhj0fGEjq4eybccpqpwCP9yL6yiaGyXE,13020
11
+ flet_charts/matplotlib_chart_with_toolbar.py,sha256=mliwIo_Yt9MgSii0_y3BHDEtPxQp79cf54n8M3WdDMQ,3407
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
- flet_charts/plotly_chart.py,sha256=UUR4lYhae_TeTH4juEei6QvRcdJ5dA4Xvhahpl7sOBo,1662
14
- flet_charts/scatter_chart.py,sha256=JhrC9rm2ni7Y1twLahvEVtzGHFsBPL6KyQwCPCNTZfk,7158
14
+ flet_charts/plotly_chart.py,sha256=ZpmO4TXVHDmeLoAXySx3iieBNPTRy36xptmGzvDP71s,1679
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.dev506.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=EYqDfQiLklRXzrkvtF8UXQU2BXa29EYFL_vQ6j42Oww,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.dev506.dist-info/METADATA,sha256=FOZQZ3eLncbw4YnbW3Cb4sMviPHYE7eOZqoVVM4Liys,1971
36
- flet_charts-0.2.0.dev506.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
37
- flet_charts-0.2.0.dev506.dist-info/top_level.txt,sha256=CVHmtljbPFTyfCiru5bxX1vvWL8L6rtUbV9bqqkSxFE,20
38
- flet_charts-0.2.0.dev506.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"
@@ -506,10 +506,10 @@ packages:
506
506
  dependency: transitive
507
507
  description:
508
508
  name: shared_preferences_android
509
- sha256: a2608114b1ffdcbc9c120eb71a0e207c71da56202852d4aab8a5e30a82269e74
509
+ sha256: bd14436108211b0d4ee5038689a56d4ae3620fd72fd6036e113bf1345bc74d9e
510
510
  url: "https://pub.dev"
511
511
  source: hosted
512
- version: "2.4.12"
512
+ version: "2.4.13"
513
513
  shared_preferences_foundation:
514
514
  dependency: transitive
515
515
  description: