Adding an Image Within a Circle Object in D3 JavaScript

Adding an image within a circle object in d3 javascript?

As Lars says you need to use pattern, once you do that it becomes pretty straightforward. Here's a link to a conversation in d3 google groups about this. I've set up a fiddle here using the image of a pint from that conversation and your code above.

To set up the pattern:

    <svg id="mySvg" width="80" height="80">
<defs id="mdef">
<pattern id="image" x="0" y="0" height="40" width="40">
<image x="0" y="0" width="40" height="40" xlink:href="http://www.e-pint.com/epint.jpg"></image>
</pattern>
</defs>
</svg>

Then the d3 where we only change the fill:

svg.append("circle")
.attr("class", "logo")
.attr("cx", 225)
.attr("cy", 225)
.attr("r", 20)
.style("fill", "transparent")
.style("stroke", "black")
.style("stroke-width", 0.25)
.on("mouseover", function(){
d3.select(this)
.style("fill", "url(#image)");
})
.on("mouseout", function(){
d3.select(this)
.style("fill", "transparent");
});

How to Add Image to Circle Dynamically in D3js

You cannot append a <defs>, a <pattern> and a <image> to a circle. That won't work.

Instead of that, you have to create the <defs>, append the patterns and images, and fill the circles according to their unique IDs:

var defs = g.append("defs");

defs.selectAll(".patterns")
.data(insects[i], function(d) {
return d
})
.enter().append("pattern")
.attr("id", function(d) {
return "insect" + (d[0].split(" ").join(""))
})
.attr("width", 1)
.attr("height", 1)
.append("svg:image")
.attr("xlink:href", function(d) {
return d[1]
})
.attr("width", 40)
.attr("height", 40);


g.selectAll("circle")
.data(insects[i], function(d) {
return d
})
.enter().append("circle")
.attr('cx', function(d, index) {
return x(insects[i].length) / insects[i].length * index;
})
.attr("r", 20)
.attr("cy", function(d, index) {
return y.bandwidth() * i
})
.style("fill", function(d) {
return "url(#insect" + (d[0].split(" ").join("")) + ")"
});
}

Here is your updated plunker: http://plnkr.co/edit/WLC2ihpzsjDUgcuu910O?p=preview

PS: Your code is working, but I have to say that your for loop is unnecessary (and even awkward) in a D3 dataviz. This is not the D3 way of accessing the data. Thus, I suggest you completely refactor your code in that block.

How to fill an image inside my svg circles in d3.js

Imagine you have a dataset like this:

data = [{
posx: 100,
posy: 100,
img: "https://cdn0.iconfinder.com/data/icons/flat-round-system/512/android-128.png",

}, {
posx: 200,
posy: 200,

img: "https://cdn1.iconfinder.com/data/icons/social-media-set/24/Reverbnation-128.png"
}, {
posx: 300,
posy: 300,

img: "https://cdn1.iconfinder.com/data/icons/user-pictures/100/male3-128.png"
}]

Make defs like this in svg like this:

var defs = svg.append('svg:defs');

Iterate over all the data and make as many defs with image and circle.
Inside circles's fill pass the def's id like this .style("fill", "url(#grump_avatar" + i + ")");

data.forEach(function(d, i) {
defs.append("svg:pattern")
.attr("id", "grump_avatar" + i)
.attr("width", config.avatar_size)
.attr("height", config.avatar_size)
.attr("patternUnits", "userSpaceOnUse")
.append("svg:image")
.attr("xlink:href", d.img)
.attr("width", config.avatar_size)
.attr("height", config.avatar_size)
.attr("x", 0)
.attr("y", 0);

var circle = svg.append("circle")
.attr("transform", "translate(" + d.posx + "," + d.posy + ")")
.attr("cx", config.avatar_size / 2)
.attr("cy", config.avatar_size / 2)
.attr("r", config.avatar_size / 2)
.style("fill", "#fff")
.style("fill", "url(#grump_avatar" + i + ")");

})

working code here

Inspired from this SO answer



Related Topics



Leave a reply



Submit