当前pyecharts
版本为1.9.0
概述
render
包结构
render
包位于pyecharts
包顶级目录中,用于渲染图表。render
包结构如下:
├─render # 渲染设置包
│ │ display.py # 定义HTML、JavaScript显示类,用于支持在notebook中嵌入输出结果
│ │ engine.py # 定义渲染相关类、函数
│ │ snapshot.py # 定义渲染图片函数
│ │ __init__.py # 暴露渲染图片函数
│ │
│ ├─templates # 定义渲染模板
│ │ components.html
│ │ macro
│ │ nb_components.html
│ │ nb_jupyter_globe.html
│ │ nb_jupyter_lab.html
│ │ nb_jupyter_lab_tab.html
│ │ nb_jupyter_notebook.html
│ │ nb_jupyter_notebook_tab.html
│ │ nb_nteract.html
│ │ simple_chart.html
│ │ simple_globe.html
│ │ simple_page.html
│ │ simple_tab.html
engine
模块
engine
模块,路径为pyecharts/render/engine.py
,作用为提供渲染接口(HTML和notebook)。
engine
模块的结构如下图所示。
write_utf8_html_file(file_name: str, html_content: str)
函数:根据HTML字符串生成HTML文件。RenderEngine(env: Optional[Environment] = None)
类:根据jinja2
的环境变量提供渲染抽象接口。render(chart, path: str, template_name: str, env: Optional[Environment], **kwargs) -> str
函数:封装RenderEngine(env: Optional[Environment] = None)
类render_chart_to_file
方法输出HTML文件。返回值为输出的HTML文件的路径。render_embed(chart, template_name: str, env: Optional[Environment], **kwargs) -> str
函数:封装RenderEngine(env: Optional[Environment] = None)
类render_chart_to_template
方法输出HTML字符串。返回值为字符串。render_notebook(self, notebook_template, lab_template)
函数:将图表嵌入到notebook中,针对不同notebook类型提供不同输出方式。notebook和jupyter lab封装RenderEngine(env: Optional[Environment] = None)
类render_chart_to_notebook
方法实现。返回值为pyecharts.render.display.HTML
类对象。load_javascript(chart)
函数:为jupyter lab提供JavaScript支持,根据chart
对象的JavaScript依赖库生成JavaScript代码。返回值为pyecharts.render.display.Javascript
类对象。
engine
模块的应用
根据图表对象基类Base
的源码可知,图表类的渲染方法底层底层由engine
模块的相应类、函数实现。
pyecharts/charts/base.py
模块源码
from ..render import engine
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
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"
)
pyecharts/render/engine.py
模块源码
import os
from collections import Iterable
from jinja2 import Environment
from ..commons import utils
from ..datasets import EXTRA, FILENAMES
from ..globals import CurrentConfig, NotebookType
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:
html_file.write(html_content)
class RenderEngine:
def __init__(self, env: Optional[Environment] = None):
self.env = env or CurrentConfig.GLOBAL_ENV
@staticmethod
def generate_js_link(chart: Any) -> Any:
if not chart.js_host:
chart.js_host = CurrentConfig.ONLINE_HOST
links = []
for dep in chart.js_dependencies.items:
# TODO: if?
if dep.startswith("https://api.map.baidu.com"):
links.append(dep)
if dep in FILENAMES:
f, ext = FILENAMES[dep]
links.append("{}{}.{}".format(chart.js_host, f, ext))
else:
for url, files in EXTRA.items():
if dep in files:
f, ext = files[dep]
links.append("{}{}.{}".format(url, f, ext))
break
chart.dependencies = links
return chart
def render_chart_to_file(self, template_name: str, chart: Any, path: str, **kwargs):
"""
Render a chart or page to local html files.
:param chart: A Chart or Page object
:param path: The destination file which the html code write to
:param template_name: The name of template file.
"""
tpl = self.env.get_template(template_name)
html = utils.replace_placeholder(
tpl.render(chart=self.generate_js_link(chart), **kwargs)
)
write_utf8_html_file(path, html)
def render_chart_to_template(self, template_name: str, chart: Any, **kwargs) -> str:
tpl = self.env.get_template(template_name)
return utils.replace_placeholder(
tpl.render(chart=self.generate_js_link(chart), **kwargs)
)
def render_chart_to_notebook(self, template_name: str, **kwargs) -> str:
tpl = self.env.get_template(template_name)
return utils.replace_placeholder(tpl.render(**kwargs))
def render(
chart, path: str, template_name: str, env: Optional[Environment], **kwargs
) -> str:
RenderEngine(env).render_chart_to_file(
template_name=template_name, chart=chart, path=path, **kwargs
)
return os.path.abspath(path)
def render_embed(
chart, template_name: str, env: Optional[Environment], **kwargs
) -> str:
return RenderEngine(env).render_chart_to_template(
template_name=template_name, chart=chart, **kwargs
)
def render_notebook(self, notebook_template, lab_template):
instance = self if isinstance(self, Iterable) else (self,)
if CurrentConfig.NOTEBOOK_TYPE == NotebookType.JUPYTER_NOTEBOOK:
require_config = utils.produce_require_dict(self.js_dependencies, self.js_host)
return HTML(
RenderEngine().render_chart_to_notebook(
template_name=notebook_template,
charts=instance,
config_items=require_config["config_items"],
libraries=require_config["libraries"],
)
)
if CurrentConfig.NOTEBOOK_TYPE == NotebookType.JUPYTER_LAB:
return HTML(
RenderEngine().render_chart_to_notebook(
template_name=lab_template, charts=instance
)
)
if CurrentConfig.NOTEBOOK_TYPE == NotebookType.NTERACT:
return HTML(self.render_embed())
if CurrentConfig.NOTEBOOK_TYPE == NotebookType.ZEPPELIN:
print("%html " + self.render_embed())
def load_javascript(chart):
scripts = []
for dep in chart.js_dependencies.items:
f, ext = FILENAMES[dep]
scripts.append("{}{}.{}".format(CurrentConfig.ONLINE_HOST, f, ext))
return Javascript(lib=scripts)