D3 Image SVG not showing

louislugas

I want to make a image fill inside svg circle, but avoid the "pattern" mode like in this Stackoverflow Link because of the circular positioning.

So I tried this:

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

defs
 .append("svg:image")
 .attr("id", "chara_avatar")
 .attr("xlink:href", imglink)
 .attr("width", 3*rad)
 .attr("height", 2*rad)
 .attr('x', (d,i)=>{ //same x position as the circle
   let x = (r * Math.sin(Math.PI * 2 * (i * 36) / 360)) + cx
   return x-rad;
   })
 .attr('y',(d,i)=>{ //same y position as the circle
   let y = (r * Math.cos(Math.PI * 2 * (i * 36) / 360)) + cy
   return y-rad;
   });

And directly use with "url('#chara_avatar')" :

var graphic = group
 .append('circle')
 .attr('cx', (d,i)=>{
   let x = (r * Math.sin(Math.PI * 2 * (i * 36) / 360)) + cx
   return x;
  })
 .attr('cy',(d,i)=>{
   let y = (r * Math.cos(Math.PI * 2 * (i * 36) / 360)) + cy
   return y;
  })
 .attr('r',rad)
 .style('fill', (d)=> {
   let init = d.val;
   if(init==1) {
     return "url(#chara_avatar)" // <------- called the url for fill
   } else if (init==0) {
     return 'black'
   }
   })
 .style('stroke', 'black')
 .style('stroke-width', '3px')
 .style('cursor',(d)=> {
   let init = d.val;
   if (init==1) {
     return 'pointer'
   }
  })

But it turns out like this: Screenshot 1

  • I got the position right, the element are there, but it doesn't show up.
  • The image tag AFAIK was properly put, but it shows only href not xlink:href even I write 'xlink:href'

If I change defs to group (append the image directly to group), it works and place the image above the circle, & I dont know how to clip it. I already used ClipPath but not working.

Screenshot 2

Full code example: Codepen Link

UPDATE:

Didn't find any good answer here, and I choose appending divs than svgs, it works with a bit more lines

Shreshth

This could be achieved by adding as many SVG <image> elements in appropriate location as circles needed.

Then you would use <clipPath> with <circle> inside them and "link" each circular clipPath to each <image>. Again the location of each circle should match the image it has to clip.

Attached a working codepen

Snippet:


<svg viewBox="0 0 1100 600" style="background-color: steelblue;">

  <defs>
    <clipPath id="clip-circle-0">
      <circle r="50" cx="100" cy="100"></circle>
    </clipPath>
  </defs>


  <image  href="https://images.unsplash.com/photo-1490730141103-6cac27aaab94?ixlib=rb-1.2.1&amp;ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&amp;auto=format&amp;fit=crop&amp;w=2070&amp;q=80" x="50" y="50" width="100" height="100" style="clip-path: url(#clip-circle-0)"></image>


</svg>

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related