简体   繁体   中英

D3 Clippath Mouseover event not working

wizards,

I'm having some trouble with a mouseover event on clippath. For some reason it is not triggering and I think it's due to the fact that the elements are clipping an image of the Dude.

My goal is to alert the userid (1, 2 or 3 in the example - the 4th element in the "dots" table) of the hovered element.

I've loaded it into a jsfiddle:

https://jsfiddle.net/vk1jc8ah/4/

Can someone make it work - or suggest another way of achieving the same goal?

HTML:

<div class="projectbounds" style="width:400px; height:300px; background-color:#000000;"></div>

JS:

var size = 30,
    w = 400,
    h = 300,
    dots = [];

dots.push([101, 200, 0, 1, 1]);
dots.push([170, 120, 0, 2, 1]);
dots.push([210, 150, 0, 3, 1]);

var svg = d3.select(".projectbounds")
    .append("svg:svg")
    .attr("id", "robsvg")
    .attr("width", w)
    .attr("height", h)
    .style("cursor", "pointer");

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

var imgbg = svg.append('svg:image')
    .attr('xlink:href', 'http://www.empireonline.com/images/features/100greatestcharacters/photos/7.jpg')
    .attr('x', 0)
    .attr('y', 0)
    .attr('width', w)
    .attr('height', h)
    .attr('clip-path', 'url(#robclip)');

var robs = defs.append("svg:clipPath").attr("id", "robclip");

function redraw() {
    for (var d in dots) {
        robs.append("circle")
            .attr("class", function () {
                return "userid" + dots[d][4] + " bgtier" + dots[d][3];
            })
            .attr("cx", function () {
                return dots[d][0];
            })
            .attr("cy", function () {
                return dots[d][1];
            })
            .attr("r", size + 1)
            .attr("onmouseover", function() { ////// not triggering...
                return "alertid()"; ////// not triggering...
            });
    }
}

function alertid(){ 
    alert("hi");
}

redraw();

I've loaded it into a jsfiddle:

https://jsfiddle.net/vk1jc8ah/4/

Can someone help?

Clipaths are not actually "drawn" elements, like rect, circle, etc... So instead of placing your event listeners on the circle elements within the clipath, you can create an overlay of the same circles for the mouseover event, and make these circles transparent.

I created a separate function to do this:

function drawEventCircles() {
    for (var d in dots) {
        svg.append("circle")
            .attr("cx", function () {
                return dots[d][0];
            })
            .attr("cy", function () {
                return dots[d][1];
            })
            .attr("r", size + 1)
            .attr("fill", "transparent")
            .on("mouseover", function() {            
              alertid();
            }
        );
    }
}

Then just call drawEventCircles() after your call to redraw();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM