Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

All circle elements stuck behind each other

I'm trying to append circles that have a color background with an image attached.

To achieve that am using <defs>, <rect> <clipPath> and <use>. I believe that my SVG hierarchy is valid, however even though all elements have a unique ID all circles are got stuck in the same point. All <a> elements itself that contain defs in it are having different x and y, but rects inside it are having same x and y.

How is it possible that all rects having a unique ID having same x's and y's.

Codepen

DOM screenshot:

enter image description here

 let personCircles = svg.selectAll("a")
            .data(data)
            .enter()
            .append("a")
            .attr("id", function(d) {
                console.log(d["Person Name"]);
                if (d && d.length !== 0) {
                    return d["Person Name"].replace(/ |,|\./g, '_');
                }
            })
            .attr('x', function(d) {
                    return markerCirclesScale(name)
                })
                .attr('y', function(d) {
                    return fullSVGHeight / 2 + 8;
                })
            .style("opacity", 1)
            .call(d3.drag()
                .on("start", dragstarted)
                .on("drag", dragged)
                .on("end", dragended));




        //Define defs 
        let defs = personCircles.append("defs");

        defs.append('rect')
            .attr('id', function(d) {
                    return "rect-" + d["Person Name"].replace(/ |,|\./g, '_');
            })
            .attr('x', function(d) {
                return markerCirclesScale(name)
            })
            .attr('y', function(d) {
                return fullSVGHeight / 2;
            })
            .attr('width', 60)
            .attr('height', 60)
            .attr('rx', 40)
            .style('fill', 'red')


        defs.append("clipPath")
           .attr('id', function(d) {
                    return "clip-" + d["Person Name"].replace(/ |,|\./g, '_');
            })
            .append("use")
            .attr('href', function(d) {
                    return "#rect-" + d["Person Name"].replace(/ |,|\./g, '_');
            })

         personCircles
                .append("use")
                .attr('href', function(d) {
                    return "#rect-" + d["Person Name"].replace(/ |,|\./g, '_');
            })
            personCircles.append('image')
                .attr('href', function(d) {
                    return 'http://pngimg.com/uploads/donald_trump/donald_trump_PNG72.png'
                })
                .attr("clip-path", function(d) {
                    return "url(#clip-" + d["Person Name"].replace(/ |,|\./g, '_');+")"
                })
                .attr('x', function(d) {
                    return markerCirclesScale(name)
                })
                .attr('y', function(d) {
                    return fullSVGHeight / 2 + 8;
                })
                .attr("width", 60)
                .attr("height", 60)
like image 520
Edgar Kiljak Avatar asked Mar 06 '26 15:03

Edgar Kiljak


1 Answers

personCircles refers to the <a> (anchor) elements which wouldn't move an inch if you set x and y co-ordinates within a SVG. The elements you're trying to position are the rects and the corresponding images and so changing the ticked function to the following i.e. positioning the rects, clipPath rects and the image:

function ticked() {
    personCircles.selectAll('rect, image') 
        .attr("x", function(d) { return d.x; })
        .attr("y", function(d) { return d.y; });
}

the result would be as seen in the following fork of your codepen:

https://codepen.io/anon/pen/aPOdON?editors=1010

Hope this clears up. Btw I like the sample image you're using in your testing :P

like image 91
Shashank Avatar answered Mar 08 '26 05:03

Shashank



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!