浏览代码

Merge pull request #2232 from zauberzeug/echart-methods

Introduce `run_chart_method` for `ui.echart`
Rodja Trappe 1 年之前
父节点
当前提交
0820ab13c3
共有 4 个文件被更改,包括 70 次插入0 次删除
  1. 7 0
      nicegui/elements/echart.js
  2. 19 0
      nicegui/elements/echart.py
  3. 16 0
      tests/test_echart.py
  4. 28 0
      website/documentation/content/echart_documentation.py

+ 7 - 0
nicegui/elements/echart.js

@@ -19,6 +19,13 @@ export default {
       convertDynamicProperties(this.options, true);
       convertDynamicProperties(this.options, true);
       this.chart.setOption(this.options, { notMerge: this.chart.options?.series.length != this.options.series.length });
       this.chart.setOption(this.options, { notMerge: this.chart.options?.series.length != this.options.series.length });
     },
     },
+    run_chart_method(name, ...args) {
+      if (name.startsWith(":")) {
+        name = name.slice(1);
+        args = args.map((arg) => new Function("return " + arg)());
+      }
+      return this.chart[name](...args);
+    },
   },
   },
   props: {
   props: {
     options: Object,
     options: Object,

+ 19 - 0
nicegui/elements/echart.py

@@ -1,5 +1,6 @@
 from typing import Callable, Dict, Optional
 from typing import Callable, Dict, Optional
 
 
+from ..awaitable_response import AwaitableResponse
 from ..element import Element
 from ..element import Element
 from ..events import EChartPointClickEventArguments, GenericEventArguments, handle_event
 from ..events import EChartPointClickEventArguments, GenericEventArguments, handle_event
 
 
@@ -55,3 +56,21 @@ class EChart(Element, component='echart.js', libraries=['lib/echarts/echarts.min
     def update(self) -> None:
     def update(self) -> None:
         super().update()
         super().update()
         self.run_method('update_chart')
         self.run_method('update_chart')
+
+    def run_chart_method(self, name: str, *args, timeout: float = 1,
+                         check_interval: float = 0.01) -> AwaitableResponse:
+        """Run a method of the JSONEditor instance.
+
+        See the `ECharts documentation <https://echarts.apache.org/en/api.html#echartsInstance>`_ for a list of methods.
+
+        If the function is awaited, the result of the method call is returned.
+        Otherwise, the method is executed without waiting for a response.
+
+        :param name: name of the method (a prefix ":" indicates that the arguments are JavaScript expressions)
+        :param args: arguments to pass to the method (Python objects or JavaScript expressions)
+        :param timeout: timeout in seconds (default: 1 second)
+        :param check_interval: interval in seconds to check for a response (default: 0.01 seconds)
+
+        :return: AwaitableResponse that can be awaited to get the result of the method call
+        """
+        return self.run_method('run_chart_method', name, *args, timeout=timeout, check_interval=check_interval)

+ 16 - 0
tests/test_echart.py

@@ -61,3 +61,19 @@ def test_nested_expansion(screen: Screen):
     canvas = screen.find_by_tag('canvas')
     canvas = screen.find_by_tag('canvas')
     assert canvas.rect['height'] == 168
     assert canvas.rect['height'] == 168
     assert canvas.rect['width'] == 568
     assert canvas.rect['width'] == 568
+
+
+def test_run_method(screen: Screen):
+    echart = ui.echart({
+        'xAxis': {'type': 'value'},
+        'yAxis': {'type': 'category', 'data': ['A', 'B', 'C']},
+        'series': [{'type': 'line', 'data': [0.1, 0.2, 0.3]}],
+    }).classes('w-[600px]')
+
+    async def get_width():
+        ui.label(f'Width: {await echart.run_chart_method("getWidth")}px')
+    ui.button('Get Width', on_click=get_width)
+
+    screen.open('/')
+    screen.click('Get Width')
+    screen.should_contain('Width: 600px')

+ 28 - 0
website/documentation/content/echart_documentation.py

@@ -47,4 +47,32 @@ def dynamic_properties() -> None:
     })
     })
 
 
 
 
+@doc.demo('Run methods', '''
+    You can run methods of the EChart instance using the `run_chart_method` method.
+    This demo shows how to show and hide the loading animation, how to get the current width of the chart,
+    and how to add tooltips with a custom formatter.
+
+    The colon ":" in front of the method name "setOption" indicates that the argument is a JavaScript expression
+    that is evaluated on the client before it is passed to the method.
+''')
+def methods_demo() -> None:
+    echart = ui.echart({
+        'xAxis': {'type': 'category', 'data': ['Mon', 'Tue', 'Wed', 'Thu', 'Fri']},
+        'yAxis': {'type': 'value'},
+        'series': [{'type': 'line', 'data': [150, 230, 224, 218, 135]}],
+    })
+
+    ui.button('Show Loading', on_click=lambda: echart.run_chart_method('showLoading'))
+    ui.button('Hide Loading', on_click=lambda: echart.run_chart_method('hideLoading'))
+
+    async def get_width():
+        width = await echart.run_chart_method('getWidth')
+        ui.notify(f'Width: {width}')
+    ui.button('Get Width', on_click=get_width)
+
+    ui.button('Set Tooltip', on_click=lambda: echart.run_chart_method(
+        ':setOption', r'{tooltip: {formatter: params => "$" + params.value}}',
+    ))
+
+
 doc.reference(ui.echart)
 doc.reference(ui.echart)