I have used d3.js to generate svg/html on the server using node and jsdom. I have also tested the use of d3 on the server in a web request to generate dynamic svg/html to then use in a template/view (ejs). The problem with this is any significant d3.js code will block the server and will force additional web requests to wait until the svg/html is generated. Is there a way to generate dynamic svg/html in a web request using d3 in nodejs/express without blocking the server?
I've wondered if there is an asynchronous way to write d3, or perhaps a way to use additional workers to generate the svg/html with d3 (and jsdom) in a way that avoids blocking.
Here are some reasons one might want to do this on the server instead of the client: pre-rendering the svg/html and using it in an express template will provide uniform page loading for the user without the "flash" of svg/html being drawn after the page loads like when using d3 in the client. You could also avoid having to send a lot of data to the browser and you could keep d3 code proprietary.
Here is a basic example of what I mean by using d3 in an express route which could block the server for other incoming web requests.
app.get("/", async function(req, res) {
// get dynamic data from database based on req.query
let data = await dbConnection.query(dynamic_sql)
// create simulated DOM using jsdom. This step will block server.
const { document } = (new JSDOM(``)).window;
// use d3 to draw svg. This step will block server.
let selection = d3.select(document).select("body")
selection.selectAll("circle")
.data(data).enter()
.append("circle").attr("r", 5).attr("cx", 10).attr("cy", 10)
// extract svg string
let svgString = selection.node().innerHTML
// pass svgString to template to render page for client
res.render("/", {svgString: svgString})
}
Please let me know if you have any thoughts!