d3.json() 后 Nodejs 脚本无法打印?
Nodejs script fails to print after d3.json()?
(编辑: 问题已被重写以更好地隔离问题。)
我正在编写一个 D3js script.js
,它可以在客户端的 Web 浏览器和服务器端的 nodejs 中重复使用 "as it"。我取得了一些不错的进步 :
- 单个 d3js
script.js
确实可以在客户端和服务器端创建基本的 svg 形状。在显示可视化项的 Web 浏览器上,在服务器端输出所需的 map.svg 文件。
- 我有一个更复杂的 d3js 地图制作代码:客户端它工作起来很有魅力 (link)
但是! nodejs 调用失败没有错误消息。 xhr d3.json()
似乎正在挂断等待并且没有触发其回调:
mapIt.node.js(服务器端,失败)
传递变量和运行我:
$ 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
);
}
);
map.svg(不完整)
由于 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)
returns 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
替换:
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
);
(编辑: 问题已被重写以更好地隔离问题。)
我正在编写一个 D3js script.js
,它可以在客户端的 Web 浏览器和服务器端的 nodejs 中重复使用 "as it"。我取得了一些不错的进步 :
- 单个 d3js
script.js
确实可以在客户端和服务器端创建基本的 svg 形状。在显示可视化项的 Web 浏览器上,在服务器端输出所需的 map.svg 文件。 - 我有一个更复杂的 d3js 地图制作代码:客户端它工作起来很有魅力 (link)
但是! nodejs 调用失败没有错误消息。 xhr d3.json()
似乎正在挂断等待并且没有触发其回调:
mapIt.node.js(服务器端,失败)
传递变量和运行我:
$ 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
);
}
);
map.svg(不完整)
由于 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)
returns 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
替换:
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
);