ex4nicegui 0.7.0__py3-none-any.whl → 0.8.0__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.
Files changed (44) hide show
  1. ex4nicegui/reactive/EChartsComponent/ECharts.js +2 -3
  2. ex4nicegui/reactive/EChartsComponent/ECharts.py +2 -4
  3. ex4nicegui/reactive/__init__.py +6 -0
  4. ex4nicegui/reactive/base.py +3 -1
  5. ex4nicegui/reactive/mermaid/mermaid.py +2 -5
  6. ex4nicegui/reactive/mixins/backgroundColor.py +1 -1
  7. ex4nicegui/reactive/mixins/flexLayout.py +51 -0
  8. ex4nicegui/reactive/mixins/textColor.py +1 -1
  9. ex4nicegui/reactive/mixins/value_element.py +27 -0
  10. ex4nicegui/reactive/officials/avatar.py +86 -0
  11. ex4nicegui/reactive/officials/badge.py +102 -0
  12. ex4nicegui/reactive/officials/card.py +32 -2
  13. ex4nicegui/reactive/officials/checkbox.py +7 -12
  14. ex4nicegui/reactive/officials/chip.py +12 -3
  15. ex4nicegui/reactive/officials/circular_progress.py +7 -11
  16. ex4nicegui/reactive/officials/color_picker.py +4 -10
  17. ex4nicegui/reactive/officials/column.py +19 -11
  18. ex4nicegui/reactive/officials/date.py +4 -11
  19. ex4nicegui/reactive/officials/dialog.py +4 -11
  20. ex4nicegui/reactive/officials/echarts.py +10 -8
  21. ex4nicegui/reactive/officials/expansion.py +4 -11
  22. ex4nicegui/reactive/officials/icon.py +2 -8
  23. ex4nicegui/reactive/officials/image.py +1 -1
  24. ex4nicegui/reactive/officials/input.py +13 -14
  25. ex4nicegui/reactive/officials/knob.py +4 -13
  26. ex4nicegui/reactive/officials/label.py +6 -4
  27. ex4nicegui/reactive/officials/linear_progress.py +6 -11
  28. ex4nicegui/reactive/officials/number.py +8 -12
  29. ex4nicegui/reactive/officials/radio.py +5 -13
  30. ex4nicegui/reactive/officials/row.py +18 -11
  31. ex4nicegui/reactive/officials/select.py +2 -2
  32. ex4nicegui/reactive/officials/slider.py +4 -12
  33. ex4nicegui/reactive/officials/switch.py +5 -13
  34. ex4nicegui/reactive/officials/tab_panels.py +4 -8
  35. ex4nicegui/reactive/officials/tabs.py +4 -9
  36. ex4nicegui/reactive/officials/textarea.py +4 -10
  37. ex4nicegui/reactive/officials/toggle.py +88 -0
  38. ex4nicegui/reactive/officials/tooltip.py +1 -1
  39. ex4nicegui/reactive/systems/reactive_system.py +2 -2
  40. ex4nicegui/reactive/view_model.py +4 -4
  41. {ex4nicegui-0.7.0.dist-info → ex4nicegui-0.8.0.dist-info}/METADATA +157 -118
  42. {ex4nicegui-0.7.0.dist-info → ex4nicegui-0.8.0.dist-info}/RECORD +44 -39
  43. {ex4nicegui-0.7.0.dist-info → ex4nicegui-0.8.0.dist-info}/LICENSE +0 -0
  44. {ex4nicegui-0.7.0.dist-info → ex4nicegui-0.8.0.dist-info}/WHEEL +0 -0
@@ -2,14 +2,14 @@ from typing import Any, Callable, Optional
2
2
  from ex4nicegui.reactive.services.reactive_service import ParameterClassifier
3
3
  from ex4nicegui.utils.signals import (
4
4
  TGetterOrReadonlyRef,
5
- to_value,
6
5
  _TMaybeRef as TMaybeRef,
7
6
  )
8
7
  from nicegui import ui
9
8
  from .base import BindableUi
9
+ from ex4nicegui.reactive.mixins.value_element import ValueElementMixin
10
10
 
11
11
 
12
- class TabsBindableUi(BindableUi[ui.tabs]):
12
+ class TabsBindableUi(BindableUi[ui.tabs], ValueElementMixin[str]):
13
13
  def __init__(
14
14
  self,
15
15
  value: Optional[TMaybeRef[str]] = None,
@@ -33,12 +33,7 @@ class TabsBindableUi(BindableUi[ui.tabs]):
33
33
  return self.element.value
34
34
 
35
35
  def bind_prop(self, prop: str, value: TGetterOrReadonlyRef):
36
- if prop == "value":
37
- return self.bind_value(value)
36
+ if ValueElementMixin._bind_specified_props(self, prop, value):
37
+ return self
38
38
 
39
39
  return super().bind_prop(prop, value)
40
-
41
- def bind_value(self, value: TGetterOrReadonlyRef):
42
- @self._ui_effect
43
- def _():
44
- self.element.set_value(to_value(value))
@@ -16,9 +16,10 @@ from ex4nicegui.utils.signals import (
16
16
  from nicegui import ui
17
17
  from nicegui.events import handle_event
18
18
  from .base import BindableUi
19
+ from ex4nicegui.reactive.mixins.value_element import ValueElementMixin
19
20
 
20
21
 
21
- class TextareaBindableUi(BindableUi[ui.textarea]):
22
+ class TextareaBindableUi(BindableUi[ui.textarea], ValueElementMixin[str]):
22
23
  def __init__(
23
24
  self,
24
25
  label: Optional[TMaybeRef[str]] = None,
@@ -53,18 +54,11 @@ class TextareaBindableUi(BindableUi[ui.textarea]):
53
54
  return self.element.value
54
55
 
55
56
  def bind_prop(self, prop: str, value: TGetterOrReadonlyRef):
56
- if prop == "value":
57
- return self.bind_value(value)
57
+ if ValueElementMixin._bind_specified_props(self, prop, value):
58
+ return self
58
59
 
59
60
  return super().bind_prop(prop, value)
60
61
 
61
- def bind_value(self, value: TGetterOrReadonlyRef[str]):
62
- @self._ui_effect
63
- def _():
64
- self.element.set_value(to_value(value))
65
-
66
- return self
67
-
68
62
 
69
63
  class LazyTextareaBindableUi(TextareaBindableUi):
70
64
  def __init__(
@@ -0,0 +1,88 @@
1
+ from typing import (
2
+ Any,
3
+ Callable,
4
+ List,
5
+ Optional,
6
+ TypeVar,
7
+ Dict,
8
+ Union,
9
+ )
10
+ from ex4nicegui.reactive.services.reactive_service import ParameterClassifier
11
+ from ex4nicegui.utils.signals import (
12
+ TGetterOrReadonlyRef,
13
+ _TMaybeRef as TMaybeRef,
14
+ to_value,
15
+ to_raw,
16
+ )
17
+ from nicegui import ui
18
+ from .base import BindableUi
19
+
20
+ T = TypeVar("T")
21
+
22
+
23
+ class ToggleBindableUi(BindableUi[ui.toggle]):
24
+ def __init__(
25
+ self,
26
+ options: Union[TMaybeRef[List], TMaybeRef[Dict]],
27
+ *,
28
+ value: TMaybeRef[Any] = None,
29
+ on_change: Optional[Callable[..., Any]] = None,
30
+ clearable: TMaybeRef[bool] = False,
31
+ ) -> None:
32
+ """Toggle
33
+
34
+ This element is based on Quasar's `QBtnToggle <https://quasar.dev/vue-components/button-toggle>`_ component.
35
+
36
+ The options can be specified as a list of values, or as a dictionary mapping values to labels.
37
+ After manipulating the options, call `update()` to update the options in the UI.
38
+
39
+ :param options: a list ['value1', ...] or dictionary `{'value1':'label1', ...}` specifying the options
40
+ :param value: the initial value
41
+ :param on_change: callback to execute when selection changes
42
+ :param clearable: whether the toggle can be cleared by clicking the selected option
43
+ """
44
+ pc = ParameterClassifier(
45
+ locals(),
46
+ maybeRefs=[
47
+ "options",
48
+ "value",
49
+ "clearable",
50
+ ],
51
+ v_model=("value", "on_change"),
52
+ events=["on_change"],
53
+ )
54
+
55
+ value_kws = pc.get_values_kws()
56
+
57
+ element = ui.toggle(**value_kws)
58
+ super().__init__(element) # type: ignore
59
+
60
+ for key, value in pc.get_bindings().items():
61
+ self.bind_prop(key, value) # type: ignore
62
+
63
+ @property
64
+ def value(self):
65
+ return self.element.value
66
+
67
+ def bind_prop(self, prop: str, value: TGetterOrReadonlyRef):
68
+ if prop == "value":
69
+ return self.bind_value(value)
70
+
71
+ if prop == "options":
72
+ return self.bind_options(value)
73
+
74
+ return super().bind_prop(prop, value)
75
+
76
+ def bind_options(self, options: TGetterOrReadonlyRef):
77
+ @self._ui_signal_on(options, deep=True)
78
+ def _():
79
+ self.element.set_options(to_value(options))
80
+
81
+ return self
82
+
83
+ def bind_value(self, value: TGetterOrReadonlyRef):
84
+ @self._ui_signal_on(value, deep=True)
85
+ def _():
86
+ self.element.set_value(to_raw(to_value(value)) or None)
87
+
88
+ return self
@@ -33,7 +33,7 @@ class TooltipBindableUi(BindableUi[ui.tooltip]):
33
33
  return super().bind_prop(prop, value)
34
34
 
35
35
  def bind_text(self, text: TGetterOrReadonlyRef):
36
- @self._ui_effect
36
+ @self._ui_signal_on(text)
37
37
  def _():
38
38
  self.element.set_text(str(to_value(text)))
39
39
 
@@ -1,9 +1,9 @@
1
1
  from typing import Callable, Dict
2
- from ex4nicegui.utils.signals import to_value
2
+ from ex4nicegui.utils.signals import to_value, to_raw
3
3
 
4
4
 
5
5
  def convert_kws_ref2value(kws: Dict) -> Dict:
6
- return {key: to_value(value) for key, value in kws.items()}
6
+ return {key: to_raw(to_value(value)) for key, value in kws.items()}
7
7
 
8
8
 
9
9
  def inject_method(obj, method_name: str, new_handle: Callable):
@@ -24,7 +24,7 @@ class ViewModel(NoProxy):
24
24
 
25
25
  @see - https://github.com/CrystalWindSnake/ex4nicegui/blob/main/README.en.md#ViewModel
26
26
 
27
- @中文文档 - https://gitee.com/carson_add/ex4nicegui/tree/main/#ViewModel
27
+ @中文文档 - https://gitee.com/carson_add/ex4nicegui/tree/main/#viewmodel
28
28
 
29
29
  Example:
30
30
  .. code-block:: python
@@ -151,9 +151,9 @@ def cached_var(func: Callable[..., _T]) -> ReadonlyRef[_T]:
151
151
  class MyVm(rxui.ViewModel):
152
152
  name = rxui.var("John")
153
153
 
154
- @rxui.cached_var
155
- def uppper_name(self):
156
- return self.name.value.upper()
154
+ @rxui.cached_var
155
+ def uppper_name(self):
156
+ return self.name.value.upper()
157
157
 
158
158
  """
159
159
  setattr(func, _CACHED_VARS_FLAG, None)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ex4nicegui
3
- Version: 0.7.0
3
+ Version: 0.8.0
4
4
  Summary: Extension library based on nicegui, providing data responsive,BI functionality modules
5
5
  Home-page: https://github.com/CrystalWindSnake/ex4nicegui
6
6
  License: MIT
@@ -16,7 +16,7 @@ Classifier: Programming Language :: Python :: 3.10
16
16
  Classifier: Programming Language :: Python :: 3.11
17
17
  Classifier: Programming Language :: Python :: 3.12
18
18
  Requires-Dist: executing (>=2.0.1,<3.0.0)
19
- Requires-Dist: nicegui (>=1.4.25,<2.0.0)
19
+ Requires-Dist: nicegui (>=2.0.0,<3.0.0)
20
20
  Requires-Dist: signe (>=0.4.20,<0.5.0)
21
21
  Project-URL: Repository, https://github.com/CrystalWindSnake/ex4nicegui
22
22
  Description-Content-Type: text/markdown
@@ -32,12 +32,16 @@ Description-Content-Type: text/markdown
32
32
  - [教程](#教程)
33
33
  - [安装](#-安装)
34
34
  - [使用](#-使用)
35
- - [功能](#-功能)
35
+ - [图表](#-图表)
36
36
  - [BI 模块](#bi-模块)
37
37
 
38
38
  对 [nicegui](https://github.com/zauberzeug/nicegui) 做的扩展库。内置响应式组件,完全实现数据响应式界面编程。
39
39
 
40
40
 
41
+ ![todo-app](https://github.com/CrystalWindSnake/ex4nicegui-examples/blob/main/asset/todo-app.02.gif)
42
+
43
+ [查看更多示例](https://github.com/CrystalWindSnake/ex4nicegui-examples)
44
+
41
45
  ## 教程
42
46
  [头条文章-秒杀官方实现,python界面库,去掉90%事件代码的nicegui](https://www.toutiao.com/item/7253786340574265860/)
43
47
 
@@ -59,10 +63,10 @@ pip install ex4nicegui -U
59
63
 
60
64
  ## 🦄 使用
61
65
 
66
+ ![](./asset/sync_input.gif)
62
67
  ```python
63
68
  from nicegui import ui
64
- from ex4nicegui import ref_computed, effect, to_ref
65
- from ex4nicegui.reactive import rxui
69
+ from ex4nicegui import rxui, ref_computed, effect, to_ref
66
70
 
67
71
  # 定义响应式数据
68
72
  r_input = to_ref("")
@@ -73,127 +77,41 @@ rxui.label(r_input)
73
77
 
74
78
  ui.run()
75
79
  ```
76
- ![](./asset/sync_input.gif)
77
-
78
-
79
- ### 提供 echarts 图表组件
80
-
81
- ```python
82
- from nicegui import ui
83
- from ex4nicegui import ref_computed, effect, to_ref
84
- from ex4nicegui.reactive import rxui
85
-
86
- r_input = to_ref("")
87
-
88
- # ref_computed 创建只读响应式变量
89
- # 函数中使用任意其他响应式变量,会自动关联
90
- @ref_computed
91
- def cp_echarts_opts():
92
- return {
93
- "title": {"text": r_input.value}, #字典中使用任意响应式变量,通过 .value 获取值
94
- "xAxis": {
95
- "type": "category",
96
- "data": ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
97
- },
98
- "yAxis": {"type": "value"},
99
- "series": [
100
- {
101
- "data": [120, 200, 150, 80, 70, 110, 130],
102
- "type": "bar",
103
- "showBackground": True,
104
- "backgroundStyle": {"color": "rgba(180, 180, 180, 0.2)"},
105
- }
106
- ],
107
- }
108
-
109
- input = rxui.input("输入内容,图表标题会同步", value=r_input)
110
- # 通过响应式组件对象的 element 属性,获取原生 nicegui 组件对象
111
- input.element.classes("w-full")
112
-
113
- rxui.echarts(cp_echarts_opts)
114
-
115
- ui.run()
116
- ```
117
- ![](./asset/asyc_echarts_title.gif)
118
80
 
119
81
 
120
- ### echarts 图表鼠标事件
121
-
122
- `on` 函数参数 `event_name` 以及 `query` 使用,查看[echarts 事件中文文档](https://echarts.apache.org/handbook/zh/concepts/event/)
82
+ ---
123
83
 
84
+ ![colors](https://github.com/CrystalWindSnake/ex4nicegui-examples/blob/main/asset/colors.01.gif)
124
85
 
125
- 以下例子绑定鼠标单击事件
126
86
  ```python
127
87
  from nicegui import ui
128
- from ex4nicegui.reactive import rxui
129
-
130
- opts = {
131
- "xAxis": {"type": "value", "boundaryGap": [0, 0.01]},
132
- "yAxis": {
133
- "type": "category",
134
- "data": ["Brazil", "Indonesia", "USA", "India", "China", "World"],
135
- },
136
- "series": [
137
- {
138
- "name": "first",
139
- "type": "bar",
140
- "data": [18203, 23489, 29034, 104970, 131744, 630230],
141
- },
142
- {
143
- "name": "second",
144
- "type": "bar",
145
- "data": [19325, 23438, 31000, 121594, 134141, 681807],
146
- },
147
- ],
148
- }
149
-
150
- bar = rxui.echarts(opts)
151
-
152
- def on_click(e: rxui.echarts.EChartsMouseEventArguments):
153
- ui.notify(f"on_click:{e.seriesName}:{e.name}:{e.value}")
154
-
155
-
156
- bar.on("click", on_click)
157
- ```
88
+ from ex4nicegui import rxui, to_ref
158
89
 
90
+ ui.radio.default_props("inline")
159
91
 
160
- 以下例子只针对指定系列触发鼠标划过事件
161
- ```python
162
- from nicegui import ui
163
- from ex4nicegui.reactive import rxui
92
+ # 定义视图数据
93
+ colors = ["red", "green", "blue", "yellow", "purple", "white"]
94
+ color = to_ref("blue")
95
+ bg_color = to_ref("red")
164
96
 
165
- opts = {
166
- "xAxis": {"type": "value", "boundaryGap": [0, 0.01]},
167
- "yAxis": {
168
- "type": "category",
169
- "data": ["Brazil", "Indonesia", "USA", "India", "China", "World"],
170
- },
171
- "series": [
172
- {
173
- "name": "first",
174
- "type": "bar",
175
- "data": [18203, 23489, 29034, 104970, 131744, 630230],
176
- },
177
- {
178
- "name": "second",
179
- "type": "bar",
180
- "data": [19325, 23438, 31000, 121594, 134141, 681807],
181
- },
182
- ],
183
- }
184
97
 
185
- bar = rxui.echarts(opts)
98
+ ## 函数中通过访问 `ref` 或其他关联函数获取值,一切会自动同步更新
99
+ def bg_text():
100
+ return f"Current background color is {bg_color.value}"
186
101
 
187
- def on_first_series_mouseover(e: rxui.echarts.EChartsMouseEventArguments):
188
- ui.notify(f"on_first_series_mouseover:{e.seriesName}:{e.name}:{e.value}")
189
102
 
103
+ # 界面
190
104
 
191
- bar.on("mouseover", on_first_series_mouseover, query={"seriesName": "first"})
105
+ with ui.row(align_items="center"):
106
+ rxui.radio(colors, value=color)
107
+ ## 可以使用 lambda
108
+ rxui.label(lambda: f"Font color is {color.value}").bind_style({"color": color})
192
109
 
193
- ui.run()
110
+ with ui.row(align_items="center"):
111
+ rxui.radio(colors, value=bg_color)
112
+ ## 直接绑定函数
113
+ rxui.label(bg_text).bind_style({"background-color": bg_color})
194
114
  ```
195
- ---
196
-
197
115
 
198
116
 
199
117
  ## ViewModel
@@ -264,19 +182,18 @@ class Home(rxui.ViewModel):
264
182
  通过 `number` 组件修改年龄,一切都会自动更新。
265
183
 
266
184
  ```python
185
+ from typing import List
267
186
  from ex4nicegui import rxui, Ref
268
187
  from itertools import count
188
+ from nicegui import ui
269
189
 
270
190
  id_generator = count()
271
191
 
272
192
  class Person(rxui.ViewModel):
273
- name = rxui.var("")
274
- age = rxui.var(0)
275
-
276
- def __init__(self, name: str = "", age: int = 0):
193
+ def __init__(self, name: str, age: int):
277
194
  super().__init__()
278
- self.name.value = name
279
- self.age.value = age
195
+ self.name = rxui.var(name)
196
+ self.age = rxui.var(age)
280
197
  self.id = next(id_generator)
281
198
 
282
199
 
@@ -318,6 +235,7 @@ with ui.row():
318
235
  rxui.input(value=person.name, placeholder="名字")
319
236
  rxui.number(value=person.age, min=1, max=100, step=1, placeholder="年龄")
320
237
 
238
+ ui.run()
321
239
  ```
322
240
 
323
241
  如果你觉得 `rxui.vfor` 代码过于复杂,可以使用 `effect_refreshable` 装饰器代替。
@@ -326,7 +244,7 @@ with ui.row():
326
244
  from ex4nicegui import rxui, Ref,effect_refreshable
327
245
  ...
328
246
 
329
- # 明确指定监控 home.persons 变化,可以避免意味刷新
247
+ # 明确指定监控 home.persons 变化,可以避免意外刷新
330
248
  @effect_refreshable.on(home.persons)
331
249
  def _():
332
250
 
@@ -343,6 +261,127 @@ def _():
343
261
 
344
262
  ---
345
263
 
264
+ ## 图表
265
+
266
+ ### 提供 echarts 图表组件
267
+
268
+ ```python
269
+ from nicegui import ui
270
+ from ex4nicegui import ref_computed, effect, to_ref
271
+ from ex4nicegui.reactive import rxui
272
+
273
+ r_input = to_ref("")
274
+
275
+ # ref_computed 创建只读响应式变量
276
+ # 函数中使用任意其他响应式变量,会自动关联
277
+ @ref_computed
278
+ def cp_echarts_opts():
279
+ return {
280
+ "title": {"text": r_input.value}, #字典中使用任意响应式变量,通过 .value 获取值
281
+ "xAxis": {
282
+ "type": "category",
283
+ "data": ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
284
+ },
285
+ "yAxis": {"type": "value"},
286
+ "series": [
287
+ {
288
+ "data": [120, 200, 150, 80, 70, 110, 130],
289
+ "type": "bar",
290
+ "showBackground": True,
291
+ "backgroundStyle": {"color": "rgba(180, 180, 180, 0.2)"},
292
+ }
293
+ ],
294
+ }
295
+
296
+ input = rxui.input("输入内容,图表标题会同步", value=r_input)
297
+ # 通过响应式组件对象的 element 属性,获取原生 nicegui 组件对象
298
+ input.element.classes("w-full")
299
+
300
+ rxui.echarts(cp_echarts_opts)
301
+
302
+ ui.run()
303
+ ```
304
+ ![](./asset/asyc_echarts_title.gif)
305
+
306
+
307
+ ### echarts 图表鼠标事件
308
+
309
+ `on` 函数参数 `event_name` 以及 `query` 使用,查看[echarts 事件中文文档](https://echarts.apache.org/handbook/zh/concepts/event/)
310
+
311
+
312
+ 以下例子绑定鼠标单击事件
313
+ ```python
314
+ from nicegui import ui
315
+ from ex4nicegui.reactive import rxui
316
+
317
+ opts = {
318
+ "xAxis": {"type": "value", "boundaryGap": [0, 0.01]},
319
+ "yAxis": {
320
+ "type": "category",
321
+ "data": ["Brazil", "Indonesia", "USA", "India", "China", "World"],
322
+ },
323
+ "series": [
324
+ {
325
+ "name": "first",
326
+ "type": "bar",
327
+ "data": [18203, 23489, 29034, 104970, 131744, 630230],
328
+ },
329
+ {
330
+ "name": "second",
331
+ "type": "bar",
332
+ "data": [19325, 23438, 31000, 121594, 134141, 681807],
333
+ },
334
+ ],
335
+ }
336
+
337
+ bar = rxui.echarts(opts)
338
+
339
+ def on_click(e: rxui.echarts.EChartsMouseEventArguments):
340
+ ui.notify(f"on_click:{e.seriesName}:{e.name}:{e.value}")
341
+
342
+
343
+ bar.on("click", on_click)
344
+ ```
345
+
346
+
347
+ 以下例子只针对指定系列触发鼠标划过事件
348
+ ```python
349
+ from nicegui import ui
350
+ from ex4nicegui.reactive import rxui
351
+
352
+ opts = {
353
+ "xAxis": {"type": "value", "boundaryGap": [0, 0.01]},
354
+ "yAxis": {
355
+ "type": "category",
356
+ "data": ["Brazil", "Indonesia", "USA", "India", "China", "World"],
357
+ },
358
+ "series": [
359
+ {
360
+ "name": "first",
361
+ "type": "bar",
362
+ "data": [18203, 23489, 29034, 104970, 131744, 630230],
363
+ },
364
+ {
365
+ "name": "second",
366
+ "type": "bar",
367
+ "data": [19325, 23438, 31000, 121594, 134141, 681807],
368
+ },
369
+ ],
370
+ }
371
+
372
+ bar = rxui.echarts(opts)
373
+
374
+ def on_first_series_mouseover(e: rxui.echarts.EChartsMouseEventArguments):
375
+ ui.notify(f"on_first_series_mouseover:{e.seriesName}:{e.name}:{e.value}")
376
+
377
+
378
+ bar.on("mouseover", on_first_series_mouseover, query={"seriesName": "first"})
379
+
380
+ ui.run()
381
+ ```
382
+ ---
383
+
384
+
346
385
  ## 响应式
347
386
 
348
387
  ```python