Node.js脚本在d3.json()之后无法打印? [英] Nodejs script fails to print after d3.json()?

查看:194
本文介绍了Node.js脚本在d3.json()之后无法打印?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

修改:问题已被重写,以更好地隔离问题。)






我写了一个单独的D3js script.js ,可以在客户端的web浏览器和服务器端的nodejs中重复使用as it。我取得了一些进展:


  1. 单个d3js script.js svg形状在客户端和服务器端。在web浏览器显示viz,在服务器端输出想要的map.svg文件。

  2. 我有一个更复杂的d3js地图制作代码:客户端它的工作方式像一个charm =http://bl.ocks.org/hugolpz/raw/1c34e14d8b7dd457f802/index.html =nofollow noreferrer>链接)

>



但!,nodejs调用失败没有错误消息。 xhr d3.json()似乎挂起等待,并且不会触发其回调:



mapIt。 node.js(服务器端,失败)



传递变量并运行:

  $ WIDTH = 800 ITEM =world-1e3node script.node.js 

script.node.js的内容:

  var jsdom = require('jsdom'); // npm install jsdom 
var fs = require('fs'); //本地在nodejs中。

jsdom.env(
< html>< body>< / body>< / html>,// CREATE DOM HOOK
['。 d3.v3.min.js',//将资源加载到窗口环境(!)
'./topojson.v1.min.js',
'./queue.v1.min.js' ,
'./script.js'],

function(err,window){
/ * *************** **************************************************** * /
/ *检查加载资源在窗口范围内的可用性************ * /
console.log(typeof window.mapIt); // expect:函数',因为存在于script.js!
console.log(typeof window.doesntExist); // expect:'undefined',因为不存在任何地方。
//如果所有都如预期,应该工作!

/ * *********************************** **************************** * /
/ * 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宽/ 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;

/ *从这里的失败失败********************** * /
d3.json(url,function错误,json){//从这里:不在服务器端激发:(
if(error)return console.warn(error);
d3.select(svg)。append ).attr(log,d3.json);
svg.append('path')
.datum(topojson.feature(json,json.objects.admin_0))
.attr('d',path)
.attr('class','L0');
});
};
window.mapIt目标);
/ * *************************************** ************************ * /
/ * SVG PRINT **************** *************************************** * /
// better svg header :
var svgheader ='<?xml version =1.0encoding =utf-8?> \\\
'
+'<!DOCTYPE svg PUBLIC - / / W3C / / DTD SVG 1.1 // ENhttp://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\\\
';
//打印+定时器,要确保打印文件时所有已准备就绪:
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 // ENhttp://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">
< svg width =800height =416.6666666666667>< / svg>

给定 map.svg 的内容,脚本首先按预期工作,设置svg width height 属性,然后 d3 .json()不工作,回调不会启动。没有返回错误消息。



注意:



同样的问题exact d3js script works client client( 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



问题



strong>如何获取请求工作?或如何运行nodejs脚本,以便允许查询



测试



Github gist ):

  git clone https://gist.github.com/9bdc50271afc49d33e35.git ./map 
cd ./map; npm install
WIDTH = 800 ITEM =world-1e3node script.node.js

帮助: D3js> API>请求

解决方案

替换:

  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
);


(Edit: the question have been rewritten to better isolate the issue.)


I'am writing a single D3js script.js which could be reused "as it" in both web browser for client side and nodejs for server side uses. I made some good progress :

  1. a single d3js script.js indeed create basic svg shapes on both client and server sides. On web browser displaying the viz, on server side outputing the wanted map.svg file.
  2. I have a more complex d3js map making code: client side it works like a charm (link)

but! the nodejs call fails without error message. The xhr d3.json() seems to be hanging up waiting and not firing up its callback:

mapIt.node.js (server side, fails)

Pass variables and run me:

$ WIDTH=800 ITEM="world-1e3" node script.node.js

Content of 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 (incomplete)

Since d3.json callback is not fired, I get the incomplete map.svg such:

<?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>

Given map.svg's content, the script first work as expected, setting the svg width and height attributes, then the d3.json() doesn't work, the call back is never fired up. There is no error message back. But given where the script stop, it seems the query is hanging up waiting.

Notes:

The same exact d3js script works client side (link).

Interestingly, console.warn(window.document.URL) returns file:///data/yug/projects_active/map/script.node.js (purely local) while the d3.json() xhr request is on http://bl.ocks.org/hugolpz/raw/1c34e14d8b7dd457f802/administrative.topo.json.

Question

How to get the request working ? or How to run nodejs script with so the query is allowed ?

Testing

To try out the script (Github gist):

git clone https://gist.github.com/9bdc50271afc49d33e35.git ./map
cd ./map; npm install
WIDTH=800 ITEM="world-1e3" node script.node.js

Help: D3js>API>Requests

解决方案

Replace :

setTimeout(
      fs.writeFileSync('map.svg', svgheader + window.d3.select("body").html()) ,
      10000
    );

by

setTimeout(
      function(){ fs.writeFileSync('map.svg', svgheader + window.d3.select("body").html()) } ,
      10000
    );

这篇关于Node.js脚本在d3.json()之后无法打印?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆