Last active
May 20, 2022 16:56
-
-
Save mef/7044786 to your computer and use it in GitHub Desktop.
proof-of-concept pre-rendering d3.js svgs on the server using node.js and jsdom module.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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 |
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
i get the content in the "index.html" as "undefined", can you tell me why it is??