Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support chart actions #23

Merged
merged 2 commits into from
Dec 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -119,14 +119,15 @@ jobs:

- name: Install browser
shell: bash -l {0}
run: npx playwright install chromium
working-directory: ui-tests
run: |
jlpm install
npx playwright install chromium

- name: Execute integration tests
shell: bash -l {0}
working-directory: ui-tests
run: |
jlpm install
npx playwright test

- name: Upload Playwright Test report
Expand Down
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -255,3 +255,18 @@ chart.on('mouseover', {'seriesIndex': 1, 'name': 'xx'}, callback) # Using object
chart.off('click') # Remove all handler on click event
chart.off('mouseover', callback) # Remove selected handler.
```

### Chart actions

Chart actions supported by ECharts can by triggered by the `EChartsWidget.dispatchAction` or `EChartsRawWidget.dispatchAction` method. This method takes the same payload as [in the Javascript version](https://echarts.apache.org/en/api.html#action):

```python
chart = EChartsWidget(option=option)
chart.dispatchAction({
'type': 'highlight',
'seriesIndex': 0,
'dataIndex': 1
})
```

![ipechart](./docs/source/images/ipecharts_action.gif)
1 change: 1 addition & 0 deletions docs/source/api/ipecharts.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ Submodules
ipecharts.baseechartswidget
ipecharts.basewidget
ipecharts.echarts
ipecharts.tools

Module contents
---------------
Expand Down
7 changes: 7 additions & 0 deletions docs/source/api/ipecharts.tools.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
ipecharts.tools module
======================

.. automodule:: ipecharts.tools
:members:
:undoc-members:
:show-inheritance:
Binary file added docs/source/images/ipecharts_action.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 15 additions & 0 deletions docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,21 @@ Event-handling functions can be added to ``EChartsWidget`` and ``EChartsRawWidge
chart.off('click') # Remove all handler on click event
chart.off('mouseover', callback) # Remove selected handler.

Chart actions
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Chart actions supported by ECharts can by triggered by the ``EChartsWidget.dispatchAction`` or ``EChartsRawWidget.dispatchAction`` method. This method takes the same payload as [in the Javascript version](https://echarts.apache.org/en/api.html#action):

.. code-block:: python

chart = EChartsWidget(option=option)
chart.dispatchAction({
'type': 'highlight',
'seriesIndex': 0,
'dataIndex': 1
})

.. figure:: images/ipecharts_action.gif

API Reference
********************************
Expand Down
178 changes: 178 additions & 0 deletions example/action.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 37,
"id": "6144d5b4-faf0-4401-8691-3a56dddb519d",
"metadata": {},
"outputs": [],
"source": [
"from ipecharts.echarts import EChartsWidget, EChartsRawWidget\n",
"import json\n",
"import numpy\n",
"from ipecharts.option import Option, XAxis, YAxis, Legend, Tooltip, Grid\n",
"from ipecharts.option.series import Pie\n",
"from ipywidgets.widgets import Button"
]
},
{
"cell_type": "code",
"execution_count": 38,
"id": "65231639-b78b-41fd-8cac-89de1d3fa41f",
"metadata": {},
"outputs": [],
"source": [
"tooltip = Tooltip(trigger='item', formatter='{a} <br/>{b} : {c} ({d}%)')"
]
},
{
"cell_type": "code",
"execution_count": 39,
"id": "0b449694-d1ab-430d-9520-4f71c3233607",
"metadata": {},
"outputs": [],
"source": [
"legend = Legend(orient='vertical', left='left', data=['Direct Access','Email Marketing','Affiliate Ads','Video Ads','Search Engines'])"
]
},
{
"cell_type": "code",
"execution_count": 40,
"id": "fd8570d4-e3e4-45d4-9508-77a1939b6d12",
"metadata": {},
"outputs": [],
"source": [
"pie = Pie(\n",
" name='Access Source',\n",
" radius='55%',\n",
" center=['50%', '60%'],\n",
" data=[\n",
" { 'value': 335, 'name': 'Direct Access' },\n",
" { 'value': 310, 'name': 'Email Marketing' },\n",
" { 'value': 234, 'name': 'Affiliate Ads' },\n",
" { 'value': 135, 'name': 'Video Ads' },\n",
" { 'value': 1548, 'name': 'Search Engines' }\n",
" ],\n",
" emphasis={\n",
" 'itemStyle': {\n",
" 'shadowBlur': 10,\n",
" 'shadowOffsetX': 0,\n",
" 'shadowColor': 'rgba(0, 0, 0, 0.5)'\n",
" }\n",
" }\n",
" )"
]
},
{
"cell_type": "code",
"execution_count": 41,
"id": "6b73428e-1e73-4adf-a09a-7b1707cdba84",
"metadata": {},
"outputs": [],
"source": [
"chart = EChartsWidget(option=Option(series=[pie], tooltip=tooltip, legend=legend))"
]
},
{
"cell_type": "code",
"execution_count": 47,
"id": "e9127c30-8f1d-4894-8ad8-6caa18c15a53",
"metadata": {},
"outputs": [],
"source": [
"button = Button(description=\"Dispatch Action\")\n",
"currentIndex = -1\n",
"dataLen = 5\n",
"def on_button_clicked(b):\n",
" global currentIndex\n",
" chart.dispatchAction({\n",
" 'type': 'downplay',\n",
" 'seriesIndex': 0,\n",
" 'dataIndex': currentIndex\n",
" })\n",
" currentIndex = (currentIndex + 1) % dataLen\n",
" chart.dispatchAction({\n",
" 'type': 'highlight',\n",
" 'seriesIndex': 0,\n",
" 'dataIndex': currentIndex\n",
" })\n",
" chart.dispatchAction({\n",
" 'type': 'showTip',\n",
" 'seriesIndex': 0,\n",
" 'dataIndex': currentIndex\n",
" })\n",
"\n",
"button.on_click(on_button_clicked)"
]
},
{
"cell_type": "code",
"execution_count": 48,
"id": "2c04edee-f416-436b-808b-83d1915c8df7",
"metadata": {},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "ddbd04409e4147d6a55716e347512db2",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"EChartsWidget(option=Option(angleAxis=None, aria=None, axisPointer=None, brush=None, calendar=None, dataset=No…"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "216a688b3116434ca3719692de853dc7",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"Button(description='Dispatch Action', style=ButtonStyle())"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"display(chart, button)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "848cd0e5-82b6-4c34-8a89-a3a9eecb1633",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"jupyter_suggestion": {},
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.15"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
8 changes: 8 additions & 0 deletions ipecharts/baseechartswidget.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,14 @@ def off(self, event_name: str, handler: T.Optional[T.Callable] = None):
}
)

def dispatchAction(self, payload: T.Dict):
self.send(
{
"action": MESSAGE_ACTION.DISPATCH_ACTION,
"payload": payload,
}
)

def _handle_frontend_msg(
self, model: "BaseEchartsWidget", msg: T.Dict, buffers: T.List
) -> None:
Expand Down
3 changes: 2 additions & 1 deletion ipecharts/tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@

class MESSAGE_ACTION(str, Enum):
REGISTER_EVENT = 'register_event'
UNREGISTER_EVENT = 'unregister_event'
UNREGISTER_EVENT = 'unregister_event'
DISPATCH_ACTION = 'dispatch_action'
4 changes: 4 additions & 0 deletions src/baseWidgetView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,10 @@ export abstract class BaseEChartsWidgetView extends DOMWidgetView {

break;
}
case 'dispatch_action': {
this._myChart?.dispatchAction(payload);
break;
}
default:
break;
}
Expand Down
10 changes: 9 additions & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,15 @@ export interface IUnregisterEventMsg {
payload: { event: string; id_to_remove?: string[] };
}

export type IKernelMsg = IRegisterEventMsg | IUnregisterEventMsg;
export interface IDispatchActionMsg {
action: 'dispatch_action';
payload: echarts.Payload;
}

export type IKernelMsg =
| IRegisterEventMsg
| IUnregisterEventMsg
| IDispatchActionMsg;

export interface IEventHandlerParams {
action: 'event_handler_params';
Expand Down
Loading