Ive added 20 SVG squares to a trend graph I made using D3.js. Ech square is a clickable object which toggles lines on and off the graph. In Firefox the squares appear in the right lace, in Chrome, the CSS apparently stops working completely and the squares just drop to the bottom of the page.
Heres a link to the graph, http://www.andkensol.com/dataviz/TrendGraph/trendMov.html
And here is some of the JavaScript and CSS I used to make and then position the squares. Using position:relative is probably the cause. Would anyone have any advice or suggestions?
//JS
//AVENGERS CONTROLS
d3.select(".chart").append("svg")
.attr("class", "AvengeDot")
.on("mouseover", function(d) {
nameInfo.transition()
.duration(100)
.style("opacity", .9);
nameInfo.html("Marvel's The Avengers")
.style("left", (d3.event.pageX + 10) + "px")
.style("top", (d3.event.pageY - 30) + "px");
})
.on("mouseout", function(d) {
nameInfo.transition()
.duration(200)
.style("opacity", 0);
})
//HUNGER GAMES CONTROLS
d3.select(".chart").append("svg")
.attr("class", "HungerDot")
.on("mouseover", function(d) {
nameInfo.transition()
.duration(100)
.style("opacity", .9);
nameInfo.html("Hunger Games")
.style("left", (d3.event.pageX + 10) + "px")
.style("top", (d3.event.pageY - 30) + "px");
})
.on("mouseout", function(d) {
nameInfo.transition()
.duration(200)
.style("opacity", 0);
})
//CSS
.AvengeDot{
position:relative;
left:77%;
bottom:118%;
width:15px;
height:15px;
background-color:#FF9604;
cursor:pointer;
}
.HungerDot{
position:relative;
left:75.5%;
bottom:114%;
width:15px;
height:15px;
background-color:#FF9F18;
cursor:pointer;
}
Related
I like to use a div position:absolute as a tooltip for my d3.js charts as seen below:
<style>
.d3-tip {
display:inline-block;
position: absolute;
pointer-events:none;
}
</style>
<body>
<script src='https://d3js.org/d3.v5.min.js'></script>
<script type="text/javascript">
var tooltip = d3.select("body")
.append("div")
.attr("class", "d3-tip")
.style("opacity", 0);
var svg = d3.select("body").append("svg")
.attr("width", 500)
.attr("height", 800);
svg.append("circle")
.attr("cx", 100)
.attr("cy", 300)
.attr("r", 45)
.style("fill", "gray")
.on("mousemove", function() {
tooltip.style("opacity", .9)
.style("left", d3.event.pageX + 40 + "px")
.style("top", d3.event.pageY - 40 + "px")
.html("this is a tooltip");
})
.on("mouseout", function() {
tooltip.style("opacity", 0);
})
.on("click", function() {
d3.select(this).style("fill", "green");
});
</script>
</body>
This shows a tooltip when the cursor is over the circle, and also changes the color of the circle when it is clicked. It works with touches too (except that I can't get the tooltip to disappear, but that's another question). My problem, is that if there are any html tags in the tooltip, the touch does not seem to register as a click touchscreens.
For some reason I can't replicate this problem on codepen or jsfiddle. It works when I try it there. But here's a page with a live example that fails on my iPhone in Chrome and Safari: https://datavis.blob.core.windows.net/lmi/tooltip%20example.html
I'm trying to add a tooltip to a rect. It does pop up on mouse pointer hover over a bar but it doesn't want to disappear on mouseout event. I've also tried to use div.style("display", "none"), but it doesn't work either. For some reason it doesn't want to trigger mouseover event again after mouseout. It just keep displaying a tooltip.
http://bl.ocks.org/edkiljak/dc85bf51a27122380c68909cdd09d388
div.tooltip {
position: absolute;
text-align: left;
padding: 4px;
font-family: Lato, arial, sans-serif;
font-size: 14px;
background: #eee;
border-radius: 2px;
border: 1px solid gray;
pointer-events: none;
}
var div = d3.select("body")
.append("div")
.attr("class", "tooltip")
.style("opacity", 0);
var bars = barGroup.selectAll("rect")
.data(data)
.enter()
.append("rect")
.attr("x", 0)
.attr("y", function (d) {
return heightScale(d.Vendor);
})
.attr("width", function (d) {
return widthScale(+d.Share2016)
})
.attr("height", heightScale.bandwidth() / 1.1)
.style("fill", function (d, i) {
return color(i);
})
.on("mouseover",function (d){
div.transition()
.duration(200)
div
.style("opacity", .9)
.html("Vendor: " + "<strong>" + d.Vendor + "</strong>" + "<br>" + "Market share in 2016: " + d.Share2016 + "%")
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY - 28) + "px");
d3.select(this)
.style("fill", "#93ceff")
})
.on("mouseout", function(){
d3.select(this)
.transition()
.duration(50)
.style("fill", function(d,i){
return color(i);
})
d3.select(div).remove()
})
What am I doing wrong here?
The problem lies here:
d3.select(div).remove()
As div is itself a selection, you're selecting a selection, and that makes little sense.
Instead of that, just use div in the mouseout:
div.remove()
Or, even better, just set its opacity to zero:
div.style("opacity", 0)
Here is the updated bl.ocks with just that change: http://bl.ocks.org/anonymous/raw/13ce2445b248fb9e44dcd33cfc3dff36/dff0c60423927960cab8aaf9e613c2c3ae205808/
I'm wondering if its possible to define a CSS style for a tooltip function displayed by d3.js on mouse over event in the actual body of the definition rather than on top of the page in the style section.
JAVASCRIPT:
var tooltip = d3.select("#scatter-load").append("div")
.attr("class", "tooltip")
//.attr("position", "absolute")
//.attr("width", "200px")
//.attr("height", "30px")
//.attr("pointer-events", "none")
.style("opacity", 0);
chocolateGroup.append("circle")
.attr("r", function(d) {return rScale(d.size);})
.attr("opacity", 0.7)
.style("fill", "steelblue")
.on("mouseover", function(d) {
tooltip.transition()
.duration(200)
.style("opacity", .9)
tooltip.html(d.manufacturer + "<br/> (" + xValue(d)
+ ", " + yValue(d) + ")")
.style("left", (d3.event.pageX + 5) + "px")
.style("top", (d3.event.pageY - 28) + "px");
})
.on("mouseout", function(d) {
tooltip.transition()
.duration(500)
.style("opacity", 0);
});
CSS:
.tooltip {
position: absolute;
width: 200px;
height: 28px;
pointer-events: none;
What I am looking for is something similar to this style where CSS styling is defined when object is created (for example fill):
svg.append("path")
.datum(data)
.attr("d", area)
.attr("fill", "steelblue");
You should be using style to set CSS style like this:
.attr("class", "tooltip")
.style("position", "absolute")
.style("width", "200px")
.style("height", "30px")
.style("pointer-events", "none")
.style("opacity", 0);
This is my first question ever.
So, I tried to run a mouseover in my D3 script to trigger a hovered textfield (which is a div object) when moving the mouse over a certain button. Works pretty well so far.
var div = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
.
.
.
node.append("foreignObject")
.attr("class", "info")
.attr("x", 55)
.attr("y", -85)
.attr("width", 30)
.attr("height", 30)
.append("xhtml:body")
.html('<img src="images/information-icon.png" width=20 height=20>')
.on("mouseover", function (d) {
div.transition()
.duration(200)
.style("opacity", 0.9);
div.html("text")
.style("left", (d3.event.pageX - 5) + "px")
.style("top", (d3.event.pageY - 10) + "px");
})
.on("mouseout", function (d) {
div.transition()
.duration(500)
.style("opacity", 0);
});
The problem now is that the textfield vanishes once I move my mouse away from the button. I somehow want to "extend" my mouseover target from the button to the textfield also, so that I'm still able to click links on it etc. Does someone have an idea how to establish that? I already tried to put the mouseout event on my textfield instead like that:
.on("mouseover", function (d) {
div.transition()
.duration(200)
.style("opacity", 0.9);
div.html("text")
.style("left", (d3.event.pageX - 5) + "px")
.style("top", (d3.event.pageY - 10) + "px")
.on("mouseout", function (d) {
div.transition()
.duration(500)
.style("opacity", 0);
});
This won't work though, as the textfield won't vanish at all then. Does someone have an idea?
**EDIT:**Defined my question a bit different, I hope it won't be that confusing now...
Ok,
when the text is displayed you should un-register the mouse over event from the button, so that the text does not move when you run your mouse over the div.
When the text is opacity 0 then register the mouse over event back to the div.
I have 7 declared divs with different class attributes using jquery. I would like to use the 7 divs in mouseover. How would I do this?
My 7 divs are divOne, divTwo ... until divSeven.
I have this sample mouseover code but only one div is used.
nodeEnter.append("circle")
.attr("r", 30)
.style("stroke","white")
.on("mouseover", function(d) {
divOne.transition()
.duration(200)
.style("opacity", .9);
divOne.html(
"Name" + "<br />" + "Address"
)
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY - 28) + "px");
})
.on("mouseout", function(d) {
divOne.transition()
.duration(500)
.style("opacity", 0);
});
How to add the other divs during mouseover? Any help. Thanks
You need to have something like this.
nodeEnter.append("circle")
.attr("r", 30)
.style("stroke", "white")
.on("mouseover", function(d) {
onMouseOver();
})
.on("mouseout", function(d) {
onMouseOut();
});
var divElements = $('.classofdiv1', '.classofdiv2'......); //add all the div's class
function onMouseOver() {
$(divElements).each(function(index) {
$(this).transition()
.duration(200)
.style("opacity", .9);
$(this).html(
"Name" + "<br />" + "Address"
)
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY - 28) + "px");
});
}
function onMouseOut() {
$(divElements).each(function(index) {
$(this).transition()
.duration(500)
.style("opacity", 0);
});
}
Hope this helps :)