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.

Files changed (32) hide show
  1. flet_charts/__init__.py +23 -1
  2. flet_charts/bar_chart.py +4 -5
  3. flet_charts/bar_chart_group.py +0 -1
  4. flet_charts/bar_chart_rod.py +0 -1
  5. flet_charts/candlestick_chart.py +266 -0
  6. flet_charts/candlestick_chart_spot.py +98 -0
  7. flet_charts/line_chart.py +4 -5
  8. flet_charts/line_chart_data.py +0 -1
  9. flet_charts/line_chart_data_point.py +0 -1
  10. flet_charts/matplotlib_backends/backend_flet_agg.py +16 -0
  11. flet_charts/matplotlib_chart.py +348 -31
  12. flet_charts/matplotlib_chart_with_toolbar.py +110 -0
  13. flet_charts/pie_chart.py +0 -1
  14. flet_charts/plotly_chart.py +1 -1
  15. flet_charts/scatter_chart.py +4 -5
  16. flet_charts/scatter_chart_spot.py +0 -1
  17. {flet_charts-0.2.0.dev524.dist-info → flet_charts-0.70.0.dev6293.dist-info}/METADATA +19 -11
  18. flet_charts-0.70.0.dev6293.dist-info/RECORD +42 -0
  19. flutter/flet_charts/CHANGELOG.md +1 -1
  20. flutter/flet_charts/LICENSE +1 -1
  21. flutter/flet_charts/analysis_options.yaml +1 -1
  22. flutter/flet_charts/lib/src/candlestick_chart.dart +136 -0
  23. flutter/flet_charts/lib/src/extension.dart +3 -0
  24. flutter/flet_charts/lib/src/utils/bar_chart.dart +136 -83
  25. flutter/flet_charts/lib/src/utils/candlestick_chart.dart +117 -0
  26. flutter/flet_charts/pubspec.yaml +10 -9
  27. flet_charts-0.2.0.dev524.dist-info/RECORD +0 -38
  28. flutter/flet_charts/README.md +0 -3
  29. flutter/flet_charts/pubspec.lock +0 -792
  30. {flet_charts-0.2.0.dev524.dist-info → flet_charts-0.70.0.dev6293.dist-info}/WHEEL +0 -0
  31. {flet_charts-0.2.0.dev524.dist-info → flet_charts-0.70.0.dev6293.dist-info}/licenses/LICENSE +0 -0
  32. {flet_charts-0.2.0.dev524.dist-info → flet_charts-0.70.0.dev6293.dist-info}/top_level.txt +0 -0
@@ -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
+ from matplotlib.figure import Figure
4
+
5
+ import flet as ft
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
@@ -2,7 +2,6 @@ from dataclasses import dataclass, field
2
2
  from typing import Optional
3
3
 
4
4
  import flet as ft
5
-
6
5
  from flet_charts.pie_chart_section import PieChartSection
7
6
  from flet_charts.types import ChartEventType
8
7
 
@@ -29,7 +29,7 @@ class PlotlyChart(ft.Container):
29
29
  figure: Figure = field(metadata={"skip": True})
30
30
  """
31
31
  Plotly figure to draw.
32
-
32
+
33
33
  The value is an instance of [`plotly.graph_objects.Figure`](https://plotly.com/python-api-reference/generated/plotly.graph_objects.Figure.html).
34
34
  """
35
35
 
@@ -2,7 +2,6 @@ from dataclasses import dataclass, field
2
2
  from typing import Any, Optional
3
3
 
4
4
  import flet as ft
5
-
6
5
  from flet_charts.chart_axis import ChartAxis
7
6
  from flet_charts.scatter_chart_spot import ScatterChartSpot
8
7
  from flet_charts.types import ChartEventType, ChartGridLines, HorizontalAlignment
@@ -173,22 +172,22 @@ class ScatterChart(ft.LayoutControl):
173
172
  Controls drawing of chart's vertical lines.
174
173
  """
175
174
 
176
- left_axis: ChartAxis = field(default_factory=lambda: ChartAxis())
175
+ left_axis: Optional[ChartAxis] = None
177
176
  """
178
177
  Configures the appearance of the left axis, its title and labels.
179
178
  """
180
179
 
181
- top_axis: ChartAxis = field(default_factory=lambda: ChartAxis())
180
+ top_axis: Optional[ChartAxis] = None
182
181
  """
183
182
  Configures the appearance of the top axis, its title and labels.
184
183
  """
185
184
 
186
- right_axis: ChartAxis = field(default_factory=lambda: ChartAxis())
185
+ right_axis: Optional[ChartAxis] = None
187
186
  """
188
187
  Configures the appearance of the right axis, its title and labels.
189
188
  """
190
189
 
191
- bottom_axis: ChartAxis = field(default_factory=lambda: ChartAxis())
190
+ bottom_axis: Optional[ChartAxis] = None
192
191
  """
193
192
  Configures the appearance of the bottom axis, its title and labels.
194
193
  """
@@ -2,7 +2,6 @@ from dataclasses import dataclass, field
2
2
  from typing import Any, Optional, Union
3
3
 
4
4
  import flet as ft
5
-
6
5
  from flet_charts.types import ChartDataPointTooltip, ChartPointShape
7
6
 
8
7
  __all__ = ["ScatterChartSpot", "ScatterChartSpotTooltip"]
@@ -1,24 +1,24 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: flet-charts
3
- Version: 0.2.0.dev524
4
- Summary: A Flet extension for creating interactive charts and graphs.
3
+ Version: 0.70.0.dev6293
4
+ Summary: Interactive chart controls for Flet apps.
5
5
  Author-email: Flet contributors <hello@flet.dev>
6
6
  License-Expression: Apache-2.0
7
7
  Project-URL: Homepage, https://flet.dev
8
- Project-URL: Documentation, https://flet-dev.github.io/flet-charts
9
- Project-URL: Repository, https://github.com/flet-dev/flet-charts
10
- Project-URL: Issues, https://github.com/flet-dev/flet-charts/issues
8
+ Project-URL: Documentation, https://docs.flet.dev/charts
9
+ Project-URL: Repository, https://github.com/flet-dev/flet/tree/main/sdk/python/packages/flet-charts
10
+ Project-URL: Issues, https://github.com/flet-dev/flet/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==0.70.0.dev6293
15
15
  Dynamic: license-file
16
16
 
17
17
  # flet-charts
18
18
 
19
19
  [![pypi](https://img.shields.io/pypi/v/flet-charts.svg)](https://pypi.python.org/pypi/flet-charts)
20
20
  [![downloads](https://static.pepy.tech/badge/flet-charts/month)](https://pepy.tech/project/flet-charts)
21
- [![license](https://img.shields.io/github/license/flet-dev/flet-charts.svg)](https://github.com/flet-dev/flet-charts/blob/main/LICENSE)
21
+ [![license](https://img.shields.io/github/license/flet-dev/flet.svg)](https://github.com/flet-dev/flet/blob/main/sdk/python/packages/flet-charts/LICENSE)
22
22
 
23
23
  A [Flet](https://flet.dev) extension for creating interactive charts and graphs.
24
24
 
@@ -26,12 +26,10 @@ 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-charts.docs.flet.dev/).
29
+ Detailed documentation to this package can be found [here](https://docs.flet.dev/charts/).
30
30
 
31
31
  ## Platform Support
32
32
 
33
- This package supports the following platforms:
34
-
35
33
  | Platform | Windows | macOS | Linux | iOS | Android | Web |
36
34
  |----------|---------|-------|-------|-----|---------|-----|
37
35
  | Supported| ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
@@ -55,4 +53,14 @@ To install the `flet-charts` package and add it to your project dependencies:
55
53
 
56
54
  ### Examples
57
55
 
58
- For examples, see [these](./examples).
56
+ For examples, see [these](https://github.com/flet-dev/flet/tree/main/sdk/python/examples/controls/charts).
57
+
58
+ ### Available charts
59
+
60
+ - `BarChart`
61
+ - `CandlestickChart`
62
+ - `LineChart`
63
+ - `MatplotlibChart`
64
+ - `PieChart`
65
+ - `PlotlyChart`
66
+ - `ScatterChart`