zlog
zlog

Reputation: 3316

How do you append a svg image to a rect element of another svg image?

I trying to append a svg image to a rect element in a svg image, using d3 and trying

chart.selectAll("rect.bar")
  .each(function(datum, index) {
    d3.select(this)
      .append("svg:image")
        // ..some attributes
  });

This adds <image> to the dom, but the image does not show. I've also tried using jquery to select this in the .each block, which adds it to the dom, but also doesn't show.

For jquery I've added it with

$(this).after("<svg:image xlink:href='/images/image.svg' x='20' y='20' width='20' height='20'/>");

with the svg and xlink namespaces in the html element

<html lang="en" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">

I've been able to create one image per rect.bar with .selectAll, but I want to create more based on the datum value.

Upvotes: 1

Views: 5696

Answers (3)

Information Technology
Information Technology

Reputation: 2333

I don't know if it matters to you but I believe you can do this without the use of jquery. Mike Bostock's "D3 Workshop" presentation shows how to properly select and append elements within the DOM.

Once you can select any element, you can append any SVG drawing (e.g. a rect, circle, text, etc. and even external images). To control the placement of the image that is appended, I believe you can simply use the "dx" and "dy" coordinate offset controllers.

In the example, "Multiple D3 Pie Charts Mixed With Common HTML Layout Constructs", I first create multiple SVG canvases based on HTML DIV locations on the HTML page. I then place the bars at specific locations on the SVG canvas. Then I append and place the legend bullets at different points on the same SVG canvas. Finally, I append the and place the legend text on the same SVG canvas at different locations. In each case, I use the dx and dy coordinate controllers to control the placement of the objects.

I hope this helps,

Frank

Upvotes: 1

zlog
zlog

Reputation: 3316

I needed to use jquery to select the parent element so that the image does not get put inside the rect.bar element, but alongside it. Code here:

chart.selectAll("rect.bar")
  .each(function(datum, index) {
    var rectBar = $(this).parent()[0]; // Needs parent object, otherwise it will append inside rect
    var num = 4;

    for (var i = 0; i < num; i++) {
      d3.select(rectBar)
        .append("svg:image")
          // ...some attributes
    }
  });

Also .parent() by itself didn't work. I needed to explicitly do .parent()[0]. Not sure why.

Upvotes: 2

Adil
Adil

Reputation: 148150

Try it like this.

chart.selectAll("rect.bar")
  .each(function(datum, index) {
    $(this).append("<img href='http://www.mysite.com/images/test.jpg' />")
        // ..some attributes
  });

Upvotes: 0

Related Questions