利用PhantomJS搭建Highcharts export服务
利用PhantomJS搭建Highcharts export服务
一直在使用Highcharts做web图表的展示, 但是当发送定时的报表邮件的遇到了这个问题. 为了保证邮件图表和web页图表样式一致, 需要能原样生图. 这里考虑如下:
1. 如何生成jpg图片
在很久以前,官方推荐用Imagemagick将SVG转成jpg. 考虑如何得到SVG, 大量文档推荐用 nodejs+jsdom从json数据中生成svg. 在实际使用中, Imagemagick和jsdom环节处理复杂的数据都非常孱弱, 复杂的图表丢东少西难看要死, 无法上线. 在google上纠结好久, 终于发现了这神器PhantomJS.
做测试这么久, 尽然不知道PhantomJS这种神器. 简单说, PhantomJS是个不显示UI的浏览器, 可以无GUI的server上使用. 而且核心为webkit, 轻松支持Highcharts等几乎所有的js库. 在本文中, PhantomJS拿来解决这个问题再合适不过. 只需要想办法把数据传给PhantomJS, 简单几句代码, 截个图就行了.
2. 数据传递
下面这个问题就是怎么把数据传给PhantomJS. PhantomJS支持命令行, 在服务器端, (一般为Java, Python, PHP), 与JS交互的最好数据格式就是JSON. 但是JSON数据比较大时, 直接用命令行就不行了. 传递方式可以选:
- fork子进程, 利用其stdin吐进去
- 生成一个json临时文件, 命令行指定该文件地址
- 利用PhantomJS的webserver模块单独开启一个服务, 向其POST
三种方式都可以, 看具体的需求. 第二种比较简单, 就是总要生成中间文件, 不是很喜欢....
还有一个问题, 利用JSON提供基本数据还可以, 但是传递控制显示样式的callback函数(比如formatter)比较麻烦. 如果所有图表样式统一还好说, 在PhantomJS脚本内写死就可以. 对于图表需要个性样式的情况, 目前想到的解决办法是, 将callback写成各个js文件, 在传递JSON时指定一个额外的配置, 确定读取哪个js文件, 然后再统一到一起.
这两个问题解决, 就可以直接从服务器端生成图片了.
补充: 刚看到了官方的解决方案, 跟我想法差不多, 地址如下:
http://www.highcharts.com/component/content/article/2-news/52-serverside-generated-charts
而且在文章后半部, 指出了PhantomJS在数据点过多情况下的性能问题.
稍有不同的是, 官方使用了命令行参数指定callback js文件, 并且callback是通过Highcharts强大的api来调整样式的. 而不是向本文一样做合并.
https://github.com/highcharts/highcharts-export-server/tree/master/phantomjs
http://www.highcharts.com/component/content/article/2-news/52-serverside-generated-charts
https://github.com/one2team/highcharts-serverside-export
http://www.cnblogs.com/mgzy/p/3850183.html
利用PhantomJS搭建Highcharts export服务的更多相关文章
- 在Windows 10上利用seafile搭建个人云服务
参考seafile官方文档 安装Python 2.7.11 32位版 下载地址:https://www.python.org/downloads/release/python-2711/ 选择 32位 ...
- 利用OpenStreetMap(OSM)数据搭建一个地图服务
http://www.cnblogs.com/LBSer/p/4451471.html 图 利用OSM数据简单发布的北京地图服务 一.OSM是什么 开放街道图(OpenStreetMap,简称O ...
- 利用NTP搭建自己的ntp服务
利用NTP搭建自己的ntp服务 发表于 2013 年 9 月 22 日 作者 admin 对于校园网/企业用户,如果您网内所有计算机都通过互联网同步时间,在速度和精度上都有一定的折扣,并且对互联网出口 ...
- 利用 MinIO 轻松搭建静态资源服务
目录 1 引言 2 MinIO 简介 3 MinIO 运行与静态资源使用 3.1 MinIO 获取 3.2 MinIO 启动与运行 3.2.1 前台简单启动 3.2.2 后台指定参数运行 3.2.3 ...
- Docker系列——利用gogs搭建属于自己的git服务
gogs简介 Gogs的目标是打造一个最简单.最快速和最轻松的方式搭建自助Git服务.使用Go语言开发使得Gogs能够通过独立的二进制分发,并且支持Go语言支持的所有平台,包括 Linux.Mac O ...
- 利用Hexo搭建个人博客-环境搭建篇
我是一个爱写博客进行总结分享的人.然而,有着热爱写博客并且深知写博客好处的我,却没有好好的把这个习惯坚持下来.如今毕业已经一年多了吧,每一次与师弟师妹们聊天,我总会意味深长的建议他们,一定要定期梳理总 ...
- 如何将phantomjs单独部署在服务端
如何将phantomjs单独部署在服务端 文章目录 一. 容我分析(lao dao)几句 二. 服务端 Look here 服务端phantomjs搭建 web端搭建及如何调用phantomjs 三. ...
- 利用 Docker 搭建 IPFS 私有网络
利用 Docker 搭建 IPFS 私有网络 本文原始地址:https://sitoi.cn/posts/40630.html 下载项目 项目地址:https://github.com/Sitoi/p ...
- ZooKeeper1 利用虚拟机搭建自己的ZooKeeper集群
前言: 前段时间自己参考网上的文章,梳理了一下基于分布式环境部署的业务系统在解决数据一致性问题上的方案,其中有一个方案是使用ZooKeeper,加之在大数据处理中,ZooKeeper确实起 ...
随机推荐
- jQuery对象和DOM对象的互相转换【 转】
jQuery对象转换为dom对象 只有jQuery对象才能调用jQuery类库的各种函数,同样有些dom对象的属性和方法在jQuery上也是无法调用的,不过基本上jQuery类库提供的函数包含了所有的 ...
- MySQL 5.6.26源码安装
5.6.26源码安装包:http://pan.baidu.com/s/1kUl44WRcmake安装包链接:http://pan.baidu.com/s/1c0LuwJA 操作系统版本:CentOS ...
- Eclipse 常用插件
/* ===================== Eclipse Color Theme 语法高亮 ======================== */ 安装方法同上,软件安装URL http:// ...
- SQL日语词汇
データベース 数据库 DATABASE インスタンス (数据库)实例 INSTANCE ユーザー 用戶 USER ログイン・ログアウト ログオン・ログオフ 登录 LOGIN/LOGOUT LOGNO/ ...
- Could not locate device support files.《This iPhone 5 (Model A1429) is running iOS 7.0.4 (11B554a), which may not be supported by this version of Xcode.》-b
原因:Xcode8 不支持 iOS7 解决方法: 在“/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/De ...
- tomcat绑定域名
现在很多的公司的网站都是用tomcat作为应用服务区的,可是对于初学者,8080端口号是如何去掉的,这些网站是如何和域名绑定到一起的呢?一个tomcat是如何绑定多域名?并且这些域名是如何对应不同的项 ...
- 来吧,给你的Winform列表控件画个妆
前言 以前看别人的控件好看只有羡慕的份:以前觉得控件重绘是个很复杂的东西:以前知道MSDN很全面很专业却一直没有好好用起来: 作为初级程序猿,不能原地踏步,来吧,让我们一起把 TreeView 美化一 ...
- 给定一颗二叉搜索树,请找出其中的第k小的结点。例如, 5 / \ 3 7 /\ /\ 2 4 6 8 中,按结点数值大小顺序第三个结点的值为4。
// ConsoleApplication2.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include "stdafx.h ...
- Matlab中数组下标是logical,如何处理?
K>> a = 10*ones(1,10); K>> b = [1 56 23 5 6 45 9 7 89 10]; K>> c = b<a c = 1 0 ...
- windows 64位整数
#include <iostream> #include <ctime> using namespace std; int main() { cout << cou ...