Search code examples
javascriptcsssvgd3.jssvg-filters

Is there any possibility to cut to a shape an image that can be moved with d3 (jquery)


I am creating a bubble graph, the problem is that I wish to add some images inside the bubbles.

I am using this code: http://bl.ocks.org/mbostock/4062045

I bigger circle (around 20px radius) and I would like to have an image as filling of the circle and a black stroke (circle).

By now what I have is a Filter with inside a feImage that filter the circle. The problem is that the image move correctly but is still a square.

I tried adding a with a circle inside, but when I apply the clipping the area of the svg clipped is fixed (I can see the image moving behind it).

How can I fix this?

<filter id="Myriel" x="0%" y="0%" width="100%" height="100%"> <feImage xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="img/vangogh.jpg"></feImage> </filter>

This is what result out from the d3 code, then is used with filter="url(#Myriel)" for example

Now I am using this, but is not working:

<filter id="Myriel" x="0%" y="0%" width="100%" height="100%">
    <feImage xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="img/vangogh.jpg" result="img1">
    </feImage>
    <circle r="15" result="circ"></circle>
    <feComposite operator="atop" in="img1" in2="circ"></feComposite>
</filter>

Solution

  • You can accomplish the same task using svg clippath.

    node.append("circle")
        .attr("r", function(d) {
            return d.radius + 2;
        })
        .style("fill", function(d) {
            return color(1 / d.rating);
        });
    
    node.append("clipPath")
        .attr('id', function(d, i) {
            return "clip" + i
        })
        .append("circle")
        .attr("class", "clip-path")
        .attr("r", function(d) {
            return d.radius;
        })
        .style("fill", function(d) {
            return color(1 / d.rating);
        });
    
    node.append("svg:image")
        .attr("class", "circle")
        .attr("xlink:href", "https://c1.staticflickr.com/9/8086/8466271529_dc5c0a958f.jpg")
        .attr("clip-path", function(d, i) {
            return "url(#clip" + i + ")"
        })
        .attr("x", function(d) {
            return -d.radius;
        })
        .attr("y", function(d) {
            return -d.radius;
        })
        .attr("width", function(d) {
            return d.radius * 2;
        })
        .attr("height", function(d) {
            return d.radius * 2;
        });
    

    I have made a JSFiddle for the same. Hope this helps.