当前位置:   article > 正文

一种pyecharts离线加载图表方法_pyecharts html离线打开

pyecharts html离线打开

环境

windows11 python-3.10.5 pyecharts-2.0.3,其他版本没试过。

需求

之前用0.5版本的pyecharts倒是没遇到离线使用的问题。换了v2版本后遇到了。

网上查到的大多数方法是开个http服务器,让浏览器访问生成图表的html时下载js脚本改为从本地服务器下载,从而解决pyecharts离线使用问题。但我的需求是:

1、不需要开服务器也能生成html图表。

2、生成的html不用再另外下载js脚本,换台电脑也能直接打开显示图表。

3、不在源码上改动,换台电脑使用一样的pyecharts也可以运行使用。

解决过程

下载js脚本

改动前,生成一份非嵌入js的图表html,找到js脚本链接,下载到本地。

浏览器访问https://assets.pyecharts.org/assets/v5/echarts.min.js,保存下js文件。

嵌入JS配置

需求2很好解决,把js代码嵌入html即可。在pyecharts手册里有提到一个渲染配置项RenderOpts,提供是否在渲染HTML时嵌入JS文件,默认False不嵌入。若想要“换台电脑也能直接打开显示图表”这个效果,则把此配置项设为True即可。

 创建图表时候,初始化时候指定下render_opts参数,如下柱状图代码:

bar = Bar(init_opts=opts.InitOpts(), render_opts=opts.RenderOpts(is_embed_js=True))

加载js代码方法重写

其实到本步骤,使用本地开服务器方式+嵌入js到html方法,也能勉强满足我原始的需求,但是运行时候发现了个问题,我是用http方式开的服务,但是嵌入js脚本代码却是用https请求访问js资源后才去嵌入html的,导致了异常报错。修改源码把HTTPSConnection改为HTTPConnection发现可以,进一步可以取scheme进行http/https判断走不同逻辑请求。但是我并不想在源码做改动,这样我换台电脑还要改,显然挺麻烦的。

这里我想到了猴子补丁的方法,将源码里的load_javascript_contents方法替换为自己编写的方法。load_javascript_contents的逻辑延用源码的逻辑,然后补充2个点。1个是如果请求的js是echarts.min.js(别的同理),则读取本地echarts.min.js文件内容赋值,达成离线使用效果。1个是判断请求是http还是https,走不同的连接,后续如果扩展可能需要。替换方法的代码如下:

  1. import http.client
  2. from typing import Optional
  3. from urllib.parse import urlparse
  4. from pyecharts import options as opts
  5. from pyecharts.charts import Bar
  6. from pyecharts.render.display import Javascript
  7. class ChartsLib(object):
  8. def __init__(self):
  9. Javascript.load_javascript_contents = self.load_javascript_contents
  10. @staticmethod
  11. def read_echarts_min_js():
  12. with open("echarts.min.js", "r", encoding="utf-8") as f:
  13. text = f.read()
  14. f.close()
  15. return text
  16. @staticmethod
  17. def load_javascript_contents(self):
  18. for lib in self.lib:
  19. if "echarts.min.js" in lib:
  20. self.javascript_contents[lib] = ChartsLib.read_echarts_min_js()
  21. continue
  22. parsed_url = urlparse(lib)
  23. scheme: str = parsed_url.scheme
  24. host: str = str(parsed_url.hostname)
  25. port: int = parsed_url.port
  26. path: str = parsed_url.path
  27. resp: Optional[http.client.HTTPResponse] = None
  28. try:
  29. if scheme == "https":
  30. conn = http.client.HTTPSConnection(host, port)
  31. else:
  32. conn = http.client.HTTPConnection(host, port)
  33. conn.request("GET", path)
  34. resp = conn.getresponse()
  35. if resp.status != 200:
  36. raise RuntimeError("Cannot load JavaScript lib: %s" % lib)
  37. self.javascript_contents[lib] = resp.read().decode("utf-8")
  38. finally:
  39. if resp is not None:
  40. resp.close()
  41. return self
  42. @staticmethod
  43. def demo_bar(infos, interactions, html_name="bar_interactions.html"):
  44. bar = Bar(init_opts=opts.InitOpts(height="1000px"), render_opts=opts.RenderOpts(is_embed_js=True))
  45. bar.add_xaxis(infos)
  46. bar.add_yaxis("xx数据", interactions)
  47. bar.reversal_axis()
  48. bar.set_series_opts(label_opts=opts.LabelOpts(position="right"))
  49. bar.set_global_opts(title_opts=opts.TitleOpts(title="示例表"),
  50. toolbox_opts=opts.ToolboxOpts(),
  51. datazoom_opts=[
  52. opts.DataZoomOpts(orient="horizontal", range_start=0, range_end=100),
  53. opts.DataZoomOpts(orient='vertical', range_start=0, range_end=100)
  54. ])
  55. bar.render(html_name)
  56. return bar

这样就达到了3个需求点要求了。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/165129
推荐阅读
相关标签
  

闽ICP备14008679号