flet-charts 0.2.0.dev506__tar.gz → 0.2.0.dev534__tar.gz
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.
- {flet_charts-0.2.0.dev506/src/flet_charts.egg-info → flet_charts-0.2.0.dev534}/PKG-INFO +6 -16
- {flet_charts-0.2.0.dev506 → flet_charts-0.2.0.dev534}/README.md +4 -14
- {flet_charts-0.2.0.dev506 → flet_charts-0.2.0.dev534}/pyproject.toml +3 -2
- {flet_charts-0.2.0.dev506 → flet_charts-0.2.0.dev534}/src/flet_charts/__init__.py +9 -1
- {flet_charts-0.2.0.dev506 → flet_charts-0.2.0.dev534}/src/flet_charts/bar_chart.py +1 -3
- {flet_charts-0.2.0.dev506 → flet_charts-0.2.0.dev534}/src/flet_charts/line_chart.py +1 -3
- flet_charts-0.2.0.dev534/src/flet_charts/matplotlib_backends/backend_flet_agg.py +16 -0
- flet_charts-0.2.0.dev534/src/flet_charts/matplotlib_chart.py +382 -0
- flet_charts-0.2.0.dev534/src/flet_charts/matplotlib_chart_with_toolbar.py +110 -0
- {flet_charts-0.2.0.dev506 → flet_charts-0.2.0.dev534}/src/flet_charts/pie_chart.py +1 -3
- {flet_charts-0.2.0.dev506 → flet_charts-0.2.0.dev534}/src/flet_charts/plotly_chart.py +3 -2
- {flet_charts-0.2.0.dev506 → flet_charts-0.2.0.dev534}/src/flet_charts/scatter_chart.py +1 -1
- {flet_charts-0.2.0.dev506 → flet_charts-0.2.0.dev534/src/flet_charts.egg-info}/PKG-INFO +6 -16
- {flet_charts-0.2.0.dev506 → flet_charts-0.2.0.dev534}/src/flet_charts.egg-info/SOURCES.txt +2 -0
- flet_charts-0.2.0.dev534/src/flet_charts.egg-info/requires.txt +1 -0
- {flet_charts-0.2.0.dev506 → flet_charts-0.2.0.dev534}/src/flutter/flet_charts/pubspec.lock +3 -3
- flet_charts-0.2.0.dev506/src/flet_charts/matplotlib_chart.py +0 -65
- flet_charts-0.2.0.dev506/src/flet_charts.egg-info/requires.txt +0 -1
- {flet_charts-0.2.0.dev506 → flet_charts-0.2.0.dev534}/LICENSE +0 -0
- {flet_charts-0.2.0.dev506 → flet_charts-0.2.0.dev534}/setup.cfg +0 -0
- {flet_charts-0.2.0.dev506 → flet_charts-0.2.0.dev534}/src/flet_charts/bar_chart_group.py +0 -0
- {flet_charts-0.2.0.dev506 → flet_charts-0.2.0.dev534}/src/flet_charts/bar_chart_rod.py +0 -0
- {flet_charts-0.2.0.dev506 → flet_charts-0.2.0.dev534}/src/flet_charts/bar_chart_rod_stack_item.py +0 -0
- {flet_charts-0.2.0.dev506 → flet_charts-0.2.0.dev534}/src/flet_charts/chart_axis.py +0 -0
- {flet_charts-0.2.0.dev506 → flet_charts-0.2.0.dev534}/src/flet_charts/line_chart_data.py +0 -0
- {flet_charts-0.2.0.dev506 → flet_charts-0.2.0.dev534}/src/flet_charts/line_chart_data_point.py +0 -0
- {flet_charts-0.2.0.dev506 → flet_charts-0.2.0.dev534}/src/flet_charts/pie_chart_section.py +0 -0
- {flet_charts-0.2.0.dev506 → flet_charts-0.2.0.dev534}/src/flet_charts/scatter_chart_spot.py +0 -0
- {flet_charts-0.2.0.dev506 → flet_charts-0.2.0.dev534}/src/flet_charts/types.py +0 -0
- {flet_charts-0.2.0.dev506 → flet_charts-0.2.0.dev534}/src/flet_charts.egg-info/dependency_links.txt +0 -0
- {flet_charts-0.2.0.dev506 → flet_charts-0.2.0.dev534}/src/flet_charts.egg-info/top_level.txt +0 -0
- {flet_charts-0.2.0.dev506 → flet_charts-0.2.0.dev534}/src/flutter/flet_charts/CHANGELOG.md +0 -0
- {flet_charts-0.2.0.dev506 → flet_charts-0.2.0.dev534}/src/flutter/flet_charts/LICENSE +0 -0
- {flet_charts-0.2.0.dev506 → flet_charts-0.2.0.dev534}/src/flutter/flet_charts/README.md +0 -0
- {flet_charts-0.2.0.dev506 → flet_charts-0.2.0.dev534}/src/flutter/flet_charts/analysis_options.yaml +0 -0
- {flet_charts-0.2.0.dev506 → flet_charts-0.2.0.dev534}/src/flutter/flet_charts/lib/flet_charts.dart +0 -0
- {flet_charts-0.2.0.dev506 → flet_charts-0.2.0.dev534}/src/flutter/flet_charts/lib/src/bar_chart.dart +0 -0
- {flet_charts-0.2.0.dev506 → flet_charts-0.2.0.dev534}/src/flutter/flet_charts/lib/src/extension.dart +0 -0
- {flet_charts-0.2.0.dev506 → flet_charts-0.2.0.dev534}/src/flutter/flet_charts/lib/src/line_chart.dart +0 -0
- {flet_charts-0.2.0.dev506 → flet_charts-0.2.0.dev534}/src/flutter/flet_charts/lib/src/pie_chart.dart +0 -0
- {flet_charts-0.2.0.dev506 → flet_charts-0.2.0.dev534}/src/flutter/flet_charts/lib/src/scatter_chart.dart +0 -0
- {flet_charts-0.2.0.dev506 → flet_charts-0.2.0.dev534}/src/flutter/flet_charts/lib/src/utils/bar_chart.dart +0 -0
- {flet_charts-0.2.0.dev506 → flet_charts-0.2.0.dev534}/src/flutter/flet_charts/lib/src/utils/charts.dart +0 -0
- {flet_charts-0.2.0.dev506 → flet_charts-0.2.0.dev534}/src/flutter/flet_charts/lib/src/utils/line_chart.dart +0 -0
- {flet_charts-0.2.0.dev506 → flet_charts-0.2.0.dev534}/src/flutter/flet_charts/lib/src/utils/pie_chart.dart +0 -0
- {flet_charts-0.2.0.dev506 → flet_charts-0.2.0.dev534}/src/flutter/flet_charts/lib/src/utils/scatter_chart.dart +0 -0
- {flet_charts-0.2.0.dev506 → flet_charts-0.2.0.dev534}/src/flutter/flet_charts/pubspec.yaml +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: flet-charts
|
|
3
|
-
Version: 0.2.0.
|
|
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
|
|
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-
|
|
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 |
|
|
36
|
-
|
|
37
|
-
|
|
|
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).
|
|
@@ -10,20 +10,15 @@ It is based on the [fl_chart](https://pub.dev/packages/fl_chart) Flutter package
|
|
|
10
10
|
|
|
11
11
|
## Documentation
|
|
12
12
|
|
|
13
|
-
Detailed documentation to this package can be found [here](https://flet-
|
|
13
|
+
Detailed documentation to this package can be found [here](https://flet-charts.docs.flet.dev/).
|
|
14
14
|
|
|
15
15
|
## Platform Support
|
|
16
16
|
|
|
17
17
|
This package supports the following platforms:
|
|
18
18
|
|
|
19
|
-
| Platform |
|
|
20
|
-
|
|
21
|
-
|
|
|
22
|
-
| macOS | ✅ |
|
|
23
|
-
| Linux | ✅ |
|
|
24
|
-
| iOS | ✅ |
|
|
25
|
-
| Android | ✅ |
|
|
26
|
-
| Web | ✅ |
|
|
19
|
+
| Platform | Windows | macOS | Linux | iOS | Android | Web |
|
|
20
|
+
|----------|---------|-------|-------|-----|---------|-----|
|
|
21
|
+
| Supported| ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
|
|
27
22
|
|
|
28
23
|
## Usage
|
|
29
24
|
|
|
@@ -42,11 +37,6 @@ To install the `flet-charts` package and add it to your project dependencies:
|
|
|
42
37
|
```
|
|
43
38
|
After this, you will have to manually add this package to your `requirements.txt` or `pyproject.toml`.
|
|
44
39
|
|
|
45
|
-
- Using `poetry`:
|
|
46
|
-
```bash
|
|
47
|
-
poetry add flet-charts
|
|
48
|
-
```
|
|
49
|
-
|
|
50
40
|
### Examples
|
|
51
41
|
|
|
52
42
|
For examples, see [these](./examples).
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "flet-charts"
|
|
3
|
-
version = "0.2.0.
|
|
3
|
+
version = "0.2.0.dev534"
|
|
4
4
|
description = "A Flet extension for creating interactive charts and graphs."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
authors = [{ name = "Flet contributors", email = "hello@flet.dev" }]
|
|
7
7
|
license = "Apache-2.0"
|
|
8
8
|
requires-python = ">=3.10"
|
|
9
9
|
dependencies = [
|
|
10
|
-
"flet
|
|
10
|
+
"flet",
|
|
11
11
|
]
|
|
12
12
|
|
|
13
13
|
[project.urls]
|
|
@@ -53,6 +53,7 @@ docs = [
|
|
|
53
53
|
"pydocstyle >=6.3.0",
|
|
54
54
|
"linkcheckmd >=1.4.0",
|
|
55
55
|
"mkdocs-external-images",
|
|
56
|
+
"mkdocs-macros-plugin>=1.4.0",
|
|
56
57
|
{ include-group = 'docs-coverage' },
|
|
57
58
|
]
|
|
58
59
|
all = [
|
|
@@ -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
|
|
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
|
]
|
|
@@ -164,11 +164,9 @@ class BarChartEvent(ft.Event["BarChart"]):
|
|
|
164
164
|
|
|
165
165
|
|
|
166
166
|
@ft.control("BarChart")
|
|
167
|
-
class BarChart(ft.
|
|
167
|
+
class BarChart(ft.LayoutControl):
|
|
168
168
|
"""
|
|
169
169
|
Draws a bar chart.
|
|
170
|
-
|
|
171
|
-

|
|
172
170
|
"""
|
|
173
171
|
|
|
174
172
|
groups: list[BarChartGroup] = field(default_factory=list)
|
|
@@ -165,11 +165,9 @@ class LineChartTooltip:
|
|
|
165
165
|
|
|
166
166
|
|
|
167
167
|
@ft.control("LineChart")
|
|
168
|
-
class LineChart(ft.
|
|
168
|
+
class LineChart(ft.LayoutControl):
|
|
169
169
|
"""
|
|
170
170
|
Draws a line chart.
|
|
171
|
-
|
|
172
|
-

|
|
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
|
|
@@ -0,0 +1,382 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
import logging
|
|
3
|
+
from dataclasses import dataclass, field
|
|
4
|
+
from io import BytesIO
|
|
5
|
+
from typing import Optional
|
|
6
|
+
|
|
7
|
+
import flet as ft
|
|
8
|
+
import flet.canvas as fc
|
|
9
|
+
|
|
10
|
+
try:
|
|
11
|
+
import matplotlib
|
|
12
|
+
from matplotlib.figure import Figure
|
|
13
|
+
except ImportError as e:
|
|
14
|
+
raise Exception(
|
|
15
|
+
'Install "matplotlib" Python package to use MatplotlibChart control.'
|
|
16
|
+
) from e
|
|
17
|
+
|
|
18
|
+
__all__ = [
|
|
19
|
+
"MatplotlibChart",
|
|
20
|
+
"MatplotlibChartMessageEvent",
|
|
21
|
+
"MatplotlibChartToolbarButtonsUpdateEvent",
|
|
22
|
+
]
|
|
23
|
+
|
|
24
|
+
logger = logging.getLogger("flet-charts.matplotlib")
|
|
25
|
+
|
|
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):
|
|
61
|
+
"""
|
|
62
|
+
Displays a [Matplotlib](https://matplotlib.org/) chart.
|
|
63
|
+
|
|
64
|
+
Warning:
|
|
65
|
+
This control requires the [`matplotlib`](https://matplotlib.org/)
|
|
66
|
+
Python package to be installed.
|
|
67
|
+
|
|
68
|
+
See this [installation guide](index.md#installation) for more information.
|
|
69
|
+
"""
|
|
70
|
+
|
|
71
|
+
figure: Figure = field(metadata={"skip": True})
|
|
72
|
+
"""
|
|
73
|
+
Matplotlib figure to draw - an instance of
|
|
74
|
+
[`matplotlib.figure.Figure`](https://matplotlib.org/stable/api/_as_gen/matplotlib.figure.Figure.html#matplotlib.figure.Figure).
|
|
75
|
+
"""
|
|
76
|
+
|
|
77
|
+
on_message: Optional[ft.EventHandler[MatplotlibChartMessageEvent]] = None
|
|
78
|
+
"""
|
|
79
|
+
The event is triggered on figure message update.
|
|
80
|
+
"""
|
|
81
|
+
|
|
82
|
+
on_toolbar_buttons_update: Optional[
|
|
83
|
+
ft.EventHandler[MatplotlibChartToolbarButtonsUpdateEvent]
|
|
84
|
+
] = None
|
|
85
|
+
"""
|
|
86
|
+
Triggers when toolbar buttons status is updated.
|
|
87
|
+
"""
|
|
88
|
+
|
|
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)
|
|
@@ -33,11 +33,9 @@ class PieChartEvent(ft.Event["PieChart"]):
|
|
|
33
33
|
|
|
34
34
|
|
|
35
35
|
@ft.control("PieChart")
|
|
36
|
-
class PieChart(ft.
|
|
36
|
+
class PieChart(ft.LayoutControl):
|
|
37
37
|
"""
|
|
38
38
|
A pie chart control displaying multiple sections as slices of a circle.
|
|
39
|
-
|
|
40
|
-

|
|
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
|
-
|
|
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
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: flet-charts
|
|
3
|
-
Version: 0.2.0.
|
|
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
|
|
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-
|
|
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 |
|
|
36
|
-
|
|
37
|
-
|
|
|
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).
|
|
@@ -11,6 +11,7 @@ src/flet_charts/line_chart.py
|
|
|
11
11
|
src/flet_charts/line_chart_data.py
|
|
12
12
|
src/flet_charts/line_chart_data_point.py
|
|
13
13
|
src/flet_charts/matplotlib_chart.py
|
|
14
|
+
src/flet_charts/matplotlib_chart_with_toolbar.py
|
|
14
15
|
src/flet_charts/pie_chart.py
|
|
15
16
|
src/flet_charts/pie_chart_section.py
|
|
16
17
|
src/flet_charts/plotly_chart.py
|
|
@@ -22,6 +23,7 @@ src/flet_charts.egg-info/SOURCES.txt
|
|
|
22
23
|
src/flet_charts.egg-info/dependency_links.txt
|
|
23
24
|
src/flet_charts.egg-info/requires.txt
|
|
24
25
|
src/flet_charts.egg-info/top_level.txt
|
|
26
|
+
src/flet_charts/matplotlib_backends/backend_flet_agg.py
|
|
25
27
|
src/flutter/flet_charts/CHANGELOG.md
|
|
26
28
|
src/flutter/flet_charts/LICENSE
|
|
27
29
|
src/flutter/flet_charts/README.md
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
flet
|
|
@@ -142,7 +142,7 @@ packages:
|
|
|
142
142
|
description:
|
|
143
143
|
path: "packages/flet"
|
|
144
144
|
ref: main
|
|
145
|
-
resolved-ref:
|
|
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:
|
|
509
|
+
sha256: bd14436108211b0d4ee5038689a56d4ae3620fd72fd6036e113bf1345bc74d9e
|
|
510
510
|
url: "https://pub.dev"
|
|
511
511
|
source: hosted
|
|
512
|
-
version: "2.4.
|
|
512
|
+
version: "2.4.13"
|
|
513
513
|
shared_preferences_foundation:
|
|
514
514
|
dependency: transitive
|
|
515
515
|
description:
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
import io
|
|
2
|
-
import re
|
|
3
|
-
import xml.etree.ElementTree as ET
|
|
4
|
-
from dataclasses import field
|
|
5
|
-
|
|
6
|
-
import flet as ft
|
|
7
|
-
|
|
8
|
-
try:
|
|
9
|
-
from matplotlib.figure import Figure
|
|
10
|
-
except ImportError as e:
|
|
11
|
-
raise Exception(
|
|
12
|
-
'Install "matplotlib" Python package to use MatplotlibChart control.'
|
|
13
|
-
) from e
|
|
14
|
-
|
|
15
|
-
__all__ = ["MatplotlibChart"]
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
@ft.control(kw_only=True)
|
|
19
|
-
class MatplotlibChart(ft.Container):
|
|
20
|
-
"""
|
|
21
|
-
Displays a [Matplotlib](https://matplotlib.org/) chart.
|
|
22
|
-
|
|
23
|
-
Warning:
|
|
24
|
-
This control requires the [`matplotlib`](https://matplotlib.org/)
|
|
25
|
-
Python package to be installed.
|
|
26
|
-
|
|
27
|
-
See this [installation guide](index.md#installation) for more information.
|
|
28
|
-
"""
|
|
29
|
-
|
|
30
|
-
figure: Figure = field(metadata={"skip": True})
|
|
31
|
-
"""
|
|
32
|
-
Matplotlib figure to draw - an instance of
|
|
33
|
-
[`matplotlib.figure.Figure`](https://matplotlib.org/stable/api/_as_gen/matplotlib.figure.Figure.html#matplotlib.figure.Figure).
|
|
34
|
-
"""
|
|
35
|
-
|
|
36
|
-
original_size: bool = False
|
|
37
|
-
"""
|
|
38
|
-
Whether to display chart in original size.
|
|
39
|
-
|
|
40
|
-
Set to `False` to display a chart that fits configured bounds.
|
|
41
|
-
"""
|
|
42
|
-
|
|
43
|
-
transparent: bool = False
|
|
44
|
-
"""
|
|
45
|
-
Whether to remove the background from the chart.
|
|
46
|
-
"""
|
|
47
|
-
|
|
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
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
flet>=0.70.0.dev0
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{flet_charts-0.2.0.dev506 → flet_charts-0.2.0.dev534}/src/flet_charts/bar_chart_rod_stack_item.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{flet_charts-0.2.0.dev506 → flet_charts-0.2.0.dev534}/src/flet_charts/line_chart_data_point.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{flet_charts-0.2.0.dev506 → flet_charts-0.2.0.dev534}/src/flet_charts.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{flet_charts-0.2.0.dev506 → flet_charts-0.2.0.dev534}/src/flet_charts.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{flet_charts-0.2.0.dev506 → flet_charts-0.2.0.dev534}/src/flutter/flet_charts/analysis_options.yaml
RENAMED
|
File without changes
|
{flet_charts-0.2.0.dev506 → flet_charts-0.2.0.dev534}/src/flutter/flet_charts/lib/flet_charts.dart
RENAMED
|
File without changes
|
{flet_charts-0.2.0.dev506 → flet_charts-0.2.0.dev534}/src/flutter/flet_charts/lib/src/bar_chart.dart
RENAMED
|
File without changes
|
{flet_charts-0.2.0.dev506 → flet_charts-0.2.0.dev534}/src/flutter/flet_charts/lib/src/extension.dart
RENAMED
|
File without changes
|
|
File without changes
|
{flet_charts-0.2.0.dev506 → flet_charts-0.2.0.dev534}/src/flutter/flet_charts/lib/src/pie_chart.dart
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|