Create a gist now

Instantly share code, notes, and snippets.

@mef /pre-render.js
Last active Jul 12, 2017

What would you like to do?
proof-of-concept pre-rendering d3.js svgs on the server using node.js and jsdom module.
// pre-render d3 charts at server side
var d3 = require('d3')
, jsdom = require('jsdom')
, fs = require('fs')
, htmlStub = '<html><head></head><body><div id="dataviz-container"></div><script src="js/d3.v3.min.js"></script></body></html>'
jsdom.env({
features : { QuerySelector : true }
, html : htmlStub
, done : function(errors, window) {
// this callback function pre-renders the dataviz inside the html document, then export result into a static file
var el = window.document.querySelector('#dataviz-container')
, body = window.document.querySelector('body')
, circleId = 'a2324' // say, this value was dynamically retrieved from some database
// generate the dataviz
d3.select(el)
.append('svg:svg')
.attr('width', 600)
.attr('height', 300)
.append('circle')
.attr('cx', 300)
.attr('cy', 150)
.attr('r', 30)
.attr('fill', '#26963c')
.attr('id', circleId) // say, this value was dynamically retrieved from some database
// make the client-side script manipulate the circle at client side)
var clientScript = "d3.select('#" + circleId + "').transition().delay(1000).attr('fill', '#f9af26')"
d3.select(body)
.append('script')
.html(clientScript)
// save result in an html file, we could also keep it in memory, or export the interesting fragment into a database for later use
var svgsrc = window.document.innerHTML
fs.writeFile('index.html', svgsrc, function(err) {
if(err) {
console.log('error saving document', err)
} else {
console.log('The file was saved!')
}
})
} // end jsDom done callback
})
// no semi-column was harmed during this development

i get the content in the "index.html" as "undefined", can you tell me why it is??

Same here

Line 37 should become:

var svgsrc = window.document.documentElement.innerHTML

@Climax777 indeed that fixed it.

Also note that jsdom need to be 3.x.x as 4.0.+ does not support node.js

Also, if you plan on using d3.json, you need to pull the XMLHTTPRequest from here, because otherwise you get get the following error:
dirname/node_modules/d3/d3.js:1931
oresend", "progress", "load", "error"), headers = {}, request = new XMLHttpReq
ReferenceError: XMLHttpRequest is not defined

@Climax777 mad props. Thanks so much!

thx, here is my first pass at using node to render js (OWASP/Maturity-Models@f35b924)

Give d3-node a try.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment