Russ Clark Russ Clark - 1 month ago 8
Javascript Question

How to add an image to an svg container using D3.js

I've created a sample Asp.Net MVC 4 application where I've used D3.js to append an SVG element and then inside the SVG I've appended a text element (see code below). This all works fine until I try to append an img to the SVG using a local png file. The img gets appended to the DOM, but the img is not rendered on the page. Any ideas what I'm doing wrong here, and how to go about fixing it?

@{
ViewBag.Title = "Home Page";
}

<script src="~/Scripts/d3.v3.js"></script>
<script type="text/javascript">
var svg = d3.select("body")
.append("svg")
.attr("width", 200)
.attr("height", 100)
.style("border", "1px solid black");

var text = svg.selectAll("text")
.data([0])
.enter()
.append("text")
.text("Testing")
.attr("x", "40")
.attr("y", "60");

var imgs = svg.selectAll("img").data([0]);
imgs.enter()
.append("img")
.attr("xlink:href", "@Url.Content("~/Content/images/icons/refresh.png")")
.attr("x", "60")
.attr("y", "60")
.attr("width", "20")
.attr("height", "20");

</script>


@Richard Marr - Below is an attempt to do the same thing in straight HTML, which gives me the same result. I'm not sure about my code to get the refresh.png file from the local drive this way.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<script src="http://d3js.org/d3.v2.js"></script>

</head>
<body>
<script type="text/javascript">
var svg = d3.select("body")
.append("svg")
.attr("width", 200)
.attr("height", 100)
.style("border", "1px solid black");

var text = svg.selectAll("text")
.data([0])
.enter()
.append("text")
.text("Testing")
.attr("x", "40")
.attr("y", "60");

var imgs = svg.selectAll("img").data([0]);
imgs.enter()
.append("svg:img")
.attr("xlink:href", "file:///D:/d3js_projects/refresh.png")
.attr("x", "60")
.attr("y", "60")
.attr("width", "20")
.attr("height", "20");

</script>
</body>
</html>

Answer

In SVG (contrasted with HTML), you will want to use <image> instead of <img> for elements.

Try changing your last block with:

var imgs = svg.selectAll("image").data([0]);
            imgs.enter()
            .append("svg:image")
            ...