1

I have the following code http://codepen.io/juanf03/pen/ZBYRNK

and I need to put a profile pic on the background, how can I do if the image comes as a squared image and I want to put it within the SVG circle? How do I do to resize the image along with the circle and the text on the click event handler? Do I have to make use add it to the g "elementGroup" I created like I did with the text and the circle? I ask this because of the resolution cause the image itself will not be an SVG but a raster.

    //listener that will be executed on setIntervalCheck to update the graphic   
setInterval(function(){
  console.log(dataset);
  moveForwardOnBubbleList();
  createElementGroup();
  }, 5000);



var profile_pic_url="https://scontent.fsst1-2.fna.fbcdn.net/v/t1.0-9/13680856_103268503450198_1479797031996897052_n.jpg?oh=f43bced91822fb210c8be8a410825da9&oe=58D46460";

var dataset = [{unique_followers: 5, profile_pic:profile_pic_url}, {unique_followers: 10, profile_pic:profile_pic_url},{ unique_followers: 15, profile_pic:profile_pic_url}, { unique_followers: 20, profile_pic:profile_pic_url}, { unique_followers: 25, profile_pic:profile_pic_url}, {unique_followers: 40, profile_pic:profile_pic_url} ];

var w=900,h=600;

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

//1st level:All circles group
var circlesGroup = svg.append("g").classed("general-group",true);
//2nd level: Group of circle and text
var elementGroup;

var circle;

var circleAttributes;
//create g's of existing data
createElementGroup();

elementGroup.on('click', function(d,i){
  var that=this;

  d3.selectAll('.element-group').each(function(d,i) {
    if(this.id!==that.id){
      d3.select(this).classed("selected",false);
    }
  });

  d3.select(this).classed("selected", !d3.select(this).classed("selected"));

  });

//adding circular background image to the circles
//var circlesSelection=svg.selectAll('circle');


function createElementGroup(){
  elementGroup = circlesGroup
  .selectAll('.element-group')
  .data(dataset, function(d){ return d.unique_followers});
 //doesn't work the exit transition 
   var elementExit = elementGroup.exit().transition().duration(1000).style("opacity", 0).remove();

  var elementEnter = elementGroup.enter()
  .append("g").classed("element-group",true).style("opacity",0);

    elementEnter.merge(elementGroup).attr("transform", function(d,i){

   //option 1 generation by mod   
   if(i%2===0){   
    return "translate(" + (i*80+45) + "," + h/1.55 + ")"; 
   }else{
    return "translate(" + (i*80+45) + "," + h/1.45 + ")"; 

   }

  /*   
  //option 2 random
  var random= (Math.random() * (1.6 - 1.45) + 1.45).toFixed(4);

         return "translate(" + (i*80+45) + "," + h/random + ")";*/ 


}).transition().duration(2000).style("opacity", 1.0);

    circle=elementEnter.append('circle');

  circleAttributes = circle
  .attr("r", 20)
  .attr("stroke","black")
  .attr("fill", "white")
  .classed("circle",true);

  //text to show
   var texts = elementEnter.append("text")
      .attr("text-anchor", "middle")
   .text(function(d) {
     return parseInt(d.unique_followers);
   })
     .style("pointer-events","none")
     .classed('tweet-number', true);

     //image to show as background

  //element group positioning for the text to be inside circle



}

function addBubbleLast(){

  var random=Math.floor(Math.random() * (40)) + 1;


    dataset.push({unique_followers: random, profile_pic:profile_pic_url});
}

function removeFirstBubble(){
  dataset.shift();

}

function moveForwardOnBubbleList(){
  addBubbleLast();
  removeFirstBubble();
}

//css

    body
    {
      /*padding-top: 50px;*/
      padding-left: 100px;
    }

    .tweet-number{
     opacity:0.25;
    }

    .circle{

    }

 .selected *{
      transform: scale(2);
      transition: all 0.5s ease;
      opacity:1.0;
}

.element-group *{
  transition: all 0.5s ease;
}
Kara
  • 6,115
  • 16
  • 50
  • 57
John
  • 1,711
  • 2
  • 29
  • 42

1 Answers1

0

I'm not JS savvy, but in HTML, you can put the image that comes as a squared image within the svg circle using the following code:

<svg width="100" height="100">
  <defs>
     <pattern id="image" patternUnits="userSpaceOnUse" height="100" width="100">
       <image x="0" y="0" height="100" width="100" xlink:href="http://i.imgur.com/7Nlcay7.jpg"></image>
    </pattern>
 </defs>
<circle id='top' cx="50" cy="50" r="50" fill="url(#image)"/>
</svg>

Hope this helps.

All credits go to Teo Inke

Community
  • 1
  • 1
Ibrahim
  • 6,006
  • 3
  • 39
  • 50
  • 1
    Have you used that pattern technique on d3, do you have an example? – John Nov 06 '16 at 19:03
  • I've researched your proposed solution but it doesn't work on this case since I need a different image for every circle......it dependes on a url that is in each object... – John Nov 06 '16 at 23:43
  • Unfortuanatly, I don't have an example on d3. I just thought we can build it on d3 using a similar structure. sorry @Juan – Ibrahim Nov 06 '16 at 23:48
  • @juan http://stackoverflow.com/questions/14610954/can-an-svg-pattern-be-implemented-in-d3 – Robert Longson Nov 07 '16 at 05:02
  • But where should I append the defs/pattern?to which object, svg or to the group that contains the circle and the label?...cause in that example the guy has only one node and uses only one url for the picture....I need to use a different url for each group of circle/label.....should I create one def/pattern per circle? With the corresponding url for that circle and then reference it from the circle? I'm a little lost with this. all of the pattern examples use only one node with one url, I need to use the profile_pic url of each object, which in this case I used the same string but are different – John Nov 07 '16 at 12:48