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:
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%;
}
