0

I am quite new to d3 and to js in general, so please bear with me :) I'm working with the tree layout in d3, and am having the following problem.

I'm trying to get the circles that i appended on the nodes to display an image as background-image. I've seen related posts on how to do this by creating patterns and then appending an image to it.

In my case things are slightly different, as i need the image to be extracted from the json object. In other words, each node should have as background image the corresponding image linked under the field "image" in my json object. The json object i'm working with looks something like

"people": [{
  "name": "John",
  "parent_id": "123",
  "image:http://test.test.com/img2.png"
}, {
  "name": "Paul",
  "parent_id": "687",
  "image:http://test.test.com/img42.png"
} {
  "name": "George",
  "parent_id": "325",
  "image:http://test.test.com/img85.png"
} {
  "name": "Ringo",
  "parent_id": "163",
  "image:http://test.test.com/img93.png"
}]

so i'm trying to get the node with text appended "Ringo" to have as background the image img93.png...

Hope this makes sense, thanks to all in advance...

Seth
  • 10,198
  • 10
  • 45
  • 68
Dodo bird
  • 1
  • 2
  • 2
    See http://stackoverflow.com/questions/7306250/does-force-directed-layout-of-d3-js-support-image-as-node – Lars Kotthoff Dec 02 '14 at 17:10
  • @LarsKotthoff, thanks for your prompt reply, but i'm trying to get each node to display the corresponding image in the array, not the same one on all nodes..can't really find a solution in the suggested post..am I not getting it? thanks though! :D – Dodo bird Dec 02 '14 at 17:23
  • 2
    So it would be `.attr("xlink:href", function(d) { return d.image; })`. BTW, the formatting of your JSON seems to be wrong, the quotes after `image` and after the `:` are missing. – Lars Kotthoff Dec 02 '14 at 18:07
  • Thanks for your reply...and thanks for noticing the quotes, luckily this was an example array, non what i'm actually using..Your answer seems right to me, but this returns the image appended to the node, not as background of a "rect" or "circle" appended to the node...you see, my problem is that the json objects are generated by other users, so the images come in different aspect ratios...setting them as background images would allow me to uniform their size and maintain their aspect ratio. – Dodo bird Dec 02 '14 at 20:59

1 Answers1

0

As suggested in @LarsKotthoff's answer here, define the image as a pattern and then fill.

var data = [{
  "name": "John",
  "parent_id": "123",
  "image": "http://placehold.it/50&text="
}, {
  "name": "Paul",
  "parent_id": "687",
  "image": "http://placehold.it/50&text="
}, {
  "name": "George",
  "parent_id": "325",
  "image": "http://placehold.it/50&text="
}, {
  "name": "Ringo",
  "parent_id": "163",
  "image": "http://placehold.it/50&text="
}];

var svg = d3.select("body")
  .append("svg")
  .attr("width", 1000)
  .attr("height", 150);

svg.append("defs")
  .selectAll("pattern")
  .data(data)
  .enter()
  .append("pattern")
  .attr('id', function(d, i) {
    return d.name;
  })
  .attr('patternUnits', 'userSpaceOnUse')
  .attr('width', 50)
  .attr('height', 50)
  .append("image")
  .attr("xlink:href", function(d) {
    return d.image + d.name;
  })
  .attr('width', 50)
  .attr('height', 50);

var circle = svg.selectAll("circle")
  .data(data)
  .enter().append("circle")
  .attr("cy", 70)
  .attr("cx", function(d, i) {
    return (i + 1) * 100;
  })
  .attr("r", 50)
  .attr("fill", function(d) {
    return "url(#" + d.name + ")";
  });

Example here.

Community
  • 1
  • 1
Mark
  • 106,305
  • 20
  • 172
  • 230