Annotation connectors blocking tooltips

三世轮回 提交于 2021-01-28 10:39:42

问题


I am creating a line plot with tooltips appearing on hovering over the data points using d3. However, I added a few annotations to the plot and the callout circles now block the tooltips from appearing on the points overlapped by the annotations.

The following is a screenshot of the tooltip appearing on the points, but it doesn't appear on the point overlayed by the annotation circle (grey circle on the image).

The code used to generate the line plot, the points, tooltip and annotations are as follows

// Create Tooltip
var tooltip = d3.select("body")
    .append("div")
    .attr("class", "tooltip")
    .style("position", "absolute")
    .style("z-index", "10")
    .style("visibility", "hidden")

// Annotations
const annotations = [
    {
        type: d3.annotationCalloutCircle,
        note: {
            label: "Label",
            title: "Title",
            wrap: 500 },
        subject: { radius: 40 },
        color: ["#bdbfbf"], x: 550, y: 100, dy: -50, dx: -120
    }
]

// Add annotations to the plot
const makeAnnotations = d3.annotation()
    .type(d3.annotationLabel)
    .annotations(annotations)
d3.select("svg")
    .append("g")
    .call(makeAnnotations)

// Draw line
var line = d3.line()
    .x(function(d) { return x(+d.hour); })
    .y(function(d) { return y(+d.val); })
svg.selectAll(".line")
    .data(groupeddata)
    .enter()
    .append("path")
    .attr("fill", "none")
    .attr("stroke", function(d){ return color(d.key) })
    .attr("stroke-width", 1.5)
    .attr("d", function (d){ return line(d.values)})

// Draw points and add tooltips
svg.selectAll(".dot")
    .data(groupeddata)
    .enter()
    .append("g")
    .style("fill", function(d){ return color(d.key) })
    .selectAll(".points")
    .data(function (d){return d.values})
    .enter()
    .append("circle")
    .attr("cx", function(d) { return x(d.hour) } )
    .attr("cy", function(d) { return y(d.val) } )
    .attr("r", 5)
    .attr("stroke", "white")
    .on("mouseover", function(d){
        return tooltip.style("visibility", "visible")
            .html("<b>" + d.day + " " + d.hour + "00h" + "</b>" + "<br/>"
                + "Average Pedestrian Count : " + parseFloat(d.val).toFixed(2))})
    .on("mousemove", function(){
        return tooltip.style("top",(d3.event.pageY-10)+"px")
            .style("left",(d3.event.pageX+10)+"px")})
    .on("mouseout", function(){
        return tooltip.style("visibility", "hidden")})

回答1:


In contrast to HTML, SVG doesn't work with z-index, but just with the order of the elements in the HTML. Later nodes overlap any earlier nodes. One way to fix your issue would be to call .raise() on all circles, so they are above the annotations and can thus be interacted with.

Another option is to check whether the annotation circle has fill: none. The following snippet shows how the first circle passes hovers to the rect behind it, while the second one doesn't. This is because fill: none literally removes the hitbox, while fill:transparent does not.

A final option is to add pointer-events: none to the annotation. That way, all events (hover, click, touch, drag, etc.) just pass through it as if it were a ghost.

Hover over the following nodes and see how they do or do not trigger a message in the console.

d3.selectAll("rect")
  .on("mouseover", () => {
    console.log("HOVER");
  });
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg>
  <rect x="5" y="5" height="10" width="10"></rect>
  <circle cx="10" cy="10" r="10" stroke="black" fill="none"></circle>
  
  <rect x="45" y="5" height="10" width="10"></rect>
  <circle cx="50" cy="10" r="10" stroke="blue" fill="transparent"></circle>
  
  <rect x="85" y="5" height="10" width="10"></rect>
  <circle cx="90" cy="10" r="10" stroke="red" fill="transparent" style="pointer-events: none;"></circle>
</svg>


来源:https://stackoverflow.com/questions/64536153/annotation-connectors-blocking-tooltips

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!