So you come across an SVG on a website, and you want to save it to a file. Maybe you want to send it by email, or put it in a presentation, etc. You think, “I know, I’ll just right-click on it and Save as…” Wrong! This saves the webpage itself. In fact, there is no easy way to do this. You can find plenty of people online who also want this functionality, but I haven’t found any solutions that render directly to an svg. I’ve found solutions that render to a PDF, but there are limitations and issues with PDFs. Besides, once you have a real SVG, you can then use other tools to convert it to whatever format you want very easily.
What to do… Well, I spent some time poking around with SVG files and D3 SVG visualizations to figure out how they compared. I noticed that the structure of the HTML <svg> tag and its descendents looked the same as the structure of the SVG element in SVG files. The only difference is that the SVG element in SVG files included two XML namespace attributes as well:
<svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" width="620" height="90">
That’s a pretty simple fix, but it’s not quite enough. Now, we need to add a proper doctype header:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
We’re almost there! If you then put these two pieces together in a new file, your SVG may look correct. If your SVG is a D3 visualization, probably not. D3 SVGs use CSS style rules to specify how SVG elements look. Luckily, HTML and SVG use the same CSS mechanism. We simply need to insert all the relevant CSS rules in a new <style> tag under the <svg> tag.
Ok, great, but this is a bit tedious… Yeah, I know, so I wrote svgrab. It’s a node.js script, so install node and npm. Then install the script: npm install -g svgrab. Now you can grab export SVGs from websites to a file like a pro! You can also define a timeout to wait for, since some D3 visualizations are time-dependent. Under the covers, svgrab runs phantomjs, which renders the website in a headless environment. It then selects the first SVG element (you can optionally specify another SVG element if you need) and performs the transformations above.
Now when you need to share your awesome D3 visualization somewhere other than in a browser, you can render to SVG (and then to something else if needed) much easier!