Question

I have a page that runs javascript on load that renders a map in SVG using d3. I want to automatically get a copy of that HTML + SVG. I can't just curl the the server -- that just returns the HTML of the page before the javascript runs. I guess I could use selenium or zombiejs -- but is there an easier way?

Was it helpful?

Solution

We had to do something very similar lately. Here are few things we tried:

  • Using jsdom
  • Use phantomjs to visit the page and grab output
  • Rewrite using some server side language + data format
  • Don't manipulate DOM at all

JSDOM

Ya, it supports SVG, but NOT SVG 1.1. Which means the text element doesn't work among other things. It may eventually have this support though.

PhantomJS

This worked but it is potentially slow. The only way you can tell if the SVG is done rendering is by adding a class or element to the page and have phantom wait for that object to appear. Once it does grab the svg element using standard DOM operations. For about 1k objects on screen after a few ajax calls this took maybe 5 seconds. 6k objects, it took around a minute.

Rewrite on the server side

Ultimately, we had to do this since we had a LOT of objects on screen. We had some data model that we took and mimic'd the output. This is faster since it's string based and doesn't require a bunch of DOM look ups/writes and not spinning up a leaky browser is also a plus. The down side is that you'll have 2 implementations of the same code.

Don't use D3 or Raphael

If you are able to write SVG using strings/templates then you can use the same JS on the client and server side. This by far seems like the best approach in retrospect. If I was able to go back I'd have acted more disgruntled towards the fact that we were using Raphael and just pushed hard on using handlebars, backbone, rendr and a node server.

OTHER TIPS

You can render the svg by running d3 server side via nodejs (as @meetamit hinted towards) and then serialize it to a file.

Here is a guide to do it: Creating an SVG file with D3 and Node.js

The issue is that you'd have to render the Javascript at some point, which CURL cannot do. I would try looking into something like http://phantomjs.org/

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top