Odd behavior on mapbox/d3.js map - blue screen on map pan

Viewed 57

I've developed a web app using d3.js along with mapbox. Basically, you can hover over points (d3 points) overlaid on a mapbox map and retrieve info in a popup.

I'm not unable to post a replicable example of my problem without revealing my mapbox api key. But will try and give the pertinent details. My issue is that there is a weird bug where when I pan the map, usually from the outer edges and if panning quickly, I get this:

enter image description here

I've documented the issue here in a video, if you advance to the 0:22 second mark:

https://www.youtube.com/watch?v=OJHxPkWZbuo

Without being able to post the entire code, here's some relevant details. My intuition is telling me this issue is happening on the "body" click-event listener, where if the user clicks anywhere on "body", the pop-up will close. Wondering if maybe this is an artifact from some of the "pointer-event" rules I have, because the blue screen almost looks like everything is being selected.

UPDATE:

It appears I can replicate this behavior consistently by clicking on a point, clicking anywhere else on "body" to remove the point, and then dragging from the far edge of the map to pan.

First, build empty Div:

var LeafletDiv = d3.select("#content").append("div")   
            .attr("class", "county2014Tooltip")  
            .style("opacity", 1)
            .style("scrollTop", 0)

Then, add points to map:

var events = mapG.selectAll("circle")
            .data(eventArray)
            .enter().append("circle")
            .attr("class", 'events')

Finally, add event listener to points:

.on("click", function(d) { 
        $('body').css({
            overflow: 'hidden'
        });
     
        const currentCircle = this; 
        //disable hover event listeners
        d3.selectAll(".events").on("mouseout", null);
        d3.selectAll(".events").on("mouseover", null);

        //add popup   
        var value2014 = currentMap.get(d.location);  

        LeafletDiv.transition()        
            .duration(200)      
            .style("opacity", .9);

                var appendText = []
                var popInfo = '<br/>' +  "this is my popup info" + '<br/>'                  
                
                appendText.push(popInfo+ '<br/>' + '<br/>')

            //append html to div
            LeafletDiv
                .html( appendText.join(""))
                .style("top", "1.5vh")
                .style("pointer-events", 'all')
                d3.select(this).style("stroke", 'black')  
                d3.select(this).style("stroke-width", '3px')
                 

        d3.event.stopPropagation();

          // if user clicks a SECOND time, anywhere, make popup disappear
          //I beleive this is where the blue screen bug is coming from.
        d3.select("body").on("click", function(d) { 
            //console.log("clicking off popup")
            d3.selectAll(".events").style("stroke", 'none')
            d3.selectAll(".events").style("stroke-width", '0px')
 
            if (this !== currentCircle) {

                //hide popup
                var elements = d3.select(LeafletDiv)
                elements.scrollTop = 0

                //take away the prior html that's been added to popup and replace with empty html
                appendText = []
                console.log(appendText)
                LeafletDiv
                    .html( appendText.join(""))
                                         
                LeafletDiv.transition()        
                    .duration(50)      
                    .style("opacity", 0)
                    .style("pointer-events", 'none') 
                    .attr("scrollTop", 0) 
                    //revert back to hover, unless user clicks again!
                    d3.selectAll(".events").on("mouseout", true);
                    d3.selectAll(".events").on("mouseover", true);
                    d3.selectAll(".events").on("mouseout", function(d) { 
                    //mousing out!     
                    LeafletDiv.transition()        
                        .duration(200)      
                        .style("opacity", 0);  
                        d3.selectAll(".events").style("stroke", 'none')
                        d3.selectAll(".events").style("stroke-width", '0px')        
                    })

                    // mouseover event listers added back in
                    d3.selectAll(".events").on("mouseover", function(d) { 
                    LeafletDiv.transition()        
                        .duration(200)      
                        .style("opacity", .9);

                    LeafletDiv .html('<br/>' + "this is my popup info" + '</b>'
                    )
                        .style("top", "1.5vh")
                        d3.select(this).style("stroke", 'black')  
                        d3.select(this).style("stroke-width", '3px')
                })
            }          
        })
    })

Relevant CSS:

body {
    font-family: 'Poppins', sans-serif;
    background: #fafafa;
    height:100%;
    max-height:100%;
    min-width:100%;
    overflow: hidden;
    position:fixed;    
}

div.county2014Tooltip { 
    word-wrap: normal;
    position: absolute;
    text-align: center;
    border-radius: 15px;           
    padding: 4px;               
    font-size: .9em ; 
    line-height: 1.5em;
    font-family:'poppins';  
    font-weight: 150;
    color: #fff;
    margin-top:11vh;
    background-color: rgba(51,51,51,.85);
    border: solid thin black;
    padding: 5px 10px 10px 5px;
    pointer-events: none;   
    overflow-y:scroll; 
    overflow-wrap: break-word;
    word-wrap: break-word;
    display:inline-block ;
    margin-left:1vh;
    opacity:.2;
    padding-bottom:3%;
    padding-left:2.5vh;
    padding-right:4.5vh
}

 @media all and (min-width:0px) and (max-width: 576px) {
     div.county2014Tooltip  {
        min-height:50vh;
        min-width: 25vh;    
        max-width: 40vh; 
        max-height:70vh; 
        overflow-wrap: break-word; 
        word-wrap: break-word;
  }
}

#map{
    height:100%;
}

#content{
    width:100%;
    height:100%;
    min-width:100%; 
}
0 Answers
Related