使用phantomJs服务器端导出Echarts图片

本文介绍了如何利用PhantomJs在服务器端直接生成Echarts图表并导出为图片,避免了需要在页面上显示图表的需求。通过在服务器端运行 PhantomJs,结合Echarts的options,创建图表并在webpage.evaluate()中执行echarts.init(),最后使用webpage.render()方法生成图片。
部署运行你感兴趣的模型镜像

背景:

    在使用Echarts过程中,有需求在页面上图表显示和服务器端导出报表。在Echarts中,原生态提供了getImage()方法,但是都需要在页面上生成。事实上,可以通过页面上使用getImage()获得base64 encode的图片数据,传输至服务器端导出图片。但是在项目需求中,有一种场景在导出报表时,页面可能不需要生成图片。因此只能调研是否在服务器端直接生成。


思路:

    phantomJs作为一个headless浏览器,支持网页截图。通过调用phantomJs,传入Echarts生成图表所需的options,与在页面上类似的方法,调用phantomJs的webpage模块,通过使用webpage.evaluate()在页面中生成div容器,调用echarts.init(container)生成图表,最终调用phantomJs的webpage.render()生成图片。


代码:

(function() {
	var system = require('system');
	var fs = require('fs');
	var config = {
		// define the location of js files
		JQUERY : 'jquery.1.9.1.min.js',
		ESL : 'esl.js',
		ECHARTS : 'echarts-plain.js',
		// default container width and height
		DEFAULT_WIDTH : '800',
		DEFAULT_HEIGHT : '400'
	}, parseParams, render, pick, usage;

	usage = function() {
		console.log("\nUsage: phantomjs echarts-convert.js -options options -outfile filename -width width -height height"
						+ "OR"
						+ "Usage: phantomjs echarts-convert.js -infile URL -outfile filename -width width -height height\n");
	};

	pick = function() {
		var args = arguments, i, arg, length = args.length;
		for (i = 0; i < length; i += 1) {
			arg = args[i];
			if (arg !== undefined && arg !== null && arg !== 'null' && arg != '0') {
				return arg;
			}
		}
	};

	parseParams = function() {
		var map = {}, i, key;
		if (system.args.length < 2) {
			usage();
			phantom.exit();
		}
		for (i = 0; i < system.args.length; i += 1) {
			if (system.args[i].charAt(0) === '-') {
				key = system.args[i].substr(1, i.length);
				if (key === 'infile') {
					// get string from file
					// force translate the key from infile to options.
					key = 'options';
					try {
						map[key] = fs.read(system.args[i + 1]).replace(/^\s+/, '');
					} catch (e) {
						console.log('Error: cannot find file, ' + system.args[i + 1]);
						phantom.exit();
					}
				} else {
					map[key] = system.args[i + 1];
				}
			}
		}
		return map;
	};

	render = function(params) {
		var page = require('webpage').create(), createChart;

		page.onConsoleMessage = function(msg) {
			console.log(msg);
		};

		page.onAlert = function(msg) {
			console.log(msg);
		};

		createChart = function(inputOption, width, height) {
			var counter = 0;
			function decrementImgCounter() {
				counter -= 1;
				if (counter < 1) {
					console.log(messages.imagesLoaded);
				}
			}

			function loadScript(varStr, codeStr) {
				var script = $('<script>').attr('type', 'text/javascript');
				script.html('var ' + varStr + ' = ' + codeStr);
				document.getElementsByTagName("head")[0].appendChild(script[0]);
				if (window[varStr] !== undefined) {
					console.log('Echarts.' + varStr + ' has been parsed');
				}
			}

			function loadImages() {
				var images = $('image'), i, img;
				if (images.length > 0) {
					counter = images.length;
					for (i = 0; i < images.length; i += 1) {
						img = new Image();
						img.onload = img.onerror = decrementImgCounter;
						img.src = images[i].getAttribute('href');
					}
				} else {
					console.log('The images have been loaded');
				}
			}
			// load opitons
			if (inputOption != 'undefined') {
				// parse the options
				loadScript('options', inputOption);
				// disable the animation
				options.animation = false;
			}

			// we render the image, so we need set background to white.
			$(document.body).css('backgroundColor', 'white');
			var container = $("<div>").appendTo(document.body);
			container.attr('id', 'container');
			container.css({
				width : width,
				height : height
			});

			// render the chart
			var myChart = echarts.init(container[0]);
			myChart.setOption(options);
			// load images
			loadImages();
		};

		// parse the params
		page.open("about:blank", function(status) {
			// inject the dependency js
			page.injectJs(config.JQUERY);
			page.injectJs(config.ESL);
			page.injectJs(config.ECHARTS);

			var width = pick(params.width, config.DEFAULT_WIDTH);
			var height = pick(params.height, config.DEFAULT_HEIGHT);

			// create the chart
			page.evaluate(createChart, params.options, width, height);

			// define the clip-rectangle
			page.clipRect = {
				top : 0,
				left : 0,
				width : width,
				
				height : height
			};
			// render the image
			page.render(params.outfile);
			console.log('render complete:' + params.outfile);
			// exit
			phantom.exit();
		});
	};
	// get the args
	var params = parseParams();

	// validate the params
	if (params.options === undefined || params.options.length === 0) {
		console.log("ERROR: No options or infile found.");
		usage();
		phantom.exit();
	}
	// set the default out file
	if (params.outfile === undefined) {
		var tmpDir = fs.workingDirectory + '/tmp';
		// exists tmpDir and is it writable?
		if (!fs.exists(tmpDir)) {
			try {
				fs.makeDirectory(tmpDir);
			} catch (e) {
				console.log('ERROR: Cannot make tmp directory');
			}
		}
		params.outfile = tmpDir + "/" + new Date().getTime() + ".png";
	}

	// render the image
	render(params);
}());

使用方法:

1. phantomjs echarts-convert.js -options options -outfile filename -width width -height height

2. phantomjs echarts-convert.js -infile URL -outfile filename -width width -height height


例子:

options文件内容:

{
    title : {
        text: '世界人口总量',
        subtext: '数据来自网络'
    },
    tooltip : {
        trigger: 'axis'
    },
    legend: {
        data:['2011年', '2012年']
    },
    calculable : true,
    xAxis : [
        {
            type : 'value',
            boundaryGap : [0, 0.01]
        }
    ],
    yAxis : [
        {
            type : 'category',
            data : ['巴西','印尼','美国','印度','中国','世界人口(万)']
        }
    ],
    series : [
        {
            name:'2011年',
            type:'bar',
            data:[18203, 23489, 29034, 104970, 131744, 630230]
        },
        {
            name:'2012年',
            type:'bar',
            data:[19325, 23438, 31000, 121594, 134141, 681807]
        }
    ]
}

命令行方法:

bin/phantomjs echarts/echarts-convert.js -infile options -outfile test.png


导出图片:





您可能感兴趣的与本文相关的镜像

Stable-Diffusion-3.5

Stable-Diffusion-3.5

图片生成
Stable-Diffusion

Stable Diffusion 3.5 (SD 3.5) 是由 Stability AI 推出的新一代文本到图像生成模型,相比 3.0 版本,它提升了图像质量、运行速度和硬件效率

评论 19
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值