(编辑:已重写问题以更好地隔离问题。)
我正在编写单个D3js script.js
,可以在客户端的Web浏览器和服务器端使用的nodejs中“重新使用”。我取得了一些进展:
script.js
确实在客户端和服务器端创建了基本的svg形状。在显示viz的Web浏览器上,在服务器端输出所需的map.svg文件。
但是! nodejs调用失败没有错误消息。 xhr d3.json()
似乎挂断了等待而没有开始回调:
传递变量并运行我:
$ WIDTH=800 ITEM="world-1e3" node script.node.js
script.node.js的内容:
var jsdom = require('jsdom'); // npm install jsdom
var fs = require('fs'); // natively in nodejs.
jsdom.env(
"<html><body></body></html>", // CREATE DOM HOOK
[ './d3.v3.min.js', // load assets into window environment (!)
'./topojson.v1.min.js',
'./queue.v1.min.js',
'./script.js' ],
function (err, window) {
/* ***************************************************************** */
/* Check availability of loaded assets in window scope. ************ */
console.log(typeof window.mapIt); // expect: 'function', because exist in script.js !
console.log(typeof window.doesntExist); // expect: 'undefined', because doesn't exist anywhere.
// if all as expected, should work !
/* ***************************************************************** */
/* COLLECT ENV.VARIABLES ******************************************* */
var width = process.env.WIDTH,
target= process.env.ITEM;
/* ***************************************************************** */
/* D3js FUNCTION *************************************************** */
var url = "http://rugger-demast.codio.io/output/"+target+"/administrative.topo.json";
console.log(url);
console.warn(window.document.URL);
var mapIt = function(width, target){
console.log("mapIt(): start");
var svg = d3.select('body').append('svg')
.attr('width', width)
.attr('height', width/960*500);
var projection = d3.geo.mercator()
.scale(100)
.translate([width / 2, height/2]);
var path = d3.geo.path()
.projection(projection);
var url = "http://rugger-demast.codio.io/output/"+target+"/administrative.topo.json";
/* FROM HERE SOMETHING FAILS ********************** */
d3.json(url, function (error, json) { // from here: NOT fired on server side :(
if (error) return console.warn(error);
d3.select("svg").append("g").attr("log","d3.json");
svg.append('path')
.datum(topojson.feature(json, json.objects.admin_0))
.attr('d', path)
.attr('class', 'L0');
});
};
window.mapIt(width,target);
/* ***************************************************************** */
/* SVG PRINT ******************************************************* */
// better svg header:
var svgheader = '<?xml version="1.0" encoding="utf-8"?>\n'
+'<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\n';
// printing + timer, to be sure all is ready when printing file:
setTimeout(
fs.writeFileSync('map.svg', svgheader + window.d3.select("body").html()) ,
30000
);
}
);
由于没有触发d3.json回调,我得到了不完整的map.svg:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="800" height="416.6666666666667"></svg>
根据map.svg
的内容,该脚本首先按预期工作,设置svg width
和height
属性,然后d3.json()
不起作用,回来永远不会被激怒。没有错误消息。但鉴于脚本停止的地方,似乎查询正在等待。
同样精确的d3js脚本适用于客户端(link)。
有趣的是,console.warn(window.document.URL)
返回file:///data/yug/projects_active/map/script.node.js
(纯粹是本地的),而d3.json()xhr请求在http://bl.ocks.org/hugolpz/raw/1c34e14d8b7dd457f802/administrative.topo.json
上。
如何让请求正常运行?或如何运行nodejs脚本,以便允许查询?
试用脚本(Github gist):
git clone https://gist.github.com/9bdc50271afc49d33e35.git ./map
cd ./map; npm install
WIDTH=800 ITEM="world-1e3" node script.node.js
答案 0 :(得分:1)
替换:
setTimeout(
fs.writeFileSync('map.svg', svgheader + window.d3.select("body").html()) ,
10000
);
通过
setTimeout(
function(){ fs.writeFileSync('map.svg', svgheader + window.d3.select("body").html()) } ,
10000
);