dojo charting on nodejs

在nodejs上运行dojo的文章很多,却找不到具体使用dojox.charting的资料,因为有 node-canvas这样的开源项目,理论上可以把dojo生成的图保存为文件,实践中碰到一些问题并都解决了。js图表库很多都把坐标轴上的刻度文字用html来显示,这样在网页上都不能保存到图片里,更别说在后台了。库rgraph文字是完全生成在canvas上的,dojo图表是可设置轴文字生成到html或canvas的。下面是具体过程和代码:

环境:
1.node-canvas windows安装参照 文档,简单说就是:
安装Python 2.7.3并设置环境变量
安装Microsoft Visual C++ 2010 Express
下载 cairo library解压到C:\GTK并设置环境变量
npm update -g npm
npm install -g node-gyp
npm install canvas
2.因为dojox.charting用到的dom相关,所以还要安装jsdom,并在代码上调整一下
npm install jsdom
原则上不改dojo代码,不改下载的库,只有一个文件实在是没办法
dojo/_base/window.js里边有一句
doc: this["document"] || null,
 改成
doc: this["document"] || window.document || null,

其它库不用改,在自己的代码中设置就行了。
代码:
1.启动代码:boot.js
var jsdom = require("jsdom").jsdom;
var document = jsdom("<html><head></head><body style='display:block;'><div id='StackedColumns_numbers' width='400' height='300'  style=''></div></body></html>", require("jsdom").level(2, "core"));
window = document.createWindow();
navigator = window.navigator;

global.dojoConfig = {
  async: true,
  forceGfxRenderer: 'canvas',
  gfxRenderer: 'canvas',
  basePath: ".",
  packages: [{
    name: "dojo",
    location: "lib/dojo"
  },{
    name: "dojox",
    location: "lib/dojox"
  },{
    name: "mynode",
    location: "mynode"
  }],
  deps: ["mynode/main"]
};

require("./lib/dojo/dojo.js");

2.主程序:mynode/main.js
define(["dojo/_base/declare", "dojo/_base/lang", "dojo/dom", "dojo/node!fs",
	"dojo/ready","dojox/charting/Chart", "dojox/charting/axis2d/Default",
	"dojox/charting/plot2d/StackedColumns"], 
	function(declare, lang, dom, fs, ready, Chart, Default, StackedColumns){


	ready(function(){

		// StackedColumns, array of numbers
		var chart6 = new Chart("StackedColumns_numbers",{title: ""});
		chart6.addAxis("x", {fixLower: "major",htmlLabels: false, fixUpper: "major"});
		chart6.addAxis("y", {vertical: true, htmlLabels: false,fixLower: "minor", fixUpper: "minor", natural: true, includeZero: true});
		chart6.addPlot("default", {type: StackedColumns, gap: 5});
		chart6.addSeries("Series A", [1, 2, 3, 4, 5], {fill: "red"});
		chart6.addSeries("Series B", [5, 4, 3, 2, 1], {fill: "blue"});
		chart6.render();
		setTimeout(function(){
		var div = dom.byId("StackedColumns_numbers");
		console.log("========"+div.children);
		for (var i=0;i<div.children.length;i++) {
			if(div.children[i].createPNGStream){
				console.log("========"+div.children[i]);
				var canvas = div.children[i];
				var out = fs.createWriteStream('charting.png')
				 , stream = canvas.createPNGStream();

				stream.on('data', function(chunk){
				 out.write(chunk);
				});
			}
		}
		}, 0);
	});
});

使用setTimeout是因为dojox/gfx/canvas.js里面使用了setTimeout:
makeDirty: function(){
			// summary:
			//		internal method, which is called when we may need to redraw
			if(!this.pendingImagesCount && !("pendingRender" in this)){
				this.pendingRender = setTimeout(lang.hitch(this, this._render), 0);
			}
},

3运行node boot.js生成图片文件,以下是解决轴上的文字和标题问题。
不能显示字是因为dojox/gfx/_base里边:
px_in_pt: function(){
			// summary:
			//		returns the current number of pixels per point.
			return g._base._getCachedFontMeasurements()["12pt"] / 12 || 1;	// Number
},
"|| 1"是后加的,通过创建dom的方式来计算在nodejs里行不通过,所以直接返回1。
如果要显示title,需要设置字体;因为title默认是用html来显示,所以要修改dojox/charting/Chart里
				var forceHtmlLabels = (g.renderer == "canvas"),
					labelType = 'gfx';//forceHtmlLabels || !has("ie")  && !has("opera") ? "html" : "gfx",
					tsize = g.normalizedLength(g.splitFontString(this.titleFont).size);
这里直接用'gfx'。设置title的代码
var chart6 = new Chart("StackedColumns_numbers",{title: "aaa",titleFont: "normal normal normal 8pt 黑体, Arial, sans-serif",});
chart6.addAxis("x", {fixLower: "major",htmlLabels: false, fixUpper: "major", natural: true});
还有个中文问题解决起来较麻烦,编译时要让node-canvas支持国际化。
还有另一种思路 svg png,它使用的是highchart.

你可能感兴趣的:(nodejs dojo)