当前pyecharts
的版本为1.9.0。
charts
包结构
charts
包位于pyecharts
包顶级目录中,用于定义图表类。charts
包的结构如下:
│
├─charts # 图表类包
│ │ base.py # 定义了图表基类Base
│ │ chart.py # 基于base类定义了基本图表基类Chart、直角坐标系图表RectChart、3D图表基类Chart3D、
│ │ mixins.py # 定义多重继承基类ChartMixin、CompositeMixin
│ │ __init__.py # 重构命名空间,将子包中具体图表类提升至charts包命名空间。
│ │
│ ├─basic_charts # 定义基本图表类
│ │ │ bar.py
│ │ │ bmap.py
│ │ │ boxplot.py
│ │ │ calendar.py
│ │ │ effectscatter.py
│ │ │ funnel.py
│ │ │ gauge.py
│ │ │ geo.py
│ │ │ graph.py
│ │ │ heatmap.py
│ │ │ kline.py
│ │ │ line.py
│ │ │ liquid.py
│ │ │ map.py
│ │ │ parallel.py
│ │ │ pictorialbar.py
│ │ │ pie.py
│ │ │ polar.py
│ │ │ radar.py
│ │ │ sankey.py
│ │ │ scatter.py
│ │ │ sunburst.py
│ │ │ themeriver.py
│ │ │ tree.py
│ │ │ treemap.py
│ │ │ wordcloud.py
│ │ │ __init__.py
│ │
│ ├─composite_charts # 定义复合图表类
│ │ │ grid.py
│ │ │ page.py
│ │ │ tab.py
│ │ │ timeline.py
│ │ │ __init__.py
│ │
│ ├─three_axis_charts # 定义3D图表类
│ │ │ bar3D.py
│ │ │ line3D.py
│ │ │ map3D.py
│ │ │ map_globe.py
│ │ │ scatter3D.py
│ │ │ surface3D.py
│ │ │ __init__.py
pyecharts
图表类的继承关系
pyecharts/charts/mixins.py
模块
pyecharts/charts/mixins.py
模块定义了ChartMixin
类和CompositeMixin
类。
ChartMixin
类为所有与图表类的基类,为图表提供JavaScript支持。
CompositeMixin(ChartMixin)
类用于为复合图表类提供可迭代对象支持和实例长度支持。
pyecharts/charts/mixins.py
模块源码:
from ..render import engine
class ChartMixin:
def add_js_funcs(self, *fns):
for fn in fns:
self.js_functions.add(fn)
return self
def load_javascript(self):
return engine.load_javascript(self)
class CompositeMixin(ChartMixin):
def __iter__(self):
for chart in self._charts:
yield chart
def __len__(self):
return len(self._charts)
pyecharts/charts/base.py
模块
pyecharts/charts/base.py
模块的结构如下:
Base
类:绝大多数图表类的基类。default函数
:json.dumps
函数实参,用于定义特殊对象类型的序列化方式。
Base
类
Base
类的签名为class Base(init_opts)
,Base
类的属性、方法如下:
属性:主要通过参数全局配置项init_opts.opts
构造。
width
:echarts
实例宽度。通过init_opts
参数获取。height
:echarts
实例宽度。通过init_opts
参数获取。renderer
:echarts
实例渲染类型。通过init_opts
参数获取。page_title
:输出页面的标题。字符串。通过init_opts
参数获取,默认值为全局变量CurrentConfig.PAGE_TITLE
。chart_id
:echarts
实例id。通过init_opts
参数或全局变量uuid.uuid4().hex
获取。options
:echarts
配置项。类型为字典,默认值为{}
。theme
:图表主题。通过init_opts
参数获取,默认值为全局变量ThemeType.WHITE
。js_host
:JavaScript库的URL。通过init_opts
参数或全局变量CurrentConfig.ONLINE_HOST
获取。js_functions
:自定义JavaScript语句。类型为OrderedSet
对象。默认值为OrderedSet()
。js_dependencies
:定义JavaScript依赖库。类型为OrderedSet
对象。默认值为OrderedSet("echarts")
。_is_geo_chart
:是否为地理图。布尔值,默认为False
。json_contents
:按照JSON格式处理的options
属性(echarts
配置项)。为渲染模板提供配置项数据。
方法:
get_options
:去除options
属性字典中值为None
的元素,获取全局配置。dump_options
:将经过get_options
方法处理过的echarts
配置项序列化为JSON格式(JsCode 生成的函数不带引号)。dump_options_with_quotes
:功能与dump_options
类似,差异仅在于配置项中的JavaScript占位符处理方式(JsCode 生成的函数带引号,在前后端分离传输数据时使用)。_use_theme
:根据选用主题,添加主题的依赖库。_prepare_render
:根据dump_options
方法生成json_contents
属性。为渲染模板提供配置项数据。render
:调用render
包engine
模块中的render
函数渲染HTML文档。render_embed
:调用render
包engine
模块中的render_embed
函数输出HTML字符串。render_notebook
:调用render
包engine
模块中的render_notebook
函数将输出嵌入到notebook中。
对于Base
类属性的理解要结合模板和模板宏。在下列宏中可以简单说明图表类属性的应用。
{%- macro render_chart_content(c) -%}
<div id="{{ c.chart_id }}" class="chart-container" style="width:{{ c.width }}; height:{{ c.height }};"></div>
<script>
var chart_{{ c.chart_id }} = echarts.init(
document.getElementById('{{ c.chart_id }}'), '{{ c.theme }}', {renderer: '{{ c.renderer }}'});
{% 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();
{% if c.bmap_js_functions %}
{% for fn in c.bmap_js_functions.items %}
{{ fn }}
{% endfor %}
{% endif %}
{% endif %}
{% if c.width.endswith('%') %}
window.addEventListener('resize', function(){
chart_{{ c.chart_id }}.resize();
})
{% endif %}
</script>
{%- endmacro %}
pyecharts/charts/base.py
模块源码
class Base(ChartMixin):
"""
`Base` is the root class for all graphical class, it provides
part of the initialization parameters and common methods
"""
def __init__(self, init_opts: Union[InitOpts, dict] = InitOpts()):
_opts = init_opts
if isinstance(init_opts, InitOpts):
_opts = init_opts.opts
self.width = _opts.get("width", "900px")
self.height = _opts.get("height", "500px")
self.renderer = _opts.get("renderer", RenderType.CANVAS)
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.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._is_geo_chart: bool = False
def get_options(self) -> dict:
return utils.remove_key_with_none_value(self.options)
def dump_options(self) -> str:
return utils.replace_placeholder(
json.dumps(self.get_options(), indent=4, default=default, ignore_nan=True)
)
def dump_options_with_quotes(self) -> str:
return utils.replace_placeholder_with_quotes(
json.dumps(self.get_options(), indent=4, default=default, ignore_nan=True)
)
def render(
self,
path: str = "render.html",
template_name: str = "simple_chart.html",
env: Optional[Environment] = None,
**kwargs,
) -> str:
self._prepare_render()
return engine.render(self, path, template_name, env, **kwargs)
def render_embed(
self,
template_name: str = "simple_chart.html",
env: Optional[Environment] = None,
**kwargs,
) -> str:
self._prepare_render()
return engine.render_embed(self, template_name, env, **kwargs)
def render_notebook(self):
self.chart_id = uuid.uuid4().hex
self._prepare_render()
return engine.render_notebook(
self, "nb_jupyter_notebook.html", "nb_jupyter_lab.html"
)
def _use_theme(self):
if self.theme not in ThemeType.BUILTIN_THEMES:
self.js_dependencies.add(self.theme)
def _prepare_render(self):
self.json_contents = self.dump_options()
self._use_theme()
def default(o):
if isinstance(o, (datetime.date, datetime.datetime)):
return o.isoformat()
if isinstance(o, utils.JsCode):
return (
o.replace("\\n|\\t", "").replace(r"\\n", "\n").replace(r"\\t", "\t").js_code
)
if isinstance(o, BasicOpts):
if isinstance(o.opts, Sequence):
return [utils.remove_key_with_none_value(item) for item in o.opts]
else:
return utils.remove_key_with_none_value(o.opts)