DEV Community

stereobooster
stereobooster

Posted on • Originally published at stereobooster.com on

Run Cystoscape.js with Node.js

Why? If you need to generate an image on the server side.

At first, I thought it was impossible. There is cytosnap that uses Puppeteer (headless browser). Then, for fun, I rewrote it with Tauri.

But later, I though, what if it would be possible to run it with Node.js. And, indeed, it’s possible.

Solution

Add polyfils for the browser (it also includes canvas):

class XMLSerializer { serializeToString(node) { return serialize(node); } } global.XMLSerializer = XMLSerializer; const dom = new JSDOM(`<!DOCTYPE html><div id="cy"></div>`); global.window = dom.window; global.document = dom.window.document; 
Enter fullscreen mode Exit fullscreen mode

Explicitly set bounding box

source.layout.boundingBox = { x1: 0, y1: 0, x2: source.width, y2: source.height, }; 
Enter fullscreen mode Exit fullscreen mode

Generate a graph the same way you would in the browser:

const container = dom.window.document.querySelector("#cy"); const cy = cytoscape({ container, ...defaults, ...source }); cy.layout(source.layout).run(); 
Enter fullscreen mode Exit fullscreen mode

For now I was able to render it only as SVG:

await loadExtension("svg"); res = cy.svg({ bg: source.background, full: true, }); 
Enter fullscreen mode Exit fullscreen mode

In order to not polute global scope with polyfills we can run this script as sub-process:

const executablePath = `bin/cyto-nodejs.js`; const bin = spawn(executablePath, args, { windowsHide: true, }); 
Enter fullscreen mode Exit fullscreen mode

That’s it.

Source code

Source code is here: https://github.com/stereobooster/cyto-nodejs

Top comments (0)