Highcharts 是一个用纯JavaScript编写的一个图表库, 能够很简单便捷的在web网站或是web应用程序添加有交互性的图表,并且免费提供给个人学习、个人网站和非商业用途使用。HighCharts支持的图表类型有曲线图、区域图、柱状图、饼状图、散状点图和综合图表等各种图形,效果非常美观,被广泛的应用于图表生成,类似图表库还有百度的Echart等.
highcharts
在html上生成highcharts图表是很容易的,我们只需要根据需求选择图形,然后定义样式,最后把数据塞进highcharts的series中即可渲染,而且highcharts还提供了页面(客户端)导出功能,可以很方便的导出为jpg、png、pdf、svg等格式,但是如何在服务器端(这里使用flask)自动生成图形然后保存为图片呢?
其实,我们在网面上看到的highcharts图形,其实不是一张图片,而是svg格式,具体的名词解释请自行搜索,说白了就是一种xml语言,格式如下:
1 | <svg xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" class="highcharts-root" ...></svg> |
那么自动生成并保存为图片思路就很清晰了:
- 获取数据填充模板html
- 从模板html中获取所有svg标签,使用Highcharts自带function-getSVG()
- 使用cairosvg将svg转换成png或者使用phantomjs
第1点渲染模板html没有什么好说的,无非就是按照需求组织数据的问题,我们直接从第2点开始
getSVG()
主要思路为一个按钮点击后通过getSVG获取所有图表的svg信息,再使用Highcharts.post构造post表单传入后端,当然这里也可以使用request库的xpath获取svg元素,Highcharts既然的现成的办法所以就直接用了,这里有个需要注意的地方就是如果想要保留图表原本的长宽的话,在chart.getSVG()时像下面代码所示那样使用长宽,不然得到的svg的长宽会变成默认值
模板html中getSVG()代码如下:
1 | <script type="text/javascript"> |
这样post到后端之后再request.form.to_dict()得到所有参数即可拿到svg信息,当然这里得到的是所有图表的svg串,需要进行分割处理,这里以‘,<svg’为分割符,然后使用开源库**cairosvg**中的svg2png将svg转换成png图片.
1 | def cairosvg2png(svg,chartlst): |
phantomjs
除了上面的方法外,还可以使用phantomjs来自动在服务器端把svg转换成png/jpeg/pdf,这也是highcharts推荐的方式,phantomjs是一个很强大的基于WebKit的服务器端JavaScript API,也是开源库,使用场景也非常广泛.特别在自动化测试及爬虫方面,有兴趣的可以看这里
而且phantomjs支持以服务的方式一直运行,只需要把信息传递到它指定的端口即可,非常方便,这次是因为不能安装在服务器上,所以没有采纳,这里使用子进程运行phantomjs.exe,直接使用时需用-resources指定js文件:
1 | def exportForm(): |