Skip to content

Commit 395b42b

Browse files
committed
Refactor chart components and update tests
Added 'isolated=True' to chart controls for better encapsulation. Replaced print statements with logger.debug for improved logging. Refactored test files to use MatplotlibChartWithToolbar, simplifying toolbar and event handling logic, and added a new 3D chart test.
1 parent b749ee6 commit 395b42b

File tree

6 files changed

+59
-213
lines changed

6 files changed

+59
-213
lines changed

src/flet_charts/matplotlib_chart.py

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ class MatplotlibChartToolbarButtonsUpdateEvent(ft.Event["MatplotlibChart"]):
5353
"""
5454

5555

56-
@ft.control(kw_only=True)
56+
@ft.control(kw_only=True, isolated=True)
5757
class MatplotlibChart(ft.GestureDetector):
5858
"""
5959
Displays a [Matplotlib](https://matplotlib.org/) chart.
@@ -84,8 +84,6 @@ class MatplotlibChart(ft.GestureDetector):
8484
"""
8585

8686
def build(self):
87-
# self.on_resize = self.on_canvas_resize
88-
# self.shapes = [fc.Line(x1=0, y1=0, x2=50, y2=50)]
8987
self.mouse_cursor = ft.MouseCursor.WAIT
9088
self.__started = False
9189
self.__dpr = self.page.media.device_pixel_ratio
@@ -120,9 +118,6 @@ def build(self):
120118
self._height = 0
121119
self._waiting = False
122120

123-
# def before_update(self):
124-
# super().before_update()
125-
126121
def _on_key_down(self, e):
127122
logger.debug(f"ON KEY DOWN: {e}")
128123

@@ -355,7 +350,7 @@ def send_message(self, message):
355350
manager.handle_json(message)
356351

357352
def send_json(self, content):
358-
print(f"send_json: {content}")
353+
logger.debug(f"send_json: {content}")
359354
self._main_loop.call_soon_threadsafe(
360355
lambda: self._receive_queue.put_nowait((False, content))
361356
)

src/flet_charts/matplotlib_chart_with_toolbar.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
]
2020

2121

22-
@ft.control(kw_only=True)
22+
@ft.control(kw_only=True, isolated=True)
2323
class MatplotlibChartWithToolbar(ft.Column):
2424
figure: Figure = field(metadata={"skip": True})
2525
"""
@@ -83,14 +83,15 @@ def build(self):
8383
self.width = self.figure.bbox.width
8484

8585
def on_message(self, e: flet_charts.MatplotlibChartMessageEvent):
86-
print(f"on_message: {e.message}")
8786
self.msg.value = e.message
87+
self.msg.update()
8888

8989
def on_toolbar_update(
9090
self, e: flet_charts.MatplotlibChartToolbarButtonsUpdateEvent
9191
):
9292
self.back_btn.disabled = not e.back_enabled
9393
self.fwd_btn.disabled = not e.forward_enabled
94+
self.update()
9495

9596
def pan_click(self):
9697
self.mpl.pan()

tests/mpl_v2_3d.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import logging
2+
3+
import flet as ft
4+
import matplotlib
5+
import matplotlib.pyplot as plt
6+
import numpy as np
7+
8+
import flet_charts
9+
10+
matplotlib.use("module://flet_charts.matplotlib_backends.backend_flet_agg")
11+
12+
logging.basicConfig(level=logging.INFO)
13+
14+
15+
def main(page: ft.Page):
16+
plt.style.use("_mpl-gallery")
17+
18+
# Make data for a double helix
19+
n = 50
20+
theta = np.linspace(0, 2 * np.pi, n)
21+
x1 = np.cos(theta)
22+
y1 = np.sin(theta)
23+
z1 = np.linspace(0, 1, n)
24+
x2 = np.cos(theta + np.pi)
25+
y2 = np.sin(theta + np.pi)
26+
z2 = z1
27+
28+
# Plot
29+
fig, ax = plt.subplots(subplot_kw={"projection": "3d"})
30+
ax.fill_between(x1, y1, z1, x2, y2, z2, alpha=0.5)
31+
ax.plot(x1, y1, z1, linewidth=2, color="C0")
32+
ax.plot(x2, y2, z2, linewidth=2, color="C0")
33+
34+
ax.set(xticklabels=[], yticklabels=[], zticklabels=[])
35+
36+
page.add(flet_charts.MatplotlibChartWithToolbar(figure=fig, expand=True))
37+
38+
39+
ft.run(main)

tests/mpl_v2_animate.py

Lines changed: 1 addition & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -53,88 +53,7 @@ def update_lines(num, walks, lines):
5353
fig, update_lines, num_steps, fargs=(walks, lines), interval=100
5454
)
5555

56-
plt.show()
57-
58-
download_formats = [
59-
"eps",
60-
"jpeg",
61-
"pgf",
62-
"pdf",
63-
"png",
64-
"ps",
65-
"raw",
66-
"svg",
67-
"tif",
68-
"webp",
69-
]
70-
71-
fp = ft.FilePicker()
72-
73-
msg = ft.Text()
74-
75-
def on_message(e: flet_charts.MatplotlibChartMessageEvent):
76-
msg.value = e.message
77-
78-
def on_toolbar_update(e: flet_charts.MatplotlibChartToolbarButtonsUpdateEvent):
79-
back_btn.disabled = not e.back_enabled
80-
fwd_btn.disabled = not e.forward_enabled
81-
82-
def pan_click():
83-
mpl.pan()
84-
pan_btn.selected = not pan_btn.selected
85-
zoom_btn.selected = False
86-
87-
def zoom_click():
88-
mpl.zoom()
89-
pan_btn.selected = False
90-
zoom_btn.selected = not zoom_btn.selected
91-
92-
async def download_click():
93-
fmt = dwnld_fmt.value
94-
buffer = mpl.download(fmt)
95-
title = fig.canvas.manager.get_window_title()
96-
await fp.save_file(file_name=f"{title}.{fmt}", src_bytes=buffer)
97-
98-
mpl = flet_charts.MatplotlibChart(
99-
figure=fig,
100-
expand=True,
101-
on_message=on_message,
102-
on_toolbar_buttons_update=on_toolbar_update,
103-
)
104-
105-
# fig1.canvas.start()
106-
page.add(
107-
ft.Row(
108-
[
109-
ft.IconButton(ft.Icons.HOME, on_click=lambda: mpl.home()),
110-
back_btn := ft.IconButton(
111-
ft.Icons.ARROW_BACK_ROUNDED, on_click=lambda: mpl.back()
112-
),
113-
fwd_btn := ft.IconButton(
114-
ft.Icons.ARROW_FORWARD_ROUNDED, on_click=lambda: mpl.forward()
115-
),
116-
pan_btn := ft.IconButton(
117-
ft.Icons.PAN_TOOL_OUTLINED,
118-
selected_icon=ft.Icons.PAN_TOOL_OUTLINED,
119-
selected_icon_color=ft.Colors.AMBER_800,
120-
on_click=pan_click,
121-
),
122-
zoom_btn := ft.IconButton(
123-
ft.Icons.ZOOM_IN,
124-
selected_icon=ft.Icons.ZOOM_IN,
125-
selected_icon_color=ft.Colors.AMBER_800,
126-
on_click=zoom_click,
127-
),
128-
ft.IconButton(ft.Icons.DOWNLOAD, on_click=download_click),
129-
dwnld_fmt := ft.Dropdown(
130-
value="png",
131-
options=[ft.DropdownOption(fmt) for fmt in download_formats],
132-
),
133-
msg,
134-
]
135-
),
136-
mpl,
137-
)
56+
page.add(flet_charts.MatplotlibChartWithToolbar(figure=fig, expand=True))
13857

13958

14059
ft.run(main)

tests/mpl_v2_basic.py

Lines changed: 10 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -13,42 +13,18 @@
1313

1414

1515
def main(page: ft.Page):
16-
# # Sample data
17-
# x = np.linspace(0, 10, 100)
18-
# y = np.sin(x)
19-
20-
# # Plot
21-
# fig = plt.figure()
22-
# print("Figure number:", fig.number)
23-
# plt.plot(x, y)
24-
# plt.title("Interactive Sine Wave")
25-
# plt.xlabel("X axis")
26-
# plt.ylabel("Y axis")
27-
# plt.grid(True)
28-
29-
# ----------------------------------------------------------
30-
31-
plt.style.use("_mpl-gallery")
32-
33-
# Make data for a double helix
34-
n = 50
35-
theta = np.linspace(0, 2 * np.pi, n)
36-
x1 = np.cos(theta)
37-
y1 = np.sin(theta)
38-
z1 = np.linspace(0, 1, n)
39-
x2 = np.cos(theta + np.pi)
40-
y2 = np.sin(theta + np.pi)
41-
z2 = z1
16+
# Sample data
17+
x = np.linspace(0, 10, 100)
18+
y = np.sin(x)
4219

4320
# Plot
44-
fig, ax = plt.subplots(subplot_kw={"projection": "3d"})
45-
ax.fill_between(x1, y1, z1, x2, y2, z2, alpha=0.5)
46-
ax.plot(x1, y1, z1, linewidth=2, color="C0")
47-
ax.plot(x2, y2, z2, linewidth=2, color="C0")
48-
49-
ax.set(xticklabels=[], yticklabels=[], zticklabels=[])
50-
51-
plt.show()
21+
fig = plt.figure()
22+
print("Figure number:", fig.number)
23+
plt.plot(x, y)
24+
plt.title("Interactive Sine Wave")
25+
plt.xlabel("X axis")
26+
plt.ylabel("Y axis")
27+
plt.grid(True)
5228

5329
page.add(flet_charts.MatplotlibChartWithToolbar(figure=fig, expand=True))
5430

tests/mpl_v2_events.py

Lines changed: 4 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -46,18 +46,13 @@ def on_press(self, event):
4646
return
4747
if event.key not in ("n", "p"):
4848
return
49-
if event.key == "n":
50-
inc = 1
51-
else:
52-
inc = -1
49+
inc = 1 if event.key == "n" else -1
5350

5451
self.lastind += inc
5552
self.lastind = np.clip(self.lastind, 0, len(xs) - 1)
5653
self.update()
5754

5855
def on_pick(self, event):
59-
print("ON PICK")
60-
6156
if event.artist != line:
6257
return True
6358

@@ -105,88 +100,9 @@ def update(self):
105100
fig.canvas.mpl_connect("pick_event", browser.on_pick)
106101
fig.canvas.mpl_connect("key_press_event", browser.on_press)
107102

108-
plt.show()
109-
110-
download_formats = [
111-
"eps",
112-
"jpeg",
113-
"pgf",
114-
"pdf",
115-
"png",
116-
"ps",
117-
"raw",
118-
"svg",
119-
"tif",
120-
"webp",
121-
]
122-
123-
fp = ft.FilePicker()
124-
125-
msg = ft.Text()
126-
127-
def on_message(e: flet_charts.MatplotlibChartMessageEvent):
128-
msg.value = e.message
129-
130-
def on_toolbar_update(e: flet_charts.MatplotlibChartToolbarButtonsUpdateEvent):
131-
back_btn.disabled = not e.back_enabled
132-
fwd_btn.disabled = not e.forward_enabled
133-
134-
def pan_click():
135-
mpl.pan()
136-
pan_btn.selected = not pan_btn.selected
137-
zoom_btn.selected = False
138-
139-
def zoom_click():
140-
mpl.zoom()
141-
pan_btn.selected = False
142-
zoom_btn.selected = not zoom_btn.selected
143-
144-
async def download_click():
145-
fmt = dwnld_fmt.value
146-
buffer = mpl.download(fmt)
147-
title = fig.canvas.manager.get_window_title()
148-
await fp.save_file(file_name=f"{title}.{fmt}", src_bytes=buffer)
149-
150-
mpl = flet_charts.MatplotlibChart(
151-
figure=fig,
152-
expand=True,
153-
on_message=on_message,
154-
on_toolbar_buttons_update=on_toolbar_update,
155-
)
156-
157-
# fig1.canvas.start()
158-
page.add(
159-
ft.Row(
160-
[
161-
ft.IconButton(ft.Icons.HOME, on_click=lambda: mpl.home()),
162-
back_btn := ft.IconButton(
163-
ft.Icons.ARROW_BACK_ROUNDED, on_click=lambda: mpl.back()
164-
),
165-
fwd_btn := ft.IconButton(
166-
ft.Icons.ARROW_FORWARD_ROUNDED, on_click=lambda: mpl.forward()
167-
),
168-
pan_btn := ft.IconButton(
169-
ft.Icons.OPEN_WITH,
170-
selected_icon=ft.Icons.OPEN_WITH,
171-
selected_icon_color=ft.Colors.AMBER_800,
172-
on_click=pan_click,
173-
),
174-
zoom_btn := ft.IconButton(
175-
ft.Icons.SEARCH,
176-
selected_icon=ft.Icons.SEARCH,
177-
selected_icon_color=ft.Colors.AMBER_800,
178-
on_click=zoom_click,
179-
),
180-
ft.IconButton(ft.Icons.DOWNLOAD, on_click=download_click),
181-
dwnld_fmt := ft.Dropdown(
182-
value="png",
183-
options=[ft.DropdownOption(fmt) for fmt in download_formats],
184-
),
185-
msg,
186-
]
187-
),
188-
mpl,
189-
)
103+
# plt.show()
104+
105+
page.add(flet_charts.MatplotlibChartWithToolbar(figure=fig, expand=True))
190106

191107

192108
ft.run(main)

0 commit comments

Comments
 (0)