Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Exporting D3.js graphs to static SVG files, programmatically

Tags:

I'm generating a large number of D3 graphs programmatically. They currently consist of HTML with SVG, CSS, and JS.

I would like to export these graphs to plain SVG programmatically. I'm having trouble figuring out how to do this.

The closest solution I found is this: Convert JavaScript-generated SVG to a file -- but the problem is that I need to do it programmatically, rather than by using a tool like Chrome Developer Tools or SVG Crowbar which requires manual clicking/saving.

I'd prefer to use Python, but at this point I am open to any tools/programming language.

like image 948
coffee-grinder Avatar asked Aug 14 '13 19:08

coffee-grinder


2 Answers

Here's what I would do:

  1. Download and install phantomjs, which is a headless webkit browser you can run from the command line and automate via scripts.

  2. Save this javascript as renderHTML.js:

    var args = require('system').args,
        page = require('webpage').create(),
        url = args[1];
    
    page.onConsoleMessage = function (msg) {
        console.log(msg);
    };
    
    page.onLoadFinished = function() {
        page.evaluate(function() {
            console.log(document.documentElement.outerHTML);
        });
        phantom.exit();
    };
    
    page.open(url);
    
  3. Run phantomjs with the above script specifying the url to render, like so:

    phantomjs renderHTML.js {urltorender} > {localfiletosave}
    
  4. You now have the entire HTML content of the document at the specified URL, including dynamic content modifications done via javascript (until page load) in a local file. Post process the local file to meet your requirements using whatever language you like.

If you need further javascript modifications before saving the file, you can use the phantomjs api to dispatch and/or wait for events before calling console.log. Just modify the script in step 2.

If you happen to know and like javascript, you can skip step 4 and put whatever "post processing" you have in mind directly into the script in step 2.

like image 145
Ray Waldin Avatar answered Sep 18 '22 13:09

Ray Waldin


I wrote a short Javascript program to do this.

You can get it off npm by running npm install -g playfair (code is on GitHub at manleyjster/playfair).

It runs from the command line, and it works by firing up PhantomJS, pointing it to an html file (which you pass in on the command line), and then capturing the first SVG element that it finds on the page.

You can also pass in an id via a command line option to select an SVG element by id.

The meat of the program is this function:

function getSvg(selector) {
    var svgNode, tmp;

    svgNode = document.querySelector(selector);

    if (svgNode) {
        tmp = document.createElement('div');
        tmp.appendChild(svgNode);
        result = { text: tmp.innerHTML };
    } else {
        result = {};
    }

    return result;
}
like image 23
Justin Manley Avatar answered Sep 19 '22 13:09

Justin Manley