<image> inside d3 SVG graph doesn't show up when page is saved locally

2,078 views
Skip to first unread message

Simon

unread,
Jun 26, 2012, 10:51:37 AM6/26/12
to d3...@googlegroups.com
Hello,

I have embedded some PNG images in a d3 bar graph like this:

chart.selectAll("img.geoflags")
.data( labels )
.enter()
.append( "svg:image" )
.attr( "x", function(d,i) {return chart.xscale(i) - flagWidth/2;} )
.attr( "y", height + properties.margin.top*2 )
.attr( "xlink:href", function(d) {return "/images/flags/png/" + d.toLowerCase() + ".png";} )
.attr( "width", flagWidth )
.attr( "height", flagHeight );

And they show up fine when the page is opened online. However, when I save a copy of the webpage locally, everything else in the graph shows up fine, except the images don't load at all, even though the <image> tags are clearly there. (and I did change the image hrefs to absolute URLs in my local copy)

Any ideas why the images aren't loading? Thanks!

Scott Murray

unread,
Jun 26, 2012, 11:13:03 AM6/26/12
to d3...@googlegroups.com
Are you viewing the page as a local file, or through a locally hosted web server, e.g. at http://localhost/project/...?

You'll need to do the latter. Use MAMP or see Python web server instructions here: https://github.com/mbostock/d3/wiki

Scott


Simon

unread,
Jun 26, 2012, 11:26:14 AM6/26/12
to d3...@googlegroups.com
Hi Scott,

Thanks for the reply, and I am viewing the page as a local file (and it needs to be a local html file - for example, for emailing that file to other people)

Why does it have to be on a web server to load those images? Does SVG have cross domain issues with images? 

All the <img> tags in the local file work fine, it's just the <image> tags within <svg> that don't load (even if I try the same absolute URL in both <img> and <image>). 

Thanks!

Scott Murray

unread,
Jun 26, 2012, 11:32:32 AM6/26/12
to d3...@googlegroups.com
You may not be able to simply email the files to other people, as they, too, will need to view the project as served through a server.

Browsers vary, but the basic idea is that, normally, when browsers see a reference to an external file (such as an HTML <img> tag), they attempt to connect to a server at the specified domain and path, and request a copy of the file. In my experience, most browsers are flexible enough to know that when opening a file on the local disk, if there's an <img> reference, they can just grab the file off the disk. But it seems you've discovered that SVG <image> tags aren't handled as flexibly. (I bet if you open the dev tools console, you will see an "error loading image..." message.)

Bottom line is that to share the project with others, you'll probably need to put it on a server somewhere and just share a link.

Scott

Chris Michael

unread,
Jun 26, 2012, 11:36:27 AM6/26/12
to d3...@googlegroups.com
It could that that when you save the file, you are saving the HTML that was first served up. However, after the file is served you are then using JavaScript to manipulate the DOM (eg add the svg elements). When you save the file you are saving the page as it was before the manipulation.

Could you post an example file?
Message has been deleted

Simon

unread,
Jun 26, 2012, 11:52:23 AM6/26/12
to d3...@googlegroups.com
I was actually saving a copy of the entire DOM as-is with jQuery - $('html').html() - so it should be after all the javascript has run.

I also tested uploading that html file to my server and tried both absolute and relative <image> href URLs, but still no luck - all the <img> tags load, but none of the <image> tags.

Ian Johnson

unread,
Jun 26, 2012, 12:07:48 PM6/26/12
to d3...@googlegroups.com
This is because the namespace attributes are removed from the image tags, you need to run a couple of regex on the html text before saving it:

var svg = ... //your html text goes into here
svg = svg.replace(/\ xlink/g, ' xmlns:xlink')
svg = svg.replace(/\ href/g, ' xlink:href')

I don't know why chrome/webkit does not give you the namespace attributes, its the same if you inspect with the console.
--
Ian Johnson

Simon

unread,
Jun 26, 2012, 12:30:16 PM6/26/12
to d3...@googlegroups.com
Hi Ian,

Thank you, that fixed it!

It was strange that even though I created those images with .attr( "xlink:href"), it ended up in the DOM as just 'href'. All it took was replacing 'href' with 'xlink:href' in my local file.

Chris Viau

unread,
Jun 27, 2012, 12:06:32 PM6/27/12
to d3...@googlegroups.com
You can also double the xlink namespace like this .attr('xlink:xlink:href', ...) and it will appears as xlink:href in the DOM.
Reply all
Reply to author
Forward
0 new messages