Skip to content Skip to sidebar Skip to footer

How To Fill An Image Inside My Svg Circles In D3.js

This is my piece of code filling circles in my svg. var svgContainer = d3.select('body').append('svg') .attr('width', 1000)

Solution 1:

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

Solution 2:

Creating pattern from image uses too much of memory and using multiple images will create a serious performance issue. So to avoid that we can use clip-path over image.

Like this:

var config = {
  "avatar_size": 100
}

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

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

data = [{
  posx: 100,
  posy: 100,
  img: "https://cdn4.iconfinder.com/data/icons/seo-and-data/500/pencil-gear-128.png",
}, {
  posx: 200,
  posy: 200,
  img: "https://cdn4.iconfinder.com/data/icons/seo-and-data/500/gear-clock-128.png"
}, {
  posx: 300,
  posy: 300,
  img: "https://cdn4.iconfinder.com/data/icons/seo-and-data/500/magnifier-data-128.png"
}];


svg .append('clipPath')
   .attr('id','clipObj')  
        .append('circle')
         .attr('cx',config.avatar_size/2)
          .attr('cy',config.avatar_size/2)
         .attr('r',config.avatar_size/2);

data.forEach(function(d,i){
  svg.append('image')
     .attr('xlink:href',d.img)
     .attr('width',config.avatar_size)
     .attr('height',config.avatar_size)
 .attr('transform','translate('+parseInt(d.posx+config.avatar_size/2)+','+parseInt(d.posy+config.avatar_size/2)+')')
     .attr('clip-path','url(#clipObj)');
});

Also we can easily replace the clipping area with new one as we want. Here is the link of Code pen : http://codepen.io/anon/pen/VagxKp?editors=0010

Post a Comment for "How To Fill An Image Inside My Svg Circles In D3.js"