ex4nicegui 0.8.5__py3-none-any.whl → 0.8.7__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.
@@ -1,6 +1,13 @@
1
1
  import 'echarts'
2
2
  import { convertDynamicProperties } from "../../static/utils/dynamic_properties.js";
3
3
 
4
+ const registerThemeTask = Promise.all(
5
+ (echarts._ex4ng_themes || []).map(async ({ name, url }) => {
6
+ const data = await fetch(url).then(response => response.json());
7
+ echarts.registerTheme(name, data);
8
+ })
9
+ );
10
+
4
11
  function collectMapRegisterTask() {
5
12
  const tasks = new Map();
6
13
 
@@ -57,6 +64,8 @@ export default {
57
64
  async mounted() {
58
65
  await new Promise((resolve) => setTimeout(resolve, 0)); // wait for Tailwind classes to be applied
59
66
 
67
+ await registerThemeTask;
68
+
60
69
  this.chart = echarts.init(this.$el, this.theme, this.initOptions);
61
70
  this.resizeObs = new ResizeObserver(this.chart.resize)
62
71
 
@@ -28,6 +28,7 @@ class echarts(Element, component="ECharts.js", dependencies=libraries): # type:
28
28
  options: Optional[dict] = None,
29
29
  code: Optional[str] = None,
30
30
  init_options: Optional[dict] = None,
31
+ theme: Optional[str] = None,
31
32
  ) -> None:
32
33
  super().__init__()
33
34
 
@@ -47,6 +48,9 @@ class echarts(Element, component="ECharts.js", dependencies=libraries): # type:
47
48
  self._props["initOptions"] = init_options
48
49
  self._props["eventTasks"] = {}
49
50
 
51
+ if theme:
52
+ self._props["theme"] = theme
53
+
50
54
  def update_chart(
51
55
  self,
52
56
  merge_opts: Optional[dict] = None,
@@ -26,7 +26,6 @@ def create_event_handler_args(
26
26
  event_name: _T_event_name, e: GenericEventArguments
27
27
  ) -> UiEventArguments:
28
28
  if is_mouse_event(event_name):
29
- print(e.args)
30
29
  return EChartsMouseEventArguments(sender=e.sender, client=e.client, **e.args)
31
30
 
32
31
  return GenericEventArguments(sender=e.sender, client=e.client, args=e.args)
@@ -1,5 +1,5 @@
1
1
  from pathlib import Path
2
- from typing import Any, Callable, Dict, List, Union, cast, Optional, Literal
2
+ from typing import Any, Callable, Dict, List, Union, cast, Optional, Literal, ClassVar
3
3
  from ex4nicegui.reactive.services.reactive_service import ParameterClassifier
4
4
  from ex4nicegui.utils.signals import (
5
5
  TGetterOrReadonlyRef,
@@ -17,10 +17,14 @@ from ex4nicegui.reactive.EChartsComponent.events import EChartsMouseEventArgumen
17
17
  from nicegui.awaitable_response import AwaitableResponse
18
18
  from nicegui import ui, app
19
19
  import orjson as json
20
+ from contextvars import ContextVar
20
21
 
21
22
 
22
23
  class EChartsBindableUi(BindableUi[echarts]):
23
24
  EChartsMouseEventArguments = EChartsMouseEventArguments
25
+ _CURRENT_THEME: ClassVar[ContextVar[Optional[str]]] = ContextVar(
26
+ "CURRENT_THEME", default=None
27
+ )
24
28
 
25
29
  def __init__(
26
30
  self,
@@ -28,6 +32,8 @@ class EChartsBindableUi(BindableUi[echarts]):
28
32
  not_merge: TMaybeRef[Union[bool, None]] = None,
29
33
  code: Optional[str] = None,
30
34
  init_options: Optional[Dict] = None,
35
+ *,
36
+ theme: Optional[str] = None,
31
37
  ) -> None:
32
38
  """Create a new ECharts instance.
33
39
 
@@ -43,10 +49,11 @@ class EChartsBindableUi(BindableUi[echarts]):
43
49
  pc = ParameterClassifier(
44
50
  locals(),
45
51
  maybeRefs=["options", "code", "init_options"],
46
- exclude=["not_merge"],
52
+ exclude=["not_merge", "theme"],
47
53
  )
48
54
 
49
55
  value_kws = pc.get_values_kws()
56
+ value_kws["theme"] = theme or self._CURRENT_THEME.get()
50
57
 
51
58
  element = echarts(**value_kws).classes("nicegui-echart")
52
59
 
@@ -59,6 +66,44 @@ class EChartsBindableUi(BindableUi[echarts]):
59
66
  for key, value in pc.get_bindings().items():
60
67
  self.bind_prop(key, value) # type: ignore
61
68
 
69
+ @classmethod
70
+ def register_theme(cls, name: str, theme: Path):
71
+ """register a new theme to echarts.
72
+
73
+ @see - https://github.com/CrystalWindSnake/ex4nicegui/blob/main/README.en.md#rxuiechartsregister_theme
74
+ @中文文档 - https://gitee.com/carson_add/ex4nicegui/tree/main/#rxuiechartsregister_theme
75
+
76
+ Args:
77
+ name (str): Theme name.
78
+ theme (Path): Theme file path.
79
+
80
+ ## Examples
81
+ .. code-block:: python
82
+
83
+ @ui.page('/)
84
+ def index():
85
+ rxui.echarts.register_theme("my_theme", Path("path/to/my_theme.json"))
86
+ rxui.echarts(opts)
87
+
88
+ """
89
+
90
+ url = app.add_static_file(local_file=theme)
91
+
92
+ ui.add_body_html(
93
+ rf"""
94
+ <script type="module">
95
+ import "echarts";
96
+ echarts._ex4ng_themes = echarts._ex4ng_themes || [];
97
+ echarts._ex4ng_themes.push({{
98
+ name: "{name}",
99
+ url: "{url}"
100
+ }});
101
+ </script>
102
+ """
103
+ )
104
+ cls._CURRENT_THEME.set(name)
105
+ return cls
106
+
62
107
  @classmethod
63
108
  def register_map(
64
109
  cls,
@@ -8,14 +8,21 @@ from ex4nicegui.reactive.services.reactive_service import ParameterClassifier
8
8
 
9
9
  from nicegui import ui
10
10
  from .base import BindableUi
11
- from ex4nicegui.utils.signals import _TMaybeRef as TMaybeRef
11
+ from ex4nicegui.utils.signals import (
12
+ _TMaybeRef as TMaybeRef,
13
+ TGetterOrReadonlyRef,
14
+ to_value,
15
+ )
16
+
17
+
18
+ _T_Template = Union[TMaybeRef[str], TMaybeRef[int]]
12
19
 
13
20
 
14
21
  class GridBindableUi(BindableUi[ui.grid]):
15
22
  def __init__(
16
23
  self,
17
- rows: Optional[TMaybeRef[Union[int, str]]] = None,
18
- columns: Optional[TMaybeRef[Union[int, str]]] = None,
24
+ rows: Optional[_T_Template] = None,
25
+ columns: Optional[_T_Template] = None,
19
26
  ) -> None:
20
27
  pc = ParameterClassifier(locals(), maybeRefs=["rows", "columns"], events=[])
21
28
 
@@ -25,6 +32,39 @@ class GridBindableUi(BindableUi[ui.grid]):
25
32
  for key, value in pc.get_bindings().items():
26
33
  self.bind_prop(key, value) # type: ignore
27
34
 
35
+ def bind_prop(self, prop: str, value: TGetterOrReadonlyRef):
36
+ if prop == "rows":
37
+ return self.bind_rows(value)
38
+
39
+ if prop == "columns":
40
+ return self.bind_columns(value)
41
+
42
+ return super().bind_prop(prop, value)
43
+
44
+ def bind_rows(self, rows: TGetterOrReadonlyRef[Union[int, str]]):
45
+ def template():
46
+ _rows = to_value(rows)
47
+ return (
48
+ f"repeat({_rows}, minmax(0, 1fr))" if isinstance(_rows, int) else _rows
49
+ )
50
+
51
+ self.bind_style({"grid-template-rows": template})
52
+
53
+ return self
54
+
55
+ def bind_columns(self, columns: TGetterOrReadonlyRef[Union[int, str]]):
56
+ def template():
57
+ _columns = to_value(columns)
58
+ return (
59
+ f"repeat({_columns}, minmax(0, 1fr))"
60
+ if isinstance(_columns, int)
61
+ else _columns
62
+ )
63
+
64
+ self.bind_style({"grid-template-columns": template})
65
+
66
+ return self
67
+
28
68
  def __enter__(self):
29
69
  self.element.__enter__()
30
70
  return self
@@ -21,6 +21,7 @@ def async_computed(
21
21
  *,
22
22
  init: Optional[_T] = None,
23
23
  evaluating: Optional[TRef[bool]] = None,
24
+ onchanges=True,
24
25
  debug_trigger: Optional[Callable] = None,
25
26
  debug_name: Optional[str] = None,
26
27
  ):
@@ -34,12 +35,14 @@ def async_computed(
34
35
  refs (Union[TGetterOrReadonlyRef, Sequence[TGetterOrReadonlyRef]]): _description_
35
36
  init (Optional[_T], optional): The initial state, used until the first evaluation finishes. Defaults to None.
36
37
  evaluating (Optional[TRef[bool]], optional): Ref passed to receive the updated of async evaluation. Defaults to None.
38
+ onchanges (bool, optional): If set to `False`, it will trigger an immediate computation. Defaults to True.
37
39
 
38
40
  """
39
41
  return signe.async_computed(
40
42
  refs,
41
43
  init=init,
42
44
  evaluating=evaluating,
45
+ onchanges=onchanges,
43
46
  debug_name=debug_name,
44
47
  debug_trigger=debug_trigger,
45
48
  scope=_CLIENT_SCOPE_MANAGER.get_current_scope(),
@@ -46,7 +46,6 @@ class DictProxy(dict, Generic[_KT, _VT]):
46
46
  return self._ref.value.__len__()
47
47
 
48
48
  def __getitem__(self, key: _KT, /):
49
- print("getitem")
50
49
  value = self._ref.value.__getitem__(key)
51
50
 
52
51
  if isinstance(value, str):
@@ -1,8 +1,7 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.3
2
2
  Name: ex4nicegui
3
- Version: 0.8.5
3
+ Version: 0.8.7
4
4
  Summary: Extension library based on nicegui, providing data responsive,BI functionality modules
5
- Home-page: https://github.com/CrystalWindSnake/ex4nicegui
6
5
  License: MIT
7
6
  Keywords: nicegui,ex4nicegui,webui
8
7
  Author: CrystalWindSnake
@@ -15,9 +14,10 @@ Classifier: Programming Language :: Python :: 3.9
15
14
  Classifier: Programming Language :: Python :: 3.10
16
15
  Classifier: Programming Language :: Python :: 3.11
17
16
  Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
18
18
  Requires-Dist: executing (>=2.0.1,<3.0.0)
19
19
  Requires-Dist: nicegui (>=2.0.0,<3.0.0)
20
- Requires-Dist: signe (>=0.4.21,<0.5.0)
20
+ Requires-Dist: signe (>=0.4.22,<0.5.0)
21
21
  Project-URL: Repository, https://github.com/CrystalWindSnake/ex4nicegui
22
22
  Description-Content-Type: text/markdown
23
23
 
@@ -458,6 +458,7 @@ class MyApp(rxui.ViewModel):
458
458
  - [echarts 图表鼠标事件](#echarts-图表鼠标事件)
459
459
  - [rxui.echarts.from\_javascript](#rxuiechartsfrom_javascript)
460
460
  - [rxui.echarts.register\_map](#rxuiechartsregister_map)
461
+ - [rxui.echarts.register\_theme](#rxuiechartsregister_theme)
461
462
  - [tab\_panels](#tab_panels)
462
463
  - [lazy\_tab\_panels](#lazy_tab_panels)
463
464
  - [scoped\_style](#scoped_style)
@@ -1346,6 +1347,35 @@ rxui.echarts.register_map(
1346
1347
  )
1347
1348
  ```
1348
1349
 
1350
+ ---
1351
+ ##### rxui.echarts.register_theme
1352
+ 注册主题.
1353
+
1354
+ ```python
1355
+ @ui.page("/")
1356
+ def page():
1357
+ # 本页范围,所有 rxui.echarts 默认主题均为 walden(最后注册的主题)
1358
+ rxui.echarts.register_theme(
1359
+ "my_theme", Path(__file__).parent / "echarts_theme.json"
1360
+ ).register_theme("walden", Path(__file__).parent / "echarts_walden.json")
1361
+
1362
+ opts = {
1363
+ "xAxis": {"data": ["Shirts", "Cardigans"]},
1364
+ "yAxis": {},
1365
+ "series": [{"type": "bar", "data": [5, 20]}],
1366
+ }
1367
+
1368
+ # 主题为 walden
1369
+ rxui.echarts(opts)
1370
+
1371
+ # 主题为 my_theme
1372
+ rxui.echarts(
1373
+ opts,
1374
+ theme="my_theme",
1375
+ )
1376
+
1377
+ ```
1378
+
1349
1379
  ---
1350
1380
 
1351
1381
  #### tab_panels
@@ -75,11 +75,11 @@ ex4nicegui/reactive/base.py,sha256=CQmWhrKHNMF2ql7O6VOKEOBdEcc3-yagOcERpnUPYus,1
75
75
  ex4nicegui/reactive/deferredTask.py,sha256=g78TTG1EIkBxjPih01xmrCZw9OxQG93veSVSELWKfcU,987
76
76
  ex4nicegui/reactive/dropZone/dropZone.js,sha256=7rSpFJX-Fk_W_NGZhOTyuEw0bzR-YUc8ZYPzQG9KzE0,2713
77
77
  ex4nicegui/reactive/dropZone/dropZone.py,sha256=hg9UKTayff8v8Ek-n38h_3wX1Qmiotvdyv1Hsqilh5Y,2590
78
- ex4nicegui/reactive/EChartsComponent/ECharts.js,sha256=K9sX34SMnghwDMCkl-IA7WsntxyryeRsboihkIwDb84,3852
79
- ex4nicegui/reactive/EChartsComponent/ECharts.py,sha256=jLRdKqJWCtKHzNlFAX9ePAmzP1WSXRzBQAO0KHHkfBA,4258
78
+ ex4nicegui/reactive/EChartsComponent/ECharts.js,sha256=Dhsfzlio9zO2T3LhK5cI7IdPXHtWhbBXMdlL3uvkU24,4110
79
+ ex4nicegui/reactive/EChartsComponent/ECharts.py,sha256=NjJocWIEF4xzvRQVbkTQSaB2fF_GIVf2_QaMKjln9hU,4359
80
80
  ex4nicegui/reactive/EChartsComponent/events.py,sha256=ln10cNw5ODiSmdKVi6KBZ6JMR3YIZ6itYZcMgNAlKhA,741
81
81
  ex4nicegui/reactive/EChartsComponent/types.py,sha256=_7AekG0IyzRpDEBZMtKRiZ3o3dUCcn6btegBk8c9Fig,1001
82
- ex4nicegui/reactive/EChartsComponent/utils.py,sha256=HIhaHZfOt3FSLX-Dk9poDnhqBFtNI9gOR_CCQlx9giw,1036
82
+ ex4nicegui/reactive/EChartsComponent/utils.py,sha256=YqxodbGD_lk_Bp-K8s8XvgqSXRf_CIHmzeubrqFRuVM,1013
83
83
  ex4nicegui/reactive/empty.js,sha256=Y-caS4CN8jUq59LgGgcvgfkndze-RgWF_ZMmAcxOrbw,50
84
84
  ex4nicegui/reactive/empty.py,sha256=kB851B12V1_VCNsFKW6OmjcdIiuZqGEGjLgA6k6yug8,132
85
85
  ex4nicegui/reactive/fileWatcher.py,sha256=gjeZhgar02f-qGQa47Tj5SMaCP_ftRtSU898XUmXl1U,1472
@@ -105,10 +105,10 @@ ex4nicegui/reactive/officials/column.py,sha256=fllKknMEUw7uNhmP7w4pgBT7HTDbpkN-d
105
105
  ex4nicegui/reactive/officials/date.py,sha256=lRiJNrgs_oNo9AZTfTX_66dYL7az4co5rfRyIzvGAIo,2440
106
106
  ex4nicegui/reactive/officials/dialog.py,sha256=3dyrvsUwM1Q7jr_PgLKt92KDA6Hris0DH90-sKamfFE,1297
107
107
  ex4nicegui/reactive/officials/drawer.py,sha256=_Ro6stOh8U3igYMeDwI4omBgi1nld5berrAk9Dv5RVw,2346
108
- ex4nicegui/reactive/officials/echarts.py,sha256=xRBKVbcCUwUGA8n7bw2eJj9FBQIayL4t_rzXZrjD3Pc,10895
108
+ ex4nicegui/reactive/officials/echarts.py,sha256=ANI74NjGFLF7LoABbc8x9L2Z5nLOguptoK4iUIoSizY,12288
109
109
  ex4nicegui/reactive/officials/element.py,sha256=-qsHcxfF3fMfU0sJlKtTksX_wYPMIPJ_AgFcZbbI754,412
110
110
  ex4nicegui/reactive/officials/expansion.py,sha256=8xwJa0SpsVhFxbYwYRZtf1ul9m4oYTjgmtrRI_lqF_0,1822
111
- ex4nicegui/reactive/officials/grid.py,sha256=Bq83jejsxQSYVc9O1IE6JUgUndUm1uexb4fq9EZWjHQ,921
111
+ ex4nicegui/reactive/officials/grid.py,sha256=0vLLJOe7t_b351TsYOWpnrPsWKaqV_bG_010Xp-_BfY,2012
112
112
  ex4nicegui/reactive/officials/html.js,sha256=lyvRAdMKZGOc7MPEapeU6WbOzq_MVzqzUJEhKuC8zWc,119
113
113
  ex4nicegui/reactive/officials/html.py,sha256=XrOpGoAJDo8dtTnZVLSmi7H5iHffmYpeZ94lXxHjBwI,629
114
114
  ex4nicegui/reactive/officials/icon.py,sha256=Um1yS681pcbsZ4o7GU_2w1NCfwFVXNu1a4asB2hzYUg,1374
@@ -165,7 +165,7 @@ ex4nicegui/tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,
165
165
  ex4nicegui/tools/debug.py,sha256=h9iYHxw7jWWvmiExSpGi2hQl1PfhPZgC2KNS_GTuHSw,4868
166
166
  ex4nicegui/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
167
167
  ex4nicegui/utils/apiEffect.py,sha256=uwIi-R4Q0MaGSVmvhEFIL0O8pjBWobB_8brGAe19Qm4,2645
168
- ex4nicegui/utils/asyncComputed.py,sha256=-v19ic20URewLkjbms5Teco1k8LPRnpP7usjrgo1pRU,1505
168
+ ex4nicegui/utils/asyncComputed.py,sha256=LPb4ytvzsUEV4sKQ9bQASJn2VPB_pjZzeKcHVwcvb_c,1672
169
169
  ex4nicegui/utils/clientScope.py,sha256=AM5GQLXSIrLALnzz72ZmplykhKVhRjRxQdHdAeR7g7k,1719
170
170
  ex4nicegui/utils/common.py,sha256=7P0vboDadLun6EMxNi3br9rKJgKt0QT4sy_66cHEwb4,994
171
171
  ex4nicegui/utils/effect.py,sha256=LTtPTxx8-sP4VtZaFQjERB-ef3L2y5hu95GvTdj-nLo,2400
@@ -174,7 +174,7 @@ ex4nicegui/utils/proxy/base.py,sha256=g_7308xGAB3bB3EiEf_-0JKfUzImwt5_T9XVyT7zJJ
174
174
  ex4nicegui/utils/proxy/bool.py,sha256=KQ2Sp2r4nLScif9DhupDmkpRhbsuXdpXTkxSrtFYtDE,1774
175
175
  ex4nicegui/utils/proxy/date.py,sha256=wS0M4nfGVQ7A1u9tJkPqilEhDwcMKBjtTC9VjUsOqac,2356
176
176
  ex4nicegui/utils/proxy/descriptor.py,sha256=VuPBXAE7mHbJ3EUAsftr3mettDvju79bR-SlwczRrAs,4594
177
- ex4nicegui/utils/proxy/dict.py,sha256=r3qMT2RRvi2aUs8kzav2iNMGgBrFUWKsbHCAuz4P0FY,3072
177
+ ex4nicegui/utils/proxy/dict.py,sha256=MPtx-09ylf_bHXnkr1c7PmJeaq2KpDp-_Shyw5YjOLU,3046
178
178
  ex4nicegui/utils/proxy/float.py,sha256=fdMUS7_xwypdDNscuZaUn3NA0vx8LGswAOc9kw0jK0c,5271
179
179
  ex4nicegui/utils/proxy/int.py,sha256=0Y7L924Zzq6LWRZEmaTmoXf0J6kC0o5EtW--2Lk7SNw,7381
180
180
  ex4nicegui/utils/proxy/list.py,sha256=bmjBMlO8UfJekL1nfGypMO21RKraIj1jw46-8QwfptE,4913
@@ -186,7 +186,7 @@ ex4nicegui/utils/scheduler.py,sha256=1gyq7Y2BkbwmPK_Q9kpRpc1MOC9H7xcpxuix-RZhN9k
186
186
  ex4nicegui/utils/signals.py,sha256=Jz0jKFPrJIRV0Gye62Bgk2kGgod1KBvDhnF-W3lRm04,7373
187
187
  ex4nicegui/utils/types.py,sha256=pE5WOSbcTHxaAhnT24FaZEd1B2Z_lTcsd46w0OKiMyc,359
188
188
  ex4nicegui/version.py,sha256=NE7u1piESstg3xCtf5hhV4iedGs2qJQw9SiC3ZSpiio,90
189
- ex4nicegui-0.8.5.dist-info/LICENSE,sha256=0KDDElS2dl-HIsWvbpy8ywbLzJMBFzXLev57LnMIZXs,1094
190
- ex4nicegui-0.8.5.dist-info/METADATA,sha256=ZwCNm1zZAVHHWNEeO-lDNBQSY_9HwWuEYS7E933usxo,46125
191
- ex4nicegui-0.8.5.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
192
- ex4nicegui-0.8.5.dist-info/RECORD,,
189
+ ex4nicegui-0.8.7.dist-info/LICENSE,sha256=0KDDElS2dl-HIsWvbpy8ywbLzJMBFzXLev57LnMIZXs,1094
190
+ ex4nicegui-0.8.7.dist-info/METADATA,sha256=FKLsKPR5EJZnSGTitaJi8RpitJ1XbTfyosp_F8_JL3Y,46832
191
+ ex4nicegui-0.8.7.dist-info/WHEEL,sha256=XbeZDeTWKc1w7CSIyre5aMDU_-PohRwTQceYnisIYYY,88
192
+ ex4nicegui-0.8.7.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: poetry-core 1.9.0
2
+ Generator: poetry-core 2.1.1
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any