diff --git a/.coveragerc b/.coveragerc
new file mode 100644
index 000000000..17dc3c414
--- /dev/null
+++ b/.coveragerc
@@ -0,0 +1,14 @@
+[run]
+omit =
+ pyecharts/render/templates/*
+ setup.py
+ install.py
+ test.py
+ test/*
+
+[report]
+show_missing = True
+omit =
+ pyecharts/render/templates/*
+ setup.py
+ install.py
\ No newline at end of file
diff --git a/.github/workflows/python-app.yml b/.github/workflows/python-app.yml
new file mode 100644
index 000000000..7b4923a45
--- /dev/null
+++ b/.github/workflows/python-app.yml
@@ -0,0 +1,59 @@
+name: pyecharts CI
+
+on:
+ push:
+ paths-ignore:
+ - '**/*.md'
+ pull_request:
+ paths-ignore:
+ - '**/*.md'
+
+jobs:
+ build:
+ strategy:
+ # Allows for matrix sub-jobs to fail without canceling the rest
+ fail-fast: false
+ matrix:
+ os:
+ - ubuntu-latest
+ - macos-latest
+ - windows-latest
+ python-version:
+ - "3.14"
+ - "3.13"
+ - "3.12"
+ - "3.11"
+ - "3.10"
+ - "3.9"
+ - "3.8"
+ - "3.7"
+ exclude: # Python < v3.8 does not support Apple Silicon ARM64.
+ - python-version: "3.7"
+ os: macos-latest
+ - python-version: "3.7"
+ os: ubuntu-latest
+ include: # So run those legacy versions on Intel CPUs.
+ # No ci env to test macos 13 with python3.7
+ #- python-version: "3.7"
+ # os: macos-13
+ - python-version: "3.7"
+ os: ubuntu-22.04
+ runs-on: ${{ matrix.os }}
+ steps:
+ - uses: actions/checkout@v4
+ - name: Set up Python
+ uses: actions/setup-python@v5
+ with:
+ python-version: ${{ matrix.python-version }}
+ - name: Install dependencies
+ run: |
+ python -m pip install --upgrade pip setuptools
+ pip install -r requirements.txt
+ pip install -r test/requirements.txt
+ - name: Run unit test
+ run: |
+ pip install .
+ pytest -v --cov-config=pyproject.toml --cov=./ test/
+ - name: Codecov
+ run: |
+ codecov
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 6bacc1e65..000000000
--- a/.travis.yml
+++ /dev/null
@@ -1,21 +0,0 @@
-sudo: false
-language: python
-notifications:
- email:
- recipients:
- - chenjiandongx@qq.com
- on_success: always # default: change
- on_failure: always # default: always
-python:
- - "3.8-dev"
- - "3.8"
- - "3.7"
- - "3.6"
-before_install:
- - pip install -r test/requirements.txt
-script:
- - python setup.py install
- - bash test.sh
-after_success:
- cd test && codecov
-
diff --git a/AGENTS.md b/AGENTS.md
new file mode 100644
index 000000000..0f153c65d
--- /dev/null
+++ b/AGENTS.md
@@ -0,0 +1,294 @@
+# AGENTS.md
+
+This file contains guidelines for agents working on the pyecharts project.
+
+## Build/Lint/Test Commands
+
+### Running Tests
+
+The project uses multiple testing frameworks. Here are the commands to run tests:
+
+1. **Run all tests**:
+ ```bash
+ make test
+ # or
+ python test.py
+ # or
+ nose2 --with-coverage --coverage pyecharts --coverage-config .coveragerc -s test
+ # or
+ pytest -cov-config=.coveragerc --cov=./ test/
+ ```
+
+2. **Run a single test file**:
+ ```bash
+ # Using pytest (recommended)
+ pytest test/test_chart.py
+
+ # Using nose2
+ nose2 --with-coverage --coverage pyecharts --coverage-config .coveragerc test.test_chart
+ ```
+
+3. **Run a specific test method**:
+ ```bash
+ # Using pytest
+ pytest test/test_chart.py::TestChartClass::test_chart_dark_mode
+
+ # Using nose2
+ nose2 --with-coverage --coverage pyecharts --coverage-config .coveragerc test.test_chart.TestChartClass.test_chart_dark_mode
+ ```
+
+4. **Run tests with verbose output**:
+ ```bash
+ pytest -v test/test_chart.py
+ ```
+
+5. **Run tests with coverage reporting**:
+ ```bash
+ pytest -v --cov=./ --cov-report=html test/test_chart.py
+ ```
+
+### Linting
+
+1. **Run linter**:
+ ```bash
+ make lint
+ # or
+ flake8 --exclude=build,images,example,examples --max-line-length=89 --ignore=F401
+ ```
+
+2. **Lint a specific file**:
+ ```bash
+ flake8 --exclude=build,images,example,examples --max-line-length=89 --ignore=F401 test/test_chart.py
+ ```
+
+### Formatting
+
+The project uses black and isort for code formatting:
+
+1. **Run black formatter**:
+ ```bash
+ black .
+ ```
+
+2. **Run isort for imports**:
+ ```bash
+ isort .
+ ```
+
+### Building
+
+1. **Build the package**:
+ ```bash
+ python setup.py sdist bdist_wheel
+ ```
+
+2. **Upload to PyPI**:
+ ```bash
+ make upload
+ # This runs the UploadCommand defined in setup.py
+ ```
+
+## Code Style Guidelines
+
+### Imports
+
+1. **Import organization**:
+ - Standard library imports
+ - Related third party imports
+ - Local application/library specific imports
+
+2. **Import style**:
+ ```python
+ # Good
+ from pyecharts import options as opts
+ from pyecharts.charts import Line, Bar
+
+ # Avoid
+ from pyecharts.options import *
+ import pyecharts.charts.Line
+ ```
+
+3. **Use aliases** for commonly used modules:
+ ```python
+ import pyecharts.options as opts
+ import pyecharts.globals as globals
+ ```
+
+### Formatting
+
+1. **Line length**: 89 characters max (as specified in flake8 command)
+
+2. **Indentation**: 4 spaces (no tabs)
+
+3. **Quotes**: Use double quotes " for strings, single quotes ' for char literals
+
+4. **Blank lines**:
+ - Top-level functions and classes: 2 blank lines
+ - Methods within a class: 1 blank line
+
+5. **Use black formatter** to ensure consistent code style
+
+### Naming Conventions
+
+1. **Variables and functions**: snake_case
+ ```python
+ def add_yaxis(self, series_name, y_axis, *args, **kwargs):
+ pass
+ ```
+
+2. **Classes**: PascalCase
+ ```python
+ class TestChartClass(unittest.TestCase):
+ pass
+ ```
+
+3. **Constants**: UPPER_CASE
+ ```python
+ MAX_RETRIES = 3
+ ```
+
+4. **Private members**: prefix with _
+ ```python
+ def _internal_method(self):
+ pass
+ ```
+
+### Error Handling
+
+1. **Use exceptions** for error conditions, not return codes
+
+2. **Be specific** with exception types:
+ ```python
+ try:
+ result = do_something()
+ except ValueError as e:
+ logger.error(f"Invalid value: {e}")
+ raise
+ except RuntimeError as e:
+ logger.error(f"Runtime error: {e}")
+ raise
+ ```
+
+3. **Don't catch all exceptions** indiscriminately:
+ ```python
+ # Avoid
+ try:
+ do_something()
+ except:
+ pass
+
+ # Prefer
+ try:
+ do_something()
+ except SpecificError:
+ handle_specific_error()
+ ```
+
+### Testing Guidelines
+
+1. **Test structure**:
+ - Use unittest framework with TestCase classes
+ - Group related tests in classes
+ - Use descriptive test method names
+
+2. **Test naming**:
+ ```python
+ def test_chart_dark_mode(self):
+ # Tests a specific feature
+
+ def test_chart_line_style_opts(self):
+ # Tests a specific option
+ ```
+
+3. **Use mocking** for external dependencies:
+ ```python
+ @patch("pyecharts.render.engine.write_utf8_html_file")
+ def test_chart_dark_mode(self, fake_writer):
+ # Test code here
+ ```
+
+4. **Test coverage**:
+ - Aim for high test coverage
+ - Test both success and failure cases
+ - Test edge cases
+
+### Documentation
+
+1. **Docstrings**:
+ - Use Google-style docstrings
+ - Include Args, Returns, and Raises sections when applicable
+
+ ```python
+ def add_yaxis(self, series_name, y_axis, color=None):
+ """Add a series to the chart.
+
+ Args:
+ series_name (str): Name of the series.
+ y_axis (list): Data values.
+ color (str, optional): Color of the series. Defaults to None.
+
+ Returns:
+ Chart: The chart instance for method chaining.
+ """
+ ```
+
+2. **Comments**:
+ - Use comments to explain "why", not "what"
+ - Keep comments up-to-date with code changes
+
+### Best Practices
+
+1. **Method chaining**: The library supports method chaining, so return self in methods that modify the object:
+ ```python
+ def add_xaxis(self, xaxis_data):
+ self.options["xAxis"][0]["data"] = xaxis_data
+ return self # Enable method chaining
+ ```
+
+2. **Type hints**: Use type hints for better code documentation and IDE support:
+ ```python
+ def add_yaxis(self, series_name: str, y_axis: list) -> "Base":
+ # method implementation
+ return self
+ ```
+
+3. **Immutable options**: When adding options, don't modify the original option objects:
+ ```python
+ # Good - create a copy
+ self.options = deepcopy(self.options)
+
+ # Or use dict constructor
+ new_opts = dict(old_opts)
+ ```
+
+4. **Performance**: Be mindful of performance when processing large datasets.
+
+5. **Backward compatibility**: When making changes, consider backward compatibility for existing users.
+
+## Development Workflow
+
+1. **Make changes** to the code
+2. **Run tests** to ensure nothing is broken:
+ ```bash
+ make test
+ ```
+3. **Lint the code**:
+ ```bash
+ make lint
+ ```
+4. **Format the code**:
+ ```bash
+ black .
+ isort .
+ ```
+5. **Commit and push** your changes
+
+## Additional Notes
+
+- The project uses both pytest and nose2 for testing. pytest is recommended for running individual tests.
+- Coverage is configured in .coveragerc to exclude test files and templates.
+- The build process is defined in setup.py with a custom UploadCommand for publishing to PyPI.
+- JavaScript dependencies are managed through the js_dependencies attribute in Base class.
+- The default locale is Chinese (ZH), but can be changed to English (EN).
+- Charts support dark mode via set_dark_mode() method.
+- Use the render() method to generate HTML files, and render_embed() for embedding charts.
\ No newline at end of file
diff --git a/Makefile b/Makefile
new file mode 100644
index 000000000..c32b0ce1c
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,28 @@
+# Variables
+PACKAGE_NAME = pyecharts
+
+# Targets
+.PHONY: help
+help:
+ @echo "Please use \`make
-
-
-
-
-
+
+
@@ -36,18 +33,45 @@
## 📣 Introduction
-[Apache ECharts (incubating)](https://github.com/apache/incubator-echarts) is easy-to-use, highly interactive and highly performant javascript visualization library under Apache license. Since its first public release in 2013, it now dominates over 74% of Chinese web front-end market. Yet Python is an expressive language and is loved by data science community. Combining the strength of both technologies, [pyecharts](https://github.com/pyecharts/pyecharts) is born.
+[Apache ECharts](https://github.com/apache/echarts) is easy-to-use, highly interactive and highly performant javascript visualization library under Apache license. Since its first public release in 2013, it now dominates over 74% of Chinese web front-end market. Yet Python is an expressive language and is loved by data science community. Combining the strength of both technologies, [pyecharts](https://github.com/pyecharts/pyecharts) is born.
+
+* **`pyecharts like` visualization projects**
+ * [py-vchart](https://github.com/VisActor/py-vchart)
+ * [py-antv](https://github.com/sunhailin-Leo/pyantv)
## ✨ Feature highlights
* Simple API, Sleek and method chaining
* Support 30 + popular charts
-* Suppot data science tools: Jupyter Notebook, JupyterLab, nteract
+* Support data science tools: Jupyter Notebook, JupyterLab, nteract, [marimo](https://github.com/marimo-team/marimo)
* Integrate with Flask,Django at ease
* Easy to use and highly configurable
* Detailed documentation and examples.
* More than 400+ geomaps assets for geograpic information processing
+## ⏳ Version
+
+v0.5.x is not compatible with V1, which is a completely new version, see [ISSUE#892](https://github.com/pyecharts/pyecharts/issues/892), [ISSUE#1033](https://github.com/pyecharts/). pyecharts/issues/1033).
+
+### V0.5.x
+
+> Support for Python 2.7, 3.4+
+
+At the discretion of the development team, version 0.5.x will no longer be maintained. Version 0.5.x code is located in the *05x* branch and documentation is located at [05x-docs.pyecharts.org](http://05x-docs.pyecharts.org).
+
+### V1
+
+> Python 3.7+ only
+
+The new version series will start with v1.0.0, documented at [pyecharts.org](https://pyecharts.org); examples at [gallery.pyecharts.org](https://gallery.pyecharts.org)
+
+### V2
+
+> Python 3.7+ only
+
+The new version is based on Echarts 5.4.1+ for rendering, and the documentation and examples are in the same location as V1.
+
+
## 🔰 Installation
**pip install**
@@ -145,7 +169,7 @@ make_snapshot(bar.render(), "bar.png")
-For more documentaiton, please visit
+For more documentation, please visit
* [Chinese documentation](https://pyecharts.org/#/zh-cn/)
* [English Documentation](https://pyecharts.org/#/en-us/)
diff --git a/README.md b/README.md
index 5574abcd4..55d9aefa9 100644
--- a/README.md
+++ b/README.md
@@ -6,11 +6,8 @@
Python ❤️ ECharts = pyecharts
-
-
-
-
-
+
+
@@ -26,7 +23,7 @@
-
+
@@ -38,13 +35,17 @@
## 📣 简介
-[Apache ECharts (incubating)](https://github.com/apache/incubator-echarts) 是一个由百度开源的数据可视化,凭借着良好的交互性,精巧的图表设计,得到了众多开发者的认可。而 Python 是一门富有表达力的语言,很适合用于数据处理。当数据分析遇上数据可视化时,[pyecharts](https://github.com/pyecharts/pyecharts) 诞生了。
+[Apache ECharts](https://github.com/apache/echarts) 是一个由百度开源的数据可视化,凭借着良好的交互性,精巧的图表设计,得到了众多开发者的认可。而 Python 是一门富有表达力的语言,很适合用于数据处理。当数据分析遇上数据可视化时,[pyecharts](https://github.com/pyecharts/pyecharts) 诞生了。
+
+* **`pyecharts like` 的可视化项目**
+ * [py-vchart](https://github.com/VisActor/py-vchart)
+ * [py-antv](https://github.com/sunhailin-Leo/pyantv)
## ✨ 特性
* 简洁的 API 设计,使用如丝滑般流畅,支持链式调用
* 囊括了 30+ 种常见图表,应有尽有
-* 支持主流 Notebook 环境,Jupyter Notebook 和 JupyterLab
+* 支持主流 Notebook 环境,Jupyter Notebook、JupyterLab 和 [marimo](https://github.com/marimo-team/marimo)
* 可轻松集成至 Flask,Sanic,Django 等主流 Web 框架
* 高度灵活的配置项,可轻松搭配出精美的图表
* 详细的文档和示例,帮助开发者更快的上手项目
@@ -56,16 +57,22 @@ v0.5.x 和 V1 间不兼容,V1 是一个全新的版本,详见 [ISSUE#892](ht
### V0.5.x
-> 支持 Python2.7,3.4+
+> 支持 Python 2.7,3.4+
经开发团队决定,0.5.x 版本将不再进行维护,0.5.x 版本代码位于 *05x* 分支,文档位于 [05x-docs.pyecharts.org](http://05x-docs.pyecharts.org)。
### V1
-> 仅支持 Python3.6+
+> 仅支持 Python 3.7+
新版本系列将从 v1.0.0 开始,文档位于 [pyecharts.org](https://pyecharts.org);示例位于 [gallery.pyecharts.org](https://gallery.pyecharts.org)
+### V2
+
+> 仅支持 Python 3.7+
+
+新版本基于 Echarts 5.4.1+ 进行渲染, 文档和示例位置与 V1 相同
+
## 🔰 安装
**pip 安装**
@@ -234,16 +241,6 @@ pyecharts 主要由以下几位开发者开发维护
更多贡献者信息可以访问 [pyecharts/graphs/contributors](https://github.com/pyecharts/pyecharts/graphs/contributors)
-## 💌 捐赠
-
-开发和维护 pyecharts 花费了我巨大的心力,如果你觉得项目帮助到您,请认真考虑请作者喝一杯咖啡 😄
-
-| 微信二维码 | 支付宝二维码 |
-| -------- | ---------- |
-|
|
|
-
-如果其他开发者帮助到了您,也可以请他们喝咖啡 [捐赠通道](http://pyecharts.org/#/zh-cn/donate)
-
## 💡 贡献
期待能有更多的开发者参与到 pyecharts 的开发中来,我们会保证尽快 Reivew PR 并且及时回复。但提交 PR 请确保
diff --git a/appveyor.yml b/appveyor.yml
deleted file mode 100644
index ad3f1e948..000000000
--- a/appveyor.yml
+++ /dev/null
@@ -1,18 +0,0 @@
-environment:
-
- matrix:
- - PYTHON: "C:\\Python36-x64"
- PYTHON_VERSION: "3.6"
- - PYTHON: "C:\\Python37-x64"
- PYTHON_VERSION: "3.7"
- - PYTHON: "C:\\Python38-x64"
- PYTHON_VERSION: "3.8"
-
-install:
- - "%PYTHON%\\python.exe -m pip install -r requirements.txt"
- - cd test
- - "%PYTHON%\\python.exe -m pip install -r requirements.txt"
-build: off
-
-test_script:
- - "%PYTHON%/Scripts/nosetests --with-coverage --cover-package pyecharts --cover-package test && cd .. && %PYTHON%/Scripts/flake8 --exclude build --max-line-length 89 --ignore=F401"
diff --git a/make.bat b/make.bat
deleted file mode 100644
index 0ae7d7984..000000000
--- a/make.bat
+++ /dev/null
@@ -1,2 +0,0 @@
-cd test
-nosetests --with-coverage --cover-package pyecharts --cover-package test && cd .. && flake8 --exclude build --max-line-length 89 --ignore=F401
diff --git a/pyecharts/_version.py b/pyecharts/_version.py
index 957cb16d7..ae17e2131 100644
--- a/pyecharts/_version.py
+++ b/pyecharts/_version.py
@@ -1,2 +1,2 @@
-__version__ = "1.9.0"
-__author__ = "chenjiandongx"
+__version__ = "2.1.0"
+__author__ = "chenjiandongx"
diff --git a/pyecharts/charts/__init__.py b/pyecharts/charts/__init__.py
index efc966e77..42d20cfec 100644
--- a/pyecharts/charts/__init__.py
+++ b/pyecharts/charts/__init__.py
@@ -1,17 +1,22 @@
# basic Charts
+from ..charts.basic_charts.amap import AMap
from ..charts.basic_charts.bar import Bar
from ..charts.basic_charts.bmap import BMap
from ..charts.basic_charts.boxplot import Boxplot
from ..charts.basic_charts.calendar import Calendar
+from ..charts.basic_charts.chord import Chord
+from ..charts.basic_charts.custom import Custom
from ..charts.basic_charts.effectscatter import EffectScatter
from ..charts.basic_charts.funnel import Funnel
from ..charts.basic_charts.gauge import Gauge
from ..charts.basic_charts.geo import Geo
+from ..charts.basic_charts.gmap import GMap
from ..charts.basic_charts.graph import Graph
from ..charts.basic_charts.heatmap import HeatMap
from ..charts.basic_charts.kline import Kline
from ..charts.basic_charts.line import Line
from ..charts.basic_charts.liquid import Liquid
+from ..charts.basic_charts.lmap import LMap
from ..charts.basic_charts.map import Map
from ..charts.basic_charts.parallel import Parallel
from ..charts.basic_charts.pictorialbar import PictorialBar
@@ -34,7 +39,9 @@
# 3d charts
from ..charts.three_axis_charts.bar3D import Bar3D
+from ..charts.three_axis_charts.graph_gl import GraphGL
from ..charts.three_axis_charts.line3D import Line3D
+from ..charts.three_axis_charts.lines3D import Lines3D
from ..charts.three_axis_charts.map3D import Map3D
from ..charts.three_axis_charts.map_globe import MapGlobe
from ..charts.three_axis_charts.scatter3D import Scatter3D
diff --git a/pyecharts/charts/base.py b/pyecharts/charts/base.py
index 3c9d724d1..f75ebfa06 100644
--- a/pyecharts/charts/base.py
+++ b/pyecharts/charts/base.py
@@ -1,15 +1,13 @@
import datetime
import uuid
-import warnings
import simplejson as json
from jinja2 import Environment
from ..commons import utils
-from ..globals import CurrentConfig, RenderType, ThemeType, WarningType
-from ..options import InitOpts
-from ..options.global_options import AnimationOpts
-from ..options.series_options import BasicOpts
+from ..globals import CurrentConfig, Locale, RenderType, ThemeType, DefaultLocale
+from ..options import InitOpts, RenderOpts
+from ..options.series_options import BasicOpts, AnimationOpts
from ..render import engine
from ..types import Optional, Sequence, Union
from .mixins import ChartMixin
@@ -21,25 +19,64 @@ class Base(ChartMixin):
part of the initialization parameters and common methods
"""
- def __init__(self, init_opts: Union[InitOpts, dict] = InitOpts()):
+ def __init__(
+ self,
+ init_opts: Union[InitOpts, dict] = InitOpts(),
+ render_opts: Union[RenderOpts, dict] = RenderOpts(),
+ ):
_opts = init_opts
if isinstance(init_opts, InitOpts):
_opts = init_opts.opts
+ _render_opts = render_opts
+ if isinstance(render_opts, RenderOpts):
+ _render_opts = render_opts.opts
+
self.width = _opts.get("width", "900px")
self.height = _opts.get("height", "500px")
+ self.horizontal_center = (
+ "text-align:center; margin: auto"
+ if _opts.get("is_horizontal_center", False)
+ else ""
+ )
self.renderer = _opts.get("renderer", RenderType.CANVAS)
+ self.locale = (
+ CurrentConfig.LOCALE if
+ getattr(Locale, CurrentConfig.LOCALE, False)
+ else DefaultLocale
+ )
self.page_title = _opts.get("page_title", CurrentConfig.PAGE_TITLE)
self.theme = _opts.get("theme", ThemeType.WHITE)
self.chart_id = _opts.get("chart_id") or uuid.uuid4().hex
+ self.fill_bg = _opts.get("fill_bg", False)
+ self.bg_color = _opts.get("bg_color")
self.options: dict = {}
+ self.render_options: dict = {}
self.js_host: str = _opts.get("js_host") or CurrentConfig.ONLINE_HOST
self.js_functions: utils.OrderedSet = utils.OrderedSet()
self.js_dependencies: utils.OrderedSet = utils.OrderedSet("echarts")
- self.options.update(backgroundColor=_opts.get("bg_color"))
- self.options.update(_opts.get("animationOpts", AnimationOpts()).opts)
+ self.js_events: utils.OrderedSet = utils.OrderedSet()
+ self.options.update(backgroundColor=self.bg_color)
+ if isinstance(_opts.get("animationOpts", AnimationOpts()), dict):
+ self.options.update(_opts.get("animationOpts", AnimationOpts().opts))
+ else:
+ self.options.update(_opts.get("animationOpts", AnimationOpts()).opts)
+ self.options.update(aria=_opts.get("ariaOpts"))
+
self._is_geo_chart: bool = False
+ self._geo_json_name: Optional[str] = None
+ self._geo_json: Optional[dict] = None
+
+ self.render_options.update(embed_js=bool(_render_opts.get("embed_js")))
+ self._render_cache: dict = dict()
+
+ def use_echarts_stat(self):
+ self.js_dependencies.add("echarts-stat")
+ return self
+
+ def get_chart_id(self) -> str:
+ return self.chart_id
def get_options(self) -> dict:
return utils.remove_key_with_none_value(self.options)
@@ -88,6 +125,12 @@ def _prepare_render(self):
self.json_contents = self.dump_options()
self._use_theme()
+ self._render_cache.clear()
+ if self.render_options.get("embed_js"):
+ self._render_cache[
+ "javascript"
+ ] = self.load_javascript().load_javascript_contents()
+
def default(o):
if isinstance(o, (datetime.date, datetime.datetime)):
diff --git a/pyecharts/charts/basic_charts/amap.py b/pyecharts/charts/basic_charts/amap.py
new file mode 100644
index 000000000..e51efdcbc
--- /dev/null
+++ b/pyecharts/charts/basic_charts/amap.py
@@ -0,0 +1,91 @@
+from ... import options as opts
+from ... import types
+from ...charts.basic_charts.geo import GeoChartBase
+from ...commons.utils import OrderedSet, JsCode
+from ...exceptions import NonexistentCoordinatesException
+from ...globals import ChartType
+
+AMAP_API = "https://webapi.amap.com/maps?v=2.0&key={}&plugin=AMap.Scale,AMap.ToolBar"
+
+
+class AMap(GeoChartBase):
+ """
+ <<< AMap(GaoDe) coordinate system >>>
+
+ Support scatter plot, line.
+ """
+
+ def __init__(
+ self,
+ init_opts: types.Init = opts.InitOpts(),
+ is_ignore_nonexistent_coord: bool = False,
+ render_opts: types.RenderInit = opts.RenderOpts(),
+ ):
+ super().__init__(init_opts=init_opts, render_opts=render_opts)
+ self.js_dependencies.add("amap")
+ self._is_geo_chart = True
+ self._coordinate_system: types.Optional[str] = "amap"
+ self.amap_js_functions: OrderedSet = OrderedSet()
+ self._is_ignore_nonexistent_coord = is_ignore_nonexistent_coord
+
+ def _feed_data(self, data_pair: types.Sequence, type_: str) -> types.Sequence:
+ result = []
+ type_list = [ChartType.LINES, ChartType.CUSTOM]
+ if type_ in type_list:
+ result = data_pair
+ else:
+ for n, v in data_pair:
+ try:
+ lng, lat = self.get_coordinate(n)
+ result.append({"name": n, "value": [lng, lat, v]})
+ except TypeError as err:
+ if self._is_ignore_nonexistent_coord is not True:
+ raise NonexistentCoordinatesException(err, (n, v))
+ return result
+
+ def add_schema(
+ self,
+ amap_ak: str,
+ center: types.Sequence,
+ zoom: types.Union[types.Numeric, str] = None,
+ is_enable_resize: bool = True,
+ map_style: types.Optional[dict] = None,
+ is_render_on_map: bool = True,
+ is_layer_interactive: bool = True,
+ is_large: bool = False,
+ ):
+ self.js_dependencies.add(AMAP_API.format(amap_ak))
+ self.options.update(
+ amap={
+ "center": center,
+ "viewMode": "3D", # default
+ "zoom": zoom,
+ "resizeEnable": is_enable_resize,
+ "mapStyle": map_style,
+ "renderOnMoving": is_render_on_map,
+ "echartsLayerInteractive": is_layer_interactive,
+ "largeMode": is_large,
+ }
+ )
+ if is_layer_interactive:
+ self.amap_js_functions.add(
+ "amapComponent.setEChartsLayerInteractive(true);"
+ )
+
+ return self
+
+ def add_control_panel(
+ self,
+ is_add_satellite_layer: bool = False,
+ is_add_road_net_layer: bool = False,
+ ):
+ if is_add_satellite_layer:
+ self.amap_js_functions.add(
+ "amap.add(new AMap.TileLayer.Satellite());",
+ )
+ if is_add_road_net_layer:
+ self.amap_js_functions.add(
+ "amap.add(new AMap.TileLayer.RoadNet());",
+ )
+
+ return self
diff --git a/pyecharts/charts/basic_charts/bar.py b/pyecharts/charts/basic_charts/bar.py
index 59612d68c..370be4804 100644
--- a/pyecharts/charts/basic_charts/bar.py
+++ b/pyecharts/charts/basic_charts/bar.py
@@ -17,14 +17,24 @@ def add_yaxis(
series_name: str,
y_axis: types.Sequence[types.Union[types.Numeric, opts.BarItem, dict]],
*,
- is_selected: bool = True,
+ coordinate_system: types.Optional[str] = None,
+ coordinate_system_usage: types.Optional[str] = None,
+ coord: types.Union[types.Sequence, types.Numeric, str] = None,
xaxis_index: types.Optional[types.Numeric] = None,
yaxis_index: types.Optional[types.Numeric] = None,
+ polar_index: types.Optional[types.Numeric] = None,
+ is_round_cap: types.Optional[bool] = None,
+ color_by: types.Optional[str] = None,
is_legend_hover_link: bool = True,
color: types.Optional[str] = None,
+ is_realtime_sort: bool = False,
is_show_background: bool = False,
background_style: types.Union[types.BarBackground, dict, None] = None,
stack: types.Optional[str] = None,
+ stack_strategy: types.Optional[str] = "samesign",
+ stack_order: types.Optional[str] = None,
+ sampling: types.Optional[str] = None,
+ cursor: types.Optional[str] = "pointer",
bar_width: types.Union[types.Numeric, str] = None,
bar_max_width: types.Union[types.Numeric, str] = None,
bar_min_width: types.Union[types.Numeric, str] = None,
@@ -33,6 +43,9 @@ def add_yaxis(
gap: types.Optional[str] = "30%",
is_large: bool = False,
large_threshold: types.Numeric = 400,
+ progressive: types.Optional[types.Numeric] = None,
+ progressive_threshold: types.Optional[types.Numeric] = None,
+ progressive_chunk_mode: types.Optional[str] = None,
dimensions: types.Union[types.Sequence, None] = None,
series_layout_by: str = "column",
dataset_index: types.Numeric = 0,
@@ -42,12 +55,16 @@ def add_yaxis(
label_opts: types.Label = opts.LabelOpts(),
markpoint_opts: types.MarkPoint = None,
markline_opts: types.MarkLine = None,
+ markarea_opts: types.MarkArea = None,
tooltip_opts: types.Tooltip = None,
itemstyle_opts: types.ItemStyle = None,
+ emphasis_opts: types.Emphasis = None,
+ blur_opts: types.Blur = None,
+ select_opts: types.Select = None,
encode: types.Union[types.JSFunc, dict, None] = None,
):
self._append_color(color)
- self._append_legend(series_name, is_selected)
+ self._append_legend(series_name)
if self.options.get("dataset") is not None:
y_axis = None
@@ -56,13 +73,24 @@ def add_yaxis(
{
"type": ChartType.BAR,
"name": series_name,
+ "coordinateSystem": coordinate_system,
+ "coordinateSystemUsage": coordinate_system_usage,
+ "coord": coord,
"xAxisIndex": xaxis_index,
"yAxisIndex": yaxis_index,
+ "polarIndex": polar_index,
+ "roundCap": is_round_cap,
+ "colorBy": color_by,
"legendHoverLink": is_legend_hover_link,
"data": y_axis,
+ "realtimeSort": is_realtime_sort,
"showBackground": is_show_background,
"backgroundStyle": background_style,
"stack": stack,
+ "stackStrategy": stack_strategy,
+ "stackOrder": stack_order,
+ "sampling": sampling,
+ "cursor": cursor,
"barWidth": bar_width,
"barMaxWidth": bar_max_width,
"barMinWidth": bar_min_width,
@@ -71,6 +99,9 @@ def add_yaxis(
"barGap": gap,
"large": is_large,
"largeThreshold": large_threshold,
+ "progressive": progressive,
+ "progressiveThreshold": progressive_threshold,
+ "progressiveChunkMode": progressive_chunk_mode,
"dimensions": dimensions,
"seriesLayoutBy": series_layout_by,
"datasetIndex": dataset_index,
@@ -80,8 +111,12 @@ def add_yaxis(
"label": label_opts,
"markPoint": markpoint_opts,
"markLine": markline_opts,
+ "markArea": markarea_opts,
"tooltip": tooltip_opts,
"itemStyle": itemstyle_opts,
+ "emphasis": emphasis_opts,
+ "blur": blur_opts,
+ "select": select_opts,
"encode": encode,
}
)
diff --git a/pyecharts/charts/basic_charts/bmap.py b/pyecharts/charts/basic_charts/bmap.py
index 1d8a3ee07..bf1e29f9c 100644
--- a/pyecharts/charts/basic_charts/bmap.py
+++ b/pyecharts/charts/basic_charts/bmap.py
@@ -20,8 +20,9 @@ def __init__(
self,
init_opts: types.Init = opts.InitOpts(),
is_ignore_nonexistent_coord: bool = False,
+ render_opts: types.RenderInit = opts.RenderOpts(),
):
- super().__init__(init_opts=init_opts)
+ super().__init__(init_opts=init_opts, render_opts=render_opts)
self.js_dependencies.add("bmap")
self._is_geo_chart = True
self._coordinate_system: types.Optional[str] = "bmap"
diff --git a/pyecharts/charts/basic_charts/boxplot.py b/pyecharts/charts/basic_charts/boxplot.py
index b53d242c2..5d52e1813 100644
--- a/pyecharts/charts/basic_charts/boxplot.py
+++ b/pyecharts/charts/basic_charts/boxplot.py
@@ -16,30 +16,75 @@ class Boxplot(RectChart):
def add_yaxis(
self,
series_name: str,
- y_axis: types.Sequence[types.Union[opts.BoxplotItem, dict]],
+ y_axis: types.Optional[
+ types.Sequence[types.Union[opts.BoxplotItem, dict]]
+ ] = None,
*,
- is_selected: bool = True,
+ chart_type: str = ChartType.BOXPLOT,
+ coordinate_system: types.Optional[str] = None,
+ coordinate_system_usage: types.Optional[str] = None,
+ coord: types.Union[types.Sequence, types.Numeric, str] = None,
xaxis_index: types.Optional[types.Numeric] = None,
+ xaxis_id: types.Optional[types.Numeric] = None,
yaxis_index: types.Optional[types.Numeric] = None,
+ yaxis_id: types.Optional[types.Numeric] = None,
+ dataset_index: types.Optional[types.Numeric] = None,
+ color_by: types.Optional[str] = None,
+ is_legend_hover_link: bool = True,
+ is_hover_animation: bool = True,
+ layout: types.Optional[str] = None,
+ box_width: types.Optional[types.Sequence] = None,
+ selected_mode: types.Union[bool, str] = False,
+ dimensions: types.Union[types.Sequence, None] = None,
label_opts: types.Label = opts.LabelOpts(),
markpoint_opts: types.MarkPoint = opts.MarkPointOpts(),
markline_opts: types.MarkLine = opts.MarkLineOpts(),
+ markarea_opts: types.MarkArea = None,
+ z_level: types.Numeric = 0,
+ z: types.Numeric = 2,
tooltip_opts: types.Tooltip = None,
itemstyle_opts: types.ItemStyle = None,
+ emphasis_opts: types.Emphasis = None,
+ blur_opts: types.Blur = None,
+ select_opts: types.Select = None,
+ encode: types.Union[types.JSFunc, dict, None] = None,
):
- self._append_legend(series_name, is_selected)
+ if box_width is None:
+ box_width = [7, 50]
+
+ self._append_legend(series_name)
self.options.get("series").append(
{
- "type": ChartType.BOXPLOT,
+ "type": chart_type,
"name": series_name,
+ "coordinateSystem": coordinate_system,
+ "coordinateSystemUsage": coordinate_system_usage,
+ "coord": coord,
"xAxisIndex": xaxis_index,
+ "xAxisId": xaxis_id,
"yAxisIndex": yaxis_index,
+ "yAxisId": yaxis_id,
+ "datasetIndex": dataset_index,
+ "colorBy": color_by,
+ "legendHoverLink": is_legend_hover_link,
+ "hoverAnimation": is_hover_animation,
+ "layout": layout,
+ "boxWidth": box_width,
+ "selectedMode": selected_mode,
+ "dimensions": dimensions,
"data": y_axis,
"label": label_opts,
"markPoint": markpoint_opts,
"markLine": markline_opts,
+ "markArea": markarea_opts,
+ "zlevel": z_level,
+ "z": z,
"tooltip": tooltip_opts,
"itemStyle": itemstyle_opts,
+ "emphasis": emphasis_opts,
+ "blur": blur_opts,
+ "select": select_opts,
+ "encode": encode,
}
)
return self
@@ -48,6 +93,8 @@ def add_yaxis(
def prepare_data(items):
data = []
for item in items:
+ if not item:
+ data.append([])
try:
d, res = sorted(item), []
for i in range(1, 4):
@@ -63,6 +110,7 @@ def prepare_data(items):
elif m == 3 / 4:
res.append(d[k - 1] * 0.25 + d[k] * 0.75)
data.append([d[0]] + res + [d[-1]])
- except Exception:
- pass
+ except TypeError:
+ # one of the item element is None
+ data.append([])
return data
diff --git a/pyecharts/charts/basic_charts/calendar.py b/pyecharts/charts/basic_charts/calendar.py
index eff3d7b54..ed565b87c 100644
--- a/pyecharts/charts/basic_charts/calendar.py
+++ b/pyecharts/charts/basic_charts/calendar.py
@@ -1,6 +1,7 @@
from ... import options as opts
from ... import types
from ...charts.chart import Chart
+from ...globals import ChartType
class Calendar(Chart):
@@ -12,34 +13,50 @@ class Calendar(Chart):
Two categories of axes must be used in rectangular coordinates.
"""
- def __init__(self, init_opts: types.Init = opts.InitOpts()):
- super().__init__(init_opts=init_opts)
- self.options.update(calendar=opts.CalendarOpts().opts)
+ def __init__(
+ self,
+ init_opts: types.Init = opts.InitOpts(),
+ render_opts: types.RenderInit = opts.RenderOpts(),
+ ):
+ super().__init__(init_opts=init_opts, render_opts=render_opts)
def add(
self,
series_name: str,
yaxis_data: types.Sequence,
*,
- is_selected: bool = True,
- label_opts: types.Label = opts.LabelOpts(),
- calendar_opts: types.Calendar = None,
+ type_: types.Union[str, ChartType] = ChartType.HEATMAP,
+ calendar_index: types.Optional[types.Numeric] = None,
+ label_opts: types.Label = opts.LabelOpts(is_show=False, position="inside"),
+ calendar_opts: types.Union[types.Calendar, types.List[types.Calendar]] = None,
tooltip_opts: types.Tooltip = None,
itemstyle_opts: types.ItemStyle = None,
+ visualmap_opts: types.VisualMap = None,
+ emphasis_opts: types.Emphasis = None,
+ **other_calendar_opts,
):
if calendar_opts:
- self.options.update(calendar=calendar_opts)
+ if self.options.get("calendar"):
+ self.options.get("calendar").append(calendar_opts)
+ else:
+ self.options.update(calendar=[calendar_opts])
+
+ if visualmap_opts:
+ self.options.update(visualMap=visualmap_opts)
- self._append_legend(series_name, is_selected)
+ self._append_legend(series_name)
self.options.get("series").append(
{
- "type": "heatmap",
+ "type": type_,
"coordinateSystem": "calendar",
+ "calendarIndex": calendar_index,
"name": series_name,
"data": yaxis_data,
"label": label_opts,
"tooltip": tooltip_opts,
"itemStyle": itemstyle_opts,
+ "emphasis": emphasis_opts,
+ **other_calendar_opts,
}
)
return self
diff --git a/pyecharts/charts/basic_charts/chord.py b/pyecharts/charts/basic_charts/chord.py
new file mode 100644
index 000000000..bd45997d0
--- /dev/null
+++ b/pyecharts/charts/basic_charts/chord.py
@@ -0,0 +1,74 @@
+from ... import types
+from ...charts.chart import Chart
+from ...globals import ChartType
+
+
+class Chord(Chart):
+ """
+ <<< Chord >>>
+
+ The chord diagram visually presents the flow and weights
+ within complex relationship networks, making it particularly
+ suitable for multidimensional relationship analysis in scenarios
+ such as financial transactions and social networks.
+ """
+
+ def add(
+ self,
+ series_name: str,
+ data: types.Sequence[types.ChordData],
+ links: types.Sequence[types.ChordLink],
+ *,
+ is_clockwise: bool = False,
+ coordinate_system: types.Optional[str] = None,
+ coordinate_system_usage: types.Optional[str] = None,
+ coord: types.Union[types.Sequence, types.Numeric, str] = None,
+ color_by: types.Optional[str] = None,
+ pos_left: types.Optional[str] = None,
+ pos_top: types.Optional[str] = None,
+ pos_right: types.Optional[str] = None,
+ pos_bottom: types.Optional[str] = None,
+ width: types.Optional[str] = None,
+ height: types.Optional[str] = None,
+ center: types.Optional[types.Sequence] = None,
+ radius: types.Optional[types.Union[types.Sequence, str]] = None,
+ start_angle: types.Numeric = 90,
+ end_angle: types.Optional[types.Numeric] = None,
+ min_angle: types.Optional[types.Numeric] = None,
+ pad_angle: types.Optional[types.Numeric] = None,
+ tooltip_opts: types.Tooltip = None,
+ label_opts: types.Label = None,
+ linestyle_opts: types.LineStyle = None,
+ itemstyle_opts: types.ItemStyle = None,
+ emphasis_opts: types.Emphasis = None,
+ ):
+ self.options.get("series").append({
+ "type": ChartType.CHORD,
+ "name": series_name,
+ "data": data,
+ "links": links,
+ "clockwise": is_clockwise,
+ "coordinateSystem": coordinate_system,
+ "coordinateSystemUsage": coordinate_system_usage,
+ "coord": coord,
+ "colorBy": color_by,
+ "left": pos_left,
+ "top": pos_top,
+ "right": pos_right,
+ "bottom": pos_bottom,
+ "width": width,
+ "height": height,
+ "center": center,
+ "radius": radius,
+ "startAngle": start_angle,
+ "endAngle": end_angle,
+ "minAngle": min_angle,
+ "padAngle": pad_angle,
+ "tooltip": tooltip_opts,
+ "label": label_opts,
+ "lineStyle": linestyle_opts,
+ "itemStyle": itemstyle_opts,
+ "emphasis": emphasis_opts,
+ })
+
+ return self
diff --git a/pyecharts/charts/basic_charts/custom.py b/pyecharts/charts/basic_charts/custom.py
new file mode 100644
index 000000000..6978a41f7
--- /dev/null
+++ b/pyecharts/charts/basic_charts/custom.py
@@ -0,0 +1,139 @@
+from ... import options as opts
+from ... import types
+from ...charts.chart import Chart
+from ...globals import ChartType
+
+
+class Custom(Chart):
+ """
+ <<< Custom >>>
+
+ Custom series allows you to customize the rendering of graphical elements
+ in the series. This enables the extension of different charts.
+ """
+
+ def register_echarts_x(self, chart_type: str):
+ if chart_type not in [
+ ChartType.VIOLIN,
+ ChartType.STAGE,
+ ChartType.DOUGHNUT,
+ ChartType.CONTOUR,
+ ChartType.BAR_RANGE,
+ ChartType.LINE_RANGE,
+ ]:
+ raise ValueError(f"Not support register this chart type: {chart_type}")
+
+ if chart_type == ChartType.VIOLIN:
+ self.js_dependencies.add("echarts-x-violin")
+ self.options.update(xAxis=[{}], yAxis=[{}])
+
+ if chart_type == ChartType.STAGE:
+ self.js_dependencies.add("echarts-x-stage")
+ self.options.update(xAxis=[{}], yAxis=[{}])
+
+ if chart_type == ChartType.DOUGHNUT:
+ self.js_dependencies.add("echarts-x-segmented-doughnut")
+
+ if chart_type == ChartType.LINE_RANGE:
+ self.js_dependencies.add("echarts-x-line-range")
+ self.options.update(xAxis=[{}], yAxis=[{}])
+
+ if chart_type == ChartType.CONTOUR:
+ self.js_dependencies.add("echarts-x-contour-d3")
+ self.js_dependencies.add("echarts-x-contour")
+ self.options.update(xAxis=[{}], yAxis=[{}])
+
+ if chart_type == ChartType.BAR_RANGE:
+ self.js_dependencies.add("echarts-x-bar-range")
+ self.options.update(xAxis=[{}], yAxis=[{}])
+
+ return self
+
+ def add_xaxis(self, xaxis_data: types.Sequence):
+ self.options["xAxis"][0].update(data=xaxis_data)
+ self._xaxis_data = xaxis_data
+ return self
+
+ def add(
+ self,
+ series_name: str,
+ render_item: types.JSFunc,
+ *,
+ type_: str = ChartType.CUSTOM,
+ color_by: str = "series",
+ is_legend_hover_link: bool = True,
+ coordinate_system: str = "cartesian2d",
+ coordinate_system_usage: types.Optional[str] = None,
+ coord: types.Union[types.Sequence, types.Numeric, str] = None,
+ x_axis_index: types.Numeric = 0,
+ xaxis_id: types.Optional[types.Numeric] = None,
+ y_axis_index: types.Numeric = 0,
+ yaxis_id: types.Optional[types.Numeric] = None,
+ polar_index: types.Numeric = 0,
+ polar_id: types.Optional[types.Numeric] = None,
+ single_axis_index: types.Optional[types.Numeric] = None,
+ single_axis_id: types.Optional[types.Numeric] = None,
+ geo_index: types.Numeric = 0,
+ geo_id: types.Optional[types.Numeric] = None,
+ calendar_index: types.Numeric = 0,
+ calendar_id: types.Optional[types.Numeric] = None,
+ matrix_index: types.Optional[types.Numeric] = None,
+ matrix_id: types.Optional[types.Numeric] = None,
+ dataset_index: types.Numeric = 0,
+ series_layout_by: str = "column",
+ selected_mode: types.Union[bool, str] = False,
+ dimensions: types.Optional[types.Sequence] = None,
+ encode: types.Union[types.Sequence, dict, None] = None,
+ data: types.Optional[types.Sequence] = None,
+ is_clip: bool = True,
+ z_level: types.Numeric = 0,
+ z: types.Numeric = 2,
+ itemstyle_opts: types.ItemStyle = None,
+ tooltip_opts: types.Tooltip = None,
+ label_opts: types.Label = None,
+ emphasis_opts: types.Emphasis = None,
+ item_payload_opts: types.CustomItemPayload = None,
+ ):
+ self._append_legend(series_name)
+
+ self.options.get("series").append(
+ {
+ "type": type_,
+ "name": series_name,
+ "renderItem": render_item,
+ "colorBy": color_by,
+ "legendHoverLink": is_legend_hover_link,
+ "coordinateSystem": coordinate_system,
+ "coordinateSystemUsage": coordinate_system_usage,
+ "coord": coord,
+ "xAxisIndex": x_axis_index,
+ "xAxisId": xaxis_id,
+ "yAxisIndex": y_axis_index,
+ "yAxisId": yaxis_id,
+ "polarIndex": polar_index,
+ "polarId": polar_id,
+ "singleAxisIndex": single_axis_index,
+ "singleAxisId": single_axis_id,
+ "geoIndex": geo_index,
+ "geoId": geo_id,
+ "calendarIndex": calendar_index,
+ "calendarId": calendar_id,
+ "matrixIndex": matrix_index,
+ "matrixId": matrix_id,
+ "datasetIndex": dataset_index,
+ "seriesLayoutBy": series_layout_by,
+ "itemStyle": itemstyle_opts,
+ "selectedMode": selected_mode,
+ "dimensions": dimensions,
+ "encode": encode,
+ "data": data,
+ "clip": is_clip,
+ "zlevel": z_level,
+ "z": z,
+ "tooltip": tooltip_opts,
+ "label": label_opts,
+ "emphasis": emphasis_opts,
+ "itemPayload": item_payload_opts,
+ }
+ )
+ return self
diff --git a/pyecharts/charts/basic_charts/effectscatter.py b/pyecharts/charts/basic_charts/effectscatter.py
index fe8534fdc..5b57901aa 100644
--- a/pyecharts/charts/basic_charts/effectscatter.py
+++ b/pyecharts/charts/basic_charts/effectscatter.py
@@ -16,20 +16,44 @@ def add_yaxis(
series_name: str,
y_axis: types.Sequence[types.Union[opts.EffectScatterItem, dict]],
*,
- is_selected: bool = True,
xaxis_index: types.Optional[types.Numeric] = None,
+ xaxis_id: types.Optional[types.Numeric] = None,
yaxis_index: types.Optional[types.Numeric] = None,
+ yaxis_id: types.Optional[types.Numeric] = None,
+ polar_index: types.Optional[types.Numeric] = None,
+ polar_id: types.Optional[types.Numeric] = None,
+ geo_index: types.Optional[types.Numeric] = None,
+ geo_id: types.Optional[types.Numeric] = None,
+ calendar_index: types.Optional[types.Numeric] = None,
+ calendar_id: types.Optional[types.Numeric] = None,
+ matrix_index: types.Optional[types.Numeric] = None,
+ matrix_id: types.Optional[types.Numeric] = None,
+ dataset_index: types.Optional[types.Numeric] = None,
color: types.Optional[str] = None,
+ color_by: types.Optional[str] = None,
+ is_legend_hover_link: bool = True,
+ show_effect_on: str = "render",
+ coordinate_system: str = "cartesian2d",
+ coordinate_system_usage: types.Optional[str] = None,
+ coord: types.Union[types.Sequence, types.Numeric, str] = None,
symbol: types.Optional[str] = None,
symbol_size: types.Numeric = 10,
symbol_rotate: types.Optional[types.Numeric] = None,
+ selected_mode: types.Union[bool, str] = False,
label_opts: types.Label = opts.LabelOpts(),
effect_opts: types.Effect = opts.EffectOpts(),
tooltip_opts: types.Tooltip = None,
itemstyle_opts: types.ItemStyle = None,
+ emphasis_opts: types.Emphasis = None,
+ markpoint_opts: types.MarkPoint = None,
+ markline_opts: types.MarkLine = None,
+ markarea_opts: types.MarkArea = None,
+ z_level: types.Numeric = 0,
+ z: types.Numeric = 2,
+ encode: types.Union[types.JSFunc, dict, None] = None,
):
self._append_color(color)
- self._append_legend(series_name, is_selected)
+ self._append_legend(series_name)
if all([isinstance(d, opts.EffectScatterItem) for d in y_axis]):
y_axis = y_axis
@@ -41,16 +65,40 @@ def add_yaxis(
"type": ChartType.EFFECT_SCATTER,
"name": series_name,
"xAxisIndex": xaxis_index,
+ "xAxisId": xaxis_id,
"yAxisIndex": yaxis_index,
- "showEffectOn": "render",
+ "yAxisId": yaxis_id,
+ "polarIndex": polar_index,
+ "polarId": polar_id,
+ "geoIndex": geo_index,
+ "geoId": geo_id,
+ "calendarIndex": calendar_index,
+ "calendarId": calendar_id,
+ "matrixIndex": matrix_index,
+ "matrixId": matrix_id,
+ "colorBy": color_by,
+ "legendHoverLink": is_legend_hover_link,
+ "showEffectOn": show_effect_on,
"rippleEffect": effect_opts,
+ "coordinateSystem": coordinate_system,
+ "coordinateSystemUsage": coordinate_system_usage,
+ "coord": coord,
+ "datasetIndex": dataset_index,
"symbol": symbol,
"symbolSize": symbol_size,
"symbolRotate": symbol_rotate,
+ "selectedMode": selected_mode,
"data": y_axis,
"label": label_opts,
"tooltip": tooltip_opts,
"itemStyle": itemstyle_opts,
+ "emphasis": emphasis_opts,
+ "markPoint": markpoint_opts,
+ "markLine": markline_opts,
+ "markArea": markarea_opts,
+ "zlevel": z_level,
+ "z": z,
+ "encode": encode,
}
)
return self
diff --git a/pyecharts/charts/basic_charts/funnel.py b/pyecharts/charts/basic_charts/funnel.py
index af191012d..454cc2259 100644
--- a/pyecharts/charts/basic_charts/funnel.py
+++ b/pyecharts/charts/basic_charts/funnel.py
@@ -20,23 +20,52 @@ def add(
series_name: str,
data_pair: types.Sequence,
*,
- is_selected: bool = True,
color: types.Optional[str] = None,
+ color_by: types.Optional[str] = None,
+ coordinate_system: types.Optional[str] = None,
+ coordinate_system_usage: types.Optional[str] = None,
+ coord: types.Union[types.Sequence, types.Numeric, str] = None,
+ calendar_index: types.Optional[types.Numeric] = None,
+ calendar_id: types.Optional[types.Numeric] = None,
+ matrix_index: types.Optional[types.Numeric] = None,
+ matrix_id: types.Optional[types.Numeric] = None,
+ min_: types.Numeric = 0,
+ max_: types.Numeric = 100,
+ min_size: types.Union[str, types.Numeric] = "0%",
+ max_size: types.Union[str, types.Numeric] = "100%",
+ orient: str = "vertical",
sort_: str = "descending",
gap: types.Numeric = 0,
+ is_legend_hover_link: bool = True,
+ funnel_align: str = "center",
label_opts: types.Label = opts.LabelOpts(),
tooltip_opts: types.Tooltip = None,
itemstyle_opts: types.ItemStyle = None,
+ emphasis_opts: types.Emphasis = None,
+ selected_mode: types.Union[bool, str] = False,
+ z_level: types.Numeric = 0,
+ z: types.Numeric = 2,
+ pos_top: types.Union[str, types.Numeric, None] = None,
+ pos_left: types.Union[str, types.Numeric, None] = None,
+ pos_bottom: types.Union[str, types.Numeric, None] = None,
+ pos_right: types.Union[str, types.Numeric, None] = None,
+ width: types.Union[str, types.Numeric, None] = None,
+ height: types.Union[str, types.Numeric, None] = None,
+ dataset_index: types.Optional[types.Numeric] = None,
+ encode: types.Union[types.JSFunc, dict, None] = None,
+ markpoint_opts: types.MarkPoint = None,
+ markline_opts: types.MarkLine = None,
+ markarea_opts: types.MarkArea = None,
):
self._append_color(color)
if all([isinstance(d, opts.FunnelItem) for d in data_pair]):
data = data_pair
for a in data_pair:
- self._append_legend(a.opts.get("name"), is_selected)
+ self._append_legend(a.opts.get("name"))
else:
data = [{"name": n, "value": v} for n, v in data_pair]
for a, _ in data_pair:
- self._append_legend(a, is_selected)
+ self._append_legend(a)
_dset = set(self.options.get("legend")[0].get("data"))
self.options.get("legend")[0].update(data=list(_dset))
@@ -46,11 +75,41 @@ def add(
"type": ChartType.FUNNEL,
"name": series_name,
"data": data,
+ "colorBy": color_by,
+ "coordinateSystem": coordinate_system,
+ "coordinateSystemUsage": coordinate_system_usage,
+ "coord": coord,
+ "calendarIndex": calendar_index,
+ "calendarId": calendar_id,
+ "matrixIndex": matrix_index,
+ "matrixId": matrix_id,
+ "min": min_,
+ "max": max_,
+ "minSize": min_size,
+ "maxSize": max_size,
+ "orient": orient,
"sort": sort_,
"gap": gap,
+ "legendHoverLink": is_legend_hover_link,
+ "funnelAlign": funnel_align,
"label": label_opts,
"tooltip": tooltip_opts,
"itemStyle": itemstyle_opts,
+ "emphasis": emphasis_opts,
+ "selectedMode": selected_mode,
+ "zlevel": z_level,
+ "z": z,
+ "left": pos_left,
+ "right": pos_right,
+ "top": pos_top,
+ "bottom": pos_bottom,
+ "width": width,
+ "height": height,
+ "datasetIndex": dataset_index,
+ "encode": encode,
+ "markPoint": markpoint_opts,
+ "markLine": markline_opts,
+ "markArea": markarea_opts,
}
)
return self
diff --git a/pyecharts/charts/basic_charts/gauge.py b/pyecharts/charts/basic_charts/gauge.py
index ab80597a7..581aa1141 100644
--- a/pyecharts/charts/basic_charts/gauge.py
+++ b/pyecharts/charts/basic_charts/gauge.py
@@ -16,25 +16,42 @@ def add(
series_name: str,
data_pair: types.Sequence,
*,
- is_selected: bool = True,
min_: types.Numeric = 0,
max_: types.Numeric = 100,
split_number: types.Numeric = 10,
+ center: types.Sequence = None,
radius: types.Union[types.Numeric, str] = "75%",
+ coordinate_system: types.Optional[str] = None,
+ coordinate_system_usage: types.Optional[str] = None,
+ coord: types.Union[types.Sequence, types.Numeric, str] = None,
+ calendar_index: types.Optional[types.Numeric] = None,
+ calendar_id: types.Optional[types.Numeric] = None,
+ matrix_index: types.Optional[types.Numeric] = None,
+ matrix_id: types.Optional[types.Numeric] = None,
start_angle: types.Numeric = 225,
end_angle: types.Numeric = -45,
is_clock_wise: bool = True,
- title_label_opts: types.GaugeTitle = opts.GaugeTitleOpts(),
+ title_label_opts: types.GaugeTitle = opts.GaugeTitleOpts(
+ offset_center=["0%", "20%"],
+ ),
detail_label_opts: types.GaugeDetail = opts.GaugeDetailOpts(
- formatter="{value}%"
+ formatter="{value}%",
+ offset_center=["0%", "40%"],
),
+ progress: types.GaugeProgress = opts.GaugeProgressOpts(),
pointer: types.GaugePointer = opts.GaugePointerOpts(),
+ anchor: types.GaugeAnchor = opts.GaugeAnchorOpts(),
tooltip_opts: types.Tooltip = None,
axisline_opts: types.AxisLine = None,
+ axistick_opts: types.AxisTick = None,
+ axislabel_opts: types.AxisLabel = None,
itemstyle_opts: types.ItemStyle = None,
+ emphasis_opts: types.Emphasis = None,
):
+ if center is None:
+ center = ["50%", "50%"]
- self._append_legend(series_name, is_selected)
+ self._append_legend(series_name)
self.options.get("series").append(
{
"type": ChartType.GAUGE,
@@ -44,15 +61,28 @@ def add(
"min": min_,
"max": max_,
"splitNumber": split_number,
+ "center": center,
"radius": radius,
+ "coordinateSystem": coordinate_system,
+ "coordinateSystemUsage": coordinate_system_usage,
+ "coord": coord,
+ "calendarIndex": calendar_index,
+ "calendarId": calendar_id,
+ "matrixIndex": matrix_index,
+ "matrixId": matrix_id,
"startAngle": start_angle,
"endAngle": end_angle,
"clockwise": is_clock_wise,
"data": [{"name": n, "value": v} for n, v in data_pair],
"tooltip": tooltip_opts,
"axisLine": axisline_opts,
+ "axisTick": axistick_opts,
+ "axisLabel": axislabel_opts,
+ "progress": progress,
+ "anchor": anchor,
"pointer": pointer,
"itemStyle": itemstyle_opts,
+ "emphasis": emphasis_opts,
}
)
return self
diff --git a/pyecharts/charts/basic_charts/geo.py b/pyecharts/charts/basic_charts/geo.py
index 0b956b3e4..2f84e92a5 100644
--- a/pyecharts/charts/basic_charts/geo.py
+++ b/pyecharts/charts/basic_charts/geo.py
@@ -9,14 +9,22 @@
class GeoChartBase(Chart):
- def __init__(self, init_opts: types.Init = opts.InitOpts()):
- super().__init__(init_opts=init_opts)
+ def __init__(
+ self,
+ init_opts: types.Init = opts.InitOpts(),
+ render_opts: types.RenderInit = opts.RenderOpts(),
+ ):
+ super().__init__(init_opts=init_opts, render_opts=render_opts)
self.set_global_opts()
self._coordinates = COORDINATES
self._zlevel = 1
self._coordinate_system: types.Optional[str] = None
self._chart_type = ChartType.GEO
+ def add_geo_json(self, geo_json: dict):
+ self._geo_json = geo_json
+ return self
+
def add_coordinate(
self, name: str, longitude: types.Numeric, latitude: types.Numeric
):
@@ -40,18 +48,18 @@ def add(
data_pair: types.Sequence,
type_: str = "scatter",
*,
- is_selected: bool = True,
symbol: types.Optional[str] = None,
symbol_size: types.Numeric = 12,
blur_size: types.Numeric = 20,
point_size: types.Numeric = 20,
+ radius: types.Optional[types.Sequence] = None,
color: types.Optional[str] = None,
is_polyline: bool = False,
is_large: bool = False,
large_threshold: types.Numeric = 2000,
progressive: types.Numeric = 400,
progressive_threshold: types.Numeric = 3000,
- label_opts: types.Label = opts.LabelOpts(),
+ label_opts: types.Label = None,
effect_opts: types.Effect = opts.EffectOpts(),
linestyle_opts: types.LineStyle = opts.LineStyleOpts(),
tooltip_opts: types.Tooltip = None,
@@ -60,10 +68,10 @@ def add(
encode: types.Union[types.JsCode, dict] = None,
):
self._zlevel += 1
- data = self._feed_data(data_pair, type_)
+ data = self._feed_data(data_pair, type_) if data_pair else data_pair
self._append_color(color)
- self._append_legend(series_name, is_selected)
+ self._append_legend(series_name)
if type_ == ChartType.SCATTER:
self.options.get("series").append(
@@ -79,7 +87,19 @@ def add(
"itemStyle": itemstyle_opts,
}
)
-
+ elif type_ == ChartType.SCATTERGL:
+ self.js_dependencies.add("echarts-gl")
+ self.options.get("series").append(
+ {
+ "type": type_,
+ "name": series_name,
+ "coordinateSystem": self._coordinate_system,
+ "symbol": symbol,
+ "symbolSize": symbol_size,
+ "data": data,
+ "itemStyle": itemstyle_opts,
+ }
+ )
elif type_ == ChartType.EFFECT_SCATTER:
self.options.get("series").append(
{
@@ -96,7 +116,17 @@ def add(
"itemStyle": itemstyle_opts,
}
)
-
+ elif type_ == ChartType.FLOWGL:
+ self.js_dependencies.add("echarts-gl")
+ self.options.get("series").append(
+ {
+ "type": type_,
+ "name": series_name,
+ "coordinateSystem": self._coordinate_system,
+ "data": data,
+ "itemStyle": itemstyle_opts,
+ }
+ )
elif type_ == ChartType.HEATMAP:
self.options.get("series").append(
{
@@ -110,7 +140,6 @@ def add(
"blurSize": blur_size,
}
)
-
elif type_ == ChartType.LINES:
self.options.get("series").append(
{
@@ -133,6 +162,19 @@ def add(
"label": label_opts,
}
)
+ elif type_ == ChartType.LINESGL:
+ self.js_dependencies.add("echarts-gl")
+ self.options.get("series").append(
+ {
+ "type": type_,
+ "name": series_name,
+ "coordinateSystem": self._coordinate_system,
+ "data": data,
+ "polyline": is_polyline,
+ "large": is_large,
+ "lineStyle": linestyle_opts,
+ }
+ )
elif type_ == ChartType.CUSTOM:
self.options.get("series").append(
{
@@ -145,6 +187,33 @@ def add(
"data": data,
}
)
+ elif type_ == ChartType.PIE:
+ if not radius:
+ radius = ["0%", "5%"]
+
+ if not tooltip_opts:
+ tooltip_opts = {"formatter": "{b}: {c} ({d}%)"}
+
+ if not isinstance(data[0], opts.PieItem):
+ data = [{"name": n, "value": v} for n, v in data]
+
+ self.options.get("series").append(
+ {
+ "type": type_,
+ "coordinateSystem": self._coordinate_system,
+ "data": data,
+ "tooltip": tooltip_opts,
+ "label": label_opts,
+ "center": self.get_coordinate(series_name),
+ "radius": radius,
+ }
+ )
+ # Legend (hard code here)
+ legend = self.options.get("legend")[0]
+ pie_series_name = [d.get("name") for d in data]
+ if len(legend.get("data")) < len(pie_series_name):
+ legend["data"] = pie_series_name
+
return self
@@ -159,13 +228,30 @@ def __init__(
self,
init_opts: types.Init = opts.InitOpts(),
is_ignore_nonexistent_coord: bool = False,
+ render_opts: types.RenderInit = opts.RenderOpts(),
):
- super().__init__(init_opts=init_opts)
+ super().__init__(init_opts=init_opts, render_opts=render_opts)
self._coordinate_system: types.Optional[str] = "geo"
self._is_ignore_nonexistent_coord = is_ignore_nonexistent_coord
def _feed_data(self, data_pair: types.Sequence, type_: str) -> types.Sequence:
+ if type_ == ChartType.PIE:
+ return data_pair
+
result = []
+ if isinstance(data_pair[0], opts.GeoItem):
+ for item in data_pair:
+ result.append({
+ "name": item.get("name"),
+ "value": [
+ item.get("longitude"),
+ item.get("latitude"),
+ item.get("value"),
+ ],
+ })
+
+ return result
+
for n, v in data_pair:
try:
if type_ == ChartType.LINES:
@@ -182,7 +268,9 @@ def _feed_data(self, data_pair: types.Sequence, type_: str) -> types.Sequence:
def add_schema(
self,
maptype: str = "china",
+ animation: types.Union[bool, str] = None,
is_roam: bool = True,
+ roam_trigger: types.Optional[str] = None,
zoom: types.Optional[types.Numeric] = None,
center: types.Optional[types.Sequence] = None,
aspect_scale: types.Numeric = 0.75,
@@ -197,8 +285,27 @@ def add_schema(
itemstyle_opts: types.ItemStyle = None,
emphasis_itemstyle_opts: types.ItemStyle = None,
emphasis_label_opts: types.Label = None,
+ regions_opts: types.Union[
+ types.Sequence[types.GeoRegions], types.Sequence[dict]
+ ] = None,
+ is_preserve_aspect: bool = False,
+ preserve_aspect_align: types.Optional[str] = None,
+ preserve_aspect_vertical_align: types.Optional[str] = None,
+ is_clip: bool = False,
+ coordinate_system: types.Optional[str] = None,
+ coordinate_system_usage: types.Optional[str] = None,
+ coord: types.Optional[types.Union[
+ types.Sequence, types.Numeric, str]
+ ] = None,
+ calendar_index: types.Optional[types.Numeric] = None,
+ calendar_id: types.Optional[types.Numeric] = None,
+ matrix_index: types.Optional[types.Numeric] = None,
+ matrix_id: types.Optional[types.Numeric] = None,
+ tooltip_opts: types.Tooltip = None,
+ select_opts: types.Select = None,
):
self.js_dependencies.add(maptype)
+ self._geo_json_name = maptype
if center:
assert len(center) == 2
@@ -212,9 +319,11 @@ def add_schema(
self.options.update(
geo={
"map": maptype,
+ "animation": animation,
"zoom": zoom,
"center": center,
"roam": is_roam,
+ "roamTrigger": roam_trigger,
"aspectScale": aspect_scale,
"boundingCoords": bounding_coords,
"scaleLimit": scale_limit,
@@ -228,6 +337,20 @@ def add_schema(
"itemStyle": emphasis_itemstyle_opts,
"label": emphasis_label_opts,
},
+ "regions": regions_opts,
+ "preserveAspect": is_preserve_aspect,
+ "preserveAspectAlign": preserve_aspect_align,
+ "preserveAspectVerticalAlign": preserve_aspect_vertical_align,
+ "clip": is_clip,
+ "coordinateSystem": coordinate_system,
+ "coordinateSystemUsage": coordinate_system_usage,
+ "coord": coord,
+ "calendarIndex": calendar_index,
+ "calendarId": calendar_id,
+ "matrixIndex": matrix_index,
+ "matrixId": matrix_id,
+ "tooltip": tooltip_opts,
+ "select": select_opts,
}
)
return self
diff --git a/pyecharts/charts/basic_charts/gmap.py b/pyecharts/charts/basic_charts/gmap.py
new file mode 100644
index 000000000..1f42de106
--- /dev/null
+++ b/pyecharts/charts/basic_charts/gmap.py
@@ -0,0 +1,77 @@
+from ... import options as opts
+from ... import types
+from ...charts.basic_charts.geo import GeoChartBase
+from ...commons.utils import OrderedSet, JsCode
+from ...exceptions import NonexistentCoordinatesException
+from ...globals import ChartType
+
+GMAP_API = "https://maps.googleapis.com/maps/api/js?key={}"
+
+
+class GMap(GeoChartBase):
+ """
+ <<< GMap(Google Map) coordinate system >>>
+
+ Support scatter plot, line.
+ """
+
+ def __init__(
+ self,
+ init_opts: types.Init = opts.InitOpts(),
+ is_ignore_nonexistent_coord: bool = False,
+ render_opts: types.RenderInit = opts.RenderOpts(),
+ ):
+ super().__init__(init_opts=init_opts, render_opts=render_opts)
+ self.js_dependencies.add("gmap")
+ self._is_geo_chart = True
+ self._coordinate_system: types.Optional[str] = "gmap"
+ self.gmap_js_functions: OrderedSet = OrderedSet()
+ self._is_ignore_nonexistent_coord = is_ignore_nonexistent_coord
+
+ def _feed_data(self, data_pair: types.Sequence, type_: str) -> types.Sequence:
+ result = []
+ type_list = [ChartType.LINES, ChartType.CUSTOM]
+ if type_ in type_list:
+ result = data_pair
+ else:
+ for n, v in data_pair:
+ try:
+ lng, lat = self.get_coordinate(n)
+ result.append({"name": n, "value": [lng, lat, v]})
+ except TypeError as err:
+ if self._is_ignore_nonexistent_coord is not True:
+ raise NonexistentCoordinatesException(err, (n, v))
+ return result
+
+ def add_schema(
+ self,
+ gmap_ak: str,
+ center: types.Sequence,
+ zoom: types.Union[types.Numeric, str] = None,
+ is_render_on_map: bool = True,
+ z_index: types.Optional[int] = None,
+ is_roam: bool = True,
+ ):
+ self.js_dependencies.add(GMAP_API.format(gmap_ak))
+ self.options.update(
+ gmap={
+ "center": center,
+ "zoom": zoom,
+ "renderOnMoving": is_render_on_map,
+ "echartsLayerZIndex": z_index,
+ "roam": is_roam
+ }
+ )
+ return self
+
+ def add_control_panel(
+ self,
+ is_add_traffic_layer: bool = False,
+ ):
+ if is_add_traffic_layer:
+ self.gmap_js_functions.add(
+ "var trafficLayer = new google.maps.TrafficLayer(); "
+ "trafficLayer.setMap(gmap);"
+ )
+
+ return self
diff --git a/pyecharts/charts/basic_charts/graph.py b/pyecharts/charts/basic_charts/graph.py
index 1c6e31f97..03bf375fc 100644
--- a/pyecharts/charts/basic_charts/graph.py
+++ b/pyecharts/charts/basic_charts/graph.py
@@ -18,16 +18,36 @@ def add(
links: types.Sequence[types.GraphLink],
categories: types.Union[types.Sequence[types.GraphCategory], None] = None,
*,
- is_selected: bool = True,
+ coordinate_system: types.Optional[str] = None,
+ coordinate_system_usage: types.Optional[str] = None,
+ coord: types.Union[types.Sequence, types.Numeric, str] = None,
+ xaxis_index: types.Optional[types.Numeric] = None,
+ xaxis_id: types.Optional[types.Numeric] = None,
+ yaxis_index: types.Optional[types.Numeric] = None,
+ yaxis_id: types.Optional[types.Numeric] = None,
+ polar_index: types.Optional[types.Numeric] = None,
+ polar_id: types.Optional[types.Numeric] = None,
+ single_axis_index: types.Optional[types.Numeric] = None,
+ single_axis_id: types.Optional[types.Numeric] = None,
+ geo_index: types.Optional[types.Numeric] = None,
+ geo_id: types.Optional[types.Numeric] = None,
+ calendar_index: types.Optional[types.Numeric] = None,
+ calendar_id: types.Optional[types.Numeric] = None,
+ matrix_index: types.Optional[types.Numeric] = None,
+ matrix_id: types.Optional[types.Numeric] = None,
is_focusnode: bool = True,
is_roam: bool = True,
+ roam_trigger: types.Optional[str] = None,
+ node_scale_ratio: types.Numeric = 0.6,
is_draggable: bool = False,
is_rotate_label: bool = False,
layout: str = "force",
symbol: types.Optional[str] = None,
symbol_size: types.Numeric = 10,
- edge_length: types.Numeric = 50,
+ edge_length: types.Numeric = 30,
gravity: types.Numeric = 0.2,
+ friction: types.Numeric = 0.6,
+ is_layout_animation: bool = True,
repulsion: types.Numeric = 50,
edge_label: types.Label = None,
edge_symbol: types.Union[types.Sequence[str], str] = None,
@@ -36,6 +56,10 @@ def add(
linestyle_opts: types.LineStyle = opts.LineStyleOpts(),
tooltip_opts: types.Tooltip = None,
itemstyle_opts: types.ItemStyle = None,
+ emphasis_opts: types.Emphasis = None,
+ is_preserve_aspect: bool = False,
+ preserve_aspect_align: types.Optional[str] = None,
+ preserve_aspect_vertical_align: types.Optional[str] = None,
):
_nodes = []
for n in nodes:
@@ -53,7 +77,7 @@ def add(
for c in categories:
if isinstance(c, opts.GraphCategory):
c = c.opts
- self._append_legend(c.get("name", ""), is_selected)
+ self._append_legend(c.get("name", ""))
if edge_label is None:
edge_label = opts.LabelOpts(is_show=False)
@@ -65,18 +89,39 @@ def add(
{
"type": ChartType.GRAPH,
"name": series_name,
+ "coordinateSystem": coordinate_system,
+ "coordinateSystemUsage": coordinate_system_usage,
+ "coord": coord,
+ "xaxisIndex": xaxis_index,
+ "xaxisId": xaxis_id,
+ "yaxisIndex": yaxis_index,
+ "yaxisId": yaxis_id,
+ "polarIndex": polar_index,
+ "polarId": polar_id,
+ "singleAxisIndex": single_axis_index,
+ "singleAxisId": single_axis_id,
+ "geoIndex": geo_index,
+ "geoId": geo_id,
+ "calendarIndex": calendar_index,
+ "calendarId": calendar_id,
+ "matrixIndex": matrix_index,
+ "matrixId": matrix_id,
"layout": layout,
"symbol": symbol,
"symbolSize": symbol_size,
"circular": {"rotateLabel": is_rotate_label},
"force": {
"repulsion": repulsion,
- "edgeLength": edge_length,
"gravity": gravity,
+ "edgeLength": edge_length,
+ "friction": friction,
+ "layoutAnimation": is_layout_animation,
},
"label": label_opts,
"lineStyle": linestyle_opts,
"roam": is_roam,
+ "roamTrigger": roam_trigger,
+ "nodeScaleRatio": node_scale_ratio,
"draggable": is_draggable,
"focusNodeAdjacency": is_focusnode,
"data": _nodes,
@@ -87,6 +132,10 @@ def add(
"links": _links,
"tooltip": tooltip_opts,
"itemStyle": itemstyle_opts,
+ "emphasis": emphasis_opts,
+ "preserveAspect": is_preserve_aspect,
+ "preserveAspectAlign": preserve_aspect_align,
+ "preserveAspectVerticalAlign": preserve_aspect_vertical_align,
}
)
return self
diff --git a/pyecharts/charts/basic_charts/heatmap.py b/pyecharts/charts/basic_charts/heatmap.py
index 9d12f399a..2b47fb42f 100644
--- a/pyecharts/charts/basic_charts/heatmap.py
+++ b/pyecharts/charts/basic_charts/heatmap.py
@@ -13,8 +13,12 @@ class HeatMap(RectChart):
Two categories of axes must be used in rectangular coordinates.
"""
- def __init__(self, init_opts: types.Init = opts.InitOpts()):
- super().__init__(init_opts=init_opts)
+ def __init__(
+ self,
+ init_opts: types.Init = opts.InitOpts(),
+ render_opts: types.RenderInit = opts.RenderOpts(),
+ ):
+ super().__init__(init_opts=init_opts, render_opts=render_opts)
self.set_global_opts(visualmap_opts=opts.VisualMapOpts(orient="horizontal"))
def add_yaxis(
@@ -23,29 +27,72 @@ def add_yaxis(
yaxis_data: types.Sequence[types.Union[dict]],
value: types.Sequence[types.Union[dict]],
*,
- is_selected: bool = True,
+ coordinate_system: str = "cartesian2d",
+ coordinate_system_usage: types.Optional[str] = None,
+ coord: types.Union[types.Sequence, types.Numeric, str] = None,
xaxis_index: types.Optional[types.Numeric] = None,
+ xaxis_id: types.Optional[types.Numeric] = None,
yaxis_index: types.Optional[types.Numeric] = None,
+ yaxis_id: types.Optional[types.Numeric] = None,
+ geo_index: types.Optional[types.Numeric] = None,
+ geo_id: types.Optional[types.Numeric] = None,
+ calendar_index: types.Optional[types.Numeric] = None,
+ calendar_id: types.Optional[types.Numeric] = None,
+ matrix_index: types.Optional[types.Numeric] = None,
+ matrix_id: types.Optional[types.Numeric] = None,
+ dataset_index: types.Optional[types.Numeric] = None,
+ point_size: types.Optional[types.Numeric] = None,
+ blur_size: types.Optional[types.Numeric] = None,
+ min_opacity: types.Optional[types.Numeric] = None,
+ max_opacity: types.Optional[types.Numeric] = None,
label_opts: types.Label = opts.LabelOpts(),
markpoint_opts: types.MarkPoint = None,
markline_opts: types.MarkLine = None,
+ markarea_opts: types.MarkArea = None,
tooltip_opts: types.Tooltip = None,
itemstyle_opts: types.ItemStyle = None,
+ emphasis_opts: types.Emphasis = None,
+ selected_mode: types.Union[bool, str] = False,
+ z_level: types.Numeric = 0,
+ z: types.Numeric = 2,
+ encode: types.Union[types.JSFunc, dict, None] = None,
):
- self._append_legend(series_name, is_selected)
+ self._append_legend(series_name)
self.options.get("yAxis")[0].update(data=yaxis_data)
self.options.get("series").append(
{
"type": ChartType.HEATMAP,
"name": series_name,
+ "coordinateSystem": coordinate_system,
+ "coordinateSystemUsage": coordinate_system_usage,
+ "coord": coord,
"xAxisIndex": xaxis_index,
+ "xAxisId": xaxis_id,
"yAxisIndex": yaxis_index,
+ "yAxisId": yaxis_id,
+ "geoIndex": geo_index,
+ "geoId": geo_id,
+ "calendarIndex": calendar_index,
+ "calendarId": calendar_id,
+ "matrixIndex": matrix_index,
+ "matrixId": matrix_id,
+ "datasetIndex": dataset_index,
+ "pointSize": point_size,
+ "blurSize": blur_size,
+ "minOpacity": min_opacity,
+ "maxOpacity": max_opacity,
"data": value,
"label": label_opts,
"markLine": markline_opts,
"markPoint": markpoint_opts,
+ "markArea": markarea_opts,
"tooltip": tooltip_opts,
"itemStyle": itemstyle_opts,
+ "emphasis": emphasis_opts,
+ "selectedMode": selected_mode,
+ "zlevel": z_level,
+ "z": z,
+ "encode": encode,
}
)
return self
diff --git a/pyecharts/charts/basic_charts/kline.py b/pyecharts/charts/basic_charts/kline.py
index dd3471548..d89dd6146 100644
--- a/pyecharts/charts/basic_charts/kline.py
+++ b/pyecharts/charts/basic_charts/kline.py
@@ -14,8 +14,12 @@ class Kline(RectChart):
the fluctuation of a certain period.
"""
- def __init__(self, init_opts: types.Init = opts.InitOpts()):
- super().__init__(init_opts=init_opts)
+ def __init__(
+ self,
+ init_opts: types.Init = opts.InitOpts(),
+ render_opts: types.RenderInit = opts.RenderOpts(),
+ ):
+ super().__init__(init_opts=init_opts, render_opts=render_opts)
self.set_global_opts(
xaxis_opts=opts.AxisOpts(is_scale=True),
yaxis_opts=opts.AxisOpts(is_scale=True),
@@ -26,26 +30,65 @@ def add_yaxis(
series_name: str,
y_axis: types.Sequence[types.Union[opts.CandleStickItem, dict]],
*,
- is_selected: bool = True,
+ coordinate_system: str = "cartesian2d",
+ coordinate_system_usage: types.Optional[str] = None,
+ coord: types.Union[types.Sequence, types.Numeric, str] = None,
+ color_by: types.Optional[str] = "series",
+ bar_width: types.Optional[types.Numeric] = None,
+ bar_min_width: types.Optional[types.Numeric] = None,
+ bar_max_width: types.Optional[types.Numeric] = None,
+ layout: types.Optional[str] = None,
xaxis_index: types.Optional[types.Numeric] = None,
+ xaxis_id: types.Optional[types.Numeric] = None,
yaxis_index: types.Optional[types.Numeric] = None,
+ yaxis_id: types.Optional[types.Numeric] = None,
+ is_legend_hover_link: bool = True,
+ is_hover_animation: bool = True,
markline_opts: types.MarkLine = None,
markpoint_opts: types.MarkPoint = None,
+ markarea_opts: types.MarkArea = None,
tooltip_opts: types.Tooltip = None,
itemstyle_opts: types.ItemStyle = None,
+ emphasis_opts: types.Emphasis = None,
+ selected_mode: types.Union[bool, str] = False,
+ is_large: bool = False,
+ encode: types.Union[types.JSFunc, dict, None] = None,
+ is_clip: bool = True,
+ z_level: types.Numeric = 0,
+ z: types.Numeric = 2,
):
- self._append_legend(series_name, is_selected)
+ self._append_legend(series_name)
self.options.get("series").append(
{
"type": ChartType.KLINE,
"name": series_name,
+ "coordinateSystem": coordinate_system,
+ "coordinateSystemUsage": coordinate_system_usage,
+ "coord": coord,
+ "colorBy": color_by,
+ "legendHoverLink": is_legend_hover_link,
+ "hoverAnimation": is_hover_animation,
+ "layout": layout,
+ "barWidth": bar_width,
+ "barMinWidth": bar_min_width,
+ "barMaxWidth": bar_max_width,
"xAxisIndex": xaxis_index,
+ "xAxisId": xaxis_id,
"yAxisIndex": yaxis_index,
+ "yAxisId": yaxis_id,
"data": y_axis,
"markPoint": markpoint_opts,
"markLine": markline_opts,
+ "markArea": markarea_opts,
"tooltip": tooltip_opts,
"itemStyle": itemstyle_opts,
+ "emphasis": emphasis_opts,
+ "selectedMode": selected_mode,
+ "large": is_large,
+ "encode": encode,
+ "clip": is_clip,
+ "zlevel": z_level,
+ "z": z,
}
)
return self
diff --git a/pyecharts/charts/basic_charts/line.py b/pyecharts/charts/basic_charts/line.py
index 011b1b15b..2613d6681 100644
--- a/pyecharts/charts/basic_charts/line.py
+++ b/pyecharts/charts/basic_charts/line.py
@@ -17,38 +17,66 @@ def add_yaxis(
series_name: str,
y_axis: types.Sequence[types.Union[opts.LineItem, dict]],
*,
- is_selected: bool = True,
is_connect_nones: bool = False,
xaxis_index: types.Optional[types.Numeric] = None,
+ xaxis_id: types.Optional[types.Numeric] = None,
yaxis_index: types.Optional[types.Numeric] = None,
+ yaxis_id: types.Optional[types.Numeric] = None,
+ polar_index: types.Optional[types.Numeric] = None,
+ polar_id: types.Optional[types.Numeric] = None,
+ dataset_index: types.Optional[types.Numeric] = None,
+ coordinate_system: types.Optional[str] = None,
+ coordinate_system_usage: types.Optional[str] = None,
+ coord: types.Union[types.Sequence, types.Numeric, str] = None,
+ color_by: types.Optional[str] = None,
color: types.Optional[str] = None,
is_symbol_show: bool = True,
symbol: types.Optional[str] = None,
symbol_size: types.Union[types.Numeric, types.Sequence] = 4,
stack: types.Optional[str] = None,
+ stack_strategy: types.Optional[str] = "samesign",
+ stack_order: types.Optional[str] = None,
is_smooth: bool = False,
is_clip: bool = True,
is_step: bool = False,
is_hover_animation: bool = True,
z_level: types.Numeric = 0,
z: types.Numeric = 0,
+ log_base: types.Numeric = 10,
+ sampling: types.Optional[str] = None,
+ dimensions: types.Union[types.Sequence, None] = None,
+ series_layout_by: str = "column",
markpoint_opts: types.MarkPoint = None,
markline_opts: types.MarkLine = None,
+ markarea_opts: types.MarkArea = None,
tooltip_opts: types.Tooltip = None,
itemstyle_opts: types.ItemStyle = None,
label_opts: types.Label = opts.LabelOpts(),
+ end_label_opts: types.Label = None,
linestyle_opts: types.LineStyle = opts.LineStyleOpts(),
areastyle_opts: types.AreaStyle = opts.AreaStyleOpts(),
+ emphasis_opts: types.Emphasis = None,
+ encode: types.Union[types.JSFunc, dict, None] = None,
):
self._append_color(color)
- self._append_legend(series_name, is_selected)
+ self._append_legend(series_name)
if all([isinstance(d, opts.LineItem) for d in y_axis]):
data = y_axis
else:
# 合并 x 和 y 轴数据,避免当 X 轴的类型设置为 'value' 的时候,
# X、Y 轴均显示 Y 轴数据
- data = [list(z) for z in zip(self._xaxis_data, y_axis)]
+ try:
+ xaxis_index = xaxis_index or 0
+ data = [
+ list(z)
+ for z in zip(self.options["xAxis"][xaxis_index]["data"], y_axis)
+ ]
+ except IndexError:
+ data = [list(z) for z in zip(self._xaxis_data, y_axis)]
+
+ if self.options.get("dataset") is not None and not y_axis:
+ data = None
self.options.get("series").append(
{
@@ -56,7 +84,16 @@ def add_yaxis(
"name": series_name,
"connectNulls": is_connect_nones,
"xAxisIndex": xaxis_index,
+ "xAxisId": xaxis_id,
"yAxisIndex": yaxis_index,
+ "yAxisId": yaxis_id,
+ "polarIndex": polar_index,
+ "polarId": polar_id,
+ "datasetIndex": dataset_index,
+ "coordinateSystem": coordinate_system,
+ "coordinateSystemUsage": coordinate_system_usage,
+ "coord": coord,
+ "colorBy": color_by,
"symbol": symbol,
"symbolSize": symbol_size,
"showSymbol": is_symbol_show,
@@ -64,13 +101,23 @@ def add_yaxis(
"clip": is_clip,
"step": is_step,
"stack": stack,
+ "stackStrategy": stack_strategy,
+ "stackOrder": stack_order,
"data": data,
"hoverAnimation": is_hover_animation,
"label": label_opts,
+ "endLabel": end_label_opts,
+ "logBase": log_base,
+ "sampling": sampling,
+ "dimensions": dimensions,
+ "encode": encode,
+ "seriesLayoutBy": series_layout_by,
"lineStyle": linestyle_opts,
"areaStyle": areastyle_opts,
+ "emphasis": emphasis_opts,
"markPoint": markpoint_opts,
"markLine": markline_opts,
+ "markArea": markarea_opts,
"tooltip": tooltip_opts,
"itemStyle": itemstyle_opts,
"zlevel": z_level,
diff --git a/pyecharts/charts/basic_charts/liquid.py b/pyecharts/charts/basic_charts/liquid.py
index 2e2a48b1e..8713631f2 100644
--- a/pyecharts/charts/basic_charts/liquid.py
+++ b/pyecharts/charts/basic_charts/liquid.py
@@ -11,8 +11,12 @@ class Liquid(Chart):
The liquid chart is mainly used to highlight the percentage of data.
"""
- def __init__(self, init_opts: types.Init = opts.InitOpts()):
- super().__init__(init_opts=init_opts)
+ def __init__(
+ self,
+ init_opts: types.Init = opts.InitOpts(),
+ render_opts: types.RenderInit = opts.RenderOpts(),
+ ):
+ super().__init__(init_opts=init_opts, render_opts=render_opts)
self.js_dependencies.add("echarts-liquidfill")
def add(
diff --git a/pyecharts/charts/basic_charts/lmap.py b/pyecharts/charts/basic_charts/lmap.py
new file mode 100644
index 000000000..68a4062e3
--- /dev/null
+++ b/pyecharts/charts/basic_charts/lmap.py
@@ -0,0 +1,66 @@
+from ... import options as opts
+from ... import types
+from ...charts.basic_charts.geo import GeoChartBase
+from ...commons.utils import OrderedSet, JsCode
+from ...exceptions import NonexistentCoordinatesException
+from ...globals import ChartType
+
+
+class LMap(GeoChartBase):
+ """
+ <<< LMap(leaflet) coordinate system >>>
+
+ Support scatter plot, line.
+ """
+
+ def __init__(
+ self,
+ init_opts: types.Init = opts.InitOpts(),
+ is_ignore_nonexistent_coord: bool = False,
+ render_opts: types.RenderInit = opts.RenderOpts(),
+ ):
+ super().__init__(init_opts=init_opts, render_opts=render_opts)
+ self.js_dependencies.add("lmap-css")
+ self.js_dependencies.add("lmap-src")
+ self.js_dependencies.add("lmap")
+ self._is_geo_chart = True
+ self._coordinate_system: types.Optional[str] = "lmap"
+ self.lmap_js_functions: OrderedSet = OrderedSet()
+ self._is_ignore_nonexistent_coord = is_ignore_nonexistent_coord
+
+ def _feed_data(self, data_pair: types.Sequence, type_: str) -> types.Sequence:
+ result = []
+ type_list = [ChartType.LINES, ChartType.CUSTOM]
+ if type_ in type_list:
+ result = data_pair
+ else:
+ for n, v in data_pair:
+ try:
+ lng, lat = self.get_coordinate(n)
+ result.append({"name": n, "value": [lng, lat, v]})
+ except TypeError as err:
+ if self._is_ignore_nonexistent_coord is not True:
+ raise NonexistentCoordinatesException(err, (n, v))
+ return result
+
+ def add_schema(
+ self,
+ center: types.Sequence,
+ zoom: types.Union[types.Numeric, str] = None,
+ is_enable_resize: bool = True,
+ is_render_on_map: bool = True,
+ is_layer_interactive: bool = True,
+ is_large: bool = False,
+ ):
+ self.options.update(
+ lmap={
+ "center": center,
+ "zoom": zoom,
+ "resizeEnable": is_enable_resize,
+ "renderOnMoving": is_render_on_map,
+ "echartsLayerInteractive": is_layer_interactive,
+ "largeMode": is_large,
+ }
+ )
+
+ return self
diff --git a/pyecharts/charts/basic_charts/map.py b/pyecharts/charts/basic_charts/map.py
index 3fa175f68..678e9ba40 100644
--- a/pyecharts/charts/basic_charts/map.py
+++ b/pyecharts/charts/basic_charts/map.py
@@ -17,7 +17,6 @@ def add(
data_pair: types.Sequence[types.Union[types.Sequence, opts.MapItem, dict]],
maptype: str = "china",
*,
- is_selected: bool = True,
is_roam: bool = True,
center: types.Optional[types.Sequence] = None,
aspect_scale: types.Numeric = 0.75,
@@ -31,8 +30,25 @@ def add(
symbol: types.Optional[str] = None,
map_value_calculation: str = "sum",
is_map_symbol_show: bool = True,
+ z_level: types.Numeric = 0,
+ z: types.Numeric = 2,
+ pos_left: types.Optional[types.Union[str, types.Numeric]] = None,
+ pos_top: types.Optional[types.Union[str, types.Numeric]] = None,
+ pos_right: types.Optional[types.Union[str, types.Numeric]] = None,
+ pos_bottom: types.Optional[types.Union[str, types.Numeric]] = None,
+ geo_index: types.Optional[types.Numeric] = None,
+ geo_id: types.Optional[types.Numeric] = None,
+ series_layout_by: str = "column",
+ dataset_index: types.Optional[types.Numeric] = 0,
layout_center: types.Optional[types.Sequence[str]] = None,
layout_size: types.Union[str, types.Numeric] = None,
+ is_preserve_aspect: bool = False,
+ preserve_aspect_align: types.Optional[str] = None,
+ preserve_aspect_vertical_align: types.Optional[str] = None,
+ is_clip: bool = False,
+ coordinate_system: types.Optional[str] = None,
+ coordinate_system_usage: types.Optional[str] = None,
+ coord: types.Union[types.Sequence, types.Numeric, str] = None,
label_opts: types.Label = opts.LabelOpts(),
tooltip_opts: types.Tooltip = None,
itemstyle_opts: types.ItemStyle = None,
@@ -40,6 +56,7 @@ def add(
emphasis_itemstyle_opts: types.ItemStyle = None,
):
self.js_dependencies.add(maptype)
+ self._geo_json_name = maptype
if isinstance(data_pair[0], opts.MapItem):
data = data_pair
@@ -53,14 +70,14 @@ def add(
if min_scale_limit is None and max_scale_limit is None:
scale_limit = None
- self._append_legend(series_name, is_selected)
+ self._append_legend(series_name)
self.options.get("series").append(
{
"type": ChartType.MAP,
"name": series_name,
"symbol": symbol,
"label": label_opts,
- "mapType": maptype,
+ "map": maptype,
"data": data,
"roam": is_roam,
"aspectScale": aspect_scale,
@@ -71,10 +88,27 @@ def add(
"center": center,
"zoom": zoom,
"nameMap": name_map,
+ "zlevel": z_level,
+ "z": z,
+ "left": pos_left,
+ "top": pos_top,
+ "right": pos_right,
+ "bottom": pos_bottom,
+ "geoIndex": geo_index,
+ "geoId": geo_id,
+ "seriesLayoutBy": series_layout_by,
+ "datasetIndex": dataset_index,
"mapValueCalculation": map_value_calculation,
"showLegendSymbol": is_map_symbol_show,
"layoutCenter": layout_center,
"layoutSize": layout_size,
+ "preserveAspect": is_preserve_aspect,
+ "preserveAspectAlign": preserve_aspect_align,
+ "preserveAspectVerticalAlign": preserve_aspect_vertical_align,
+ "clip": is_clip,
+ "coordinateSystem": coordinate_system,
+ "coordinateSystemUsage": coordinate_system_usage,
+ "coord": coord,
"tooltip": tooltip_opts,
"itemStyle": itemstyle_opts,
"emphasis": {
@@ -87,4 +121,6 @@ def add(
class Map(Chart, MapMixin):
- pass
+ def add_geo_json(self, geo_json: dict):
+ self._geo_json = geo_json
+ return self
diff --git a/pyecharts/charts/basic_charts/parallel.py b/pyecharts/charts/basic_charts/parallel.py
index 8a2f73119..3138ad106 100644
--- a/pyecharts/charts/basic_charts/parallel.py
+++ b/pyecharts/charts/basic_charts/parallel.py
@@ -12,8 +12,12 @@ class Parallel(Chart):
high dimensional data.
"""
- def __init__(self, init_opts: types.Init = opts.InitOpts()):
- super().__init__(init_opts=init_opts)
+ def __init__(
+ self,
+ init_opts: types.Init = opts.InitOpts(),
+ render_opts: types.RenderInit = opts.RenderOpts(),
+ ):
+ super().__init__(init_opts=init_opts, render_opts=render_opts)
self.options.update(parallel=opts.ParallelOpts().opts)
def add_schema(
@@ -37,25 +41,47 @@ def add_schema(
def add(
self,
series_name: str,
- data: types.Sequence[types.Union[dict]],
+ data: types.Sequence[types.Union[opts.ParallelItem, dict]],
*,
+ coordinate_system: types.Optional[str] = "parallel",
+ coordinate_system_usage: types.Optional[str] = None,
+ coord: types.Union[types.Sequence, types.Numeric, str] = None,
+ parallel_index: types.Optional[types.Numeric] = None,
+ parallel_id: types.Optional[types.Numeric] = None,
+ color_by: types.Optional[str] = None,
+ inactive_opacity: types.Optional[types.Numeric] = 0.05,
+ active_opacity: types.Optional[types.Numeric] = 1,
+ is_realtime: bool = True,
is_smooth: bool = False,
- is_selected: bool = True,
+ z_level: types.Numeric = 0,
+ z: types.Numeric = 2,
linestyle_opts: types.LineStyle = opts.LineStyleOpts(),
tooltip_opts: types.Tooltip = None,
itemstyle_opts: types.ItemStyle = None,
+ emphasis_opts: types.Emphasis = None,
):
- self._append_legend(series_name, is_selected)
+ self._append_legend(series_name)
self.options.get("series").append(
{
"type": ChartType.PARALLEL,
- "coordinateSystem": "parallel",
+ "coordinateSystem": coordinate_system,
+ "coordinateSystemUsage": coordinate_system_usage,
+ "coord": coord,
+ "parallelIndex": parallel_index,
+ "parallelId": parallel_id,
+ "colorBy": color_by,
+ "inactiveOpacity": inactive_opacity,
+ "activeOpacity": active_opacity,
+ "realTime": is_realtime,
+ "zlevel": z_level,
+ "z": z,
"lineStyle": linestyle_opts,
"name": series_name,
"data": data,
"smooth": is_smooth,
"tooltip": tooltip_opts,
"itemStyle": itemstyle_opts,
+ "emphasis": emphasis_opts,
}
)
return self
diff --git a/pyecharts/charts/basic_charts/pictorialbar.py b/pyecharts/charts/basic_charts/pictorialbar.py
index 84fcbe02b..94c221d65 100644
--- a/pyecharts/charts/basic_charts/pictorialbar.py
+++ b/pyecharts/charts/basic_charts/pictorialbar.py
@@ -26,9 +26,13 @@ def add_yaxis(
symbol_repeat_direction: types.Optional[str] = None,
symbol_margin: types.Union[types.Numeric, str, None] = None,
is_symbol_clip: bool = False,
- is_selected: bool = True,
+ coordinate_system: types.Optional[str] = None,
+ coordinate_system_usage: types.Optional[str] = None,
+ coord: types.Union[types.Sequence, types.Numeric, str] = None,
xaxis_index: types.Optional[types.Numeric] = None,
+ xaxis_id: types.Optional[types.Numeric] = None,
yaxis_index: types.Optional[types.Numeric] = None,
+ yaxis_id: types.Optional[types.Numeric] = None,
color: types.Optional[str] = None,
category_gap: types.Union[types.Numeric, str] = "20%",
gap: types.Optional[str] = None,
@@ -38,9 +42,10 @@ def add_yaxis(
tooltip_opts: types.Tooltip = None,
itemstyle_opts: types.ItemStyle = None,
encode: types.Union[types.JsCode, dict] = None,
+ emphasis_opts: types.Emphasis = None,
):
self._append_color(color)
- self._append_legend(series_name, is_selected)
+ self._append_legend(series_name)
self.options.get("series").append(
{
"type": ChartType.PICTORIALBAR,
@@ -54,8 +59,13 @@ def add_yaxis(
"symbolMargin": symbol_margin,
"symbolClip": is_symbol_clip,
"name": series_name,
+ "coordinateSystem": coordinate_system,
+ "coordinateSystemUsage": coordinate_system_usage,
+ "coord": coord,
"xAxisIndex": xaxis_index,
+ "xAxisId": xaxis_id,
"yAxisIndex": yaxis_index,
+ "yAxisId": yaxis_id,
"data": y_axis,
"barCategoryGap": category_gap,
"barGap": gap,
@@ -65,6 +75,7 @@ def add_yaxis(
"tooltip": tooltip_opts,
"itemStyle": itemstyle_opts,
"encode": encode,
+ "emphasis": emphasis_opts,
}
)
return self
diff --git a/pyecharts/charts/basic_charts/pie.py b/pyecharts/charts/basic_charts/pie.py
index e6de03f64..87dd561b0 100644
--- a/pyecharts/charts/basic_charts/pie.py
+++ b/pyecharts/charts/basic_charts/pie.py
@@ -19,20 +19,46 @@ def add(
data_pair: types.Sequence[types.Union[types.Sequence, opts.PieItem, dict]],
*,
color: types.Optional[str] = None,
+ color_by: types.Optional[str] = "data",
+ is_legend_hover_link: bool = True,
+ coordinate_system: types.Optional[str] = None,
+ coordinate_system_usage: types.Optional[str] = None,
+ coord: types.Union[types.Sequence, types.Numeric, str] = None,
+ geo_index: types.Optional[types.Numeric] = None,
+ geo_id: types.Optional[types.Numeric] = None,
+ calendar_index: types.Optional[types.Numeric] = None,
+ calendar_id: types.Optional[types.Numeric] = None,
+ matrix_index: types.Optional[types.Numeric] = None,
+ matrix_id: types.Optional[types.Numeric] = None,
+ selected_mode: types.Union[str, bool] = False,
+ selected_offset: types.Numeric = 10,
radius: types.Optional[types.Sequence] = None,
center: types.Optional[types.Sequence] = None,
- rosetype: types.Optional[str] = None,
+ rosetype: types.Union[str, bool] = None,
is_clockwise: bool = True,
+ start_angle: types.Numeric = 90,
+ end_angle: types.Optional[types.Numeric] = None,
+ min_angle: types.Numeric = 0,
+ min_show_label_angle: types.Numeric = 0,
+ is_avoid_label_overlap: bool = True,
+ is_still_show_zero_sum: bool = True,
+ percent_precision: types.Numeric = 2,
+ is_show_empty_circle: bool = True,
+ empty_circle_style_opts: types.PieEmptyCircle = opts.PieEmptyCircleStyle(),
label_opts: types.Label = opts.LabelOpts(),
- label_line_opts: types.PieLabelLine = None,
+ label_line_opts: types.PieLabelLine = opts.PieLabelLineOpts(),
tooltip_opts: types.Tooltip = None,
itemstyle_opts: types.ItemStyle = None,
+ emphasis_opts: types.Emphasis = None,
encode: types.Union[types.JSFunc, dict, None] = None,
+ markpoint_opts: types.MarkPoint = None,
+ markline_opts: types.MarkLine = None,
+ markarea_opts: types.MarkArea = None,
):
if self.options.get("dataset") is not None:
data = None
self.options.get("legend")[0].update(
- data=[d[0] for d in self.options.get("dataset").get("source")][1:]
+ data=[d[0] for d in self.options.get("dataset")[0].get("source")][1:]
)
elif isinstance(data_pair[0], opts.PieItem):
data = data_pair
@@ -57,7 +83,29 @@ def add(
{
"type": ChartType.PIE,
"name": series_name,
+ "colorBy": color_by,
+ "legendHoverLink": is_legend_hover_link,
+ "coordinateSystem": coordinate_system,
+ "coordinateSystemUsage": coordinate_system_usage,
+ "coord": coord,
+ "geoIndex": geo_index,
+ "geoId": geo_id,
+ "calendarIndex": calendar_index,
+ "calendarId": calendar_id,
+ "matrixIndex": matrix_index,
+ "matrixId": matrix_id,
+ "selectedMode": selected_mode,
+ "selectedOffset": selected_offset,
"clockwise": is_clockwise,
+ "startAngle": start_angle,
+ "endAngle": end_angle,
+ "minAngle": min_angle,
+ "minShowLabelAngle": min_show_label_angle,
+ "avoidLabelOverlap": is_avoid_label_overlap,
+ "stillShowZeroSum": is_still_show_zero_sum,
+ "percentPrecision": percent_precision,
+ "showEmptyCircle": is_show_empty_circle,
+ "emptyCircleStyle": empty_circle_style_opts,
"data": data,
"radius": radius,
"center": center,
@@ -66,7 +114,11 @@ def add(
"labelLine": label_line_opts,
"tooltip": tooltip_opts,
"itemStyle": itemstyle_opts,
+ "emphasis": emphasis_opts,
"encode": encode,
+ "markPoint": markpoint_opts,
+ "markLine": markline_opts,
+ "markArea": markarea_opts,
}
)
return self
diff --git a/pyecharts/charts/basic_charts/polar.py b/pyecharts/charts/basic_charts/polar.py
index ec56fbfb8..c0b34185c 100644
--- a/pyecharts/charts/basic_charts/polar.py
+++ b/pyecharts/charts/basic_charts/polar.py
@@ -12,8 +12,12 @@ class Polar(Chart):
Polar coordinates can be used for scatter and polyline graphs.
"""
- def __init__(self, init_opts: types.Init = opts.InitOpts()):
- super().__init__(init_opts=init_opts)
+ def __init__(
+ self,
+ init_opts: types.Init = opts.InitOpts(),
+ render_opts: types.RenderInit = opts.RenderOpts(),
+ ):
+ super().__init__(init_opts=init_opts, render_opts=render_opts)
self.add_schema()
def add_schema(
@@ -33,20 +37,43 @@ def add(
series_name: str,
data: types.Sequence,
*,
- is_selected: bool = True,
type_: str = "line",
symbol: types.Optional[str] = None,
symbol_size: types.Numeric = 4,
stack: types.Optional[str] = None,
+ center: types.Optional[types.Sequence] = None,
+ z_level: types.Numeric = 0,
+ z: types.Numeric = 2,
+ coordinate_system: types.Optional[str] = None,
+ coordinate_system_usage: types.Optional[str] = None,
+ coord: types.Union[types.Sequence, types.Numeric, str] = None,
+ calendar_index: types.Optional[types.Numeric] = None,
+ calendar_id: types.Optional[types.Numeric] = None,
+ matrix_index: types.Optional[types.Numeric] = None,
+ matrix_id: types.Optional[types.Numeric] = None,
label_opts: types.Label = opts.LabelOpts(is_show=False),
areastyle_opts: types.AreaStyle = opts.AreaStyleOpts(),
effect_opts: types.Effect = opts.EffectOpts(),
tooltip_opts: types.Tooltip = None,
itemstyle_opts: types.ItemStyle = None,
+ emphasis_opts: types.Emphasis = None,
):
- self._append_legend(series_name, is_selected)
- self.options.update(polar={})
+ self._append_legend(series_name)
+ self.options.update(polar={
+ "center": center if center else ["50%", "50%"],
+ "zlevel": z_level,
+ "z": z,
+ "coordinateSystem": coordinate_system,
+ "coordinateSystemUsage": coordinate_system_usage,
+ "coord": coord,
+ "calendarIndex": calendar_index,
+ "calendarId": calendar_id,
+ "matrixIndex": matrix_index,
+ "matrixId": matrix_id,
+ "tooltip": tooltip_opts,
+ })
+ # polar with other series config
if type_ in (ChartType.SCATTER, ChartType.LINE, ChartType.BAR):
self.options.get("series").append(
{
@@ -61,6 +88,7 @@ def add(
"areaStyle": areastyle_opts,
"tooltip": tooltip_opts,
"itemStyle": itemstyle_opts,
+ "emphasis": emphasis_opts,
}
)
@@ -78,6 +106,7 @@ def add(
"label": label_opts,
"tooltip": tooltip_opts,
"itemStyle": itemstyle_opts,
+ "emphasis": emphasis_opts,
}
)
diff --git a/pyecharts/charts/basic_charts/radar.py b/pyecharts/charts/basic_charts/radar.py
index e687fa1aa..8bd3ca772 100644
--- a/pyecharts/charts/basic_charts/radar.py
+++ b/pyecharts/charts/basic_charts/radar.py
@@ -17,17 +17,30 @@ def add_schema(
shape: types.Optional[str] = None,
center: types.Optional[types.Sequence] = None,
radius: types.Optional[types.Union[types.Sequence, str]] = None,
+ coordinate_system: types.Optional[str] = None,
+ coordinate_system_usage: types.Optional[str] = None,
+ coord: types.Union[types.Sequence, types.Numeric, str] = None,
+ calendar_index: types.Optional[types.Numeric] = None,
+ calendar_id: types.Optional[types.Numeric] = None,
+ matrix_index: types.Optional[types.Numeric] = None,
+ matrix_id: types.Optional[types.Numeric] = None,
+ start_angle: types.Numeric = 90,
textstyle_opts: types.TextStyle = opts.TextStyleOpts(),
splitline_opt: types.SplitLine = opts.SplitLineOpts(is_show=True),
splitarea_opt: types.SplitArea = opts.SplitAreaOpts(),
axisline_opt: types.AxisLine = opts.AxisLineOpts(),
+ axistick_opt: types.AxisTick = None,
+ minor_tick_opts: types.MinorTick = None,
+ axislabel_opt: types.Label = None,
+ axispointer_opt: types.AxisPointer = None,
radiusaxis_opts: types.RadiusAxis = None,
angleaxis_opts: types.AngleAxis = None,
polar_opts: types.Polar = None,
):
-
self.options.update(
- radiusAxis=radiusaxis_opts, angleAxis=angleaxis_opts, polar=polar_opts
+ radiusAxis=radiusaxis_opts,
+ angleAxis=angleaxis_opts,
+ polar=polar_opts,
)
indicators = []
@@ -36,16 +49,31 @@ def add_schema(
s = s.opts
indicators.append(s)
- self.options.update(
- radar={
+ if self.options.get("radar") is None:
+ self.options.update(radar=[])
+
+ self.options.get("radar").append(
+ {
"indicator": indicators,
"shape": shape,
"center": center,
"radius": radius,
+ "coordinateSystem": coordinate_system,
+ "coordinateSystemUsage": coordinate_system_usage,
+ "coord": coord,
+ "calendarIndex": calendar_index,
+ "calendarId": calendar_id,
+ "matrixIndex": matrix_index,
+ "matrixId": matrix_id,
+ "startAngle": start_angle,
"name": {"textStyle": textstyle_opts},
"splitLine": splitline_opt,
"splitArea": splitarea_opt,
"axisLine": axisline_opt,
+ "axisTick": axistick_opt,
+ "minorTick": minor_tick_opts,
+ "axisLabel": axislabel_opt,
+ "axisPointer": axispointer_opt,
}
)
return self
@@ -55,30 +83,41 @@ def add(
series_name: str,
data: types.Sequence[types.Union[opts.RadarItem, dict]],
*,
- is_selected: bool = True,
+ color_by: types.Optional[str] = None,
symbol: types.Optional[str] = None,
color: types.Optional[str] = None,
label_opts: opts.LabelOpts = opts.LabelOpts(),
+ radar_index: types.Numeric = None,
+ selected_mode: types.Union[bool, str] = False,
+ z_level: types.Numeric = 0,
+ z: types.Numeric = 2,
linestyle_opts: opts.LineStyleOpts = opts.LineStyleOpts(),
areastyle_opts: opts.AreaStyleOpts = opts.AreaStyleOpts(),
tooltip_opts: types.Tooltip = None,
+ emphasis_opts: types.Emphasis = None,
):
if all([isinstance(d, opts.RadarItem) for d in data]):
for a in data:
- self._append_legend(a.get("name"), is_selected)
+ self._append_legend(a.get("name"))
else:
- self._append_legend(series_name, is_selected)
+ self._append_legend(series_name)
self.options.get("series").append(
{
"type": ChartType.RADAR,
"name": series_name,
"data": data,
+ "colorBy": color_by,
"symbol": symbol,
"label": label_opts,
+ "radarIndex": radar_index,
+ "selectedMode": selected_mode,
+ "zlevel": z_level,
+ "z": z,
"itemStyle": {"normal": {"color": color}},
"lineStyle": linestyle_opts,
"areaStyle": areastyle_opts,
"tooltip": tooltip_opts,
+ "emphasis": emphasis_opts,
}
)
return self
diff --git a/pyecharts/charts/basic_charts/sankey.py b/pyecharts/charts/basic_charts/sankey.py
index 03edf80ea..e0c8f628c 100644
--- a/pyecharts/charts/basic_charts/sankey.py
+++ b/pyecharts/charts/basic_charts/sankey.py
@@ -19,28 +19,38 @@ def add(
nodes: types.Sequence,
links: types.Sequence,
*,
- is_selected: bool = True,
pos_left: types.Union[str, types.Numeric] = "5%",
pos_top: types.Union[str, types.Numeric] = "5%",
pos_right: types.Union[str, types.Numeric] = "20%",
pos_bottom: types.Union[str, types.Numeric] = "5%",
+ width: types.Union[str, types.Numeric] = None,
+ height: types.Union[str, types.Numeric] = None,
+ coordinate_system: types.Optional[str] = None,
+ coordinate_system_usage: types.Optional[str] = None,
+ coord: types.Union[types.Sequence, types.Numeric, str] = None,
+ calendar_index: types.Optional[types.Numeric] = None,
+ calendar_id: types.Optional[types.Numeric] = None,
+ matrix_index: types.Optional[types.Numeric] = None,
+ matrix_id: types.Optional[types.Numeric] = None,
node_width: types.Numeric = 20,
node_gap: types.Numeric = 8,
node_align: str = "justify",
- layout_iterations: types.Numeric = 32,
+ layout_iterations: types.Optional[types.Numeric] = None,
orient: str = "horizontal",
is_draggable: bool = True,
- focus_node_adjacency: types.Union[bool, str] = False,
+ center: types.Optional[types.Sequence] = None,
+ zoom: types.Numeric = 1,
+ is_roam: bool = False,
+ roam_trigger: types.Optional[str] = None,
+ edge_label_opt: types.Label = None,
levels: types.SankeyLevel = None,
label_opts: types.Label = opts.LabelOpts(),
linestyle_opt: types.LineStyle = opts.LineStyleOpts(),
tooltip_opts: types.Tooltip = None,
itemstyle_opts: types.ItemStyle = None,
+ emphasis_opts: types.Emphasis = None,
):
- if layout_iterations < 32:
- layout_iterations = 32
-
- self._append_legend(series_name, is_selected)
+ self._append_legend(series_name)
self.options.get("series").append(
{
"type": ChartType.SANKEY,
@@ -51,18 +61,32 @@ def add(
"top": pos_top,
"right": pos_right,
"bottom": pos_bottom,
+ "width": width,
+ "height": height,
+ "coordinateSystem": coordinate_system,
+ "coordinateSystemUsage": coordinate_system_usage,
+ "coord": coord,
+ "calendarIndex": calendar_index,
+ "calendarId": calendar_id,
+ "matrixIndex": matrix_index,
+ "matrixId": matrix_id,
"nodeWidth": node_width,
"nodeGap": node_gap,
"nodeAlign": node_align,
- "layoutIteration": layout_iterations,
+ "layoutIterations": layout_iterations,
"orient": orient,
"draggable": is_draggable,
- "focusNodeAdjacency": focus_node_adjacency,
+ "center": center,
+ "zoom": zoom,
+ "roam": is_roam,
+ "roamTrigger": roam_trigger,
+ "edgeLabel": edge_label_opt,
"levels": levels,
"label": label_opts,
"lineStyle": linestyle_opt,
"tooltip": tooltip_opts,
"itemStyle": itemstyle_opts,
+ "emphasis": emphasis_opts,
}
)
return self
diff --git a/pyecharts/charts/basic_charts/scatter.py b/pyecharts/charts/basic_charts/scatter.py
index d028b5d6f..7ac26f591 100644
--- a/pyecharts/charts/basic_charts/scatter.py
+++ b/pyecharts/charts/basic_charts/scatter.py
@@ -38,23 +38,40 @@ def add_yaxis(
series_name: str,
y_axis: types.Sequence[types.Union[opts.ScatterItem, dict]],
*,
- is_selected: bool = True,
+ color_by: types.Optional[str] = None,
+ coordinate_system: types.Optional[str] = None,
+ coordinate_system_usage: types.Optional[str] = None,
+ coord: types.Union[types.Sequence, types.Numeric, str] = None,
xaxis_index: types.Optional[types.Numeric] = None,
+ xaxis_id: types.Optional[types.Numeric] = None,
yaxis_index: types.Optional[types.Numeric] = None,
+ yaxis_id: types.Optional[types.Numeric] = None,
+ polar_index: types.Optional[types.Numeric] = None,
+ polar_id: types.Optional[types.Numeric] = None,
+ single_axis_index: types.Optional[types.Numeric] = None,
+ single_axis_id: types.Optional[types.Numeric] = None,
+ geo_index: types.Optional[types.Numeric] = None,
+ geo_id: types.Optional[types.Numeric] = None,
+ calendar_index: types.Optional[types.Numeric] = None,
+ calendar_id: types.Optional[types.Numeric] = None,
+ matrix_index: types.Optional[types.Numeric] = None,
+ matrix_id: types.Optional[types.Numeric] = None,
color: types.Optional[str] = None,
symbol: types.Optional[str] = None,
symbol_size: types.Union[types.Numeric, types.Sequence] = 10,
symbol_rotate: types.Optional[types.Numeric] = None,
label_opts: types.Label = opts.LabelOpts(position="right"),
+ is_silent: bool = False,
markpoint_opts: types.MarkPoint = None,
markline_opts: types.MarkLine = None,
markarea_opts: types.MarkArea = None,
tooltip_opts: types.Tooltip = None,
itemstyle_opts: types.ItemStyle = None,
+ emphasis_opts: types.Emphasis = None,
encode: types.Union[types.JSFunc, dict, None] = None,
):
self._append_color(color)
- self._append_legend(series_name, is_selected)
+ self._append_legend(series_name)
data = self._parse_data(y_axis=y_axis)
@@ -62,18 +79,36 @@ def add_yaxis(
{
"type": ChartType.SCATTER,
"name": series_name,
+ "colorBy": color_by,
+ "coordinateSystem": coordinate_system,
+ "coordinateSystemUsage": coordinate_system_usage,
+ "coord": coord,
"xAxisIndex": xaxis_index,
+ "xAxisId": xaxis_id,
"yAxisIndex": yaxis_index,
+ "yAxisId": yaxis_id,
+ "polarIndex": polar_index,
+ "polarId": polar_id,
+ "singleAxisIndex": single_axis_index,
+ "singleAxisId": single_axis_id,
+ "geoIndex": geo_index,
+ "geoId": geo_id,
+ "calendarIndex": calendar_index,
+ "calendarId": calendar_id,
+ "matrixIndex": matrix_index,
+ "matrixId": matrix_id,
"symbol": symbol,
"symbolSize": symbol_size,
"symbolRotate": symbol_rotate,
"data": data,
"label": label_opts,
+ "silent": is_silent,
"markPoint": markpoint_opts,
"markLine": markline_opts,
"markArea": markarea_opts,
"tooltip": tooltip_opts,
"itemStyle": itemstyle_opts,
+ "emphasis": emphasis_opts,
"encode": encode,
}
)
diff --git a/pyecharts/charts/basic_charts/sunburst.py b/pyecharts/charts/basic_charts/sunburst.py
index cb16b9f72..15ad5c5d0 100644
--- a/pyecharts/charts/basic_charts/sunburst.py
+++ b/pyecharts/charts/basic_charts/sunburst.py
@@ -21,12 +21,26 @@ def add(
*,
center: types.Optional[types.Sequence] = None,
radius: types.Optional[types.Sequence] = None,
+ coordinate_system: types.Optional[str] = None,
+ coordinate_system_usage: types.Optional[str] = None,
+ coord: types.Union[types.Sequence, types.Numeric, str] = None,
+ calendar_index: types.Optional[types.Numeric] = None,
+ calendar_id: types.Optional[types.Numeric] = None,
+ matrix_index: types.Optional[types.Numeric] = None,
+ matrix_id: types.Optional[types.Numeric] = None,
highlight_policy: str = "descendant",
node_click: str = "rootToNode",
sort_: types.Optional[types.JSFunc] = "desc",
- levels: types.Optional[types.Sequence] = None,
+ is_render_label_for_zero_data: bool = False,
+ is_clockwise: bool = True,
+ start_angle: types.Numeric = 90,
+ levels: types.Optional[types.Sequence[types.SunburstLevelOpts]] = None,
label_opts: types.Label = opts.LabelOpts(),
+ label_line_opts: types.SunburstLabelLine = None,
+ label_layout_opts: types.SunburstLabelLayout = None,
itemstyle_opts: types.ItemStyle = None,
+ tooltip_opts: types.Tooltip = None,
+ emphasis_opts: types.Emphasis = None,
):
if not center:
center = ["50%", "50%"]
@@ -40,12 +54,26 @@ def add(
"data": data_pair,
"center": center,
"radius": radius,
+ "coordinateSystem": coordinate_system,
+ "coordinateSystemUsage": coordinate_system_usage,
+ "coord": coord,
+ "calendarIndex": calendar_index,
+ "calendarId": calendar_id,
+ "matrixIndex": matrix_index,
+ "matrixId": matrix_id,
"highlightPolicy": highlight_policy,
"nodeClick": node_click,
"sort": sort_,
+ "renderLabelForZeroData": is_render_label_for_zero_data,
+ "clockwise": is_clockwise,
+ "startAngle": start_angle,
"levels": levels,
"label": label_opts,
+ "labelLine": label_line_opts,
+ "labelLayout": label_layout_opts,
"itemStyle": itemstyle_opts,
+ "tooltip": tooltip_opts,
+ "emphasis": emphasis_opts,
}
)
return self
diff --git a/pyecharts/charts/basic_charts/themeriver.py b/pyecharts/charts/basic_charts/themeriver.py
index 7692ef68e..b5ae258da 100644
--- a/pyecharts/charts/basic_charts/themeriver.py
+++ b/pyecharts/charts/basic_charts/themeriver.py
@@ -18,23 +18,50 @@ def add(
series_name: types.Sequence,
data: types.Sequence[types.Union[opts.ThemeRiverItem, dict]],
*,
- is_selected: bool = True,
+ color_by: types.Optional[str] = None,
+ pos_left: types.Union[str, types.Numeric] = "5%",
+ pos_top: types.Union[str, types.Numeric] = "5%",
+ pos_right: types.Union[str, types.Numeric] = "5%",
+ pos_bottom: types.Union[str, types.Numeric] = "5%",
+ width: types.Union[str, types.Numeric] = None,
+ height: types.Union[str, types.Numeric] = None,
+ coordinate_system: types.Optional[str] = None,
+ coordinate_system_usage: types.Optional[str] = None,
+ coord: types.Union[types.Sequence, types.Numeric, str] = None,
+ single_axis_index: types.Optional[types.Numeric] = None,
+ single_axis_id: types.Optional[types.Numeric] = None,
+ boundary_gap: types.Optional[types.Sequence] = None,
label_opts: types.Label = opts.LabelOpts(),
singleaxis_opts: types.SingleAxis = opts.SingleAxisOpts(),
tooltip_opts: types.Tooltip = None,
itemstyle_opts: types.ItemStyle = None,
+ emphasis_opts: types.Emphasis = None,
):
for n in series_name:
- self._append_legend(n, is_selected)
+ self._append_legend(n)
self.options.get("series").append(
{
"type": ChartType.THEMERIVER,
"name": series_name,
"data": data,
+ "colorBy": color_by,
+ "left": pos_left,
+ "top": pos_top,
+ "right": pos_right,
+ "bottom": pos_bottom,
+ "width": width,
+ "height": height,
+ "coordinateSystem": coordinate_system,
+ "coordinateSystemUsage": coordinate_system_usage,
+ "coord": coord,
+ "singleAxisIndex": single_axis_index,
+ "singleAxisId": single_axis_id,
+ "boundaryGap": boundary_gap,
"label": label_opts,
"tooltip": tooltip_opts,
"itemStyle": itemstyle_opts,
+ "emphasis": emphasis_opts,
}
)
diff --git a/pyecharts/charts/basic_charts/tree.py b/pyecharts/charts/basic_charts/tree.py
index 02a1d55d7..34c006618 100644
--- a/pyecharts/charts/basic_charts/tree.py
+++ b/pyecharts/charts/basic_charts/tree.py
@@ -37,24 +37,40 @@ def add(
series_name: str,
data: types.Sequence[types.Union[opts.TreeItem, dict]],
*,
+ zoom: types.Optional[types.Numeric] = 1,
layout: str = "orthogonal",
symbol: types.JSFunc = "emptyCircle",
symbol_size: types.Union[types.JSFunc, types.Numeric, types.Sequence] = 7,
orient: str = "LR",
- pos_top: types.Optional[str] = None,
- pos_left: types.Optional[str] = None,
- pos_bottom: types.Optional[str] = None,
- pos_right: types.Optional[str] = None,
+ pos_top: types.Union[str, types.Numeric, None] = None,
+ pos_left: types.Union[str, types.Numeric, None] = None,
+ pos_bottom: types.Union[str, types.Numeric, None] = None,
+ pos_right: types.Union[str, types.Numeric, None] = None,
+ width: types.Union[str, types.Numeric, None] = None,
+ height: types.Union[str, types.Numeric, None] = None,
+ coordinate_system: types.Optional[str] = None,
+ coordinate_system_usage: types.Optional[str] = None,
+ coord: types.Union[types.Sequence, types.Numeric, str] = None,
+ calendar_index: types.Optional[types.Numeric] = None,
+ calendar_id: types.Optional[types.Numeric] = None,
+ matrix_index: types.Optional[types.Numeric] = None,
+ matrix_id: types.Optional[types.Numeric] = None,
+ center: types.Optional[types.Sequence[types.Union[str, types.Numeric]]] = None,
collapse_interval: types.Numeric = 0,
edge_shape: str = "curve",
edge_fork_position: str = "50%",
is_roam: bool = False,
+ roam_trigger: types.Optional[str] = None,
is_expand_and_collapse: bool = True,
initial_tree_depth: types.Optional[types.Numeric] = None,
label_opts: types.Label = opts.LabelOpts(),
- leaves_label_opts: types.Label = opts.LabelOpts(),
+ leaves_opts: types.TreeLeavesOpts = opts.TreeLeavesOpts(),
tooltip_opts: types.Tooltip = None,
itemstyle_opts: types.ItemStyle = None,
+ emphasis_opts: types.Emphasis = None,
+ selected_mode: types.Union[bool, str] = False,
+ blur_opts: types.Blur = None,
+ select_opts: types.Select = None,
):
_data = self._set_collapse_interval(data, collapse_interval)
self.options.get("series").append(
@@ -66,19 +82,35 @@ def add(
"right": pos_right,
"top": pos_top,
"bottom": pos_bottom,
+ "width": width,
+ "height": height,
+ "coordinateSystem": coordinate_system,
+ "coordinateSystemUsage": coordinate_system_usage,
+ "coord": coord,
+ "calendarIndex": calendar_index,
+ "calendarId": calendar_id,
+ "matrixIndex": matrix_index,
+ "matrixId": matrix_id,
+ "center": center,
+ "zoom": zoom,
"symbol": symbol,
"symbolSize": symbol_size,
"edgeShape": edge_shape,
"edgeForkPosition": edge_fork_position,
"roam": is_roam,
+ "roamTrigger": roam_trigger,
"expandAndCollapse": is_expand_and_collapse,
"initialTreeDepth": initial_tree_depth,
"layout": layout,
"orient": orient,
"label": label_opts,
- "leaves": {"label": leaves_label_opts},
+ "leaves": leaves_opts,
"tooltip": tooltip_opts,
"itemStyle": itemstyle_opts,
+ "emphasis": emphasis_opts,
+ "selectedMode": selected_mode,
+ "blur": blur_opts,
+ "select": select_opts,
}
)
return self
diff --git a/pyecharts/charts/basic_charts/treemap.py b/pyecharts/charts/basic_charts/treemap.py
index b47f84da6..27395d5af 100644
--- a/pyecharts/charts/basic_charts/treemap.py
+++ b/pyecharts/charts/basic_charts/treemap.py
@@ -17,7 +17,6 @@ def add(
series_name: str,
data: types.Sequence[types.Union[opts.TreeItem, dict]],
*,
- is_selected: bool = True,
leaf_depth: types.Optional[types.Numeric] = None,
pos_left: types.Optional[str] = None,
pos_right: types.Optional[str] = None,
@@ -25,6 +24,13 @@ def add(
pos_bottom: types.Optional[str] = None,
width: types.Union[str, types.Numeric] = "80%",
height: types.Union[str, types.Numeric] = "80%",
+ coordinate_system: types.Optional[str] = None,
+ coordinate_system_usage: types.Optional[str] = None,
+ coord: types.Union[types.Sequence, types.Numeric, str] = None,
+ calendar_index: types.Optional[types.Numeric] = None,
+ calendar_id: types.Optional[types.Numeric] = None,
+ matrix_index: types.Optional[types.Numeric] = None,
+ matrix_id: types.Optional[types.Numeric] = None,
square_ratio: types.Optional[types.JSFunc] = None,
drilldown_icon: str = "▶",
roam: types.Union[bool, str] = True,
@@ -33,6 +39,7 @@ def add(
levels: types.TreeMapLevel = None,
visual_min: types.Optional[types.Numeric] = None,
visual_max: types.Optional[types.Numeric] = None,
+ visual_dimension: types.Optional[types.Numeric] = None,
color_alpha: types.Union[types.Numeric, types.Sequence] = None,
color_saturation: types.Union[types.Numeric, types.Sequence] = None,
color_mapping_by: str = "index",
@@ -43,8 +50,9 @@ def add(
tooltip_opts: types.Tooltip = None,
itemstyle_opts: types.ItemStyle = None,
breadcrumb_opts: types.TreeMapBreadcrumb = None,
+ emphasis_opts: types.Emphasis = None,
):
- self._append_legend(series_name, is_selected)
+ self._append_legend(series_name)
self.options.get("series").append(
{
"type": ChartType.TREEMAP,
@@ -55,10 +63,17 @@ def add(
"top": pos_top,
"width": width,
"height": height,
+ "coordinateSystem": coordinate_system,
+ "coordinateSystemUsage": coordinate_system_usage,
+ "coord": coord,
+ "calendarIndex": calendar_index,
+ "calendarId": calendar_id,
+ "matrixIndex": matrix_index,
+ "matrixId": matrix_id,
"bottom": pos_bottom,
"squareRatio": square_ratio,
"label": label_opts,
- "upperlabel": upper_label_opts,
+ "upperLabel": upper_label_opts,
"leafDepth": leaf_depth,
"drillDownIcon": drilldown_icon,
"roam": roam,
@@ -67,6 +82,7 @@ def add(
"levels": levels,
"visualMin": visual_min,
"visualMax": visual_max,
+ "visualDimension": visual_dimension,
"colorAlpha": color_alpha,
"colorSaturation": color_saturation,
"colorMappingBy": color_mapping_by,
@@ -75,6 +91,7 @@ def add(
"tooltip": tooltip_opts,
"itemStyle": itemstyle_opts,
"breadcrumb": breadcrumb_opts,
+ "emphasis": emphasis_opts,
}
)
return self
diff --git a/pyecharts/charts/basic_charts/wordcloud.py b/pyecharts/charts/basic_charts/wordcloud.py
index 098427796..60dcd94d4 100644
--- a/pyecharts/charts/basic_charts/wordcloud.py
+++ b/pyecharts/charts/basic_charts/wordcloud.py
@@ -31,8 +31,12 @@ class WordCloud(Chart):
appear frequently in the text.
"""
- def __init__(self, init_opts: types.Init = opts.InitOpts()):
- super().__init__(init_opts=init_opts)
+ def __init__(
+ self,
+ init_opts: types.Init = opts.InitOpts(),
+ render_opts: types.RenderInit = opts.RenderOpts(),
+ ):
+ super().__init__(init_opts=init_opts, render_opts=render_opts)
self.js_dependencies.add("echarts-wordcloud")
self._mask_image_suffix: types.Sequence = ["jpg", "jpeg", "png", "ico"]
@@ -89,9 +93,7 @@ def add(
):
data = []
for n, v in data_pair:
- data.append(
- {"name": n, "value": v, "textStyle": {"normal": {"color": gen_color()}}}
- )
+ data.append({"name": n, "value": v, "textStyle": {"color": gen_color()}})
word_size_range = word_size_range or (12, 60)
diff --git a/pyecharts/charts/chart.py b/pyecharts/charts/chart.py
index fb156a677..f83071601 100644
--- a/pyecharts/charts/chart.py
+++ b/pyecharts/charts/chart.py
@@ -6,19 +6,16 @@
class Chart(Base):
- def __init__(self, init_opts: types.Init = opts.InitOpts()):
+ def __init__(
+ self,
+ init_opts: types.Init = opts.InitOpts(),
+ render_opts: types.RenderInit = opts.RenderOpts(),
+ ):
if isinstance(init_opts, dict):
temp_opts = opts.InitOpts()
temp_opts.update(**init_opts)
init_opts = temp_opts
- super().__init__(init_opts=init_opts)
- self.colors = (
- "#c23531 #2f4554 #61a0a8 #d48265 #749f83 #ca8622 #bda29a #6e7074 "
- "#546570 #c4ccd3 #f05b72 #ef5b9c #f47920 #905a3d #fab27b #2a5caa "
- "#444693 #726930 #b2d235 #6d8346 #ac6767 #1d953f #6950a1 #918597"
- ).split()
- if init_opts.opts.get("theme") == ThemeType.WHITE:
- self.options.update(color=self.colors)
+ super().__init__(init_opts=init_opts, render_opts=render_opts)
self.options.update(
series=[],
legend=[{"data": [], "selected": dict()}],
@@ -26,6 +23,25 @@ def __init__(self, init_opts: types.Init = opts.InitOpts()):
)
self._chart_type: Optional[str] = None
+ def set_dark_mode(
+ self,
+ dark_mode_colors: Optional[Sequence[str]] = None,
+ dark_mode_bg_color: str = "#100C2A",
+ ):
+ # [Hard Code Here] The Echarts default Dark Mode Configurations
+ if dark_mode_colors is None:
+ dark_mode_colors = (
+ "#4992ff #7cffb2 #fddd60 #ff6e76 #58d9f9 #05c091 #ff8a45 "
+ "#8d48e3 #dd79ff"
+ ).split()
+ self.options.update(
+ backgroundColor=dark_mode_bg_color,
+ darkMode=True,
+ color=dark_mode_colors,
+ )
+ self.theme = ThemeType.DARK
+ return self
+
def set_colors(self, colors: Sequence[str]):
self.options.update(color=colors)
return self
@@ -84,15 +100,15 @@ def set_series_opts(
return self
- def _append_legend(self, name, is_selected):
+ def _append_legend(self, name):
self.options.get("legend")[0].get("data").append(name)
- self.options.get("legend")[0].get("selected").update({name: is_selected})
def _append_color(self, color: Optional[str]):
if color:
- self.colors = [color] + self.colors
- if self.theme == ThemeType.WHITE:
- self.options.update(color=self.colors)
+ if self.options.get("color"):
+ self.options.get("color").append(color)
+ else:
+ self.options.update(color=[color])
def set_global_opts(
self,
@@ -107,11 +123,14 @@ def set_global_opts(
datazoom_opts: types.DataZoom = None,
graphic_opts: types.Graphic = None,
axispointer_opts: types.AxisPointer = None,
+ matrix_opts: types.Matrix = None,
+ thumbnail_opts: types.Thumbnail = None,
):
if tooltip_opts is None:
tooltip_opts = opts.TooltipOpts(
formatter=ToolTipFormatterType.get(self._chart_type, None)
)
+
self.options.update(
title=title_opts,
toolbox=toolbox_opts,
@@ -120,6 +139,8 @@ def set_global_opts(
dataZoom=datazoom_opts,
graphic=graphic_opts,
axisPointer=axispointer_opts,
+ matrix=matrix_opts,
+ thumbnail=thumbnail_opts,
)
if brush_opts is not None:
@@ -128,7 +149,8 @@ def set_global_opts(
if isinstance(legend_opts, opts.LegendOpts):
legend_opts = legend_opts.opts
for _s in self.options["legend"]:
- _s.update(legend_opts)
+ # _s.update(legend_opts)
+ _s.update(**{k: v for k, v in legend_opts.items() if v is not None})
if xaxis_opts and self.options.get("xAxis", None):
if isinstance(xaxis_opts, opts.AxisOpts):
@@ -147,20 +169,47 @@ def add_dataset(
source: types.Union[types.Sequence, types.JSFunc] = None,
dimensions: types.Optional[types.Sequence] = None,
source_header: types.Optional[bool] = None,
+ transform: types.Optional[Sequence[opts.DatasetTransformOpts]] = None,
+ from_dataset_index: types.Optional[types.Numeric] = None,
+ from_dataset_id: types.Optional[types.Numeric] = None,
+ from_transform_result: types.Optional[types.Numeric] = None,
):
- self.options.update(
- dataset={
- "source": source,
- "dimensions": dimensions,
- "sourceHeader": source_header,
- }
- )
+ if self.options.get("dataset") is not None:
+ self.options.get("dataset").append(
+ {
+ "source": source,
+ "dimensions": dimensions,
+ "sourceHeader": source_header,
+ "transform": transform,
+ "fromDatasetIndex": from_dataset_index,
+ "fromDatasetId": from_dataset_id,
+ "fromTransformResult": from_transform_result,
+ }
+ )
+ else:
+ self.options.update(
+ dataset=[
+ {
+ "source": source,
+ "dimensions": dimensions,
+ "sourceHeader": source_header,
+ "transform": transform,
+ "fromDatasetIndex": from_dataset_index,
+ "fromDatasetId": from_dataset_id,
+ "fromTransformResult": from_transform_result,
+ }
+ ]
+ )
return self
class RectChart(Chart):
- def __init__(self, init_opts: types.Init = opts.InitOpts()):
- super().__init__(init_opts=init_opts)
+ def __init__(
+ self,
+ init_opts: types.Init = opts.InitOpts(),
+ render_opts: types.RenderInit = opts.RenderOpts(),
+ ):
+ super().__init__(init_opts=init_opts, render_opts=render_opts)
self.options.update(xAxis=[opts.AxisOpts().opts], yAxis=[opts.AxisOpts().opts])
def extend_axis(
@@ -194,10 +243,19 @@ def overlap(self, chart: Base):
self.options.get("legend")[0].get("data").extend(
chart.options.get("legend")[0].get("data")
)
- self.options.get("legend")[0].get("selected").update(
- chart.options.get("legend")[0].get("selected")
- )
+ if self.options.get("legend")[0].get("selected") is not None:
+ self.options.get("legend")[0].get("selected").update(
+ chart.options.get("legend")[0].get("selected")
+ )
self.options.get("series").extend(chart.options.get("series"))
+ # to merge colors of chart
+ chart_colors = chart.options.get("color")
+ if self.options.get("color") is None:
+ if chart_colors:
+ self.options.update(color=chart_colors)
+ else:
+ if chart_colors:
+ self.options.get("color").extend(chart_colors)
return self
@@ -206,27 +264,97 @@ class Chart3D(Chart):
`Chart3D`类是所有 3D 类图表的基类,继承自 `Chart` 类
"""
- def __init__(self, init_opts: types.Init = opts.InitOpts()):
+ def __init__(
+ self,
+ init_opts: types.Init = opts.InitOpts(),
+ render_opts: types.RenderInit = opts.RenderOpts(),
+ ):
init_opts.renderer = RenderType.CANVAS
- super().__init__(init_opts)
+ super().__init__(init_opts, render_opts)
self.js_dependencies.add("echarts-gl")
- self.options.update(visualMap=opts.VisualMapOpts().opts)
self._3d_chart_type: Optional[str] = None # 3d chart type,don't use it directly
+ def add_globe(
+ self,
+ is_show: bool = True,
+ globe_radius: types.Numeric = 100,
+ globe_outer_radius: types.Numeric = 150,
+ environment: str = "auto",
+ base_texture: types.Union[str, types.JsCode, None] = None,
+ height_texture: types.Union[str, types.JsCode, None] = None,
+ displacement_texture: types.Union[str, types.JsCode, None] = None,
+ displacement_scale: types.Numeric = 0,
+ displacement_quality: str = "medium",
+ shading: types.Optional[str] = None,
+ realistic_material_opts: types.Optional[types.Map3DRealisticMaterial] = None,
+ lambert_material_opts: types.Optional[types.Map3DLambertMaterial] = None,
+ color_material_opts: types.Optional[types.Map3DColorMaterial] = None,
+ light_opts: types.Optional[types.Map3DLight] = None,
+ post_effect_opts: types.Optional[types.Map3DPostEffect] = None,
+ is_enable_super_sampling: types.Union[str, bool] = "auto",
+ view_control_opts: types.Optional[types.Map3DViewControl] = None,
+ layers: types.Optional[types.GlobeLayers] = None,
+ z_level: types.Numeric = -10,
+ pos_left: types.Union[str, types.Numeric] = "auto",
+ pos_top: types.Union[str, types.Numeric] = "auto",
+ pos_right: types.Union[str, types.Numeric] = "auto",
+ pos_bottom: types.Union[str, types.Numeric] = "auto",
+ width: types.Union[str, types.Numeric] = "auto",
+ height: types.Union[str, types.Numeric] = "auto",
+ ):
+ self.options.update(
+ globe={
+ "show": is_show,
+ "globeRadius": globe_radius,
+ "globeOuterRadius": globe_outer_radius,
+ "environment": environment,
+ "baseTexture": base_texture,
+ "heightTexture": height_texture,
+ "displacementTexture": displacement_texture,
+ "displacementScale": displacement_scale,
+ "displacementQuality": displacement_quality,
+ "shading": shading,
+ "realisticMaterial": realistic_material_opts,
+ "lambertMaterial": lambert_material_opts,
+ "colorMaterial": color_material_opts,
+ "light": light_opts,
+ "postEffect": post_effect_opts,
+ "temporalSuperSampling": {"enable": is_enable_super_sampling},
+ "viewControl": view_control_opts,
+ "layers": layers,
+ "zlevel": z_level,
+ "left": pos_left,
+ "top": pos_top,
+ "right": pos_right,
+ "bottom": pos_bottom,
+ "width": width,
+ "height": height,
+ }
+ )
+ return self
+
class ThreeAxisChart(Chart3D):
def add(
self,
series_name: str,
data: Sequence,
+ coordinate_system: Optional[str] = None,
shading: Optional[str] = None,
itemstyle_opts: types.ItemStyle = None,
label_opts: types.Label = opts.LabelOpts(is_show=False),
- xaxis3d_opts: types.Axis3D = opts.Axis3DOpts(type_="category"),
- yaxis3d_opts: types.Axis3D = opts.Axis3DOpts(type_="category"),
- zaxis3d_opts: types.Axis3D = opts.Axis3DOpts(type_="value"),
+ grid_3d_index: types.Numeric = 0,
+ xaxis3d_opts: types.Axis3D = opts.Axis3DOpts(type_="value", name="X"),
+ yaxis3d_opts: types.Axis3D = opts.Axis3DOpts(type_="value", name="Y"),
+ zaxis3d_opts: types.Axis3D = opts.Axis3DOpts(type_="value", name="Z"),
grid3d_opts: types.Grid3D = opts.Grid3DOpts(),
encode: types.Union[types.JSFunc, dict, None] = None,
+ emphasis_opts: types.Optional[types.Emphasis3D] = None,
+ is_parametric: types.Optional[bool] = None,
+ is_show_wire_frame: types.Optional[bool] = None,
+ wire_frame_line_style_opts: types.Optional[opts.LineStyleOpts] = None,
+ equation: types.Optional[dict] = None,
+ parametric_equation: types.Optional[dict] = None,
):
self.options.get("legend")[0].get("data").append(series_name)
self.options.update(
@@ -236,15 +364,39 @@ def add(
grid3D=grid3d_opts,
)
- self.options.get("series").append(
- {
- "type": self._3d_chart_type,
- "name": series_name,
- "data": data,
- "label": label_opts,
- "shading": shading,
- "itemStyle": itemstyle_opts,
- "encode": encode,
- }
- )
+ if self._3d_chart_type == "surface":
+ self.options.get("series").append(
+ {
+ "type": self._3d_chart_type,
+ "name": series_name,
+ "coordinateSystem": coordinate_system,
+ "data": data,
+ "label": label_opts,
+ "shading": shading,
+ "grid3DIndex": grid_3d_index,
+ "itemStyle": itemstyle_opts,
+ "parametric": is_parametric,
+ "wireframe": {
+ "show": is_show_wire_frame,
+ "lineStyle": wire_frame_line_style_opts,
+ },
+ "equation": equation,
+ "parametricEquation": parametric_equation,
+ }
+ )
+ else:
+ self.options.get("series").append(
+ {
+ "type": self._3d_chart_type,
+ "name": series_name,
+ "coordinateSystem": coordinate_system,
+ "data": data,
+ "label": label_opts,
+ "shading": shading,
+ "grid3DIndex": grid_3d_index,
+ "itemStyle": itemstyle_opts,
+ "emphasis": emphasis_opts,
+ "encode": encode,
+ }
+ )
return self
diff --git a/pyecharts/charts/composite_charts/grid.py b/pyecharts/charts/composite_charts/grid.py
index 97d8738d0..4a220df9c 100644
--- a/pyecharts/charts/composite_charts/grid.py
+++ b/pyecharts/charts/composite_charts/grid.py
@@ -1,8 +1,10 @@
import copy
+from typing import Optional
from ... import options as opts
from ... import types
from ...globals import ThemeType
+from ..basic_charts.radar import Radar
from ..chart import Base, Chart, RectChart
@@ -13,8 +15,12 @@ class Grid(Base):
and scatter chart (bubble chart) can be drawn in grid.
"""
- def __init__(self, init_opts: types.Init = opts.InitOpts()):
- super().__init__(init_opts=init_opts)
+ def __init__(
+ self,
+ init_opts: types.Init = opts.InitOpts(),
+ render_opts: types.RenderInit = opts.RenderOpts(),
+ ):
+ super().__init__(init_opts=init_opts, render_opts=render_opts)
self.options: types.Optional[dict] = None
self._axis_index: int = 0
self._grow_grid_index: int = 0
@@ -25,12 +31,11 @@ def add(
chart: Chart,
grid_opts: types.Union[opts.GridOpts, dict],
*,
- grid_index: int = 0,
+ grid_index: Optional[int] = None,
is_control_axis_index: bool = False,
):
if self.options is None:
self.options = copy.deepcopy(chart.options)
- self.chart_id = chart.chart_id
self.options.update(grid=[], title=[])
if self.theme != ThemeType.WHITE:
self.options.update(color=[])
@@ -38,10 +43,42 @@ def add(
# Priority Order: Grid > Other Chart
self.options.update(backgroundColor=self.bg_color)
+ # 如果是第一个添加的图表,则初始化 dataZoom 和 visualMap 配置
+ self.options.update({"dataZoom": None, "visualMap": None})
+
if not is_control_axis_index:
for s in self.options.get("series"):
s.update(xAxisIndex=self._axis_index, yAxisIndex=self._axis_index)
+ # visualMap 配置添加
+ visual_map = chart.options.get("visualMap")
+ if visual_map is not None:
+ if self.options.get("visualMap") is None:
+ self.options.update(
+ visualMap=[visual_map] if not isinstance(visual_map, list)
+ else visual_map
+ )
+ else:
+ self.options.get("visualMap").extend(
+ [visual_map] if not isinstance(visual_map, list)
+ else visual_map
+ )
+
+ # dataZoom 配置添加
+ data_zoom = chart.options.get("dataZoom")
+ if data_zoom is not None:
+ if self.options.get("dataZoom") is None:
+ self.options.update(
+ dataZoom=[data_zoom] if not isinstance(data_zoom, list)
+ else data_zoom
+ )
+ else:
+ self.options.get("dataZoom").extend(
+ [data_zoom] if not isinstance(data_zoom, list)
+ else data_zoom
+ )
+
+ # title 配置添加
title = chart.options.get("title", opts.TitleOpts().opts)
if isinstance(title, opts.TitleOpts):
title = title.opts
@@ -57,16 +94,26 @@ def add(
self.js_dependencies.add(dep)
if chart.options.get("geo") is not None:
- self.options.update(geo=chart.options.get("geo"))
+ _grid_geo_option = self.options.get("geo")
+ if _grid_geo_option is None or isinstance(_grid_geo_option, dict):
+ self.options.update(geo=[chart.options.get("geo")])
+ else:
+ _grid_geo_option.append(chart.options.get("geo"))
if isinstance(chart, RectChart):
- if grid_index == 0:
+ if grid_index is None:
grid_index = self._grow_grid_index
- for x in chart.options.get("xAxis"):
- x.update(gridIndex=grid_index)
- for y in chart.options.get("yAxis"):
- y.update(gridIndex=grid_index)
+ if self._grow_grid_index == 0:
+ for x in self.options.get("xAxis"):
+ x.update(gridIndex=grid_index) if x.get("gridIndex") is None else ...
+ for y in self.options.get("yAxis"):
+ y.update(gridIndex=grid_index) if y.get("gridIndex") is None else ...
+ else:
+ for x in chart.options.get("xAxis"):
+ x.update(gridIndex=grid_index) if x.get("gridIndex") is None else ...
+ for y in chart.options.get("yAxis"):
+ y.update(gridIndex=grid_index) if y.get("gridIndex") is None else ...
self._grow_grid_index += 1
if self._axis_index > 0:
@@ -75,6 +122,8 @@ def add(
if isinstance(chart, RectChart):
self.options.get("xAxis").extend(chart.options.get("xAxis"))
self.options.get("yAxis").extend(chart.options.get("yAxis"))
+ if isinstance(chart, Radar):
+ self.options.get("radar").extend(chart.options.get("radar"))
self.options.get("grid").append(grid_opts)
self._axis_index += 1
diff --git a/pyecharts/charts/composite_charts/page.py b/pyecharts/charts/composite_charts/page.py
index e870462d5..65e18a354 100644
--- a/pyecharts/charts/composite_charts/page.py
+++ b/pyecharts/charts/composite_charts/page.py
@@ -54,17 +54,25 @@ def __init__(
page_title: str = CurrentConfig.PAGE_TITLE,
js_host: str = "",
interval: int = 1,
+ is_remove_br: bool = False,
+ is_embed_js: bool = False,
+ page_border_color: str = "",
layout: types.Union[PageLayoutOpts, dict] = PageLayoutOpts(),
):
self.js_host: str = js_host or CurrentConfig.ONLINE_HOST
self.page_title = page_title
self.page_interval = interval
+ self.remove_br = is_remove_br
+ self.page_border_color = page_border_color
self.layout = self._assembly_layout(layout)
self.js_functions: utils.OrderedSet = utils.OrderedSet()
self.js_dependencies = utils.OrderedSet()
self.download_button: bool = False
self._charts: list = []
+ self.render_options: dict = {"embed_js": is_embed_js}
+ self._render_cache: dict = dict()
+
def add(self, *charts):
for c in charts:
self._charts.append(c)
@@ -124,6 +132,12 @@ def _prepare_render(self):
self.css_libs = [self.js_host + link for link in ("jquery-ui.css",)]
self.layout = ""
+ self._render_cache.clear()
+ if self.render_options.get("embed_js"):
+ self._render_cache[
+ "javascript"
+ ] = self.load_javascript().load_javascript_contents()
+
def render(
self,
path: str = "render.html",
diff --git a/pyecharts/charts/composite_charts/tab.py b/pyecharts/charts/composite_charts/tab.py
index d6b5064a0..789c27dc4 100644
--- a/pyecharts/charts/composite_charts/tab.py
+++ b/pyecharts/charts/composite_charts/tab.py
@@ -5,15 +5,67 @@
from ... import types
from ...commons import utils
from ...globals import CurrentConfig, ThemeType
+from ...options.charts_options import TabChartGlobalOpts
from ...render import engine
from ..mixins import CompositeMixin
+DEFAULT_TAB_CSS: str = """
+.chart-container {
+ display: block;
+}
+
+.chart-container:nth-child(n+2) {
+ display: none;
+}
+
+.tab {
+ overflow: hidden;
+ border: 1px solid #ccc;
+ background-color: #f1f1f1;
+}
+
+"""
+DEFAULT_TAB_BUTTON_CSS: str = """
+.tab button {
+ background-color: inherit;
+ float: left;
+ border: none;
+ outline: none;
+ cursor: pointer;
+ padding: 12px 16px;
+ transition: 0.3s;
+}
+
+"""
+DEFAULT_TAB_BUTTON_HOVER_CSS: str = """
+.tab button:hover {
+ background-color: #ddd;
+}
+
+"""
+DEFAULT_TAB_BUTTON_ACTIVE_CSS: str = """
+.tab button.active {
+ background-color: #ccc;
+}
+
+"""
+
+
class Tab(CompositeMixin):
- def __init__(self, page_title: str = CurrentConfig.PAGE_TITLE, js_host: str = ""):
+ def __init__(
+ self,
+ page_title: str = CurrentConfig.PAGE_TITLE,
+ js_host: str = "",
+ bg_color: str = "",
+ tab_css_opts: TabChartGlobalOpts = TabChartGlobalOpts(),
+ ):
self.js_host: str = js_host or CurrentConfig.ONLINE_HOST
self.page_title: str = page_title
+ self.bg_color = bg_color
self.download_button: bool = False
+ self.use_custom_tab_css = tab_css_opts.opts.get("enable")
+ self.tab_custom_css = self._prepare_tab_css(css_opts=tab_css_opts)
self.js_functions: utils.OrderedSet = utils.OrderedSet()
self.js_dependencies: utils.OrderedSet = utils.OrderedSet()
self._charts: list = []
@@ -25,8 +77,58 @@ def add(self, chart, tab_name):
self.js_dependencies.add(d)
return self
+ def _prepare_tab_css(self, css_opts: TabChartGlobalOpts) -> str:
+ result = ""
+ if isinstance(css_opts, TabChartGlobalOpts):
+ css_opts = css_opts.opts
+ css_opts = utils.remove_key_with_none_value(css_opts)
+
+ def _dict_to_str(opts: dict, key: str, css_selector: str) -> str:
+ _inner_result = ""
+ for k, v in opts.get(key, dict()).items():
+ _inner_result += "{}:{}; ".format(k, v)
+ return (
+ f"{css_selector} " + "{ " + _inner_result + " }\n"
+ if _inner_result != ""
+ else ""
+ )
+
+ # .tab
+ tab_base = _dict_to_str(opts=css_opts, key="base", css_selector=".tab")
+ result += tab_base if tab_base != "" else DEFAULT_TAB_CSS
+ # .tab button
+ tab_button_base = _dict_to_str(
+ opts=css_opts, key="button_base", css_selector=".tab button"
+ )
+ result += tab_button_base if tab_button_base != "" else DEFAULT_TAB_BUTTON_CSS
+ # .tab button:hover
+ tab_button_hover = _dict_to_str(
+ opts=css_opts, key="button_hover", css_selector=".tab button:hover"
+ )
+ result += (
+ tab_button_hover if tab_button_hover != "" else DEFAULT_TAB_BUTTON_HOVER_CSS
+ )
+ # .tab button.active
+ tab_button_active = _dict_to_str(
+ opts=css_opts, key="button_active", css_selector=".tab button.active"
+ )
+ result += (
+ tab_button_active
+ if tab_button_active != ""
+ else DEFAULT_TAB_BUTTON_ACTIVE_CSS
+ )
+ if ".chart-container" not in result:
+ result += """
+ .chart-container { display: block; }
+
+ .chart-container:nth-child(n+2) { display: none; }
+ """
+ return result
+
def _prepare_render(self):
for c in self:
+ if not hasattr(c, "_is_tab_chart"):
+ setattr(c, "_is_tab_chart", True)
if hasattr(c, "dump_options"):
c.json_contents = c.dump_options()
if hasattr(c, "theme"):
diff --git a/pyecharts/charts/composite_charts/timeline.py b/pyecharts/charts/composite_charts/timeline.py
index d83a93572..648c8d4d1 100644
--- a/pyecharts/charts/composite_charts/timeline.py
+++ b/pyecharts/charts/composite_charts/timeline.py
@@ -1,3 +1,5 @@
+from typing import Sequence
+
from ... import options as opts
from ... import types
from ...charts.chart import Base
@@ -8,8 +10,12 @@ class Timeline(Base):
`Timeline` provides functions like switching and playing between multiple charts.
"""
- def __init__(self, init_opts: types.Init = opts.InitOpts()):
- super().__init__(init_opts=init_opts)
+ def __init__(
+ self,
+ init_opts: types.Init = opts.InitOpts(),
+ render_opts: types.RenderInit = opts.RenderOpts(),
+ ):
+ super().__init__(init_opts=init_opts, render_opts=render_opts)
self.options = {"baseOption": {"series": [], "timeline": {}}, "options": []}
self.add_schema()
self._time_points: types.Sequence = []
@@ -17,6 +23,7 @@ def __init__(self, init_opts: types.Init = opts.InitOpts()):
def add_schema(
self,
axis_type: str = "category",
+ current_index: types.Numeric = 0,
orient: str = "horizontal",
symbol: types.Optional[str] = None,
symbol_size: types.Optional[types.Numeric] = None,
@@ -33,16 +40,29 @@ def add_schema(
pos_bottom: types.Optional[str] = "-5px",
width: types.Optional[str] = None,
height: types.Optional[str] = None,
- linestyle_opts: types.Union[opts.LineStyleOpts, dict, None] = None,
- label_opts: types.Optional[opts.LabelOpts] = None,
+ linestyle_opts: types.LineStyle = None,
+ label_opts: types.Label = None,
itemstyle_opts: types.ItemStyle = None,
graphic_opts: types.Graphic = None,
checkpointstyle_opts: types.TimeLinkCheckPoint = None,
controlstyle_opts: types.TimeLineControl = None,
+ progress_linestyle_opts: types.LineStyle = None,
+ progress_itemstyle_opts: types.ItemStyle = None,
+ progress_label_opts: types.Label = None,
+ coordinate_system: types.Optional[str] = None,
+ coordinate_system_usage: types.Optional[str] = None,
+ coord: types.Optional[types.Union[
+ Sequence, types.Numeric, str]
+ ] = None,
+ calendar_index: types.Optional[types.Numeric] = None,
+ calendar_id: types.Optional[types.Numeric] = None,
+ matrix_index: types.Optional[types.Numeric] = None,
+ matrix_id: types.Optional[types.Numeric] = None,
):
self.options.get("baseOption").get("timeline").update(
{
"axisType": axis_type,
+ "currentIndex": current_index,
"orient": orient,
"autoPlay": is_auto_play,
"controlPosition": control_position,
@@ -65,6 +85,18 @@ def add_schema(
"graphic": graphic_opts,
"checkpointStyle": checkpointstyle_opts,
"controlStyle": controlstyle_opts,
+ "progress": {
+ "lineStyle": progress_linestyle_opts,
+ "itemStyle": progress_itemstyle_opts,
+ "label": progress_label_opts,
+ },
+ "coordinateSystem": coordinate_system,
+ "coordinateSystemUsage": coordinate_system_usage,
+ "coord": coord,
+ "calendarIndex": calendar_index,
+ "calendarId": calendar_id,
+ "matrixIndex": matrix_index,
+ "matrixId": matrix_id,
}
)
return self
@@ -88,6 +120,14 @@ def add(self, chart: Base, time_point: str):
"color": chart.options.get("color"),
"graphic": chart.options.get("graphic"),
"bmap": chart.options.get("bmap"),
+ "toolbox": chart.options.get("toolbox"),
+ "dataset": chart.options.get("dataset"),
+ "radiusAxis": chart.options.get("radiusAxis"),
+ "angleAxis": chart.options.get("angleAxis"),
+ "xAxis3D": chart.options.get("xAxis3D"),
+ "yAxis3D": chart.options.get("yAxis3D"),
+ "zAxis3D": chart.options.get("zAxis3D"),
+ "grid3D": chart.options.get("grid3D"),
}
)
self.__check_components(chart)
@@ -107,6 +147,7 @@ def __check_components(self, chart: Base):
"visualMap",
"dataZoom",
"parallelAxis",
+ "legend",
]
for component in components:
diff --git a/pyecharts/charts/mixins.py b/pyecharts/charts/mixins.py
index 10bf45129..a45b59d89 100644
--- a/pyecharts/charts/mixins.py
+++ b/pyecharts/charts/mixins.py
@@ -7,6 +7,11 @@ def add_js_funcs(self, *fns):
self.js_functions.add(fn)
return self
+ def add_js_events(self, *fns):
+ for fn in fns:
+ self.js_events.add(fn)
+ return self
+
def load_javascript(self):
return engine.load_javascript(self)
diff --git a/pyecharts/charts/three_axis_charts/bar3D.py b/pyecharts/charts/three_axis_charts/bar3D.py
index 0c020dd11..8958a8a98 100644
--- a/pyecharts/charts/three_axis_charts/bar3D.py
+++ b/pyecharts/charts/three_axis_charts/bar3D.py
@@ -1,6 +1,7 @@
from ... import types
from ...charts.chart import ThreeAxisChart
-from ...options import InitOpts
+from ...globals import ChartType
+from ...options import InitOpts, RenderOpts
class Bar3D(ThreeAxisChart):
@@ -8,6 +9,10 @@ class Bar3D(ThreeAxisChart):
<<< 3D Bar-Chart >>>
"""
- def __init__(self, init_opts: types.Init = InitOpts()):
- super().__init__(init_opts)
- self._3d_chart_type = "bar3D"
+ def __init__(
+ self,
+ init_opts: types.Init = InitOpts(),
+ render_opts: types.RenderInit = RenderOpts(),
+ ):
+ super().__init__(init_opts, render_opts)
+ self._3d_chart_type = ChartType.BAR3D
diff --git a/pyecharts/charts/three_axis_charts/graph_gl.py b/pyecharts/charts/three_axis_charts/graph_gl.py
new file mode 100644
index 000000000..f2a88293a
--- /dev/null
+++ b/pyecharts/charts/three_axis_charts/graph_gl.py
@@ -0,0 +1,51 @@
+from ... import options as opts
+from ... import types
+from ...charts.chart import Chart3D
+from ...globals import ChartType
+from ...options import InitOpts, RenderOpts
+
+
+class GraphGL(Chart3D):
+ """
+ <<< GraphGL Relational graphs using WebGL to support the layout and
+ drawing of large-scale network/relational data. >>>
+ """
+
+ def __init__(
+ self,
+ init_opts: types.Init = InitOpts(),
+ render_opts: types.RenderInit = RenderOpts(),
+ ):
+ super().__init__(init_opts, render_opts)
+ self._3d_chart_type = ChartType.GRAPHGL
+
+ def add(
+ self,
+ series_name: str,
+ nodes: types.Sequence[types.GraphGLNode],
+ links: types.Sequence[types.GraphGLLink],
+ *,
+ layout: str = "forceAtlas2",
+ force_atlas2_opts: types.GraphGLForceAtlas2 = None,
+ symbol: types.Optional[str] = "circle",
+ symbol_size: types.Numeric = 5,
+ itemstyle_opts: types.ItemStyle = None,
+ linestyle_opts: types.LineStyle = opts.LineStyleOpts(),
+ z_level: types.Numeric = 10,
+ ):
+ self.options.get("series").append(
+ {
+ "type": ChartType.GRAPHGL,
+ "name": series_name,
+ "layout": layout,
+ "forceAtlas2": force_atlas2_opts,
+ "nodes": nodes,
+ "links": links,
+ "symbol": symbol,
+ "symbolSize": symbol_size,
+ "itemStyle": itemstyle_opts,
+ "lineStyle": linestyle_opts,
+ "zlevel": z_level,
+ }
+ )
+ return self
diff --git a/pyecharts/charts/three_axis_charts/line3D.py b/pyecharts/charts/three_axis_charts/line3D.py
index d96fd991e..67d2230b9 100644
--- a/pyecharts/charts/three_axis_charts/line3D.py
+++ b/pyecharts/charts/three_axis_charts/line3D.py
@@ -1,6 +1,7 @@
from ... import types
from ...charts.chart import ThreeAxisChart
-from ...options import InitOpts
+from ...globals import ChartType
+from ...options import InitOpts, RenderOpts
class Line3D(ThreeAxisChart):
@@ -8,6 +9,10 @@ class Line3D(ThreeAxisChart):
<<< 3D Line-Chart >>>
"""
- def __init__(self, init_opts: types.Init = InitOpts()):
- super().__init__(init_opts)
- self._3d_chart_type = "line3D"
+ def __init__(
+ self,
+ init_opts: types.Init = InitOpts(),
+ render_opts: types.RenderInit = RenderOpts(),
+ ):
+ super().__init__(init_opts, render_opts)
+ self._3d_chart_type = ChartType.LINE3D
diff --git a/pyecharts/charts/three_axis_charts/lines3D.py b/pyecharts/charts/three_axis_charts/lines3D.py
new file mode 100644
index 000000000..e0948b456
--- /dev/null
+++ b/pyecharts/charts/three_axis_charts/lines3D.py
@@ -0,0 +1,66 @@
+from ... import options as opts
+from ... import types
+from ...charts.chart import Chart3D
+from ...globals import ChartType
+from ...options import InitOpts, RenderOpts
+
+
+class Lines3D(Chart3D):
+ """
+ Lines 3D
+ """
+
+ def __init__(
+ self,
+ init_opts: types.Init = InitOpts(),
+ render_opts: types.RenderInit = RenderOpts(),
+ ):
+ super().__init__(init_opts, render_opts)
+ self._3d_chart_type = ChartType.LINES3D
+
+ def add(
+ self,
+ series_name: str,
+ data_pair: types.Sequence,
+ coordinate_system: str,
+ *,
+ geo_3d_index: types.Numeric = 0,
+ globe_index: types.Numeric = 0,
+ is_polyline: bool = False,
+ is_show_lines_effect: bool = False,
+ lines_effect_period: types.Numeric = 4,
+ lines_effect_constant_speed: types.Optional[types.Numeric] = None,
+ lines_effect_trail_width: types.Numeric = 4,
+ lines_effect_trail_length: types.Numeric = 0.1,
+ lines_effect_trail_color: types.Optional[str] = None,
+ lines_effect_trail_opacity: types.Optional[types.Numeric] = None,
+ blend_mode: str = "source-over",
+ linestyle_opts: types.Optional[types.LineStyle] = None,
+ z_level: types.Numeric = -10,
+ is_silent: bool = False,
+ ):
+ self.options.get("series").append(
+ {
+ "type": ChartType.LINES3D,
+ "name": series_name,
+ "data": data_pair,
+ "coordinateSystem": coordinate_system,
+ "geo3DIndex": geo_3d_index,
+ "globeIndex": globe_index,
+ "polyline": is_polyline,
+ "effect": {
+ "show": is_show_lines_effect,
+ "period": lines_effect_period,
+ "constantSpeed": lines_effect_constant_speed,
+ "trailWidth": lines_effect_trail_width,
+ "trailLength": lines_effect_trail_length,
+ "trailColor": lines_effect_trail_color,
+ "trailOpacity": lines_effect_trail_opacity,
+ },
+ "lineStyle": linestyle_opts,
+ "blendMode": blend_mode,
+ "zlevel": z_level,
+ "silent": is_silent,
+ }
+ )
+ return self
diff --git a/pyecharts/charts/three_axis_charts/map3D.py b/pyecharts/charts/three_axis_charts/map3D.py
index 01617697c..4a6086295 100644
--- a/pyecharts/charts/three_axis_charts/map3D.py
+++ b/pyecharts/charts/three_axis_charts/map3D.py
@@ -2,7 +2,7 @@
from ... import types
from ...charts.chart import Chart3D
from ...globals import ChartType
-from ...options import InitOpts
+from ...options import InitOpts, RenderOpts
class Map3D(Chart3D):
@@ -10,9 +10,13 @@ class Map3D(Chart3D):
3D map
"""
- def __init__(self, init_opts: types.Init = InitOpts()):
- super().__init__(init_opts)
- self._3d_chart_type = "map3D"
+ def __init__(
+ self,
+ init_opts: types.Init = InitOpts(),
+ render_opts: types.RenderInit = RenderOpts(),
+ ):
+ super().__init__(init_opts, render_opts)
+ self._3d_chart_type = ChartType.MAP3D
def add(
self,
@@ -21,7 +25,6 @@ def add(
*,
type_: ChartType = None,
maptype: str = "china",
- is_selected: bool = True,
is_map_symbol_show: bool = True,
grid_3d_index: types.Numeric = 0,
geo_3d_index: types.Numeric = 0,
@@ -56,7 +59,7 @@ def add(
data = [{"name": n, "value": v} for n, v in data_pair]
else:
data = data_pair
- self._append_legend(series_name, is_selected)
+ self._append_legend(series_name)
if type_ is None or type_ == ChartType.MAP3D:
self.options.get("series").append(
{
diff --git a/pyecharts/charts/three_axis_charts/map_globe.py b/pyecharts/charts/three_axis_charts/map_globe.py
index 6f72ad756..868be02bf 100644
--- a/pyecharts/charts/three_axis_charts/map_globe.py
+++ b/pyecharts/charts/three_axis_charts/map_globe.py
@@ -7,7 +7,7 @@
from ...charts.chart import Chart3D
from ...commons import utils
from ...globals import CurrentConfig, NotebookType
-from ...options import InitOpts
+from ...options import InitOpts, RenderOpts
from ...render.display import HTML
from ...render.engine import RenderEngine
@@ -17,8 +17,12 @@ class MapGlobe(Chart3D, MapMixin):
Globe Map
"""
- def __init__(self, init_opts: types.Init = InitOpts()):
- super().__init__(init_opts)
+ def __init__(
+ self,
+ init_opts: types.Init = InitOpts(),
+ render_opts: types.RenderInit = RenderOpts(),
+ ):
+ super().__init__(init_opts, render_opts)
def add_schema(self, maptype: str = "china"):
self.js_dependencies.add(maptype)
diff --git a/pyecharts/charts/three_axis_charts/scatter3D.py b/pyecharts/charts/three_axis_charts/scatter3D.py
index 763b781dd..0b43dd380 100644
--- a/pyecharts/charts/three_axis_charts/scatter3D.py
+++ b/pyecharts/charts/three_axis_charts/scatter3D.py
@@ -1,6 +1,7 @@
from ... import types
from ...charts.chart import ThreeAxisChart
-from ...options import InitOpts
+from ...globals import ChartType
+from ...options import InitOpts, RenderOpts
class Scatter3D(ThreeAxisChart):
@@ -8,6 +9,10 @@ class Scatter3D(ThreeAxisChart):
<<< 3D Scatter-Chart >>>
"""
- def __init__(self, init_opts: types.Init = InitOpts()):
- super().__init__(init_opts)
- self._3d_chart_type = "scatter3D"
+ def __init__(
+ self,
+ init_opts: types.Init = InitOpts(),
+ render_opts: types.RenderInit = RenderOpts(),
+ ):
+ super().__init__(init_opts, render_opts)
+ self._3d_chart_type = ChartType.SCATTER3D
diff --git a/pyecharts/charts/three_axis_charts/surface3D.py b/pyecharts/charts/three_axis_charts/surface3D.py
index 5659d7ce0..9727d89b3 100644
--- a/pyecharts/charts/three_axis_charts/surface3D.py
+++ b/pyecharts/charts/three_axis_charts/surface3D.py
@@ -1,6 +1,8 @@
+from ... import options as opts
from ... import types
from ...charts.chart import ThreeAxisChart
-from ...options import InitOpts
+from ...globals import ChartType
+from ...options import InitOpts, RenderOpts
class Surface3D(ThreeAxisChart):
@@ -8,6 +10,10 @@ class Surface3D(ThreeAxisChart):
<<< 3D Surface-Chart >>>
"""
- def __init__(self, init_opts: types.Init = InitOpts()):
- super().__init__(init_opts)
- self._3d_chart_type = "surface"
+ def __init__(
+ self,
+ init_opts: types.Init = InitOpts(),
+ render_opts: types.RenderInit = RenderOpts(),
+ ):
+ super().__init__(init_opts, render_opts)
+ self._3d_chart_type = ChartType.SURFACE
diff --git a/pyecharts/commons/utils.py b/pyecharts/commons/utils.py
index 2da93772c..fa4e4951e 100644
--- a/pyecharts/commons/utils.py
+++ b/pyecharts/commons/utils.py
@@ -32,6 +32,9 @@ def produce_require_dict(js_dependencies, js_host) -> dict:
if name.startswith("https://api.map.baidu.com"):
confs.append("'baidu_map_api{}':'{}'".format(len(name), name))
libraries.append("'baidu_map_api{}'".format(len(name)))
+ if name.startswith("https://webapi.amap.com"):
+ confs.append("'amap_map_api{}':'{}'".format(len(name), name))
+ libraries.append("'amap_map_api{}'".format(len(name)))
if name in FILENAMES:
f, _ = FILENAMES[name]
confs.append("'{}':'{}{}'".format(name, js_host, f))
@@ -54,14 +57,14 @@ def replace_placeholder_with_quotes(html: str) -> str:
return re.sub("--x_x--0_0--", "", html)
-def _flat(obj):
- if hasattr(obj, "js_dependencies"):
- return list(obj.js_dependencies)
-
- if isinstance(obj, (list, tuple, set)):
- return obj
-
- return (obj,) # tuple
+# def _flat(obj):
+# if hasattr(obj, "js_dependencies"):
+# return list(obj.js_dependencies)
+#
+# if isinstance(obj, (list, tuple, set)):
+# return obj
+#
+# return (obj,) # tuple
def _expand(dict_generator):
@@ -77,6 +80,13 @@ def _clean_dict(mydict):
elif isinstance(value, (list, tuple, set)):
value = list(_clean_array(value))
+ # Not elegant, but effective and less code-intrusive.
+ elif type(value).__name__ in ["ndarray", "Series"]:
+ raise ValueError(
+ "Can't use non-native data structures "
+ "as axis data to render chart"
+ )
+
elif isinstance(value, str) and not value:
# delete key with empty string
continue
diff --git a/pyecharts/components/table.py b/pyecharts/components/table.py
index 3b8141b26..fe85f5cc8 100644
--- a/pyecharts/components/table.py
+++ b/pyecharts/components/table.py
@@ -22,9 +22,15 @@ def __init__(self, page_title: str = CurrentConfig.PAGE_TITLE, js_host: str = ""
self._component_type: str = "table"
self.chart_id: str = uuid.uuid4().hex
- def add(self, headers: Sequence, rows: Sequence, attributes: Optional[dict] = None):
+ def add(
+ self,
+ headers: Sequence,
+ rows: Sequence,
+ attributes: Optional[dict] = None,
+ **kwargs,
+ ):
attributes = attributes or {"class": "fl-table"}
- table = PrettyTable(headers, attributes=attributes)
+ table = PrettyTable(headers, attributes=attributes, **kwargs)
for r in rows:
table.add_row(r)
self.html_content = table.get_html_string()
diff --git a/pyecharts/datasets/__init__.py b/pyecharts/datasets/__init__.py
index 630291ca6..c76dffe99 100644
--- a/pyecharts/datasets/__init__.py
+++ b/pyecharts/datasets/__init__.py
@@ -72,10 +72,7 @@ def _search(self, lookfor: typing.Any, stop_on_first: bool = False):
return best_ratio >= self.cutoff, best_key, best_match, best_ratio
def __contains__(self, item: typing.Any):
- if self._search(item, True)[0]:
- return True
- else:
- return False
+ return self._search(item, True)[0]
def __getitem__(self, lookfor: typing.Any):
matched, key, item, ratio = self._search(lookfor)
diff --git a/pyecharts/datasets/map_filename.json b/pyecharts/datasets/map_filename.json
index e6b23443e..37b63015f 100644
--- a/pyecharts/datasets/map_filename.json
+++ b/pyecharts/datasets/map_filename.json
@@ -1,4 +1,9 @@
{
+ "amap": ["echarts-extension-amap.min", "js"],
+ "lmap": ["echarts-extension-leaflet.min", "js"],
+ "lmap-src": ["leaflet/leaflet", "js"],
+ "lmap-css": ["leaflet/leaflet", "css"],
+ "gmap": ["echarts-extension-gmap.min", "js"],
"bulma": ["bulma.min", "css"],
"jquery": ["jquery.min", "js"],
"jquery-ui": ["jquery-ui.min", "js"],
@@ -7,6 +12,14 @@
"echarts-gl": ["echarts-gl.min", "js"],
"echarts-liquidfill": ["echarts-liquidfill.min", "js"],
"echarts-wordcloud": ["echarts-wordcloud.min", "js"],
+ "echarts-stat": ["ecStat.min", "js"],
+ "echarts-x-violin": ["echarts-x/violin/index.auto.min", "js"],
+ "echarts-x-stage": ["echarts-x/stage/index.auto.min", "js"],
+ "echarts-x-contour-d3": ["echarts-x/contour/d3.min", "js"],
+ "echarts-x-contour": ["echarts-x/contour/index.auto.min", "js"],
+ "echarts-x-segmented-doughnut": ["echarts-x/segmented-doughnut/index.auto.min", "js"],
+ "echarts-x-line-range": ["echarts-x/line-range/index.auto.min", "js"],
+ "echarts-x-bar-range": ["echarts-x/bar-range/index.auto.min", "js"],
"bmap": ["bmap.min", "js"],
"chalk": ["themes/chalk", "js"],
"essos": ["themes/essos", "js"],
diff --git a/pyecharts/faker.py b/pyecharts/faker.py
index cf551eb5f..cc0e8cbc9 100644
--- a/pyecharts/faker.py
+++ b/pyecharts/faker.py
@@ -30,7 +30,7 @@ class _Faker:
"#a50026",
]
months = ["{}月".format(i) for i in range(1, 13)]
- provinces = ["广东", "北京", "上海", "江西", "湖南", "浙江", "江苏"]
+ provinces = ["广东省", "北京市", "上海市", "江西省", "湖南省", "浙江省", "江苏省"]
guangdong_city = ["汕头市", "汕尾市", "揭阳市", "阳江市", "肇庆市", "广州市", "惠州市"]
country = [
"China",
@@ -100,241 +100,3 @@ class Collector:
@staticmethod
def funcs(fn):
Collector.charts.append((fn, fn.__name__))
-
-
-POPULATION = [
- ["Country (or dependency)", "Population\n(2019)"],
- ["China", 1420062022],
- ["India", 1368737513],
- ["United States", 329093110],
- ["Indonesia", 269536482],
- ["Brazil", 212392717],
- ["Pakistan", 204596442],
- ["Nigeria", 200962417],
- ["Bangladesh", 168065920],
- ["Russia", 143895551],
- ["Mexico", 132328035],
- ["Japan", 126854745],
- ["Ethiopia", 110135635],
- ["Philippines", 108106310],
- ["Egypt", 101168745],
- ["Vietnam", 97429061],
- ["DR Congo", 86727573],
- ["Turkey", 82961805],
- ["Iran", 82820766],
- ["Germany", 82438639],
- ["Thailand", 69306160],
- ["United Kingdom", 66959016],
- ["France", 65480710],
- ["Tanzania", 60913557],
- ["Italy", 59216525],
- ["South Africa", 58065097],
- ["Myanmar", 54336138],
- ["Kenya", 52214791],
- ["South Korea", 51339238],
- ["Colombia", 49849818],
- ["Spain", 46441049],
- ["Uganda", 45711874],
- ["Argentina", 45101781],
- ["Ukraine", 43795220],
- ["Algeria", 42679018],
- ["Sudan", 42514094],
- ["Iraq", 40412299],
- ["Poland", 38028278],
- ["Canada", 37279811],
- ["Afghanistan", 37209007],
- ["Morocco", 36635156],
- ["Saudi Arabia", 34140662],
- ["Peru", 32933835],
- ["Uzbekistan", 32807368],
- ["Venezuela", 32779868],
- ["Malaysia", 32454455],
- ["Angola", 31787566],
- ["Mozambique", 31408823],
- ["Ghana", 30096970],
- ["Nepal", 29942018],
- ["Yemen", 29579986],
- ["Madagascar", 26969642],
- ["North Korea", 25727408],
- ["Côte d'Ivoire", 25531083],
- ["Cameroon", 25312993],
- ["Australia", 25088636],
- ["Taiwan", 23758247],
- ["Niger", 23176691],
- ["Sri Lanka", 21018859],
- ["Burkina Faso", 20321560],
- ["Malawi", 19718743],
- ["Mali", 19689140],
- ["Romania", 19483360],
- ["Kazakhstan", 18592970],
- ["Syria", 18499181],
- ["Chile", 18336653],
- ["Zambia", 18137369],
- ["Guatemala", 17577842],
- ["Zimbabwe", 17297495],
- ["Netherlands", 17132908],
- ["Ecuador", 17100444],
- ["Senegal", 16743859],
- ["Cambodia", 16482646],
- ["Chad", 15814345],
- ["Somalia", 15636171],
- ["Guinea", 13398180],
- ["South Sudan", 13263184],
- ["Rwanda", 12794412],
- ["Benin", 11801595],
- ["Tunisia", 11783168],
- ["Burundi", 11575964],
- ["Belgium", 11562784],
- ["Cuba", 11492046],
- ["Bolivia", 11379861],
- ["Haiti", 11242856],
- ["Greece", 11124603],
- ["Dominican Republic", 10996774],
- ["Czechia", 10630589],
- ["Portugal", 10254666],
- ["Jordan", 10069794],
- ["Sweden", 10053135],
- ["Azerbaijan", 10014575],
- ["United Arab Emirates", 9682088],
- ["Hungary", 9655361],
- ["Honduras", 9568688],
- ["Belarus", 9433874],
- ["Tajikistan", 9292000],
- ["Austria", 8766201],
- ["Serbia", 8733407],
- ["Switzerland", 8608259],
- ["Papua New Guinea", 8586525],
- ["Israel", 8583916],
- ["Togo", 8186384],
- ["Sierra Leone", 7883123],
- ["Hong Kong", 7490776],
- ["Laos", 7064242],
- ["Bulgaria", 6988739],
- ["Paraguay", 6981981],
- ["Libya", 6569864],
- ["El Salvador", 6445405],
- ["Nicaragua", 6351157],
- ["Kyrgyzstan", 6218616],
- ["Lebanon", 6065922],
- ["Turkmenistan", 5942561],
- ["Singapore", 5868104],
- ["Denmark", 5775224],
- ["Finland", 5561389],
- ["Congo", 5542197],
- ["Slovakia", 5450987],
- ["Norway", 5400916],
- ["Eritrea", 5309659],
- ["State of Palestine", 5186790],
- ["Oman", 5001875],
- ["Costa Rica", 4999384],
- ["Liberia", 4977720],
- ["Ireland", 4847139],
- ["Central African Republic", 4825711],
- ["New Zealand", 4792409],
- ["Mauritania", 4661149],
- ["Kuwait", 4248974],
- ["Panama", 4226197],
- ["Croatia", 4140148],
- ["Moldova", 4029750],
- ["Georgia", 3904204],
- ["Puerto Rico", 3654978],
- ["Bosnia and Herzegovina", 3501774],
- ["Uruguay", 3482156],
- ["Mongolia", 3166244],
- ["Albania", 2938428],
- ["Armenia", 2936706],
- ["Jamaica", 2906339],
- ["Lithuania", 2864459],
- ["Qatar", 2743901],
- ["Namibia", 2641996],
- ["Botswana", 2374636],
- ["Lesotho", 2292682],
- ["Gambia", 2228075],
- ["Gabon", 2109099],
- ["North Macedonia", 2086720],
- ["Slovenia", 2081900],
- ["Guinea-Bissau", 1953723],
- ["Latvia", 1911108],
- ["Bahrain", 1637896],
- ["Swaziland", 1415414],
- ["Trinidad and Tobago", 1375443],
- ["Equatorial Guinea", 1360104],
- ["Timor-Leste", 1352360],
- ["Estonia", 1303798],
- ["Mauritius", 1271368],
- ["Cyprus", 1198427],
- ["Djibouti", 985690],
- ["Fiji", 918757],
- ["Réunion", 889918],
- ["Comoros", 850910],
- ["Bhutan", 826229],
- ["Guyana", 786508],
- ["Macao", 642090],
- ["Solomon Islands", 635254],
- ["Montenegro", 629355],
- ["Luxembourg", 596992],
- ["Western Sahara", 582478],
- ["Suriname", 573085],
- ["Cabo Verde", 560349],
- ["Micronesia", 536579],
- ["Maldives", 451738],
- ["Guadeloupe", 448798],
- ["Brunei", 439336],
- ["Malta", 433245],
- ["Bahamas", 403095],
- ["Belize", 390231],
- ["Martinique", 385320],
- ["Iceland", 340566],
- ["French Guiana", 296847],
- ["French Polynesia", 288506],
- ["Vanuatu", 288017],
- ["Barbados", 287010],
- ["New Caledonia", 283376],
- ["Mayotte", 266380],
- ["Sao Tome & Principe", 213379],
- ["Samoa", 198909],
- ["Saint Lucia", 180454],
- ["Guam", 167245],
- ["Channel Islands", 166828],
- ["Curaçao", 162547],
- ["Kiribati", 120428],
- ["St. Vincent & Grenadines", 110488],
- ["Tonga", 110041],
- ["Grenada", 108825],
- ["Aruba", 106053],
- ["U.S. Virgin Islands", 104909],
- ["Antigua and Barbuda", 104084],
- ["Seychelles", 95702],
- ["Isle of Man", 85369],
- ["Andorra", 77072],
- ["Dominica", 74679],
- ["Cayman Islands", 63129],
- ["Bermuda", 60833],
- ["Greenland", 56673],
- ["Saint Kitts & Nevis", 56345],
- ["American Samoa", 55727],
- ["Northern Mariana Islands", 55246],
- ["Marshall Islands", 53211],
- ["Faeroe Islands", 49692],
- ["Sint Maarten", 40939],
- ["Monaco", 39102],
- ["Liechtenstein", 38404],
- ["Turks and Caicos", 36461],
- ["Gibraltar", 34879],
- ["San Marino", 33683],
- ["British Virgin Islands", 32206],
- ["Caribbean Netherlands", 25971],
- ["Palau", 22206],
- ["Cook Islands", 17462],
- ["Anguilla", 15174],
- ["Wallis & Futuna", 11617],
- ["Tuvalu", 11393],
- ["Nauru", 11260],
- ["Saint Pierre & Miquelon", 6375],
- ["Montserrat", 5220],
- ["Saint Helena", 4096],
- ["Falkland Islands", 2921],
- ["Niue", 1628],
- ["Tokelau", 1340],
- ["Holy See", 799],
-]
diff --git a/pyecharts/globals.py b/pyecharts/globals.py
index 2179e0556..1d2d18e69 100644
--- a/pyecharts/globals.py
+++ b/pyecharts/globals.py
@@ -10,6 +10,11 @@ class _RenderType:
SVG: str = "svg"
+class _Locale:
+ EN: str = "EN"
+ ZH: str = "ZH"
+
+
class _FileType:
SVG: str = "svg"
PNG: str = "png"
@@ -29,16 +34,20 @@ class _ChartType:
BAR: str = "bar"
BAR3D: str = "bar3D"
BOXPLOT: str = "boxplot"
+ CHORD: str = "chord"
EFFECT_SCATTER: str = "effectScatter"
FUNNEL: str = "funnel"
+ FLOWGL: str = "flowGL"
GAUGE: str = "gauge"
GEO: str = "geo"
GRAPH: str = "graph"
+ GRAPHGL: str = "graphGL"
HEATMAP: str = "heatmap"
KLINE: str = "candlestick"
LINE: str = "line"
LINE3D: str = "line3D"
LINES: str = "lines"
+ LINESGL: str = "linesGL"
LINES3D: str = "lines3D"
LIQUID: str = "liquidFill"
MAP: str = "map"
@@ -51,12 +60,21 @@ class _ChartType:
SANKEY: str = "sankey"
SCATTER: str = "scatter"
SCATTER3D: str = "scatter3D"
+ SCATTERGL: str = "scatterGL"
SUNBURST: str = "sunburst"
+ SURFACE: str = "surface"
THEMERIVER: str = "themeRiver"
TREE: str = "tree"
TREEMAP: str = "treemap"
WORDCLOUD: str = "wordCloud"
CUSTOM: str = "custom"
+ # below chart types are Echarts 6 new custom chart
+ VIOLIN: str = "violin"
+ STAGE: str = "stage"
+ DOUGHNUT: str = "segmentedDoughnut"
+ CONTOUR: str = "contour"
+ BAR_RANGE: str = "barRange"
+ LINE_RANGE: str = "lineRange"
ToolTipFormatterType = {
@@ -123,15 +141,16 @@ class _NotebookType:
class _OnlineHost:
- DEFAULT_HOST = "https://assets.pyecharts.org/assets/"
+ DEFAULT_HOST = "https://assets.pyecharts.org/assets/v6/"
NOTEBOOK_HOST = "http://localhost:8888/nbextensions/assets/"
-class _WarningControl:
- ShowWarning = True
+class _RenderSepType:
+ SepType = os.linesep
RenderType = _RenderType()
+Locale = _Locale()
FileType = _FileType()
SymbolType = _SymbolType()
ChartType = _ChartType
@@ -140,13 +159,15 @@ class _WarningControl:
BMapType = _BMapType
NotebookType = _NotebookType()
OnlineHostType = _OnlineHost()
-WarningType = _WarningControl()
+RenderSepType = _RenderSepType()
+DefaultLocale = Locale.ZH
class _CurrentConfig:
PAGE_TITLE = "Awesome-pyecharts"
ONLINE_HOST = OnlineHostType.DEFAULT_HOST
NOTEBOOK_TYPE = NotebookType.JUPYTER_NOTEBOOK
+ LOCALE = DefaultLocale
GLOBAL_ENV = Environment(
keep_trailing_newline=True,
trim_blocks=True,
diff --git a/pyecharts/options/__init__.py b/pyecharts/options/__init__.py
index dd58ccf67..704104fcf 100644
--- a/pyecharts/options/__init__.py
+++ b/pyecharts/options/__init__.py
@@ -11,12 +11,24 @@
BMapTypeControlOpts,
BoxplotItem,
CandleStickItem,
+ ChordData,
+ ChordLink,
ComponentTitleOpts,
+ CustomBarRangeItemPayloadOpts,
+ CustomContourItemPayloadOpts,
+ CustomLineRangeItemPayloadOpts,
+ CustomSegmentedDoughnutItemPayloadOpts,
+ CustomStageItemPayloadOpts,
+ CustomViolinItemPayloadOpts,
EffectScatterItem,
FunnelItem,
GaugeDetailOpts,
GaugePointerOpts,
+ GaugeAnchorOpts,
+ GaugeProgressOpts,
GaugeTitleOpts,
+ GeoItem,
+ GeoRegionsOpts,
GraphCategory,
GraphicBasicStyleOpts,
GraphicGroup,
@@ -29,6 +41,8 @@
GraphicTextStyleOpts,
GraphLink,
GraphNode,
+ GraphGLLink,
+ GraphGLNode,
LineItem,
MapItem,
Map3DColorMaterialOpts,
@@ -39,12 +53,18 @@
Map3DRealisticMaterialOpts,
Map3DViewControlOpts,
PageLayoutOpts,
+ ParallelItem,
PieItem,
PieLabelLineOpts,
+ PieEmptyCircleStyle,
RadarItem,
SankeyLevelsOpts,
ScatterItem,
SunburstItem,
+ SunburstLabelLayoutOpts,
+ SunburstLabelLineOpts,
+ SunburstLevelOpts,
+ TabChartGlobalOpts,
ThemeRiverItem,
TimelineCheckPointerStyle,
TimelineControlStyle,
@@ -56,28 +76,50 @@
AngleAxisItem,
AngleAxisOpts,
AnimationOpts,
+ AriaDecalOpts,
+ AriaLabelOpts,
+ AriaOpts,
Axis3DOpts,
+ AxisBreakOpts,
+ AxisBreakAreaOpts,
+ AxisBreakLabelLayoutOpts,
AxisLineOpts,
AxisOpts,
AxisPointerOpts,
AxisTickOpts,
+ BlurOpts,
BrushOpts,
CalendarOpts,
CalendarDayLabelOpts,
CalendarMonthLabelOpts,
CalendarYearLabelOpts,
DataZoomOpts,
+ DatasetTransformOpts,
+ EmphasisOpts,
+ Emphasis3DOpts,
Grid3DOpts,
GridOpts,
+ GridOuterOpts,
InitOpts,
+ RenderOpts,
LegendOpts,
+ MatrixAxisOpts,
+ MatrixAxisDataOpts,
+ MatrixBackgroundStyleOpts,
+ MatrixBodyDataOpts,
+ MatrixBodyOrCornerOpts,
+ MatrixDividerLineStyleOpts,
+ MatrixOpts,
ParallelAxisOpts,
ParallelOpts,
PolarOpts,
RadarIndicatorItem,
RadiusAxisItem,
RadiusAxisOpts,
+ SelectOpts,
SingleAxisOpts,
+ ThumbnailOpts,
+ ThumbnailWindowStyleOpts,
TitleOpts,
ToolBoxFeatureBrushOpts,
ToolBoxFeatureDataViewOpts,
@@ -88,11 +130,13 @@
ToolBoxFeatureSaveAsImageOpts,
ToolboxOpts,
TooltipOpts,
+ TreeLeavesOpts,
VisualMapOpts,
)
from .series_options import (
AreaStyleOpts,
EffectOpts,
+ GraphGLForceAtlas2Opts,
ItemStyleOpts,
LabelOpts,
LineStyleOpts,
diff --git a/pyecharts/options/charts_options.py b/pyecharts/options/charts_options.py
index cae6d369a..17099cf78 100644
--- a/pyecharts/options/charts_options.py
+++ b/pyecharts/options/charts_options.py
@@ -17,450 +17,239 @@
)
-# Data Item
-class BarItem(BasicOpts):
+# Chart Options
+class ChordData(BasicOpts):
def __init__(
self,
- name: Union[int, str],
- value: Numeric,
- *,
- label_opts: Union[LabelOpts, dict, None] = None,
- itemstyle_opts: Union[ItemStyleOpts, dict, None] = None,
- tooltip_opts: Union[TooltipOpts, dict, None] = None,
+ name: Optional[str] = None,
):
self.opts: dict = {
"name": name,
- "value": value,
- "label": label_opts,
- "itemStyle": itemstyle_opts,
- "tooltip": tooltip_opts,
}
-class BoxplotItem(BasicOpts):
+class ChordLink(BasicOpts):
def __init__(
self,
- name: Union[int, str],
- value: Sequence,
- *,
- itemstyle_opts: Union[ItemStyleOpts, dict, None] = None,
- tooltip_opts: Union[TooltipOpts, dict, None] = None,
+ source: Union[str, int, None] = None,
+ target: Union[str, int, None] = None,
+ value: Optional[Numeric] = None,
):
self.opts: dict = {
- "name": name,
+ "source": source,
+ "target": target,
"value": value,
- "itemStyle": itemstyle_opts,
- "tooltip": tooltip_opts,
}
-class CandleStickItem(BasicOpts):
+class GraphNode(BasicOpts):
def __init__(
self,
- name: Union[str, int],
- value: Sequence,
- *,
+ name: Optional[str] = None,
+ x: Optional[Numeric] = None,
+ y: Optional[Numeric] = None,
+ is_fixed: bool = False,
+ value: Union[str, Sequence, None] = None,
+ category: Optional[int] = None,
+ symbol: Optional[str] = None,
+ symbol_size: Union[Numeric, Sequence, None] = None,
+ symbol_rotate: Optional[int] = None,
itemstyle_opts: Union[ItemStyleOpts, dict, None] = None,
+ label_opts: Union[LabelOpts, dict, None] = None,
+ is_disabled_emphasis: Optional[bool] = None,
+ emphasis_itemstyle_opts: Union[ItemStyleOpts, dict, None] = None,
+ emphasis_label_opts: Union[LabelOpts, dict, None] = None,
+ blur_itemstyle_opts: Union[ItemStyleOpts, dict, None] = None,
+ blur_label_opts: Union[LabelOpts, dict, None] = None,
+ is_disabled_select: Optional[bool] = None,
+ select_itemstyle_opts: Union[ItemStyleOpts, dict, None] = None,
+ select_label_opts: Union[LabelOpts, dict, None] = None,
tooltip_opts: Union[TooltipOpts, dict, None] = None,
):
self.opts: dict = {
"name": name,
+ "x": x,
+ "y": y,
+ "fixed": is_fixed,
"value": value,
+ "category": category,
+ "symbol": symbol,
+ "symbolSize": symbol_size,
+ "symbolRotate": symbol_rotate,
"itemStyle": itemstyle_opts,
+ "label": label_opts,
+ "emphasis": {
+ "disabled": is_disabled_emphasis,
+ "itemStyle": emphasis_itemstyle_opts,
+ "label": emphasis_label_opts,
+ },
+ "blur": {
+ "itemStyle": blur_itemstyle_opts,
+ "label": blur_label_opts,
+ },
+ "select": {
+ "disabled": is_disabled_select,
+ "itemStyle": select_itemstyle_opts,
+ "label": select_label_opts,
+ },
"tooltip": tooltip_opts,
}
-class EffectScatterItem(BasicOpts):
+class GraphLink(BasicOpts):
def __init__(
self,
- name: Union[str, Numeric],
- value: Union[str, Numeric],
- *,
- symbol: Optional[str] = None,
- symbol_size: Union[Sequence[Numeric], Numeric] = None,
- symbol_rotate: Optional[Numeric] = None,
- symbol_keep_aspect: bool = False,
- symbol_offset: Optional[Sequence] = None,
+ source: Union[str, int, None] = None,
+ target: Union[str, int, None] = None,
+ value: Optional[Numeric] = None,
+ symbol: Union[str, Sequence, None] = None,
+ symbol_size: Union[Numeric, Sequence, None] = None,
+ linestyle_opts: Union[LineStyleOpts, dict, None] = None,
label_opts: Union[LabelOpts, dict, None] = None,
- itemstyle_opts: Union[ItemStyleOpts, dict, None] = None,
- tooltip_opts: Union[TooltipOpts, dict, None] = None,
+ is_disabled_emphasis: Optional[bool] = None,
+ emphasis_linestyle_opts: Union[LineStyleOpts, dict, None] = None,
+ emphasis_label_opts: Union[LabelOpts, dict, None] = None,
+ blur_linestyle_opts: Union[LineStyleOpts, dict, None] = None,
+ blur_label_opts: Union[LabelOpts, dict, None] = None,
+ is_disabled_select: Optional[bool] = None,
+ select_linestyle_opts: Union[LineStyleOpts, dict, None] = None,
+ select_label_opts: Union[LabelOpts, dict, None] = None,
+ is_ignore_force_layout: bool = False
):
self.opts: dict = {
- "name": name,
+ "source": source,
+ "target": target,
"value": value,
"symbol": symbol,
"symbolSize": symbol_size,
- "symbolRotate": symbol_rotate,
- "symbolKeepAspect": symbol_keep_aspect,
- "symbolOffset": symbol_offset,
+ "lineStyle": linestyle_opts,
"label": label_opts,
- "itemStyle": itemstyle_opts,
- "tooltip": tooltip_opts,
+ "emphasis": {
+ "disabled": is_disabled_emphasis,
+ "lineStyle": emphasis_linestyle_opts,
+ "label": emphasis_label_opts,
+ },
+ "blur": {
+ "lineStyle": blur_linestyle_opts,
+ "label": blur_label_opts,
+ },
+ "select": {
+ "disabled": is_disabled_select,
+ "lineStyle": select_linestyle_opts,
+ "label": select_label_opts,
+ },
+ "ignoreForceLayout": is_ignore_force_layout,
}
-class FunnelItem(BasicOpts):
+class GraphCategory(BasicOpts):
def __init__(
self,
- name: Union[str, int],
- value: Union[Sequence, str, Numeric],
- *,
- is_show_label_line: Optional[bool] = None,
- label_line_width: Optional[int] = None,
- label_line_linestyle_opts: Union[LineStyleOpts, dict, None] = None,
+ name: Optional[str] = None,
+ symbol: Optional[str] = None,
+ symbol_size: Union[Numeric, Sequence, None] = None,
label_opts: Union[LabelOpts, dict, None] = None,
- itemstyle_opts: Union[ItemStyleOpts, dict, None] = None,
- tooltip_opts: Union[TooltipOpts, dict, None] = None,
):
self.opts: dict = {
"name": name,
- "value": value,
- "labelLine": {
- "show": is_show_label_line,
- "length": label_line_width,
- "lineStyle": label_line_linestyle_opts,
- },
+ "symbol": symbol,
+ "symbolSize": symbol_size,
"label": label_opts,
- "itemStyle": itemstyle_opts,
- "tooltip": tooltip_opts,
}
-class LineItem(BasicOpts):
+class BMapNavigationControlOpts(BasicOpts):
def __init__(
self,
- name: Union[str, Numeric] = None,
- value: Union[str, Numeric] = None,
- *,
- symbol: Optional[str] = "circle",
- symbol_size: Numeric = 4,
- symbol_rotate: Optional[Numeric] = None,
- symbol_keep_aspect: bool = False,
- symbol_offset: Optional[Sequence] = None,
- label_opts: Union[LabelOpts, dict, None] = None,
- itemstyle_opts: Union[ItemStyleOpts, dict, None] = None,
- tooltip_opts: Union[TooltipOpts, dict, None] = None,
+ position: Numeric = BMapType.ANCHOR_TOP_LEFT,
+ offset_width: Numeric = 10,
+ offset_height: Numeric = 10,
+ type_: Numeric = BMapType.NAVIGATION_CONTROL_LARGE,
+ is_show_zoom_info: bool = False,
+ is_enable_geo_location: bool = False,
):
+ bmap_nav_config = json.dumps(
+ {
+ "anchor": position,
+ "offset": {"width": offset_width, "height": offset_height},
+ "type": type_,
+ "showZoomInfo": is_show_zoom_info,
+ "enableGeolocation": is_enable_geo_location,
+ }
+ )
+
self.opts: dict = {
- "name": name,
- "value": value,
- "symbol": symbol,
- "symbolSize": symbol_size,
- "symbolRotate": symbol_rotate,
- "symbolKeepAspect": symbol_keep_aspect,
- "symbolOffset": symbol_offset,
- "label": label_opts,
- "itemStyle": itemstyle_opts,
- "tooltip": tooltip_opts,
+ "functions": [
+ "bmap.addControl(new BMap.NavigationControl({}));".format(
+ bmap_nav_config
+ )
+ ]
}
-class MapItem(BasicOpts):
+class BMapOverviewMapControlOpts(BasicOpts):
def __init__(
self,
- name: Optional[str] = None,
- value: Union[Sequence, Numeric, str] = None,
- is_selected: bool = False,
- label_opts: Union[LabelOpts, dict, None] = None,
- itemstyle_opts: Union[ItemStyleOpts, dict, None] = None,
- tooltip_opts: Union[TooltipOpts, dict, None] = None,
+ position: Numeric = BMapType.ANCHOR_BOTTOM_RIGHT,
+ offset_width: Numeric = 10,
+ offset_height: Numeric = 50,
+ is_open: bool = False,
):
+ bmap_overview_config = json.dumps(
+ {
+ "anchor": position,
+ "offset": {"width": offset_width, "height": offset_height},
+ "isOpen": is_open,
+ }
+ )
+
self.opts: dict = {
- "name": name,
- "value": value,
- "selected": is_selected,
- "label": label_opts,
- "itemStyle": itemstyle_opts,
- "tooltip": tooltip_opts,
+ "functions": [
+ "var overview = new BMap.OverviewMapControl({});".format(
+ bmap_overview_config
+ ),
+ "bmap.addControl(overview);",
+ ]
}
-class PieItem(BasicOpts):
+class BMapScaleControlOpts(BasicOpts):
def __init__(
self,
- name: Optional[str] = None,
- value: Optional[Numeric] = None,
- is_selected: bool = False,
- label_opts: Union[LabelOpts, dict, None] = None,
- itemstyle_opts: Union[ItemStyleOpts, dict, None] = None,
- tooltip_opts: Union[TooltipOpts, dict, None] = None,
+ position: Numeric = BMapType.ANCHOR_BOTTOM_LEFT,
+ offset_width: Numeric = 80,
+ offset_height: Numeric = 21,
):
+ bmap_scale_config = json.dumps(
+ {
+ "anchor": position,
+ "offset": {"width": offset_width, "height": offset_height},
+ }
+ )
+
self.opts: dict = {
- "name": name,
- "value": value,
- "selected": is_selected,
- "label": label_opts,
- "itemStyle": itemstyle_opts,
- "tooltip": tooltip_opts,
+ "functions": [
+ "bmap.addControl(new BMap.ScaleControl({}));".format(bmap_scale_config)
+ ]
}
-class RadarItem(BasicOpts):
+class BMapTypeControlOpts(BasicOpts):
def __init__(
self,
- name: Optional[str] = None,
- value: Union[Sequence, Numeric, str] = None,
- symbol: Optional[str] = None,
- symbol_size: Union[Sequence[Numeric], Numeric] = None,
- symbol_rotate: Optional[Numeric] = None,
- symbol_keep_aspect: bool = False,
- symbol_offset: Optional[Sequence] = None,
- label_opts: Union[LabelOpts, dict, None] = None,
- itemstyle_opts: Union[ItemStyleOpts, dict, None] = None,
- tooltip_opts: Union[TooltipOpts, dict, None] = None,
- linestyle_opts: Union[LineStyleOpts, dict, None] = None,
- areastyle_opts: Union[AreaStyleOpts, dict, None] = None,
+ position: Numeric = BMapType.ANCHOR_TOP_RIGHT,
+ type_: Numeric = BMapType.MAPTYPE_CONTROL_HORIZONTAL,
):
+ bmap_type_config = json.dumps({"anchor": position, "type": type_})
+
self.opts: dict = {
- "name": name,
- "value": value,
- "symbol": symbol,
- "symbolSize": symbol_size,
- "symbolRotate": symbol_rotate,
- "symbolKeepAspect": symbol_keep_aspect,
- "symbolOffset": symbol_offset,
- "label": label_opts,
- "itemStyle": itemstyle_opts,
- "tooltip": tooltip_opts,
- "lineStyle": linestyle_opts,
- "areaStyle": areastyle_opts,
+ "functions": [
+ "bmap.addControl(new BMap.MapTypeControl({}));".format(bmap_type_config)
+ ]
}
-class ScatterItem(BasicOpts):
- def __init__(
- self,
- name: Union[str, Numeric] = None,
- value: Union[str, Numeric] = None,
- symbol: Optional[str] = None,
- symbol_size: Union[Sequence[Numeric], Numeric] = None,
- symbol_rotate: Optional[Numeric] = None,
- symbol_keep_aspect: bool = False,
- symbol_offset: Optional[Sequence] = None,
- label_opts: Union[LabelOpts, dict, None] = None,
- itemstyle_opts: Union[ItemStyleOpts, dict, None] = None,
- tooltip_opts: Union[TooltipOpts, dict, None] = None,
- ):
- self.opts: dict = {
- "name": name,
- "value": value,
- "symbol": symbol,
- "symbolSize": symbol_size,
- "symbolRotate": symbol_rotate,
- "symbolKeepAspect": symbol_keep_aspect,
- "symbolOffset": symbol_offset,
- "label": label_opts,
- "itemStyle": itemstyle_opts,
- "tooltip": tooltip_opts,
- }
-
-
-class SunburstItem(BasicOpts):
- def __init__(
- self,
- value: Optional[Numeric] = None,
- name: Optional[str] = None,
- link: Optional[str] = None,
- target: Optional[str] = "blank",
- label_opts: Union[LabelOpts, dict, None] = None,
- itemstyle_opts: Union[ItemStyleOpts, dict, None] = None,
- children: Optional[Sequence] = None,
- ):
- self.opts: dict = {
- "value": value,
- "name": name,
- "link": link,
- "target": target,
- "label": label_opts,
- "itemStyle": itemstyle_opts,
- "children": children,
- }
-
-
-class ThemeRiverItem(BasicOpts):
- def __init__(
- self,
- date: Optional[str] = None,
- value: Optional[Numeric] = None,
- name: Optional[str] = None,
- ):
- self.opts: dict = {"date": date, "value": value, "name": name}
-
-
-class TreeItem(BasicOpts):
- def __init__(
- self,
- name: Optional[str] = None,
- value: Optional[Numeric] = None,
- label_opts: Union[LabelOpts, dict, None] = None,
- children: Optional[Sequence] = None,
- ):
- self.opts: dict = {
- "name": name,
- "value": value,
- "children": children,
- "label": label_opts,
- }
-
-
-# Chart Options
-class GraphNode(BasicOpts):
- def __init__(
- self,
- name: Optional[str] = None,
- x: Optional[Numeric] = None,
- y: Optional[Numeric] = None,
- is_fixed: bool = False,
- value: Union[str, Sequence, None] = None,
- category: Optional[int] = None,
- symbol: Optional[str] = None,
- symbol_size: Union[Numeric, Sequence, None] = None,
- label_opts: Union[LabelOpts, dict, None] = None,
- ):
- self.opts: dict = {
- "name": name,
- "x": x,
- "y": y,
- "fixed": is_fixed,
- "value": value,
- "category": category,
- "symbol": symbol,
- "symbolSize": symbol_size,
- "label": label_opts,
- }
-
-
-class GraphLink(BasicOpts):
- def __init__(
- self,
- source: Union[str, int, None] = None,
- target: Union[str, int, None] = None,
- value: Optional[Numeric] = None,
- symbol: Union[str, Sequence, None] = None,
- symbol_size: Union[Numeric, Sequence, None] = None,
- linestyle_opts: Union[LineStyleOpts, dict, None] = None,
- label_opts: Union[LabelOpts, dict, None] = None,
- ):
- self.opts: dict = {
- "source": source,
- "target": target,
- "value": value,
- "symbol": symbol,
- "symbolSize": symbol_size,
- "lineStyle": linestyle_opts,
- "label": label_opts,
- }
-
-
-class GraphCategory(BasicOpts):
- def __init__(
- self,
- name: Optional[str] = None,
- symbol: Optional[str] = None,
- symbol_size: Union[Numeric, Sequence, None] = None,
- label_opts: Union[LabelOpts, dict, None] = None,
- ):
- self.opts: dict = {
- "name": name,
- "symbol": symbol,
- "symbolSize": symbol_size,
- "label": label_opts,
- }
-
-
-class BMapNavigationControlOpts(BasicOpts):
- def __init__(
- self,
- position: Numeric = BMapType.ANCHOR_TOP_LEFT,
- offset_width: Numeric = 10,
- offset_height: Numeric = 10,
- type_: Numeric = BMapType.NAVIGATION_CONTROL_LARGE,
- is_show_zoom_info: bool = False,
- is_enable_geo_location: bool = False,
- ):
- bmap_nav_config = json.dumps(
- {
- "anchor": position,
- "offset": {"width": offset_width, "height": offset_height},
- "type": type_,
- "showZoomInfo": is_show_zoom_info,
- "enableGeolocation": is_enable_geo_location,
- }
- )
-
- self.opts: dict = {
- "functions": [
- "bmap.addControl(new BMap.NavigationControl({}));".format(
- bmap_nav_config
- )
- ]
- }
-
-
-class BMapOverviewMapControlOpts(BasicOpts):
- def __init__(
- self,
- position: Numeric = BMapType.ANCHOR_BOTTOM_RIGHT,
- offset_width: Numeric = 10,
- offset_height: Numeric = 50,
- is_open: bool = False,
- ):
- bmap_overview_config = json.dumps(
- {
- "anchor": position,
- "offset": {"width": offset_width, "height": offset_height},
- "isOpen": is_open,
- }
- )
-
- self.opts: dict = {
- "functions": [
- "var overview = new BMap.OverviewMapControl({});".format(
- bmap_overview_config
- ),
- "bmap.addControl(overview);",
- ]
- }
-
-
-class BMapScaleControlOpts(BasicOpts):
- def __init__(
- self,
- position: Numeric = BMapType.ANCHOR_BOTTOM_LEFT,
- offset_width: Numeric = 80,
- offset_height: Numeric = 21,
- ):
- bmap_scale_config = json.dumps(
- {
- "anchor": position,
- "offset": {"width": offset_width, "height": offset_height},
- }
- )
-
- self.opts: dict = {
- "functions": [
- "bmap.addControl(new BMap.ScaleControl({}));".format(bmap_scale_config)
- ]
- }
-
-
-class BMapTypeControlOpts(BasicOpts):
- def __init__(
- self,
- position: Numeric = BMapType.ANCHOR_TOP_RIGHT,
- type_: Numeric = BMapType.MAPTYPE_CONTROL_HORIZONTAL,
- ):
- bmap_type_config = json.dumps({"anchor": position, "type": type_})
-
- self.opts: dict = {
- "functions": [
- "bmap.addControl(new BMap.MapTypeControl({}));".format(bmap_type_config)
- ]
- }
-
-
-class BMapCopyrightTypeOpts(BasicOpts):
+class BMapCopyrightTypeOpts(BasicOpts):
def __init__(
self,
position: Numeric = BMapType.ANCHOR_BOTTOM_LEFT,
@@ -632,6 +421,8 @@ def __init__(
pos_x: Numeric = 0,
pos_y: Numeric = 0,
font: Optional[str] = None,
+ font_size: Optional[Numeric] = 0,
+ font_weight: Optional[str] = None,
text_align: str = "left",
text_vertical_align: Optional[str] = None,
graphic_basicstyle_opts: Union[GraphicBasicStyleOpts, dict, None] = None,
@@ -641,6 +432,8 @@ def __init__(
"x": pos_x,
"y": pos_y,
"font": font,
+ "fontSize": font_size,
+ "fontWeight": font_weight,
"textAlign": text_align,
"textVerticalAlign": text_vertical_align,
}
@@ -657,7 +450,7 @@ def __init__(
self,
id_: Optional[str] = None,
action: str = "merge",
- position: [Sequence, Numeric, None] = None,
+ position: Union[Sequence, Numeric, None] = None,
rotation: Union[Numeric, JSFunc, None] = 0,
scale: Union[Sequence, Numeric, None] = None,
origin: Union[Numeric, Sequence, None] = None,
@@ -835,6 +628,7 @@ def __init__(
class TreeMapLevelsOpts(BasicOpts):
def __init__(
self,
+ color: Union[str, Sequence] = None,
color_alpha: Union[Numeric, Sequence] = None,
color_saturation: Union[Numeric, Sequence] = None,
color_mapping_by: str = "index",
@@ -843,6 +637,7 @@ def __init__(
upper_label_opts: Union[LabelOpts, dict, None] = None,
):
self.opts: dict = {
+ "color": color,
"colorAlpha": color_alpha,
"colorSaturation": color_saturation,
"colorMappingBy": color_mapping_by,
@@ -1066,6 +861,30 @@ def __init__(
}
+class GlobeLayersOpts(BasicOpts):
+ def __init__(
+ self,
+ is_show: bool = True,
+ type_: str = "overlay",
+ name: Optional[str] = None,
+ blend_to: str = "albedo",
+ intensity: Numeric = 1,
+ shading: str = "lambert",
+ distance: Optional[Numeric] = None,
+ texture: Union[JSFunc, None] = None,
+ ):
+ self.opts: dict = {
+ "show": is_show,
+ "type": type_,
+ "name": name,
+ "blendTo": blend_to,
+ "intensity": intensity,
+ "shading": shading,
+ "distance": distance,
+ "texture": texture,
+ }
+
+
class BarBackgroundStyleOpts(BasicOpts):
def __init__(
self,
@@ -1073,7 +892,7 @@ def __init__(
border_color: str = "#000",
border_width: Numeric = 0,
border_type: str = "solid",
- bar_border_radius: Union[Numeric, Sequence] = 0,
+ border_radius: Union[Numeric, Sequence] = 0,
shadow_blur: Optional[Numeric] = None,
shadow_color: Optional[str] = None,
shadow_offset_x: Numeric = 0,
@@ -1085,7 +904,7 @@ def __init__(
"borderColor": border_color,
"borderWidth": border_width,
"borderType": border_type,
- "barBorderRadius": bar_border_radius,
+ "borderRadius": border_radius,
"shadowBlur": shadow_blur,
"shadowColor": shadow_color,
"shadowOffsetX": shadow_offset_x,
@@ -1113,6 +932,9 @@ def __init__(
shadow_blur: Optional[Numeric] = 0,
shadow_offset_x: Numeric = 0,
shadow_offset_y: Numeric = 0,
+ overflow: Optional[str] = "none",
+ rich: Optional[dict] = None,
+ is_value_animation: bool = True,
):
if offset_center is None:
offset_center = [0, "-40%"]
@@ -1133,6 +955,9 @@ def __init__(
"shadowBlur": shadow_blur,
"shadowOffsetX": shadow_offset_x,
"shadowOffsetY": shadow_offset_y,
+ "overflow": overflow,
+ "rich": rich,
+ "valueAnimation": is_value_animation,
}
@@ -1145,7 +970,7 @@ def __init__(
border_color: str = "transparent",
offset_center: Sequence = None,
formatter: Optional[JSFunc] = None,
- color: str = "auto",
+ color: str = "#464646",
font_style: str = "normal",
font_weight: str = "normal",
font_family: str = "sans-serif",
@@ -1156,6 +981,9 @@ def __init__(
shadow_blur: Optional[Numeric] = 0,
shadow_offset_x: Numeric = 0,
shadow_offset_y: Numeric = 0,
+ overflow: Optional[str] = "none",
+ rich: Optional[dict] = None,
+ is_value_animation: bool = True,
):
if offset_center is None:
offset_center = [0, "-40%"]
@@ -1177,34 +1005,119 @@ def __init__(
"shadowBlur": shadow_blur,
"shadowOffsetX": shadow_offset_x,
"shadowOffsetY": shadow_offset_y,
+ "overflow": overflow,
+ "rich": rich,
+ "valueAnimation": is_value_animation,
}
-class GaugePointerOpts(BasicOpts):
+class GaugeProgressOpts(BasicOpts):
def __init__(
self,
- is_show: bool = True,
- length: Union[str, Numeric] = "80%",
- width: Numeric = 8,
+ is_show: bool = False,
+ is_overlap: bool = True,
+ width: Numeric = 10,
+ is_round_cap: bool = False,
+ is_clip: bool = False,
+ itemstyle_opts: Union[ItemStyleOpts, dict, None] = None,
):
- self.opts: dict = {"show": is_show, "length": length, "width": width}
+ self.opts: dict = {
+ "show": is_show,
+ "overlap": is_overlap,
+ "width": width,
+ "roundCap": is_round_cap,
+ "clip": is_clip,
+ "itemStyle": itemstyle_opts,
+ }
-class PieLabelLineOpts(BasicOpts):
+class GaugePointerOpts(BasicOpts):
def __init__(
self,
is_show: bool = True,
- length: Numeric = None,
- length_2: Numeric = None,
- smooth: Union[bool, Numeric] = False,
- linestyle_opts: Union[LineStyleOpts, dict, None] = None,
+ length: Union[str, Numeric] = "80%",
+ width: Numeric = 8,
+ itemstyle_opts: Union[ItemStyleOpts, dict, None] = None,
):
self.opts: dict = {
"show": is_show,
"length": length,
- "length2": length_2,
- "smooth": smooth,
- "lineStyle": linestyle_opts,
+ "width": width,
+ "itemStyle": itemstyle_opts,
+ }
+
+
+class GaugeAnchorOpts(BasicOpts):
+ def __init__(
+ self,
+ is_show: bool = True,
+ is_show_above: bool = False,
+ size: Numeric = 6,
+ icon: str = "circle",
+ offset_center: Optional[Sequence] = None,
+ is_keep_aspect: bool = False,
+ itemstyle_opts: Union[ItemStyleOpts, dict, None] = None,
+ ):
+ if offset_center is None:
+ offset_center = [0, 0]
+ self.opts: dict = {
+ "show": is_show,
+ "showAbove": is_show_above,
+ "size": size,
+ "icon": icon,
+ "offsetCenter": offset_center,
+ "keepAspect": is_keep_aspect,
+ "itemStyle": itemstyle_opts,
+ }
+
+
+class PieLabelLineOpts(BasicOpts):
+ def __init__(
+ self,
+ is_show: bool = True,
+ is_show_above: bool = False,
+ length: Numeric = 15,
+ length_2: Numeric = 15,
+ smooth: Union[bool, Numeric] = False,
+ min_turn_angle: Numeric = 90,
+ linestyle_opts: Union[LineStyleOpts, dict, None] = None,
+ max_surface_angle: Numeric = 90,
+ ):
+ self.opts: dict = {
+ "show": is_show,
+ "showAbove": is_show_above,
+ "length": length,
+ "length2": length_2,
+ "smooth": smooth,
+ "minTurnAngle": min_turn_angle,
+ "lineStyle": linestyle_opts,
+ "maxSurfaceAngle": max_surface_angle,
+ }
+
+
+class PieEmptyCircleStyle(BasicOpts):
+ def __init__(
+ self,
+ color: str = "lightgray",
+ border_color: str = "#000",
+ border_width: Numeric = 0,
+ border_type: str = "solid",
+ border_dash_offset: Numeric = 0,
+ border_cap: str = "butt",
+ border_join: str = "bevel",
+ border_miter_limit: Numeric = 10,
+ opacity: Numeric = 1,
+ ):
+ self.opts: dict = {
+ "color": color,
+ "borderColor": border_color,
+ "borderWidth": border_width,
+ "borderType": border_type,
+ "borderDashOffset": border_dash_offset,
+ "borderCap": border_cap,
+ "borderJoin": border_join,
+ "borderMiterLimit": border_miter_limit,
+ "opacity": opacity,
}
@@ -1275,3 +1188,588 @@ def __init__(
"borderColor": border_color,
"borderWidth": border_width,
}
+
+
+class TabChartGlobalOpts(BasicOpts):
+ def __init__(
+ self,
+ is_enable: bool = False,
+ tab_base_css: Optional[dict] = None,
+ tab_button_css: Optional[dict] = None,
+ tab_button_hover_css: Optional[dict] = None,
+ tab_button_active_css: Optional[dict] = None,
+ ):
+ self.opts: dict = {
+ "enable": is_enable,
+ "base": tab_base_css,
+ "button_base": tab_button_css,
+ "button_hover": tab_button_hover_css,
+ "button_active": tab_button_active_css,
+ }
+
+
+class GraphGLNode(BasicOpts):
+ def __init__(
+ self,
+ name: Optional[str] = None,
+ x: Optional[Numeric] = None,
+ y: Optional[Numeric] = None,
+ value: Union[str, Numeric, Sequence, None] = None,
+ itemstyle_opts: Union[ItemStyleOpts, dict, None] = None,
+ ):
+ self.opts: dict = {
+ "name": name,
+ "x": x,
+ "y": y,
+ "value": value,
+ "itemStyle": itemstyle_opts,
+ }
+
+
+class GraphGLLink(BasicOpts):
+ def __init__(
+ self,
+ source: Union[str, int, None] = None,
+ target: Union[str, int, None] = None,
+ value: Optional[Numeric] = None,
+ linestyle_opts: Union[LineStyleOpts, dict, None] = None,
+ ):
+ self.opts: dict = {
+ "source": source,
+ "target": target,
+ "value": value,
+ "lineStyle": linestyle_opts,
+ }
+
+
+class GeoRegionsOpts(BasicOpts):
+ def __init__(
+ self,
+ name: Optional[str] = None,
+ is_selected: bool = False,
+ itemstyle_opts: Union[ItemStyleOpts, dict, None] = None,
+ label_opts: Union[LabelOpts, dict, None] = None,
+ emphasis_itemstyle_opts: Union[ItemStyleOpts, dict, None] = None,
+ emphasis_label_opts: Union[LabelOpts, dict, None] = None,
+ select_itemstyle_opts: Union[ItemStyleOpts, dict, None] = None,
+ select_label_opts: Union[LabelOpts, dict, None] = None,
+ blur_itemstyle_opts: Union[ItemStyleOpts, dict, None] = None,
+ blur_label_opts: Union[LabelOpts, dict, None] = None,
+ tooltip_opts: Union[TooltipOpts, dict, None] = None,
+ is_silent: bool = False,
+ ):
+ self.opts: dict = {
+ "name": name,
+ "selected": is_selected,
+ "itemStyle": itemstyle_opts,
+ "label": label_opts,
+ "emphasis": {
+ "itemStyle": emphasis_itemstyle_opts,
+ "label": emphasis_label_opts,
+ },
+ "select": {
+ "itemStyle": select_itemstyle_opts,
+ "label": select_label_opts,
+ },
+ "blur": {
+ "itemStyle": blur_itemstyle_opts,
+ "label": blur_label_opts,
+ },
+ "tooltip": tooltip_opts,
+ "silent": is_silent,
+ }
+
+
+class SunburstLabelLineOpts(BasicOpts):
+ def __init__(
+ self,
+ is_show: Optional[bool] = None,
+ is_show_above: Optional[bool] = None,
+ length_2: Optional[Numeric] = None,
+ smooth: Union[bool, Numeric] = False,
+ min_turn_angle: Optional[Numeric] = None,
+ linestyle_opts: Union[LineStyleOpts, dict, None] = None,
+ ):
+ self.opts: dict = {
+ "show": is_show,
+ "showAbove": is_show_above,
+ "length2": length_2,
+ "smooth": smooth,
+ "minTurnAngle": min_turn_angle,
+ "lineStyle": linestyle_opts,
+ }
+
+
+class SunburstLabelLayoutOpts(BasicOpts):
+ def __init__(
+ self,
+ is_hide_overlap: Optional[bool] = None,
+ is_move_overlap: Optional[bool] = None,
+ rotate: Optional[Numeric] = None,
+ width: Optional[Numeric] = None,
+ height: Optional[Numeric] = None,
+ align: Optional[str] = None,
+ vertical_align: Optional[str] = None,
+ font_size: Optional[Numeric] = None,
+ is_draggable: Optional[bool] = None,
+ ):
+ self.opts: dict = {
+ "hideOverlap": is_hide_overlap,
+ "moveOverlap": is_move_overlap,
+ "rotate": rotate,
+ "width": width,
+ "height": height,
+ "align": align,
+ "verticalAlign": vertical_align,
+ "fontSize": font_size,
+ "draggable": is_draggable,
+ }
+
+
+class SunburstLevelOpts(BasicOpts):
+ def __init__(
+ self,
+ radius: Optional[Sequence] = None,
+ label_opts: Union[LabelOpts, dict, None] = None,
+ label_line_opts: Union[SunburstLabelLineOpts, dict, None] = None,
+ itemstyle_opts: Union[ItemStyleOpts, dict, None] = None,
+ ):
+ self.opts: dict = {
+ "radius": radius,
+ "label": label_opts,
+ "labelLine": label_line_opts,
+ "itemStyle": itemstyle_opts,
+ }
+
+
+# Data Item
+class BarItem(BasicOpts):
+ def __init__(
+ self,
+ name: Union[int, str, None],
+ value: Numeric,
+ *,
+ group_id: Optional[str] = None,
+ label_opts: Union[LabelOpts, dict, None] = None,
+ is_show_label_line: Optional[bool] = None,
+ label_line_linestyle_opts: Union[LineStyleOpts, dict, None] = None,
+ itemstyle_opts: Union[ItemStyleOpts, dict, None] = None,
+ tooltip_opts: Union[TooltipOpts, dict, None] = None,
+ ):
+ label_line = None
+ if is_show_label_line:
+ label_line = {
+ "show": is_show_label_line,
+ "lineStyle": label_line_linestyle_opts,
+ }
+
+ self.opts: dict = {
+ "name": name,
+ "value": value,
+ "groupId": group_id,
+ "label": label_opts,
+ "labelLine": label_line,
+ "itemStyle": itemstyle_opts,
+ "tooltip": tooltip_opts,
+ }
+
+
+class BoxplotItem(BasicOpts):
+ def __init__(
+ self,
+ name: Union[int, str],
+ value: Sequence,
+ *,
+ itemstyle_opts: Union[ItemStyleOpts, dict, None] = None,
+ tooltip_opts: Union[TooltipOpts, dict, None] = None,
+ ):
+ self.opts: dict = {
+ "name": name,
+ "value": value,
+ "itemStyle": itemstyle_opts,
+ "tooltip": tooltip_opts,
+ }
+
+
+class CandleStickItem(BasicOpts):
+ def __init__(
+ self,
+ name: Union[str, int],
+ value: Sequence,
+ *,
+ itemstyle_opts: Union[ItemStyleOpts, dict, None] = None,
+ tooltip_opts: Union[TooltipOpts, dict, None] = None,
+ ):
+ self.opts: dict = {
+ "name": name,
+ "value": value,
+ "itemStyle": itemstyle_opts,
+ "tooltip": tooltip_opts,
+ }
+
+
+class EffectScatterItem(BasicOpts):
+ def __init__(
+ self,
+ name: Union[str, Numeric],
+ value: Union[str, Numeric],
+ *,
+ symbol: Optional[str] = None,
+ symbol_size: Union[Sequence[Numeric], Numeric] = None,
+ symbol_rotate: Optional[Numeric] = None,
+ symbol_keep_aspect: bool = False,
+ symbol_offset: Optional[Sequence] = None,
+ label_opts: Union[LabelOpts, dict, None] = None,
+ itemstyle_opts: Union[ItemStyleOpts, dict, None] = None,
+ tooltip_opts: Union[TooltipOpts, dict, None] = None,
+ ):
+ self.opts: dict = {
+ "name": name,
+ "value": value,
+ "symbol": symbol,
+ "symbolSize": symbol_size,
+ "symbolRotate": symbol_rotate,
+ "symbolKeepAspect": symbol_keep_aspect,
+ "symbolOffset": symbol_offset,
+ "label": label_opts,
+ "itemStyle": itemstyle_opts,
+ "tooltip": tooltip_opts,
+ }
+
+
+class FunnelItem(BasicOpts):
+ def __init__(
+ self,
+ name: Union[str, int],
+ value: Union[Sequence, str, Numeric],
+ *,
+ is_show_label_line: Optional[bool] = None,
+ label_line_width: Optional[int] = None,
+ label_line_linestyle_opts: Union[LineStyleOpts, dict, None] = None,
+ label_opts: Union[LabelOpts, dict, None] = None,
+ itemstyle_opts: Union[ItemStyleOpts, dict, None] = None,
+ tooltip_opts: Union[TooltipOpts, dict, None] = None,
+ ):
+ self.opts: dict = {
+ "name": name,
+ "value": value,
+ "labelLine": {
+ "show": is_show_label_line,
+ "length": label_line_width,
+ "lineStyle": label_line_linestyle_opts,
+ },
+ "label": label_opts,
+ "itemStyle": itemstyle_opts,
+ "tooltip": tooltip_opts,
+ }
+
+
+class LineItem(BasicOpts):
+ def __init__(
+ self,
+ name: Union[str, Numeric] = None,
+ value: Union[str, Numeric] = None,
+ *,
+ symbol: Optional[str] = "circle",
+ symbol_size: Numeric = 4,
+ symbol_rotate: Optional[Numeric] = None,
+ symbol_keep_aspect: bool = False,
+ symbol_offset: Optional[Sequence] = None,
+ label_opts: Union[LabelOpts, dict, None] = None,
+ itemstyle_opts: Union[ItemStyleOpts, dict, None] = None,
+ tooltip_opts: Union[TooltipOpts, dict, None] = None,
+ ):
+ self.opts: dict = {
+ "name": name,
+ "value": value,
+ "symbol": symbol,
+ "symbolSize": symbol_size,
+ "symbolRotate": symbol_rotate,
+ "symbolKeepAspect": symbol_keep_aspect,
+ "symbolOffset": symbol_offset,
+ "label": label_opts,
+ "itemStyle": itemstyle_opts,
+ "tooltip": tooltip_opts,
+ }
+
+
+class MapItem(BasicOpts):
+ def __init__(
+ self,
+ name: Optional[str] = None,
+ value: Union[Sequence, Numeric, str] = None,
+ group_id: Optional[str] = None,
+ is_selected: bool = False,
+ label_opts: Union[LabelOpts, dict, None] = None,
+ itemstyle_opts: Union[ItemStyleOpts, dict, None] = None,
+ tooltip_opts: Union[TooltipOpts, dict, None] = None,
+ ):
+ self.opts: dict = {
+ "name": name,
+ "value": value,
+ "groupId": group_id,
+ "selected": is_selected,
+ "label": label_opts,
+ "itemStyle": itemstyle_opts,
+ "tooltip": tooltip_opts,
+ }
+
+
+class GeoItem(BasicOpts):
+ def __init__(
+ self,
+ longitude: Numeric,
+ latitude: Numeric,
+ name: str,
+ value: Union[Sequence, Numeric, str] = None,
+ ):
+ self.opts: dict = {
+ "longitude": longitude,
+ "latitude": latitude,
+ "name": name,
+ "value": value,
+ }
+
+
+class ParallelItem(BasicOpts):
+ def __init__(
+ self,
+ name: Optional[str] = None,
+ value: Optional[Sequence] = None,
+ linestyle_opts: Union[LineStyleOpts, dict, None] = None,
+ color: Union[str, dict] = "#000",
+ width: Numeric = 2,
+ type_: str = "solid",
+ dash_offset: Numeric = 0,
+ cap: str = "butt",
+ join: str = "bevel",
+ miter_limit: Optional[Numeric] = None,
+ opacity: Numeric = 0.45,
+ ):
+ self.opts: dict = {
+ "name": name,
+ "value": value,
+ "lineStyle": linestyle_opts,
+ "color": color,
+ "width": width,
+ "type": type_,
+ "dashOffset": dash_offset,
+ "cap": cap,
+ "join": join,
+ "miterLimit": miter_limit,
+ "opacity": opacity,
+ }
+
+
+class PieItem(BasicOpts):
+ def __init__(
+ self,
+ name: Optional[str] = None,
+ value: Optional[Numeric] = None,
+ group_id: Optional[str] = None,
+ is_selected: bool = False,
+ label_opts: Union[LabelOpts, dict, None] = None,
+ itemstyle_opts: Union[ItemStyleOpts, dict, None] = None,
+ tooltip_opts: Union[TooltipOpts, dict, None] = None,
+ label_line_opts: Union[PieLabelLineOpts, dict, None] = None,
+ ):
+ self.opts: dict = {
+ "name": name,
+ "value": value,
+ "groupId": group_id,
+ "selected": is_selected,
+ "label": label_opts,
+ "labelLine": label_line_opts,
+ "itemStyle": itemstyle_opts,
+ "tooltip": tooltip_opts,
+ }
+
+
+class RadarItem(BasicOpts):
+ def __init__(
+ self,
+ name: Optional[str] = None,
+ value: Union[Sequence, Numeric, str] = None,
+ symbol: Optional[str] = None,
+ symbol_size: Union[Sequence[Numeric], Numeric] = None,
+ symbol_rotate: Optional[Numeric] = None,
+ symbol_keep_aspect: bool = False,
+ symbol_offset: Optional[Sequence] = None,
+ label_opts: Union[LabelOpts, dict, None] = None,
+ itemstyle_opts: Union[ItemStyleOpts, dict, None] = None,
+ tooltip_opts: Union[TooltipOpts, dict, None] = None,
+ linestyle_opts: Union[LineStyleOpts, dict, None] = None,
+ areastyle_opts: Union[AreaStyleOpts, dict, None] = None,
+ ):
+ self.opts: dict = {
+ "name": name,
+ "value": value,
+ "symbol": symbol,
+ "symbolSize": symbol_size,
+ "symbolRotate": symbol_rotate,
+ "symbolKeepAspect": symbol_keep_aspect,
+ "symbolOffset": symbol_offset,
+ "label": label_opts,
+ "itemStyle": itemstyle_opts,
+ "tooltip": tooltip_opts,
+ "lineStyle": linestyle_opts,
+ "areaStyle": areastyle_opts,
+ }
+
+
+class ScatterItem(BasicOpts):
+ def __init__(
+ self,
+ name: Union[str, Numeric] = None,
+ value: Union[str, Numeric, Sequence] = None,
+ symbol: Optional[str] = None,
+ symbol_size: Union[Sequence[Numeric], Numeric] = None,
+ symbol_rotate: Optional[Numeric] = None,
+ symbol_keep_aspect: bool = False,
+ symbol_offset: Optional[Sequence] = None,
+ label_opts: Union[LabelOpts, dict, None] = None,
+ itemstyle_opts: Union[ItemStyleOpts, dict, None] = None,
+ tooltip_opts: Union[TooltipOpts, dict, None] = None,
+ ):
+ self.opts: dict = {
+ "name": name,
+ "value": value,
+ "symbol": symbol,
+ "symbolSize": symbol_size,
+ "symbolRotate": symbol_rotate,
+ "symbolKeepAspect": symbol_keep_aspect,
+ "symbolOffset": symbol_offset,
+ "label": label_opts,
+ "itemStyle": itemstyle_opts,
+ "tooltip": tooltip_opts,
+ }
+
+
+class SunburstItem(BasicOpts):
+ def __init__(
+ self,
+ value: Optional[Numeric] = None,
+ name: Optional[str] = None,
+ link: Optional[str] = None,
+ target: Optional[str] = "blank",
+ label_opts: Union[LabelOpts, dict, None] = None,
+ itemstyle_opts: Union[ItemStyleOpts, dict, None] = None,
+ children: Optional[Sequence] = None,
+ ):
+ self.opts: dict = {
+ "value": value,
+ "name": name,
+ "link": link,
+ "target": target,
+ "label": label_opts,
+ "itemStyle": itemstyle_opts,
+ "children": children,
+ }
+
+
+class ThemeRiverItem(BasicOpts):
+ def __init__(
+ self,
+ date: Optional[str] = None,
+ value: Optional[Numeric] = None,
+ name: Optional[str] = None,
+ ):
+ self.opts: dict = {"date": date, "value": value, "name": name}
+
+
+class TreeItem(BasicOpts):
+ def __init__(
+ self,
+ name: Optional[str] = None,
+ value: Optional[Numeric] = None,
+ label_opts: Union[LabelOpts, dict, None] = None,
+ children: Optional[Sequence] = None,
+ ):
+ self.opts: dict = {
+ "name": name,
+ "value": value,
+ "children": children,
+ "label": label_opts,
+ }
+
+
+class CustomBarRangeItemPayloadOpts(BasicOpts):
+ def __init__(
+ self,
+ bar_width: Union[Numeric, str, None] = None,
+ border_radius: Optional[Numeric] = None,
+ margin: Optional[Numeric] = None,
+ ):
+ self.opts: dict = {
+ "barWidth": bar_width,
+ "borderRadius": border_radius,
+ "margin": margin,
+ }
+
+
+class CustomContourItemPayloadOpts(BasicOpts):
+ def __init__(
+ self,
+ itemstyle_opts: Union[ItemStyleOpts, dict, None] = None,
+ linestyle_opts: Union[LineStyleOpts, dict, None] = None,
+ bandwidth: Optional[Numeric] = None,
+ ):
+ self.opts: dict = {
+ "itemStyle": itemstyle_opts,
+ "lineStyle": linestyle_opts,
+ "bandwidth": bandwidth,
+ }
+
+
+class CustomLineRangeItemPayloadOpts(BasicOpts):
+ def __init__(
+ self,
+ linestyle_opts: Union[LineStyleOpts, dict, None] = None,
+ areastyle_opts: Union[AreaStyleOpts, dict, None] = None,
+ ):
+ self.opts: dict = {
+ "areaStyle": areastyle_opts,
+ "lineStyle": linestyle_opts,
+ }
+
+
+class CustomSegmentedDoughnutItemPayloadOpts(BasicOpts):
+ def __init__(
+ self,
+ center: Optional[Sequence] = None,
+ radius: Optional[Sequence] = None,
+ segment_count: Optional[Numeric] = None,
+ label_opts: Union[LabelOpts, dict, None] = None,
+ ):
+ self.opts: dict = {
+ "center": center,
+ "radius": radius,
+ "segmentCount": segment_count,
+ "label": label_opts,
+ }
+
+
+class CustomStageItemPayloadOpts(BasicOpts):
+ def __init__(
+ self,
+ itemstyle_opts: Union[ItemStyleOpts, dict, None] = None,
+ ):
+ self.opts: dict = {
+ "itemStyle": itemstyle_opts,
+ }
+
+
+class CustomViolinItemPayloadOpts(BasicOpts):
+ def __init__(
+ self,
+ symbol_size: Optional[Numeric] = None,
+ area_opacity: Optional[Numeric] = None,
+ bandwidth_scale: Optional[Numeric] = None,
+ bin_count: Optional[Numeric] = None,
+ ):
+ self.opts: dict = {
+ "symbolSize": symbol_size,
+ "areaOpacity": area_opacity,
+ "bandWidthScale": bandwidth_scale,
+ "binCount": bin_count,
+ }
diff --git a/pyecharts/options/global_options.py b/pyecharts/options/global_options.py
index 0cf8015f8..aa9eed2be 100644
--- a/pyecharts/options/global_options.py
+++ b/pyecharts/options/global_options.py
@@ -1,6 +1,8 @@
from ..globals import CurrentConfig, RenderType, ThemeType
from ..options.series_options import (
BasicOpts,
+ AnimationOpts,
+ AreaStyleOpts,
ItemStyleOpts,
JSFunc,
LabelOpts,
@@ -17,27 +19,111 @@
)
-class AnimationOpts(BasicOpts):
+class AriaLabelOpts(BasicOpts):
def __init__(
self,
- animation: bool = True,
- animation_threshold: Numeric = 2000,
- animation_duration: Union[Numeric, JSFunc] = 1000,
- animation_easing: Union[str] = "cubicOut",
- animation_delay: Union[Numeric, JSFunc] = 0,
- animation_duration_update: Union[Numeric, JSFunc] = 300,
- animation_easing_update: Union[Numeric] = "cubicOut",
- animation_delay_update: Union[Numeric, JSFunc] = 0,
+ is_enable: bool = True,
+ description: Optional[str] = None,
+ general_with_title: str = "这是一个关于“{title}”的图表。",
+ general_without_title: str = "这是一个图表,",
+ series_max_count: int = 10,
+ series_single_prefix: str = "",
+ series_single_with_name: str = "图表类型是{seriesType},表示{seriesName}。",
+ series_single_without_name: str = "图表类型是{seriesType}。",
+ series_multiple_prefix: str = "它由{seriesCount}个图表系列组成。",
+ series_multiple_with_name: str = "图表类型是{seriesType},表示{seriesName}。",
+ series_multiple_without_name: str = "图表类型是{seriesType}。",
+ series_multiple_separator_middle: str = ";",
+ series_multiple_separator_end: str = "。",
+ data_max_count: int = 10,
+ data_all_data: str = "其数据是——",
+ data_partial_data: str = "其中,前{displayCnt}项是——",
+ data_with_name: str = "{name}的数据是{value}",
+ data_without_name: str = "{value}",
+ data_separator_middle: str = ",",
+ data_separator_end: str = "",
):
self.opts: dict = {
- "animation": animation,
- "animationThreshold": animation_threshold,
- "animationDuration": animation_duration,
- "animationEasing": animation_easing,
- "animationDelay": animation_delay,
- "animationDurationUpdate": animation_duration_update,
- "animationEasingUpdate": animation_easing_update,
- "animationDelayUpdate": animation_delay_update,
+ "enabled": is_enable,
+ "description": description,
+ "general": {
+ "withTitle": general_with_title,
+ "withoutTitle": general_without_title,
+ },
+ "series": {
+ "maxCount": series_max_count,
+ "single": {
+ "prefix": series_single_prefix,
+ "withName": series_single_with_name,
+ "withoutName": series_single_without_name,
+ },
+ "multiple": {
+ "prefix": series_multiple_prefix,
+ "withName": series_multiple_with_name,
+ "withoutName": series_multiple_without_name,
+ "separator": {
+ "middle": series_multiple_separator_middle,
+ "end": series_multiple_separator_end,
+ },
+ },
+ },
+ "data": {
+ "maxCount": data_max_count,
+ "allData": data_all_data,
+ "partialData": data_partial_data,
+ "withName": data_with_name,
+ "withoutName": data_without_name,
+ "separator": {
+ "middle": data_separator_middle,
+ "end": data_separator_end,
+ },
+ },
+ }
+
+
+class AriaDecalOpts(BasicOpts):
+ def __init__(
+ self,
+ is_show: bool = False,
+ decals_symbol: Union[str, Sequence] = "rect",
+ decals_symbol_size: Numeric = 1,
+ decals_symbol_keep_aspect: bool = True,
+ decals_color: str = "rgba(0, 0, 0, 0.2)",
+ decals_background_color: Optional[str] = None,
+ decals_dash_array_x: Union[Numeric, Sequence] = 5,
+ decals_dash_array_y: Union[Numeric, Sequence] = 5,
+ decals_rotation: Numeric = 0,
+ decals_max_tile_width: Numeric = 512,
+ decals_max_tile_height: Numeric = 512,
+ ):
+ self.opts: dict = {
+ "show": is_show,
+ "decals": {
+ "symbol": decals_symbol,
+ "symbolSize": decals_symbol_size,
+ "symbolKeepAspect": decals_symbol_keep_aspect,
+ "color": decals_color,
+ "backgroundColor": decals_background_color,
+ "dashArrayX": decals_dash_array_x,
+ "dashArrayY": decals_dash_array_y,
+ "rotation": decals_rotation,
+ "maxTileWidth": decals_max_tile_width,
+ "maxTileHeight": decals_max_tile_height,
+ },
+ }
+
+
+class AriaOpts(BasicOpts):
+ def __init__(
+ self,
+ is_enable: bool = False,
+ aria_label_opts: Optional[AriaLabelOpts] = None,
+ aria_decal_opts: Optional[AriaDecalOpts] = None,
+ ):
+ self.opts: dict = {
+ "enabled": is_enable,
+ "label": aria_label_opts,
+ "decal": aria_decal_opts,
}
@@ -46,24 +132,91 @@ def __init__(
self,
width: str = "900px",
height: str = "500px",
+ is_horizontal_center: bool = False,
chart_id: Optional[str] = None,
renderer: str = RenderType.CANVAS,
page_title: str = CurrentConfig.PAGE_TITLE,
theme: str = ThemeType.WHITE,
bg_color: Union[str, dict] = None,
+ is_fill_bg_color: bool = False,
js_host: str = "",
animation_opts: Union[AnimationOpts, dict] = AnimationOpts(),
+ aria_opts: Union[AriaOpts, dict] = AriaOpts(),
):
self.opts: dict = {
"width": width,
"height": height,
+ "is_horizontal_center": is_horizontal_center,
"chart_id": chart_id,
"renderer": renderer,
"page_title": page_title,
"theme": theme,
"bg_color": bg_color,
+ "fill_bg": is_fill_bg_color,
"js_host": js_host,
"animationOpts": animation_opts,
+ "ariaOpts": aria_opts,
+ }
+
+
+class RenderOpts(BasicOpts):
+ def __init__(self, is_embed_js: bool = False):
+ self.opts: dict = {
+ "embed_js": is_embed_js,
+ }
+
+
+class TooltipOpts(BasicOpts):
+ def __init__(
+ self,
+ is_show: bool = True,
+ trigger: str = "item",
+ trigger_on: str = "mousemove|click",
+ axis_pointer_type: str = "line",
+ is_show_content: bool = True,
+ is_always_show_content: bool = False,
+ show_delay: Numeric = 0,
+ hide_delay: Numeric = 100,
+ is_enterable: bool = False,
+ is_confine: bool = False,
+ is_append_to_body: bool = False,
+ transition_duration: Numeric = 0.4,
+ is_display_transition: bool = True,
+ position: Union[str, Sequence, JSFunc] = None,
+ formatter: Optional[JSFunc] = None,
+ value_formatter: Optional[JSFunc] = None,
+ background_color: Optional[str] = None,
+ border_color: Optional[str] = None,
+ border_width: Numeric = 0,
+ padding: Union[Numeric, Sequence[Numeric]] = 5,
+ textstyle_opts: Optional[TextStyleOpts] = TextStyleOpts(font_size=14),
+ extra_css_text: Optional[str] = None,
+ order: str = "seriesAsc",
+ ):
+ self.opts: dict = {
+ "show": is_show,
+ "trigger": trigger,
+ "triggerOn": trigger_on,
+ "axisPointer": {"type": axis_pointer_type},
+ "showContent": is_show_content,
+ "alwaysShowContent": is_always_show_content,
+ "showDelay": show_delay,
+ "hideDelay": hide_delay,
+ "enterable": is_enterable,
+ "confine": is_confine,
+ "appendToBody": is_append_to_body,
+ "transitionDuration": transition_duration,
+ "displayTransition": is_display_transition,
+ "position": position,
+ "formatter": formatter,
+ "valueFormatter": value_formatter,
+ "textStyle": textstyle_opts,
+ "backgroundColor": background_color,
+ "borderColor": border_color,
+ "borderWidth": border_width,
+ "padding": padding,
+ "extraCssText": extra_css_text,
+ "order": order,
}
@@ -76,7 +229,7 @@ def __init__(
connected_background_color: str = "#fff",
exclude_components: Optional[Sequence[str]] = None,
is_show: bool = True,
- title: str = "保存为图片",
+ title: Optional[str] = None,
icon: Optional[JSFunc] = None,
pixel_ratio: Numeric = 1,
):
@@ -95,7 +248,10 @@ def __init__(
class ToolBoxFeatureRestoreOpts(BasicOpts):
def __init__(
- self, is_show: bool = True, title: str = "还原", icon: Optional[JSFunc] = None
+ self,
+ is_show: bool = True,
+ title: Optional[str] = None,
+ icon: Optional[JSFunc] = None
):
self.opts: dict = {"show": is_show, "title": title, "icon": icon}
@@ -104,7 +260,7 @@ class ToolBoxFeatureDataViewOpts(BasicOpts):
def __init__(
self,
is_show: bool = True,
- title: str = "数据视图",
+ title: Optional[str] = None,
icon: Optional[JSFunc] = None,
is_read_only: bool = False,
option_to_content: Optional[JSFunc] = None,
@@ -117,9 +273,6 @@ def __init__(
button_color: str = "#c23531",
button_text_color: str = "#fff",
):
- if lang is None:
- lang = ["数据视图", "关闭", "刷新"]
-
self.opts: dict = {
"show": is_show,
"title": title,
@@ -141,12 +294,12 @@ class ToolBoxFeatureDataZoomOpts(BasicOpts):
def __init__(
self,
is_show: bool = True,
- zoom_title: str = "区域缩放",
- back_title: str = "区域缩放还原",
+ zoom_title: Optional[str] = None,
+ back_title: Optional[str] = None,
zoom_icon: Optional[JSFunc] = None,
back_icon: Optional[JSFunc] = None,
- xaxis_index: Union[Numeric, Sequence, bool] = False,
- yaxis_index: Union[Numeric, Sequence, bool] = False,
+ xaxis_index: Union[Numeric, Sequence, bool] = None,
+ yaxis_index: Union[Numeric, Sequence, bool] = None,
filter_mode: str = "filter",
):
self.opts: dict = {
@@ -164,10 +317,10 @@ def __init__(
self,
is_show: bool = True,
type_: Optional[Sequence] = None,
- line_title: str = "切换为折线图",
- bar_title: str = "切换为柱状图",
- stack_title: str = "切换为堆叠",
- tiled_title: str = "切换为平铺",
+ line_title: Optional[str] = None,
+ bar_title: Optional[str] = None,
+ stack_title: Optional[str] = None,
+ tiled_title: Optional[str] = None,
line_icon: Optional[JSFunc] = None,
bar_icon: Optional[JSFunc] = None,
stack_icon: Optional[JSFunc] = None,
@@ -204,12 +357,12 @@ def __init__(
line_y_icon: Optional[JSFunc] = None,
keep_icon: Optional[JSFunc] = None,
clear_icon: Optional[JSFunc] = None,
- rect_title: str = "矩形选择",
- polygon_title: str = "圈选",
- line_x_title: str = "横向选择",
- line_y_title: str = "纵向选择",
- keep_title: str = "保持选择",
- clear_title: str = "清除选择",
+ rect_title: Optional[str] = None,
+ polygon_title: Optional[str] = None,
+ line_x_title: Optional[str] = None,
+ line_y_title: Optional[str] = None,
+ keep_title: Optional[str] = None,
+ clear_title: Optional[str] = None,
):
self.opts: dict = {
"type": type_,
@@ -248,7 +401,7 @@ def __init__(
magic_type: Union[
ToolBoxFeatureMagicTypeOpts, dict
] = ToolBoxFeatureMagicTypeOpts(),
- brush: Union[ToolBoxFeatureBrushOpts, dict] = ToolBoxFeatureBrushOpts(),
+ brush: Union[ToolBoxFeatureBrushOpts, dict] = None,
):
self.opts: dict = {
"saveAsImage": save_as_image,
@@ -272,6 +425,18 @@ def __init__(
pos_top: Optional[str] = None,
pos_bottom: Optional[str] = None,
feature: Union[ToolBoxFeatureOpts, dict] = ToolBoxFeatureOpts(),
+ z_level: Optional[Numeric] = None,
+ z: Optional[Numeric] = None,
+ width: Optional[str] = None,
+ height: Optional[str] = None,
+ coordinate_system: Optional[str] = None,
+ coordinate_system_usage: Optional[str] = None,
+ coord: Optional[Union[Sequence, Numeric, str]] = None,
+ calendar_index: Optional[Numeric] = None,
+ calendar_id: Optional[Numeric] = None,
+ matrix_index: Optional[Numeric] = None,
+ matrix_id: Optional[Numeric] = None,
+ tooltip_opts: Union[TooltipOpts, dict, None] = None,
):
self.opts: dict = {
"show": is_show,
@@ -283,6 +448,18 @@ def __init__(
"top": pos_top,
"bottom": pos_bottom,
"feature": feature,
+ "zlevel": z_level,
+ "z": z,
+ "width": width,
+ "height": height,
+ "coordinateSystem": coordinate_system,
+ "coordinateSystemUsage": coordinate_system_usage,
+ "coord": coord,
+ "calendarIndex": calendar_index,
+ "calendarId": calendar_id,
+ "matrixIndex": matrix_index,
+ "matrixId": matrix_id,
+ "tooltip": tooltip_opts,
}
@@ -302,7 +479,9 @@ def __init__(
throttle_type: str = "fixRate",
throttle_delay: Numeric = 0,
remove_on_click: bool = True,
- out_of_brush: dict = None,
+ in_brush: Optional[dict] = None,
+ out_of_brush: Optional[dict] = None,
+ z: Numeric = 10000,
):
if tool_box is None:
tool_box = ["rect", "polygon", "keep", "clear"]
@@ -328,30 +507,44 @@ def __init__(
"throttleType": throttle_type,
"throttleDelay": throttle_delay,
"removeOnClick": remove_on_click,
+ "inBrush": in_brush,
"outOfBrush": out_of_brush,
+ "z": z,
}
class TitleOpts(BasicOpts):
def __init__(
self,
+ is_show: bool = True,
title: Optional[str] = None,
title_link: Optional[str] = None,
- title_target: Optional[str] = None,
+ title_target: Optional[str] = "blank",
subtitle: Optional[str] = None,
subtitle_link: Optional[str] = None,
- subtitle_target: Optional[str] = None,
- pos_left: Optional[str] = None,
- pos_right: Optional[str] = None,
- pos_top: Optional[str] = None,
- pos_bottom: Optional[str] = None,
+ subtitle_target: Optional[str] = "blank",
+ pos_left: Union[str, Numeric] = None,
+ pos_right: Union[str, Numeric] = None,
+ pos_top: Union[str, Numeric] = None,
+ pos_bottom: Union[str, Numeric] = None,
+ coordinate_system: Optional[str] = None,
+ coordinate_system_usage: Optional[str] = None,
+ coord: Optional[Union[Sequence, Numeric, str]] = None,
+ calendar_index: Optional[Numeric] = None,
+ calendar_id: Optional[Numeric] = None,
+ matrix_index: Optional[Numeric] = None,
+ matrix_id: Optional[Numeric] = None,
padding: Union[Sequence, Numeric] = 5,
item_gap: Numeric = 10,
+ text_align: str = "auto",
+ text_vertical_align: str = "auto",
+ is_trigger_event: bool = False,
title_textstyle_opts: Union[TextStyleOpts, dict, None] = None,
subtitle_textstyle_opts: Union[TextStyleOpts, dict, None] = None,
):
self.opts: Sequence = [
{
+ "show": is_show,
"text": title,
"link": title_link,
"target": title_target,
@@ -362,8 +555,18 @@ def __init__(
"right": pos_right,
"top": pos_top,
"bottom": pos_bottom,
+ "coordinateSystem": coordinate_system,
+ "coordinateSystemUsage": coordinate_system_usage,
+ "coord": coord,
+ "calendarIndex": calendar_index,
+ "calendarId": calendar_id,
+ "matrixIndex": matrix_index,
+ "matrixId": matrix_id,
"padding": padding,
"itemGap": item_gap,
+ "textAlign": text_align,
+ "textVerticalAlign": text_vertical_align,
+ "triggerEvent": is_trigger_event,
"textStyle": title_textstyle_opts,
"subtextStyle": subtitle_textstyle_opts,
}
@@ -375,51 +578,126 @@ def __init__(
self,
is_show: bool = True,
type_: str = "slider",
+ is_disabled: bool = False,
is_realtime: bool = True,
+ is_show_detail: bool = True,
+ is_show_data_shadow: bool = True,
range_start: Union[Numeric, None] = 20,
range_end: Union[Numeric, None] = 80,
start_value: Union[int, str, None] = None,
end_value: Union[int, str, None] = None,
+ min_span: Union[int, None] = None,
+ max_span: Union[int, None] = None,
+ min_value_span: Union[int, str, None] = None,
+ max_value_span: Union[int, str, None] = None,
orient: str = "horizontal",
xaxis_index: Union[int, Sequence[int], None] = None,
yaxis_index: Union[int, Sequence[int], None] = None,
+ radius_axis_index: Union[int, Sequence[int], None] = None,
+ angle_axis_index: Union[int, Sequence[int], None] = None,
is_zoom_lock: bool = False,
- pos_left: Optional[str] = None,
- pos_right: Optional[str] = None,
- pos_top: Optional[str] = None,
- pos_bottom: Optional[str] = None,
+ throttle: Optional[int] = None,
+ range_mode: Optional[Sequence] = None,
+ pos_left: Union[Numeric, str] = None,
+ pos_right: Union[Numeric, str] = None,
+ pos_top: Union[Numeric, str] = None,
+ pos_bottom: Union[Numeric, str] = None,
+ width: Union[Numeric, str] = None,
+ height: Union[Numeric, str] = None,
filter_mode: str = "filter",
+ is_zoom_on_mouse_wheel: bool = True,
+ is_move_on_mouse_move: bool = True,
+ is_move_on_mouse_wheel: bool = True,
+ is_prevent_default_mouse_move: bool = True,
+ coordinate_system: Optional[str] = None,
+ coordinate_system_usage: Optional[str] = None,
+ coord: Optional[Union[Sequence, Numeric, str]] = None,
+ calendar_index: Optional[Numeric] = None,
+ calendar_id: Optional[Numeric] = None,
+ matrix_index: Optional[Numeric] = None,
+ matrix_id: Optional[Numeric] = None,
):
self.opts: dict = {
"show": is_show,
"type": type_,
+ "showDetail": is_show_detail,
+ "showDataShadow": is_show_data_shadow,
"realtime": is_realtime,
"startValue": start_value,
"endValue": end_value,
"start": range_start,
"end": range_end,
+ "minSpan": min_span,
+ "maxSpan": max_span,
+ "minValueSpan": min_value_span,
+ "maxValueSpan": max_value_span,
"orient": orient,
"xAxisIndex": xaxis_index,
"yAxisIndex": yaxis_index,
+ "radiusAxisIndex": radius_axis_index,
+ "angleAxisIndex": angle_axis_index,
"zoomLock": is_zoom_lock,
+ "throttle": throttle,
+ "rangeMode": range_mode,
"left": pos_left,
"right": pos_right,
"top": pos_top,
"bottom": pos_bottom,
"filterMode": filter_mode,
+ "coordinateSystem": coordinate_system,
+ "coordinateSystemUsage": coordinate_system_usage,
+ "coord": coord,
+ "calendarIndex": calendar_index,
+ "calendarId": calendar_id,
+ "matrixIndex": matrix_index,
+ "matrixId": matrix_id,
}
+ # inside have some different configurations.
+ if type_ == "inside":
+ self.opts.update({
+ "disabled": is_disabled,
+ "zoomOnMouseWheel": is_zoom_on_mouse_wheel,
+ "moveOnMouseMove": is_move_on_mouse_move,
+ "moveOnMouseWheel": is_move_on_mouse_wheel,
+ "preventDefaultMouseMove": is_prevent_default_mouse_move,
+ })
+
+ # slider have some different configurations.
+ if type_ == "slider":
+ self.opts.update({
+ "coordinateSystem": coordinate_system,
+ "coordinateSystemUsage": coordinate_system_usage,
+ "coord": coord,
+ "calendarIndex": calendar_index,
+ "calendarId": calendar_id,
+ "matrixIndex": matrix_index,
+ "matrixId": matrix_id,
+ "width": width,
+ "height": height,
+ })
+
class LegendOpts(BasicOpts):
def __init__(
self,
type_: Optional[str] = None,
selected_mode: Union[str, bool, None] = None,
+ selected_map: Optional[dict] = None,
is_show: bool = True,
pos_left: Union[str, Numeric, None] = None,
pos_right: Union[str, Numeric, None] = None,
pos_top: Union[str, Numeric, None] = None,
pos_bottom: Union[str, Numeric, None] = None,
+ width: Union[str, Numeric, None] = None,
+ height: Union[str, Numeric, None] = None,
+ coordinate_system: Optional[str] = None,
+ coordinate_system_usage: Optional[str] = None,
+ coord: Optional[Union[Sequence, Numeric, str]] = None,
+ calendar_index: Optional[Numeric] = None,
+ calendar_id: Optional[Numeric] = None,
+ matrix_index: Optional[Numeric] = None,
+ matrix_id: Optional[Numeric] = None,
orient: Optional[str] = None,
align: Optional[str] = None,
padding: int = 5,
@@ -429,15 +707,45 @@ def __init__(
inactive_color: Optional[str] = None,
textstyle_opts: Union[TextStyleOpts, dict, None] = None,
legend_icon: Optional[str] = None,
+ background_color: Optional[str] = "transparent",
+ border_color: Optional[str] = "#ccc",
+ border_width: Optional[int] = None,
+ border_radius: Union[int, Sequence] = 0,
+ page_button_item_gap: int = 5,
+ page_button_gap: Optional[int] = None,
+ page_button_position: str = "end",
+ page_formatter: JSFunc = "{current}/{total}",
+ page_icon: Optional[str] = None,
+ page_icon_color: str = "#2f4554",
+ page_icon_inactive_color: str = "#aaa",
+ page_icon_size: Union[int, Sequence] = 15,
+ is_page_animation: Optional[bool] = None,
+ page_animation_duration_update: int = 800,
+ selector: Union[bool, Sequence] = False,
+ selector_label: Union[LabelOpts, dict, None] = None,
+ selector_position: str = "auto",
+ selector_item_gap: int = 7,
+ selector_button_gap: int = 10,
+ is_trigger_event: bool = False,
):
self.opts: dict = {
"type": type_,
"selectedMode": selected_mode,
+ "selected": selected_map,
"show": is_show,
"left": pos_left,
"right": pos_right,
"top": pos_top,
"bottom": pos_bottom,
+ "width": width,
+ "height": height,
+ "coordinateSystem": coordinate_system,
+ "coordinateSystemUsage": coordinate_system_usage,
+ "coord": coord,
+ "calendarIndex": calendar_index,
+ "calendarId": calendar_id,
+ "matrixIndex": matrix_index,
+ "matrixId": matrix_id,
"orient": orient,
"align": align,
"padding": padding,
@@ -447,6 +755,26 @@ def __init__(
"inactiveColor": inactive_color,
"textStyle": textstyle_opts,
"icon": legend_icon,
+ "backgroundColor": background_color,
+ "borderColor": border_color,
+ "borderWidth": border_width,
+ "borderRadius": border_radius,
+ "pageButtonItemGap": page_button_item_gap,
+ "pageButtonGap": page_button_gap,
+ "pageButtonPosition": page_button_position,
+ "pageFormatter": page_formatter,
+ "pageIcon": page_icon,
+ "pageIconColor": page_icon_color,
+ "pageIconInactiveColor": page_icon_inactive_color,
+ "pageIconSize": page_icon_size,
+ "animation": is_page_animation,
+ "animationDurationUpdate": page_animation_duration_update,
+ "selector": selector,
+ "selectorLabel": selector_label,
+ "selectorPosition": selector_position,
+ "selectorItemGap": selector_item_gap,
+ "selectorButtonGap": selector_button_gap,
+ "triggerEvent": is_trigger_event,
}
@@ -457,29 +785,40 @@ def __init__(
type_: str = "color",
min_: Numeric = 0,
max_: Numeric = 100,
+ range_: Sequence[Numeric] = None,
range_text: Optional[Sequence] = None,
range_color: Optional[Sequence[str]] = None,
range_size: Optional[Sequence[int]] = None,
- range_opacity: Optional[Numeric] = None,
+ range_opacity: Union[Numeric, Sequence[Numeric]] = None,
orient: str = "vertical",
- pos_left: Optional[str] = None,
- pos_right: Optional[str] = None,
- pos_top: Optional[str] = None,
- pos_bottom: Optional[str] = None,
+ pos_left: Union[str, Numeric] = None,
+ pos_right: Union[str, Numeric] = None,
+ pos_top: Union[str, Numeric] = None,
+ pos_bottom: Union[str, Numeric] = None,
+ padding: Union[int, Sequence[int]] = 5,
split_number: int = 5,
series_index: Union[Numeric, Sequence, None] = None,
+ is_hover_link: bool = True,
dimension: Optional[Numeric] = None,
is_calculable: bool = True,
is_piecewise: bool = False,
is_inverse: bool = False,
precision: Optional[int] = None,
pieces: Optional[Sequence] = None,
- out_of_range: Optional[Sequence] = None,
+ categories: Optional[Sequence] = None,
+ out_of_range: Optional[dict] = None,
item_width: int = 0,
item_height: int = 0,
background_color: Optional[str] = None,
border_color: Optional[str] = None,
border_width: int = 0,
+ coordinate_system: Optional[str] = None,
+ coordinate_system_usage: Optional[str] = None,
+ coord: Optional[Union[Sequence, Numeric, str]] = None,
+ calendar_index: Optional[Numeric] = None,
+ calendar_id: Optional[Numeric] = None,
+ matrix_index: Optional[Numeric] = None,
+ matrix_id: Optional[Numeric] = None,
textstyle_opts: Union[TextStyleOpts, dict, None] = None,
):
_inrange_op: dict = {}
@@ -493,6 +832,14 @@ def __init__(
_inrange_op.update(opacity=range_opacity)
_visual_typ = "piecewise" if is_piecewise else "continuous"
+ if type_ in ["piecewise", "continuous"] and (
+ range_color or range_size or range_opacity,
+ ):
+ _inrange_op.update(
+ color=range_color,
+ symbolSize=range_size,
+ opacity=range_opacity,
+ )
if is_piecewise and item_width == 0 and item_height == 0:
item_width, item_height = 20, 14
@@ -506,18 +853,21 @@ def __init__(
"max": max_,
"text": range_text,
"textStyle": textstyle_opts,
- "inRange": _inrange_op,
+ "range": range_,
+ "inRange": _inrange_op if _inrange_op else None,
"calculable": is_calculable,
"inverse": is_inverse,
"precision": precision,
"splitNumber": split_number,
"dimension": dimension,
"seriesIndex": series_index,
+ "hoverLink": is_hover_link,
"orient": orient,
"left": pos_left,
"top": pos_top,
"bottom": pos_bottom,
"right": pos_right,
+ "padding": padding,
"showLabel": True,
"itemWidth": item_width,
"itemHeight": item_height,
@@ -525,47 +875,16 @@ def __init__(
"backgroundColor": background_color,
"borderColor": border_color,
"borderWidth": border_width,
+ "coordinateSystem": coordinate_system,
+ "coordinateSystemUsage": coordinate_system_usage,
+ "coord": coord,
+ "calendarIndex": calendar_index,
+ "calendarId": calendar_id,
+ "matrixIndex": matrix_index,
+ "matrixId": matrix_id,
}
if is_piecewise:
- self.opts.update(pieces=pieces)
-
-
-class TooltipOpts(BasicOpts):
- def __init__(
- self,
- is_show: bool = True,
- trigger: str = "item",
- trigger_on: str = "mousemove|click",
- axis_pointer_type: str = "line",
- is_show_content: bool = True,
- is_always_show_content: bool = False,
- show_delay: Numeric = 0,
- hide_delay: Numeric = 100,
- position: Union[str, Sequence, JSFunc] = None,
- formatter: Optional[JSFunc] = None,
- background_color: Optional[str] = None,
- border_color: Optional[str] = None,
- border_width: Numeric = 0,
- padding: Numeric = 5,
- textstyle_opts: TextStyleOpts = TextStyleOpts(font_size=14),
- ):
- self.opts: dict = {
- "show": is_show,
- "trigger": trigger,
- "triggerOn": trigger_on,
- "axisPointer": {"type": axis_pointer_type},
- "showContent": is_show_content,
- "alwaysShowContent": is_always_show_content,
- "showDelay": show_delay,
- "hideDelay": hide_delay,
- "position": position,
- "formatter": formatter,
- "textStyle": textstyle_opts,
- "backgroundColor": background_color,
- "borderColor": border_color,
- "borderWidth": border_width,
- "padding": padding,
- }
+ self.opts.update(pieces=pieces, categories=categories)
class AxisLineOpts(BasicOpts):
@@ -610,15 +929,69 @@ def __init__(
is_show: bool = False,
link: Sequence[dict] = None,
type_: str = "line",
+ is_snap: Optional[bool] = None,
+ is_trigger_tooltip: bool = True,
+ trigger_on: str = "mousemove|click",
label: Union[LabelOpts, dict, None] = None,
linestyle_opts: Union[LineStyleOpts, dict, None] = None,
):
self.opts: dict = {
"show": is_show,
"type": type_,
+ "snap": is_snap,
"link": link,
"label": label,
"lineStyle": linestyle_opts,
+ "triggerTooltip": is_trigger_tooltip,
+ "triggerOn": trigger_on,
+ }
+
+
+class AxisBreakOpts(BasicOpts):
+ def __init__(
+ self,
+ start: Union[Numeric, str] = None,
+ end: Union[Numeric, str] = None,
+ gap: Union[Numeric, str] = None,
+ is_expanded: Optional[bool] = None,
+ ):
+ self.opts: dict = {
+ "start": start,
+ "end": end,
+ "gap": gap,
+ "isExpanded": is_expanded,
+ }
+
+
+class AxisBreakAreaOpts(BasicOpts):
+ def __init__(
+ self,
+ is_show: Optional[bool] = None,
+ itemstyle_opts: Union[ItemStyleOpts, dict, None] = None,
+ zigzag_amplitude: Optional[Numeric] = None,
+ zigzag_min_span: Optional[Numeric] = None,
+ zigzag_max_span: Optional[Numeric] = None,
+ zigzag_z: Optional[Numeric] = None,
+ is_expand_onclick: Optional[bool] = None,
+ ):
+ self.opts: dict = {
+ "show": is_show,
+ "itemStyle": itemstyle_opts,
+ "zigzagAmplitude": zigzag_amplitude,
+ "zigzagMinSpan": zigzag_min_span,
+ "zigzagMaxSpan": zigzag_max_span,
+ "zigzagZ": zigzag_z,
+ "expandOnClick": is_expand_onclick,
+ }
+
+
+class AxisBreakLabelLayoutOpts(BasicOpts):
+ def __init__(
+ self,
+ is_move_overlap: Optional[bool] = None,
+ ):
+ self.opts: dict = {
+ "moveOverlap": is_move_overlap,
}
@@ -633,25 +1006,42 @@ def __init__(
name_location: str = "end",
name_gap: Numeric = 15,
name_rotate: Optional[Numeric] = None,
+ name_truncate_max_width: Optional[Numeric] = None,
+ name_truncate_ellipsis: Optional[str] = None,
+ is_name_move_overlap: bool = True,
interval: Optional[Numeric] = None,
- grid_index: Numeric = 0,
+ grid_index: Optional[Numeric] = None,
+ grid_id: Optional[Numeric] = None,
position: Optional[str] = None,
offset: Numeric = 0,
split_number: Numeric = 5,
boundary_gap: Union[str, bool, None] = None,
- min_: Union[Numeric, str, None] = None,
- max_: Union[Numeric, str, None] = None,
+ min_: Union[Numeric, JSFunc, None] = None,
+ max_: Union[Numeric, JSFunc, None] = None,
min_interval: Numeric = 0,
max_interval: Optional[Numeric] = None,
+ log_base: Optional[Numeric] = None,
+ start_value: Optional[Numeric] = None,
+ is_silent: bool = False,
+ is_trigger_event: bool = False,
+ jitter: Optional[Numeric] = None,
+ is_jitter_overlap: Optional[bool] = None,
+ jitter_margin: Optional[Numeric] = None,
+ axisbreaks_opts: Sequence[Union[AxisBreakOpts, dict, None]] = None,
+ axisbreak_area_opts: Union[AxisBreakAreaOpts, dict, None] = None,
+ axisbreak_label_layout_opts: Union[
+ AxisBreakLabelLayoutOpts, dict, None,
+ ] = None,
axisline_opts: Union[AxisLineOpts, dict, None] = None,
axistick_opts: Union[AxisTickOpts, dict, None] = None,
axislabel_opts: Union[LabelOpts, dict, None] = None,
axispointer_opts: Union[AxisPointerOpts, dict, None] = None,
name_textstyle_opts: Union[TextStyleOpts, dict, None] = None,
splitarea_opts: Union[SplitAreaOpts, dict, None] = None,
- splitline_opts: Union[SplitLineOpts, dict] = SplitLineOpts(),
+ splitline_opts: Union[SplitLineOpts, dict] = SplitLineOpts(is_show=True),
minor_tick_opts: Union[MinorTickOpts, dict, None] = None,
minor_split_line_opts: Union[MinorSplitLineOpts, dict, None] = None,
+ animation_opts: Union[AnimationOpts, dict] = AnimationOpts(),
):
self.opts: dict = {
"type": type_,
@@ -661,9 +1051,15 @@ def __init__(
"nameLocation": name_location,
"nameGap": name_gap,
"nameRotate": name_rotate,
+ "nameTruncate": {
+ "maxWidth": name_truncate_max_width,
+ "ellipsis": name_truncate_ellipsis,
+ },
+ "nameMoveOverlap": is_name_move_overlap,
"interval": interval,
"nameTextStyle": name_textstyle_opts,
"gridIndex": grid_index,
+ "gridId": grid_id,
"axisLine": axisline_opts,
"axisTick": axistick_opts,
"axisLabel": axislabel_opts,
@@ -677,12 +1073,45 @@ def __init__(
"max": max_,
"minInterval": min_interval,
"maxInterval": max_interval,
+ "logBase": log_base,
+ "startValue": start_value,
+ "silent": is_silent,
+ "triggerEvent": is_trigger_event,
+ "jitter": jitter,
+ "jitterOverlap": is_jitter_overlap,
+ "jitterMargin": jitter_margin,
+ "breaks": axisbreaks_opts,
+ "breakArea": axisbreak_area_opts,
+ "breakLabelLayout": axisbreak_label_layout_opts,
"splitLine": splitline_opts,
"splitArea": splitarea_opts,
"minorTick": minor_tick_opts,
"minorSplitLine": minor_split_line_opts,
}
+ if animation_opts:
+ self.opts.update(**animation_opts.opts)
+
+
+class GridOuterOpts(BasicOpts):
+ def __init__(
+ self,
+ pos_left: Union[Numeric, str, None] = None,
+ pos_top: Union[Numeric, str, None] = None,
+ pos_right: Union[Numeric, str, None] = None,
+ pos_bottom: Union[Numeric, str, None] = None,
+ width: Union[Numeric, str, None] = None,
+ height: Union[Numeric, str, None] = None,
+ ):
+ self.opts: dict = {
+ "left": pos_left,
+ "top": pos_top,
+ "right": pos_right,
+ "bottom": pos_bottom,
+ "width": width,
+ "height": height,
+ }
+
class GridOpts(BasicOpts):
def __init__(
@@ -697,10 +1126,24 @@ def __init__(
width: Union[Numeric, str, None] = None,
height: Union[Numeric, str, None] = None,
is_contain_label: bool = False,
+ outer_bounds_mode: Optional[str] = None,
+ outer_bounds_opts: Union[GridOuterOpts, dict, None] = None,
+ outer_bounds_contain: Optional[str] = None,
background_color: str = "transparent",
border_color: str = "#ccc",
border_width: Numeric = 1,
+ shadow_blur: Optional[Numeric] = None,
+ shadow_color: Optional[str] = None,
+ shadow_offset_x: Numeric = 0,
+ shadow_offset_y: Numeric = 0,
tooltip_opts: Union[TooltipOpts, dict, None] = None,
+ coordinate_system: Optional[str] = None,
+ coordinate_system_usage: Optional[str] = None,
+ coord: Optional[Union[Sequence, Numeric, str]] = None,
+ calendar_index: Optional[Numeric] = None,
+ calendar_id: Optional[Numeric] = None,
+ matrix_index: Optional[Numeric] = None,
+ matrix_id: Optional[Numeric] = None,
):
self.opts: dict = {
"show": is_show,
@@ -713,32 +1156,84 @@ def __init__(
"width": width,
"height": height,
"containLabel": is_contain_label,
+ "outerBoundsMode": outer_bounds_mode,
+ "outerBounds": outer_bounds_opts,
+ "outerBoundsContain": outer_bounds_contain,
"backgroundColor": background_color,
"borderColor": border_color,
"borderWidth": border_width,
+ "shadowBlur": shadow_blur,
+ "shadowColor": shadow_color,
+ "shadowOffsetX": shadow_offset_x,
+ "shadowOffsetY": shadow_offset_y,
"tooltip": tooltip_opts,
+ "coordinateSystem": coordinate_system,
+ "coordinateSystemUsage": coordinate_system_usage,
+ "coord": coord,
+ "calendarIndex": calendar_index,
+ "calendarId": calendar_id,
+ "matrixIndex": matrix_index,
+ "matrixId": matrix_id,
}
class Grid3DOpts(BasicOpts):
def __init__(
self,
+ is_show: Optional[bool] = None,
width: Numeric = 200,
height: Numeric = 100,
depth: Numeric = 80,
is_rotate: bool = False,
rotate_speed: Numeric = 10,
rotate_sensitivity: Numeric = 1,
+ axisline_opts: Union[AxisLineOpts, dict, None] = None,
+ axistick_opts: Union[AxisTickOpts, dict, None] = None,
+ axislabel_opts: Union[LabelOpts, dict, None] = None,
+ axispointer_opts: Union[AxisPointerOpts, dict, None] = None,
+ splitarea_opts: Union[SplitAreaOpts, dict, None] = None,
+ splitline_opts: Union[SplitLineOpts, dict] = SplitLineOpts(is_show=True),
+ environment: JSFunc = "auto",
+ view_control_alpha: Numeric = 20,
+ view_control_beta: Numeric = 40,
+ view_control_min_alpha: Numeric = -90,
+ view_control_max_alpha: Numeric = 90,
+ view_control_min_beta: Optional[int] = None,
+ view_control_max_beta: Optional[int] = None,
+ z_level: Numeric = -10,
+ pos_left: Union[str, Numeric] = "auto",
+ pos_top: Union[str, Numeric] = "auto",
+ pos_right: Union[str, Numeric] = "auto",
+ pos_bottom: Union[str, Numeric] = "auto",
):
self.opts: dict = {
+ "show": is_show,
"boxWidth": width,
"boxHeight": height,
"boxDepth": depth,
+ "axisLine": axisline_opts,
+ "axisTick": axistick_opts,
+ "axisLabel": axislabel_opts,
+ "axisPointer": axispointer_opts,
+ "splitLine": splitline_opts,
+ "splitArea": splitarea_opts,
+ "environment": environment,
"viewControl": {
"autoRotate": is_rotate,
"autoRotateSpeed": rotate_speed,
"rotateSensitivity": rotate_sensitivity,
+ "alpha": view_control_alpha,
+ "beta": view_control_beta,
+ "minAlpha": view_control_min_alpha,
+ "maxAlpha": view_control_max_alpha,
+ "minBeta": view_control_min_beta,
+ "maxBeta": view_control_max_beta,
},
+ "zlevel": z_level,
+ "left": pos_left,
+ "top": pos_top,
+ "right": pos_right,
+ "bottom": pos_bottom,
}
@@ -748,24 +1243,41 @@ def __init__(
data: Optional[Sequence] = None,
type_: Optional[str] = None,
name: Optional[str] = None,
+ is_show: bool = True,
+ is_scale: bool = False,
+ grid_3d_index: Numeric = 0,
name_gap: Numeric = 20,
min_: Union[str, Numeric, None] = None,
max_: Union[str, Numeric, None] = None,
- splitnum: Optional[Numeric] = None,
- interval: Optional[Numeric] = None,
- margin: Numeric = 8,
+ split_number: Optional[Numeric] = None,
+ log_base: Numeric = 10,
+ axisline_opts: Union[AxisLineOpts, dict, None] = None,
+ axistick_opts: Union[AxisTickOpts, dict, None] = None,
+ axislabel_opts: Union[LabelOpts, dict, None] = None,
+ axispointer_opts: Union[AxisPointerOpts, dict, None] = None,
+ splitarea_opts: Union[SplitAreaOpts, dict, None] = None,
+ splitline_opts: Union[SplitLineOpts, dict] = SplitLineOpts(is_show=True),
textstyle_opts: Union[TextStyleOpts, dict, None] = None,
):
self.opts: dict = {
"data": data,
"name": name,
+ "show": is_show,
+ "scale": is_scale,
+ "grid3DIndex": grid_3d_index,
"nameGap": name_gap,
"nameTextStyle": textstyle_opts,
- "splitNum": splitnum,
+ "splitNumber": split_number,
+ "logBase": log_base,
"type": type_,
"min": min_,
"max": max_,
- "axisLabel": {"margin": margin, "interval": interval},
+ "axisLine": axisline_opts,
+ "axisTick": axistick_opts,
+ "axisLabel": axislabel_opts,
+ "axisPointer": axispointer_opts,
+ "splitLine": splitline_opts,
+ "splitArea": splitarea_opts,
}
@@ -776,14 +1288,46 @@ def __init__(
pos_right: str = "13%",
pos_bottom: str = "10%",
pos_top: str = "20%",
+ z_level: Optional[Numeric] = None,
+ z: Optional[Numeric] = None,
+ width: Optional[str] = None,
+ height: Optional[str] = None,
+ coordinate_system: Optional[str] = None,
+ coordinate_system_usage: Optional[str] = None,
+ coord: Optional[Union[Sequence, Numeric, str]] = None,
+ calendar_index: Optional[Numeric] = None,
+ calendar_id: Optional[Numeric] = None,
+ matrix_index: Optional[Numeric] = None,
+ matrix_id: Optional[Numeric] = None,
layout: Optional[str] = None,
+ is_axis_expandable: bool = False,
+ axis_expand_center: Optional[Numeric] = None,
+ axis_expand_count: Numeric = 0,
+ axis_expand_width: Numeric = 50,
+ axis_expand_trigger_on: str = "click",
):
self.opts: dict = {
"left": pos_left,
"right": pos_right,
"bottom": pos_bottom,
"top": pos_top,
+ "zlevel": z_level,
+ "z": z,
+ "width": width,
+ "height": height,
+ "coordinateSystem": coordinate_system,
+ "coordinateSystemUsage": coordinate_system_usage,
+ "coord": coord,
+ "calendarIndex": calendar_index,
+ "calendarId": calendar_id,
+ "matrixIndex": matrix_index,
+ "matrixId": matrix_id,
"layout": layout,
+ "axisExpandable": is_axis_expandable,
+ "axisExpandCenter": axis_expand_center,
+ "axisExpandCount": axis_expand_count,
+ "axisExpandWidth": axis_expand_width,
+ "axisExpandTriggerOn": axis_expand_trigger_on,
}
@@ -791,21 +1335,47 @@ class ParallelAxisOpts(BasicOpts):
def __init__(
self,
dim: Numeric,
- name: str,
+ parallel_index: Numeric = 0,
+ is_realtime: bool = True,
+ name: Optional[str] = None,
data: Sequence = None,
type_: Optional[str] = None,
+ name_location: str = "end",
+ name_gap: Numeric = 15,
+ name_rotate: Optional[int] = None,
+ is_inverse: bool = False,
min_: Union[str, Numeric, None] = None,
max_: Union[str, Numeric, None] = None,
is_scale: bool = False,
+ log_base: Numeric = 10,
+ is_silent: bool = False,
+ is_trigger_event: bool = False,
+ axisline_opts: Union[AxisLineOpts, dict, None] = None,
+ axistick_opts: Union[AxisTickOpts, dict, None] = None,
+ axislabel_opts: Union[LabelOpts, dict, None] = None,
+ minor_tick_opts: Union[MinorTickOpts, dict, None] = None,
):
self.opts: dict = {
"dim": dim,
+ "parallelIndex": parallel_index,
+ "realtime": is_realtime,
"name": name,
"data": data,
"type": type_,
+ "name_location": name_location,
+ "name_gap": name_gap,
+ "name_rotate": name_rotate,
+ "inverse": is_inverse,
"min": min_,
"max": max_,
"scale": is_scale,
+ "logBase": log_base,
+ "silent": is_silent,
+ "triggerEvent": is_trigger_event,
+ "axisLine": axisline_opts,
+ "axisTick": axistick_opts,
+ "axisLabel": axislabel_opts,
+ "minorTick": minor_tick_opts,
}
@@ -917,6 +1487,8 @@ def __init__(
class CalendarOpts(BasicOpts):
def __init__(
self,
+ z_level: Numeric = 0,
+ z: Numeric = 2,
pos_left: Optional[str] = None,
pos_top: Optional[str] = None,
pos_right: Optional[str] = None,
@@ -931,8 +1503,11 @@ def __init__(
daylabel_opts: Union[CalendarDayLabelOpts, dict, None] = None,
monthlabel_opts: Union[CalendarMonthLabelOpts, dict, None] = None,
yearlabel_opts: Union[CalendarYearLabelOpts, dict, None] = None,
+ is_silent: bool = False,
):
self.opts: dict = {
+ "zlevel": z_level,
+ "z": z,
"left": pos_left,
"top": pos_top,
"right": pos_right,
@@ -947,6 +1522,7 @@ def __init__(
"dayLabel": daylabel_opts,
"monthLabel": monthlabel_opts,
"yearLabel": yearlabel_opts,
+ "silent": is_silent,
}
@@ -964,6 +1540,15 @@ def __init__(
height: Optional[str] = None,
orient: Optional[str] = None,
type_: Optional[str] = None,
+ axisline_opts: Union[AxisLineOpts, dict, None] = None,
+ axistick_opts: Union[AxisTickOpts, dict, None] = None,
+ axislabel_opts: Union[LabelOpts, dict, None] = None,
+ axispointer_opts: Union[AxisPointerOpts, dict, None] = None,
+ splitarea_opts: Union[SplitAreaOpts, dict, None] = None,
+ splitline_opts: Union[SplitLineOpts, dict, None] = None,
+ minor_tick_opts: Union[MinorTickOpts, dict, None] = None,
+ minor_split_line_opts: Union[MinorSplitLineOpts, dict, None] = None,
+ tooltip_opts: Union[TooltipOpts, dict, None] = None,
):
self.opts: dict = {
"name": name,
@@ -977,6 +1562,15 @@ def __init__(
"height": height,
"orient": orient,
"type": type_,
+ "axisLine": axisline_opts,
+ "axisTick": axistick_opts,
+ "minorTick": minor_tick_opts,
+ "axisLabel": axislabel_opts,
+ "splitLine": splitline_opts,
+ "minorSplitLine": minor_split_line_opts,
+ "splitArea": splitarea_opts,
+ "axisPointer": axispointer_opts,
+ "tooltip": tooltip_opts,
}
@@ -1007,16 +1601,25 @@ def __init__(
type_: Optional[str] = None,
name: Optional[str] = None,
name_location: Optional[str] = None,
+ name_gap: Numeric = 15,
+ name_rotate: Optional[Numeric] = None,
+ is_inverse: bool = False,
min_: Union[str, Numeric, None] = None,
max_: Union[str, Numeric, None] = None,
is_scale: bool = False,
+ split_number: Numeric = 5,
interval: Optional[Numeric] = None,
+ min_interval: Numeric = 0,
+ max_interval: Optional[Numeric] = None,
splitline_opts: Union[SplitLineOpts, dict, None] = None,
splitarea_opts: Union[SplitAreaOpts, dict, None] = None,
axistick_opts: Union[AxisTickOpts, dict, None] = None,
axisline_opts: Union[AxisLineOpts, dict, None] = None,
axislabel_opts: Union[LabelOpts, dict, None] = None,
+ minor_tick_opts: Union[MinorTickOpts, dict, None] = None,
+ minor_split_line_opts: Union[MinorSplitLineOpts, dict, None] = None,
z: Optional[int] = None,
+ z_level: Optional[int] = None,
):
_data = []
if data:
@@ -1032,16 +1635,25 @@ def __init__(
"boundaryGap": boundary_gap,
"name": name,
"nameLocation": name_location,
+ "nameGap": name_gap,
+ "nameRotate": name_rotate,
+ "inverse": is_inverse,
"min": min_,
"max": max_,
"scale": is_scale,
+ "splitNumber": split_number,
"interval": interval,
+ "minInterval": min_interval,
+ "maxInterval": max_interval,
"splitLine": splitline_opts,
"splitArea": splitarea_opts,
"axisTick": axistick_opts,
"axisLine": axisline_opts,
"axisLabel": axislabel_opts,
+ "minorTick": minor_tick_opts,
+ "minorSplitLine": minor_split_line_opts,
"z": z,
+ "zlevel": z_level,
}
@@ -1050,7 +1662,7 @@ def __init__(
self,
polar_index: Optional[int] = None,
data: Optional[Sequence[Union[AngleAxisItem, Numeric, dict, str]]] = None,
- start_angle: Optional[Numeric] = None,
+ start_angle: Optional[Numeric] = 90,
is_clockwise: bool = False,
boundary_gap: Union[bool, Sequence, None] = None,
type_: Optional[str] = None,
@@ -1063,7 +1675,10 @@ def __init__(
axisline_opts: Union[AxisLineOpts, dict, None] = None,
axistick_opts: Union[AxisTickOpts, dict, None] = None,
axislabel_opts: Union[LabelOpts, dict, None] = None,
+ minor_tick_opts: Union[MinorTickOpts, dict, None] = None,
+ minor_split_line_opts: Union[MinorSplitLineOpts, dict, None] = None,
z: Optional[int] = None,
+ z_level: Optional[int] = None,
):
_data = []
if data:
@@ -1088,7 +1703,10 @@ def __init__(
"axisLine": axisline_opts,
"axisTick": axistick_opts,
"axisLabel": axislabel_opts,
+ "minorTick": minor_tick_opts,
+ "minorSplitLine": minor_split_line_opts,
"z": z,
+ "zlevel": z_level,
}
@@ -1100,3 +1718,381 @@ def __init__(
tooltip_opts: TooltipOpts = None,
):
self.opts: dict = {"center": center, "radius": radius, "tooltip": tooltip_opts}
+
+
+class DatasetTransformOpts(BasicOpts):
+ def __init__(
+ self,
+ type_: str = "filter",
+ config: Optional[dict] = None,
+ is_print: bool = False,
+ ):
+ self.opts: dict = {"type": type_, "config": config, "print": is_print}
+
+
+class EmphasisOpts(BasicOpts):
+ def __init__(
+ self,
+ is_disabled: bool = False,
+ is_scale: bool = True,
+ focus: str = "none",
+ blur_scope: str = "coordinateSystem",
+ label_opts: Union[LabelOpts, dict, None] = None,
+ is_show_label_line: bool = False,
+ label_linestyle_opts: Union[LineStyleOpts, dict, None] = None,
+ itemstyle_opts: Union[ItemStyleOpts, dict, None] = None,
+ linestyle_opts: Union[LineStyleOpts, dict, None] = None,
+ areastyle_opts: Union[AreaStyleOpts, dict, None] = None,
+ end_label_opts: Union[LabelOpts, dict, None] = None,
+ ):
+ self.opts: dict = {
+ "disabled": is_disabled,
+ "scale": is_scale,
+ "focus": focus,
+ "blurScope": blur_scope,
+ "label": label_opts,
+ "labelLine": {
+ "show": is_show_label_line,
+ "lineStyle": label_linestyle_opts
+ },
+ "itemStyle": itemstyle_opts,
+ "lineStyle": linestyle_opts,
+ "areaStyle": areastyle_opts,
+ "endLabel": end_label_opts,
+ }
+
+
+class Emphasis3DOpts(BasicOpts):
+ def __init__(
+ self,
+ itemstyle_opts: Union[ItemStyleOpts, dict, None] = None,
+ label_opts: Union[LabelOpts, dict, None] = None,
+ ):
+ self.opts: dict = {
+ "itemStyle": itemstyle_opts,
+ "label": label_opts,
+ }
+
+
+class BlurOpts(BasicOpts):
+ def __init__(
+ self,
+ label_opts: Union[LabelOpts, dict, None] = None,
+ linestyle_opts: Union[LineStyleOpts, dict, None] = None,
+ is_show_label_line: bool = False,
+ label_linestyle_opts: Union[LineStyleOpts, dict, None] = None,
+ itemstyle_opts: Union[ItemStyleOpts, dict, None] = None,
+ ):
+ self.opts: dict = {
+ "label": label_opts,
+ "lineStyle": linestyle_opts,
+ "labelLine": {
+ "show": is_show_label_line,
+ "lineStyle": label_linestyle_opts
+ },
+ "itemStyle": itemstyle_opts,
+ }
+
+
+class SelectOpts(BasicOpts):
+ def __init__(
+ self,
+ is_disabled: Optional[bool] = None,
+ itemstyle_opts: Union[ItemStyleOpts, dict, None] = None,
+ linestyle_opts: Union[LineStyleOpts, dict, None] = None,
+ label_opts: Union[LabelOpts, dict, None] = None,
+ ):
+ self.opts: dict = {
+ "disabled": is_disabled,
+ "itemStyle": itemstyle_opts,
+ "lineStyle": linestyle_opts,
+ "label": label_opts,
+ }
+
+
+class TreeLeavesOpts(BasicOpts):
+ def __init__(
+ self,
+ label_opts: Union[LabelOpts, dict, None] = None,
+ itemstyle_opts: Union[ItemStyleOpts, dict, None] = None,
+ emphasis_opts: Union[EmphasisOpts, dict, None] = None,
+ blur_opts: Union[BlurOpts, dict, None] = None,
+ select_opts: Union[SelectOpts, dict, None] = None,
+ ):
+ self.opts: dict = {
+ "label": label_opts,
+ "itemStyle": itemstyle_opts,
+ "emphasis": emphasis_opts,
+ "blur": blur_opts,
+ "select": select_opts,
+ }
+
+
+class MatrixDividerLineStyleOpts(BasicOpts):
+ def __init__(
+ self,
+ color: Optional[str] = "#aaa",
+ width: Optional[Numeric] = 1,
+ type_: Optional[str] = "solid",
+ dash_offset: Optional[Numeric] = 0,
+ cap: Optional[str] = "butt",
+ join: Optional[str] = "bevel",
+ miter_limit: Optional[Numeric] = 10,
+ shadow_blur: Optional[Numeric] = None,
+ shadow_color: Optional[str] = None,
+ shadow_offset_x: Optional[Numeric] = None,
+ shadow_offset_y: Optional[Numeric] = None,
+ opacity: Optional[Numeric] = 1,
+ ):
+ self.opts: dict = {
+ "color": color,
+ "width": width,
+ "type": type_,
+ "dashOffset": dash_offset,
+ "cap": cap,
+ "join": join,
+ "miterLimit": miter_limit,
+ "shadowBlur": shadow_blur,
+ "shadowColor": shadow_color,
+ "shadowOffsetX": shadow_offset_x,
+ "shadowOffsetY": shadow_offset_y,
+ "opacity": opacity,
+ }
+
+
+class MatrixAxisDataOpts(BasicOpts):
+ def __init__(
+ self,
+ value: Union[Numeric, str] = None,
+ children: Union[dict, JSFunc, None] = None,
+ size: Optional[Numeric] = None,
+ ):
+ self.opts: dict = {
+ "value": value,
+ "children": children,
+ "size": size,
+ }
+
+
+class MatrixAxisOpts(BasicOpts):
+ def __init__(
+ self,
+ is_show: bool = True,
+ data: Union[Sequence, dict, JSFunc, None] = None,
+ label_opts: Union[LabelOpts, dict, None] = None,
+ itemstyle_opts: Union[ItemStyleOpts, dict, None] = None,
+ is_silent: bool = False,
+ cursor: Optional[str] = None,
+ z2: Optional[Numeric] = None,
+ level_size: Union[Numeric, str, None] = None,
+ levels: Optional[Sequence] = None,
+ divider_line_style_opts: Union[
+ MatrixDividerLineStyleOpts, dict, None,
+ ] = None,
+ ):
+ self.opts: dict = {
+ "show": is_show,
+ "data": data,
+ "label": label_opts,
+ "itemStyle": itemstyle_opts,
+ "silent": is_silent,
+ "cursor": cursor,
+ "z2": z2,
+ "levelSize": level_size,
+ "levels": levels,
+ "dividerLineStyle": divider_line_style_opts,
+ }
+
+
+class MatrixBodyDataOpts(BasicOpts):
+ def __init__(
+ self,
+ coord: Optional[Sequence] = None,
+ is_coord_clamp: Optional[bool] = None,
+ is_merge_cells: Optional[bool] = None,
+ value: Union[Numeric, str, None] = None,
+ label_opts: Union[LabelOpts, dict, None] = None,
+ ):
+ self.opts: dict = {
+ "coord": coord,
+ "coordClamp": is_coord_clamp,
+ "mergeCells": is_merge_cells,
+ "value": value,
+ "label": label_opts,
+ }
+
+
+class MatrixBodyOrCornerOpts(BasicOpts):
+ def __init__(
+ self,
+ data: Union[Sequence[MatrixBodyDataOpts], dict, None] = None,
+ label_opts: Union[LabelOpts, dict, None] = None,
+ itemstyle_opts: Union[ItemStyleOpts, dict, None] = None,
+ is_silent: bool = False,
+ cursor: Optional[str] = None,
+ z2: Optional[Numeric] = None,
+ ):
+ self.opts: dict = {
+ "data": data,
+ "label": label_opts,
+ "itemStyle": itemstyle_opts,
+ "silent": is_silent,
+ "cursor": cursor,
+ "z2": z2,
+ }
+
+
+class MatrixBackgroundStyleOpts(BasicOpts):
+ def __init__(
+ self,
+ color: Optional[str] = None,
+ border_color: str = "#ccc",
+ border_width: Numeric = 1,
+ border_type: str = "solid",
+ border_radius: Union[Numeric, Sequence] = 0,
+ border_cap: str = "butt",
+ border_join: str = "bevel",
+ border_miter_limit: Optional[Numeric] = 10,
+ shadow_blur: Optional[Numeric] = None,
+ shadow_color: Optional[str] = None,
+ shadow_offset_x: Numeric = 0,
+ shadow_offset_y: Numeric = 0,
+ opacity: Optional[Numeric] = 1,
+ ):
+ self.opts: dict = {
+ "color": color,
+ "borderColor": border_color,
+ "borderWidth": border_width,
+ "borderType": border_type,
+ "borderRadius": border_radius,
+ "borderCap": border_cap,
+ "borderJoin": border_join,
+ "borderMiterLimit": border_miter_limit,
+ "shadowBlur": shadow_blur,
+ "shadowColor": shadow_color,
+ "shadowOffsetX": shadow_offset_x,
+ "shadowOffsetY": shadow_offset_y,
+ "opacity": opacity,
+ }
+
+
+class MatrixOpts(BasicOpts):
+ def __init__(
+ self,
+ z_level: Numeric = 0,
+ z: Numeric = 2,
+ pos_left: Union[Numeric, str, None] = None,
+ pos_top: Union[Numeric, str, None] = None,
+ pos_right: Union[Numeric, str, None] = None,
+ pos_bottom: Union[Numeric, str, None] = None,
+ width: Union[Numeric, str, None] = None,
+ height: Union[Numeric, str, None] = None,
+ x_data: Union[MatrixAxisOpts, dict, None] = None,
+ y_data: Union[MatrixAxisOpts, dict, None] = None,
+ body_opts: Union[MatrixBodyOrCornerOpts, dict, None] = None,
+ corner_opts: Union[MatrixBodyOrCornerOpts, dict, None] = None,
+ background_style: Union[MatrixBackgroundStyleOpts, dict, None] = None,
+ border_z2: Optional[Numeric] = None,
+ tooltip_opts: TooltipOpts = None,
+ ):
+ self.opts: dict = {
+ "zlevel": z_level,
+ "z": z,
+ "left": pos_left,
+ "top": pos_top,
+ "right": pos_right,
+ "bottom": pos_bottom,
+ "width": width,
+ "height": height,
+ "x": x_data,
+ "y": y_data,
+ "body": body_opts,
+ "corner": corner_opts,
+ "backgroundStyle": background_style,
+ "borderZ2": border_z2,
+ "tooltip": tooltip_opts,
+ }
+
+
+class ThumbnailWindowStyleOpts(BasicOpts):
+ def __init__(
+ self,
+ color: Optional[str] = "#9ea0a5",
+ border_color: str = "#b7b9be",
+ border_width: Numeric = 1,
+ border_type: str = "solid",
+ border_dash_offset: Numeric = 0,
+ border_cap: str = "butt",
+ border_join: str = "bevel",
+ border_miter_limit: Optional[Numeric] = 10,
+ shadow_blur: Optional[Numeric] = None,
+ shadow_color: Optional[str] = None,
+ shadow_offset_x: Numeric = 0,
+ shadow_offset_y: Numeric = 0,
+ opacity: Optional[Numeric] = 0.3,
+ ):
+ self.opts: dict = {
+ "color": color,
+ "borderColor": border_color,
+ "borderWidth": border_width,
+ "borderType": border_type,
+ "borderDashOffset": border_dash_offset,
+ "borderCap": border_cap,
+ "borderJoin": border_join,
+ "borderMiterLimit": border_miter_limit,
+ "shadowBlur": shadow_blur,
+ "shadowColor": shadow_color,
+ "shadowOffsetX": shadow_offset_x,
+ "shadowOffsetY": shadow_offset_y,
+ "opacity": opacity,
+ }
+
+
+class ThumbnailOpts(BasicOpts):
+ def __init__(
+ self,
+ is_show: bool = True,
+ z_level: Numeric = 0,
+ z: Numeric = 2,
+ pos_left: Union[Numeric, str, None] = None,
+ pos_top: Union[Numeric, str, None] = None,
+ pos_right: Union[Numeric, str, None] = None,
+ pos_bottom: Union[Numeric, str, None] = None,
+ width: Union[Numeric, str, None] = None,
+ height: Union[Numeric, str, None] = None,
+ coordinate_system: Optional[str] = None,
+ coordinate_system_usage: Optional[str] = None,
+ coord: Optional[Union[Sequence, Numeric, str]] = None,
+ calendar_index: Optional[Numeric] = None,
+ calendar_id: Optional[Numeric] = None,
+ matrix_index: Optional[Numeric] = None,
+ matrix_id: Optional[Numeric] = None,
+ itemstyle_opts: Union[ItemStyleOpts, dict, None] = None,
+ window_style_opts: Union[
+ ThumbnailWindowStyleOpts, dict, None,
+ ] = None,
+ series_index: Optional[Numeric] = None,
+ series_id: Union[Numeric, str, None] = None,
+ ):
+ self.opts: dict = {
+ "show": is_show,
+ "zlevel": z_level,
+ "z": z,
+ "left": pos_left,
+ "top": pos_top,
+ "right": pos_right,
+ "bottom": pos_bottom,
+ "width": width,
+ "height": height,
+ "coordinateSystem": coordinate_system,
+ "coordinateSystemUsage": coordinate_system_usage,
+ "coord": coord,
+ "calendarIndex": calendar_index,
+ "calendarId": calendar_id,
+ "matrixIndex": matrix_index,
+ "matrixId": matrix_id,
+ "itemStyle": itemstyle_opts,
+ "windowStyle": window_style_opts,
+ "seriesIndex": series_index,
+ "seriesId": series_id,
+ }
diff --git a/pyecharts/options/series_options.py b/pyecharts/options/series_options.py
index b6c5b6e5c..7e59a436f 100644
--- a/pyecharts/options/series_options.py
+++ b/pyecharts/options/series_options.py
@@ -16,6 +16,30 @@ def get(self, key: str) -> Any:
return self.opts.get(key)
+class AnimationOpts(BasicOpts):
+ def __init__(
+ self,
+ animation: bool = True,
+ animation_threshold: Numeric = 2000,
+ animation_duration: Union[Numeric, JSFunc] = 1000,
+ animation_easing: Union[str] = "cubicOut",
+ animation_delay: Union[Numeric, JSFunc] = 0,
+ animation_duration_update: Union[Numeric, JSFunc] = 300,
+ animation_easing_update: Union[str] = "cubicOut",
+ animation_delay_update: Union[Numeric, JSFunc] = 0,
+ ):
+ self.opts: dict = {
+ "animation": animation,
+ "animationThreshold": animation_threshold,
+ "animationDuration": animation_duration,
+ "animationEasing": animation_easing,
+ "animationDelay": animation_delay,
+ "animationDurationUpdate": animation_duration_update,
+ "animationEasingUpdate": animation_easing_update,
+ "animationDelayUpdate": animation_delay_update,
+ }
+
+
class ItemStyleOpts(BasicOpts):
def __init__(
self,
@@ -25,6 +49,7 @@ def __init__(
border_color0: Optional[str] = None,
border_width: Optional[Numeric] = None,
border_type: Optional[str] = None,
+ border_radius: Optional[Numeric] = None,
opacity: Optional[Numeric] = None,
area_color: Optional[str] = None,
):
@@ -35,6 +60,7 @@ def __init__(
"borderColor0": border_color0,
"borderWidth": border_width,
"borderType": border_type,
+ "borderRadius": border_radius,
"opacity": opacity,
"areaColor": area_color,
}
@@ -61,6 +87,7 @@ def __init__(
width: Optional[str] = None,
height: Optional[str] = None,
rich: Optional[dict] = None,
+ is_rich_inherit_plain_label: bool = True,
):
self.opts: dict = {
"color": color,
@@ -81,6 +108,7 @@ def __init__(
"width": width,
"height": height,
"rich": rich,
+ "richInheritPlainLabel": is_rich_inherit_plain_label,
}
@@ -88,15 +116,19 @@ class LabelOpts(BasicOpts):
def __init__(
self,
is_show: bool = True,
- position: Union[str, Sequence] = "top",
+ position: Optional[Union[str, Sequence]] = None,
color: Optional[str] = None,
+ opacity: Optional[Numeric] = None,
distance: Union[Numeric, Sequence, None] = None,
font_size: Optional[Numeric] = None,
font_style: Optional[str] = None,
font_weight: Optional[str] = None,
font_family: Optional[str] = None,
rotate: Optional[Numeric] = None,
+ offset: Optional[Sequence[Numeric]] = None,
margin: Optional[Numeric] = 8,
+ text_margin: Union[Numeric, Sequence, None] = None,
+ min_margin: Optional[Numeric] = None,
interval: Union[Numeric, str, None] = None,
horizontal_align: Optional[str] = None,
vertical_align: Optional[str] = None,
@@ -105,15 +137,32 @@ def __init__(
border_color: Optional[str] = None,
border_width: Optional[Numeric] = None,
border_radius: Optional[Numeric] = None,
+ padding: Union[Numeric, Sequence[Numeric], None] = None,
+ text_width: Optional[Numeric] = None,
+ text_height: Optional[Numeric] = None,
+ text_border_color: Optional[str] = None,
+ text_border_width: Optional[Numeric] = None,
+ text_shadow_color: Optional[str] = None,
+ text_shadow_blur: Optional[Numeric] = None,
+ text_shadow_offset_x: Optional[Numeric] = None,
+ text_shadow_offset_y: Optional[Numeric] = None,
+ overflow: Optional[str] = None,
rich: Optional[dict] = None,
+ is_rich_inherit_plain_label: bool = True,
+ is_value_animation: bool = False,
+ text_style_opts: Optional[TextStyleOpts] = None,
):
self.opts: dict = {
"show": is_show,
"position": position,
"color": color,
+ "opacity": opacity,
"distance": distance,
"rotate": rotate,
+ "offset": offset,
"margin": margin,
+ "textMargin": text_margin,
+ "minMargin": min_margin,
"interval": interval,
"fontSize": font_size,
"fontStyle": font_style,
@@ -126,18 +175,31 @@ def __init__(
"borderColor": border_color,
"borderWidth": border_width,
"borderRadius": border_radius,
+ "padding": padding,
+ "width": text_width,
+ "height": text_height,
+ "textBorderColor": text_border_color,
+ "textBorderWidth": text_border_width,
+ "textShadowColor": text_shadow_color,
+ "textShadowBlur": text_shadow_blur,
+ "textShadowOffsetX": text_shadow_offset_x,
+ "textShadowOffsetY": text_shadow_offset_y,
+ "overflow": overflow,
"rich": rich,
+ "richInheritPlainLabel": is_rich_inherit_plain_label,
+ "valueAnimation": is_value_animation,
+ "textStyle": text_style_opts,
}
class LineStyleOpts(BasicOpts):
def __init__(
self,
- is_show: bool = True,
- width: Numeric = 1,
- opacity: Numeric = 1,
- curve: Numeric = 0,
- type_: str = "solid",
+ is_show: bool = False,
+ width: Optional[Numeric] = None,
+ opacity: Optional[Numeric] = None,
+ curve: Optional[Numeric] = None,
+ type_: Optional[str] = None,
color: Union[str, Sequence, None] = None,
):
self.opts: dict = {
@@ -170,7 +232,11 @@ def __init__(
value: Optional[Numeric] = None,
symbol: Optional[str] = None,
symbol_size: Union[Numeric, Sequence, None] = None,
+ symbol_rotate: Optional[Numeric] = None,
+ symbol_keep_aspect: bool = None,
+ symbol_offset: Optional[Sequence] = None,
itemstyle_opts: Union[ItemStyleOpts, dict, None] = None,
+ label_opts: Optional[LabelOpts] = None,
):
self.opts: dict = {
"name": name,
@@ -183,7 +249,11 @@ def __init__(
"value": value,
"symbol": symbol,
"symbolSize": symbol_size,
+ "symbolRotate": symbol_rotate,
+ "symbolKeepAspect": symbol_keep_aspect,
+ "symbolOffset": symbol_offset,
"itemStyle": itemstyle_opts,
+ "label": label_opts,
}
@@ -193,15 +263,29 @@ def __init__(
data: Sequence[Union[MarkPointItem, dict]] = None,
symbol: Optional[str] = None,
symbol_size: Union[None, Numeric] = None,
- label_opts: LabelOpts = LabelOpts(position="inside", color="#fff"),
+ symbol_rotate: Optional[Numeric] = None,
+ symbol_keep_aspect: bool = None,
+ symbol_offset: Optional[Sequence] = None,
+ silent: bool = None,
+ label_opts: Optional[LabelOpts] = None,
+ itemstyle_opts: Union[ItemStyleOpts, dict, None] = None,
+ animation_opts: Union[AnimationOpts, dict, None] = None,
):
self.opts: dict = {
"symbol": symbol,
"symbolSize": symbol_size,
+ "symbolRotate": symbol_rotate,
+ "symbolKeepAspect": symbol_keep_aspect,
+ "symbolOffset": symbol_offset,
+ "silent": silent,
"label": label_opts,
+ "itemStyle": itemstyle_opts,
"data": data,
}
+ if animation_opts:
+ self.opts.update(**animation_opts.opts)
+
class MarkLineItem(BasicOpts):
def __init__(
@@ -215,6 +299,7 @@ def __init__(
value_index: Optional[Numeric] = None,
value_dim: Optional[str] = None,
coord: Optional[Sequence] = None,
+ linestyle_opts: Union[LineStyleOpts, dict, None] = None,
symbol: Optional[str] = None,
symbol_size: Optional[Numeric] = None,
):
@@ -227,6 +312,7 @@ def __init__(
"x": xcoord,
"yAxis": y,
"y": ycoord,
+ "lineStyle": linestyle_opts,
"coord": coord,
"symbol": symbol,
"symbolSize": symbol_size,
@@ -243,6 +329,7 @@ def __init__(
precision: int = 2,
label_opts: LabelOpts = LabelOpts(),
linestyle_opts: Union[LineStyleOpts, dict, None] = None,
+ animation_opts: Union[AnimationOpts, dict, None] = None,
):
self.opts: dict = {
"silent": is_silent,
@@ -254,6 +341,9 @@ def __init__(
"data": data,
}
+ if animation_opts:
+ self.opts.update(**animation_opts.opts)
+
class MarkAreaItem(BasicOpts):
def __init__(
@@ -295,6 +385,7 @@ def __init__(
label_opts: LabelOpts = LabelOpts(),
data: Sequence[Union[MarkAreaItem, Sequence, dict]] = None,
itemstyle_opts: ItemStyleOpts = None,
+ animation_opts: Union[AnimationOpts, dict, None] = None,
):
self.opts: dict = {
"silent": is_silent,
@@ -303,6 +394,9 @@ def __init__(
"itemStyle": itemstyle_opts,
}
+ if animation_opts:
+ self.opts.update(**animation_opts.opts)
+
class EffectOpts(BasicOpts):
def __init__(
@@ -351,8 +445,23 @@ def __init__(
class AreaStyleOpts(BasicOpts):
- def __init__(self, opacity: Optional[Numeric] = 0, color: Optional[str] = None):
- self.opts: dict = {"opacity": opacity, "color": color}
+ def __init__(
+ self,
+ opacity: Optional[Numeric] = 0,
+ color: Optional[JSFunc] = None,
+ shadow_blur: Optional[Numeric] = None,
+ shadow_color: Optional[str] = None,
+ shadow_offset_x: Optional[Numeric] = None,
+ shadow_offset_y: Optional[Numeric] = None,
+ ):
+ self.opts: dict = {
+ "opacity": opacity,
+ "color": color,
+ "shadowBlur": shadow_blur,
+ "shadowColor": shadow_color,
+ "shadowOffsetX": shadow_offset_x,
+ "shadowOffsetY": shadow_offset_y,
+ }
class SplitAreaOpts(BasicOpts):
@@ -416,3 +525,37 @@ def __init__(
"opacity": opacity,
"lineStyle": linestyle_opts,
}
+
+
+class GraphGLForceAtlas2Opts(BasicOpts):
+ def __init__(
+ self,
+ is_gpu: bool = True,
+ steps: Numeric = 1,
+ stop_threshold: Numeric = 1,
+ is_barnes_hut_optimize: Optional[bool] = None,
+ is_repulsion_by_degree: bool = True,
+ is_lin_log_mode: bool = False,
+ gravity: Numeric = 1,
+ gravity_center: Optional[Sequence] = None,
+ scaling: Optional[Numeric] = None,
+ edge_weight_influence: Numeric = 1,
+ edge_weight: Union[Sequence, Numeric] = None,
+ node_weight: Union[Sequence, Numeric] = None,
+ is_prevent_overlap: bool = False,
+ ):
+ self.opts: dict = {
+ "GPU": is_gpu,
+ "steps": steps,
+ "stopThreshold": stop_threshold,
+ "barnesHutOptimize": is_barnes_hut_optimize,
+ "repulsionByDegree": is_repulsion_by_degree,
+ "linLogMode": is_lin_log_mode,
+ "gravity": gravity,
+ "gravityCenter": gravity_center,
+ "scaling": scaling,
+ "edgeWeightInfluence": edge_weight_influence,
+ "edgeWeight": edge_weight,
+ "nodeWeight": node_weight,
+ "preventOverlap": is_prevent_overlap,
+ }
diff --git a/pyecharts/render/display.py b/pyecharts/render/display.py
index f419adef8..78c93e2a0 100644
--- a/pyecharts/render/display.py
+++ b/pyecharts/render/display.py
@@ -1,4 +1,6 @@
from ..types import Optional, Sequence, Union
+from urllib.parse import urlparse
+import http.client
class HTML:
@@ -50,6 +52,7 @@ def __init__(
self.lib = lib
self.css = css
self.data = data or ""
+ self.javascript_contents = dict()
def _repr_javascript_(self):
r = ""
@@ -60,3 +63,24 @@ def _repr_javascript_(self):
r += self.data
r += _lib_t2 * len(self.lib)
return r
+
+ def load_javascript_contents(self):
+ for lib in self.lib:
+ parsed_url = urlparse(lib)
+
+ host: str = str(parsed_url.hostname)
+ port: int = parsed_url.port
+ path: str = parsed_url.path
+
+ resp: Optional[http.client.HTTPResponse] = None
+ try:
+ conn = http.client.HTTPSConnection(host, port)
+ conn.request("GET", path)
+ resp = conn.getresponse()
+ if resp.status != 200:
+ raise RuntimeError("Cannot load JavaScript lib: %s" % lib)
+ self.javascript_contents[lib] = resp.read().decode("utf-8")
+ finally:
+ if resp is not None:
+ resp.close()
+ return self
diff --git a/pyecharts/render/engine.py b/pyecharts/render/engine.py
index 8a267cd9f..715286376 100644
--- a/pyecharts/render/engine.py
+++ b/pyecharts/render/engine.py
@@ -1,17 +1,24 @@
import os
-from collections import Iterable
+
+try:
+ from collections.abc import Iterable
+except ImportError:
+ from collections import Iterable
from jinja2 import Environment
from ..commons import utils
from ..datasets import EXTRA, FILENAMES
-from ..globals import CurrentConfig, NotebookType
+from ..globals import CurrentConfig, NotebookType, RenderSepType
from ..types import Any, Optional
from .display import HTML, Javascript
def write_utf8_html_file(file_name: str, html_content: str):
- with open(file_name, "w+", encoding="utf-8") as html_file:
+ with open(file=file_name,
+ mode="w+",
+ encoding="utf-8",
+ newline=RenderSepType.SepType) as html_file:
html_file.write(html_content)
@@ -24,20 +31,37 @@ def generate_js_link(chart: Any) -> Any:
if not chart.js_host:
chart.js_host = CurrentConfig.ONLINE_HOST
links = []
+ css_links = []
for dep in chart.js_dependencies.items:
# TODO: if?
if dep.startswith("https://api.map.baidu.com"):
links.append(dep)
+ if dep.startswith("https://webapi.amap.com"):
+ links.append(dep)
+ if dep.startswith("https://maps.googleapis.com"):
+ links.append(dep)
if dep in FILENAMES:
f, ext = FILENAMES[dep]
- links.append("{}{}.{}".format(chart.js_host, f, ext))
+ _link = "{}{}.{}".format(chart.js_host, f, ext)
+ if ext == "css":
+ css_links.append(_link)
+ else:
+ links.append(_link)
else:
for url, files in EXTRA.items():
if dep in files:
f, ext = files[dep]
- links.append("{}{}.{}".format(url, f, ext))
+ _link = "{}{}.{}".format(url, f, ext)
+ if ext == "css":
+ css_links.append(_link)
+ else:
+ links.append(_link)
break
chart.dependencies = links
+ if hasattr(chart, "css_libs"):
+ chart.css_libs = chart.css_libs + css_links
+ else:
+ chart.css_libs = css_links
return chart
def render_chart_to_file(self, template_name: str, chart: Any, path: str, **kwargs):
diff --git a/pyecharts/render/snapshot.py b/pyecharts/render/snapshot.py
index dbe49427a..62e40f3a4 100644
--- a/pyecharts/render/snapshot.py
+++ b/pyecharts/render/snapshot.py
@@ -91,7 +91,9 @@ def save_as(image_data: bytes, output_name: str, file_type: str):
m.load()
color = (255, 255, 255)
b = Image.new("RGB", m.size, color)
- b.paste(m, mask=m.split()[3])
+ # BUG for Mac:
+ # b.paste(m, mask=m.split()[3])
+ b.paste(m)
b.save(output_name, file_type, quality=100)
except ModuleNotFoundError:
raise Exception(f"Please install PIL for {file_type} image type")
diff --git a/pyecharts/render/templates/macro b/pyecharts/render/templates/macro
index 691d1ed64..71c203b23 100644
--- a/pyecharts/render/templates/macro
+++ b/pyecharts/render/templates/macro
@@ -1,19 +1,86 @@
{%- macro render_chart_content(c) -%}
-
+
+ {% if c._geo_json_name and c._geo_json %}
+ {% endif %}
+
{%- endmacro %}
@@ -30,15 +102,57 @@
{% for c in charts %}
{% if c._component_type not in ("table", "image") %}
var chart_{{ c.chart_id }} = echarts.init(
- document.getElementById('{{ c.chart_id }}'), '{{ c.theme }}', {renderer: '{{ c.renderer }}'});
+ document.getElementById('{{ c.chart_id }}'), '{{ c.theme }}', {renderer: '{{ c.renderer }}', locale: '{{ c.locale }}'});
{% for js in c.js_functions.items %}
{{ js }}
{% endfor %}
var option_{{ c.chart_id }} = {{ c.json_contents }};
chart_{{ c.chart_id }}.setOption(option_{{ c.chart_id }});
{% if c._is_geo_chart %}
- var bmap = chart_{{ c.chart_id }}.getModel().getComponent('bmap').getBMap();
- bmap.addControl(new BMap.MapTypeControl());
+ {% if c._coordinate_system == 'bmap' %}
+ var bmap = chart_{{ c.chart_id }}.getModel().getComponent('bmap').getBMap();
+ {% if c.bmap_js_functions %}
+ {% for fn in c.bmap_js_functions.items %}
+ {{ fn }}
+ {% endfor %}
+ {% endif %}
+ {% elif c._coordinate_system == 'amap' %}
+ // Get AMap extension component
+ var amapComponent = chart_{{ c.chart_id }}.getModel().getComponent('amap');
+ // Get the instance of AMap
+ var amap = amapComponent.getAMap();
+ // Add some controls provided by AMap.
+ amap.addControl(new AMap.Scale());
+ amap.addControl(new AMap.ToolBar());
+ {% if c.amap_js_functions %}
+ {% for fn in c.amap_js_functions.items %}
+ {{ fn }}
+ {% endfor %}
+ {% endif %}
+ {% elif c._coordinate_system == 'lmap' %}
+ var lmapComponent = chart_{{ c.chart_id }}.getModel().getComponent('lmap');
+ var lmap = lmapComponent.getLeaflet();
+ L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
+ attribution: '© OpenStreetMap contributors'
+ }).addTo(lmap);
+ {% elif c._coordinate_system == 'gmap' %}
+ // Get the instance of Google Map
+ var gmap = chart_{{ c.chart_id }}.getModel().getComponent('gmap').getGoogleMap();
+ // Add some markers to map
+ var marker = new google.maps.Marker({ position: gmap.getCenter() });
+ marker.setMap(gmap);
+ // Add TrafficLayer to map
+ {% if c.gmap_js_functions %}
+ {% for fn in c.gmap_js_functions.items %}
+ {{ fn }}
+ {% endfor %}
+ {% endif %}
+ {% endif %}
+ {% endif %}
+ {% if c.js_events %}
+ {% for fn in c.js_events.items %}
+ {{ fn }}
+ {% endfor %}
{% endif %}
{% endif %}
{% endfor %}
@@ -47,14 +161,23 @@
{%- endmacro %}
{%- macro render_chart_dependencies(c) -%}
- {% for dep in c.dependencies %}
-
- {% endfor %}
+ {% if 'embed_js' in c.render_options and 'javascript' in c._render_cache and c.render_options.embed_js -%}
+ {% set _javascript = c._render_cache.javascript %}
+ {% for dep in c.dependencies %}
+
+ {% endfor %}
+ {%- else -%}
+ {% for dep in c.dependencies %}
+
+ {% endfor %}
+ {%- endif %}
{%- endmacro %}
{%- macro render_chart_css(c) -%}
{% for dep in c.css_libs %}
-
+
{% endfor %}
{%- endmacro %}
@@ -119,9 +242,11 @@
}
.chart-container {
+ display: block;
+ }
+
+ .chart-container:nth-child(n+2) {
display: none;
- padding: 6px 12px;
- border-top: none;
}
{%- endmacro %}
diff --git a/pyecharts/render/templates/nb_jupyter_globe.html b/pyecharts/render/templates/nb_jupyter_globe.html
index e9b4d442a..88c3a0c2e 100644
--- a/pyecharts/render/templates/nb_jupyter_globe.html
+++ b/pyecharts/render/templates/nb_jupyter_globe.html
@@ -20,7 +20,7 @@
var mapOption_{{ c.chart_id }} = {{ c.json_contents }};
mapChart_{{ c.chart_id }}.setOption(mapOption_{{ c.chart_id }});
var chart_{{ c.chart_id }} = echarts.init(
- document.getElementById('{{ c.chart_id }}'), '{{ c.theme }}', {renderer: '{{ c.renderer }}'});
+ document.getElementById('{{ c.chart_id }}'), '{{ c.theme }}', {renderer: '{{ c.renderer }}', locale: '{{ c.locale }}'});
{% for js in c.js_functions.items %}
{{ js }}
{% endfor %}
diff --git a/pyecharts/render/templates/nb_nteract.html b/pyecharts/render/templates/nb_nteract.html
index c975bcf8b..c9739b387 100644
--- a/pyecharts/render/templates/nb_nteract.html
+++ b/pyecharts/render/templates/nb_nteract.html
@@ -3,7 +3,7 @@