node.js with d3

7,702 views
Skip to first unread message

Zach Bjornson

unread,
Apr 22, 2012, 5:48:47 AM4/22/12
to d3...@googlegroups.com
Hello,

I'm trying to use d3 with node.js. The following doesn't behave as I expect:

var d3 = require("d3"),
    jsdom = require("jsdom"),
    htmlStub = '<html><body><div id="chart"></div></body></html>';

jsdom.env(htmlStub, function(errors, window) {
    //with or without `Sizzle = require("sizzle")' here
    var vis = d3.select("#chart")
            .append("svg:svg")
            .attr("id", "background")
            .attr("width", 750)
            .attr("height", 750);
    var svgsrc = window.document.innerHTML;
    console.log(svgsrc);
});

$ node test.js
<html><body><div id="chart"></div></body></html>

Shouldn't this output have an svg div?

I've tried this as well:
jsdom.env({features:{QuerySelector:true}, html:htmlStub, done:function(errors, window) {
    var el = window.document.querySelector("#chart");
    var vis = d3.select(el)
    ...
or
    var el = window.document.getElementById("chart");
    var vis = d3.select(el)
    ...

both of which give "Error: Wrong document".

What am I missing here? I've tried a few other methods, borrowing from the d3 test suite, but not making any progress.

Thanks,
Zach

Mike Bostock

unread,
Apr 22, 2012, 12:28:35 PM4/22/12
to d3...@googlegroups.com
When you require("d3"), it creates a window and a document and
includes JSDOM for you. So you can say something like this:

var d3 = require("d3");

d3.select("body").append("div")
.attr("id", "chart")
.append("svg")
.attr("id", "background")
.attr("width", 750)
.attr("height", 750);

And then:

> window.document.innerHTML
'<html><head></head><body><div id="chart"><svg id="background"
width="750" height="750"></svg></div></body></html>'

Of course, this is missing <!DOCTYPE html>, so don't forget to add
that. Also, note that JSDOM doesn't really know about SVG. It will
still create SVG elements, but it doesn't support SVG's special APIs
(e.g., getBBox). Depending on what you are trying to do, you might
have better luck with PhantomJS.

Mike

Zach Bjornson

unread,
Apr 22, 2012, 8:15:13 PM4/22/12
to d3...@googlegroups.com
Neat and simple. Is this documented somewhere? (If not, may I suggest it be added to the d3 site?)

Thanks Mike!
Zach

infovis_enthusiast

unread,
Jun 4, 2012, 6:38:31 PM6/4/12
to d3...@googlegroups.com
Hello!

is there are a complete (short) example / tutorial that shows how to use node.js + d3.js? This would be very helpful!

Best Regards,
Sabri

infovis_enthusiast

unread,
Jun 4, 2012, 6:39:06 PM6/4/12
to d3...@googlegroups.com

Mateusz J

unread,
Jul 5, 2013, 2:48:11 PM7/5/13
to d3...@googlegroups.com
Hello,

I have similar problem. I am tryiing to generate SVG on the server side using d3.js and GeddyJS (NodeJS). I tried your solution but It does not work!

My code looks like:

Result looks  like:
[ SVG#background ]

I do not know what is wrong. 
Can someone give me hand?

Greetings,
Mateusz

Victor Powell

unread,
Jul 7, 2013, 9:31:04 PM7/7/13
to d3...@googlegroups.com
next time, you should remove all the commented out parts and post your code in a way that directly isolates the issue you're running into. for example, could we easily take that code and run it ourselves? well, no because `params` is undefined and so is `this.respond` fixing these issues your code runs fine:


var d3 = require("d3");
var xy = d3.geo.mercator().translate([-600, 4800]).scale(25000), path = d3.geo.path().projection(xy);
var l = d3.select("body").append("div")
  .attr("id", "chart")
  .append("svg")
  .attr("id", "background")
  .attr("width", 750)
  .attr("height", 750);

console.log(d3.select('body').node().innerHTML); // => <div id="chart"><svg id="background" width="750" height="750"></svg></div>

Dimitrios C. Michalakos

unread,
Apr 1, 2014, 9:28:41 AM4/1/14
to d3...@googlegroups.com, mbos...@cs.stanford.edu
Any idea why case sensitive tags get converted to lowercase?
e.g. append('svg:linearGradient') would produce <lineargradient /> instead of <linearGradient />

Cheers,

Nicolas Hasemann

unread,
Dec 9, 2014, 7:48:29 AM12/9/14
to d3...@googlegroups.com, sabri.h...@googlemail.com
Did you find an example tutorial?

Maxime Hebrard

unread,
Mar 26, 2015, 10:43:34 PM3/26/15
to d3...@googlegroups.com
Hello,

Hmm still confusing with d3 on node.js

I have a simple project on node.
a server.js which run,
a call to my script.js which run,

my script.js is :

console.log("RUN");
var d3 = require('d3');
console.log("d3 sel")
console.log(d3.select("body"));

but when I execute the server, I get this :

( exec : >node ./server.js )
RUN
d3 sel
*path\module\node_modules\d3\d3.js:562
    return n.querySelector(s);
               ^
TypeError: Cannot read property 'querySelector' of undefined
    at d3_select (*path\module\node_modules\d3\d3.js:562:13
.....

Do I miss something ?

Is there a proper way to use d3 on server side, to generate a SVG then send to client ?
Or definitively, d3 is client side ^_^.

Tanks
Maxime

Drew Winget

unread,
Mar 27, 2015, 2:07:31 PM3/27/15
to d3...@googlegroups.com
Node has no DOM. In the browser the "window" and "document" objects are defined in the javascript runtime. This is not so in node (by default); instead there is a default "global" object. Instead "this" is undefined by default. In order to work with a DOM, you need a browser environment like phantom. If you just need the markup, then try using the jsDOM node module.

--
You received this message because you are subscribed to the Google Groups "d3-js" group.
To unsubscribe from this group and stop receiving emails from it, send an email to d3-js+un...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Drew Winget

unread,
Mar 27, 2015, 2:08:13 PM3/27/15
to d3...@googlegroups.com
Reply all
Reply to author
Forward
0 new messages