tooltip javascript onmouseover
Mostrar datos sobre el mouseover del círculo (5)
Este ejemplo conciso muestra una forma común de cómo crear información sobre herramientas personalizada en d3.
var w = 500;
var h = 150;
var dataset = [5, 10, 15, 20, 25];
// firstly we create div element that we can use as
// tooltip container, it have absolute position and
// visibility: hidden by default
var tooltip = d3.select("body")
.append("div")
.attr(''class'', ''tooltip'');
var svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);
// here we add some circles on the page
var circles = svg.selectAll("circle")
.data(dataset)
.enter()
.append("circle");
circles.attr("cx", function(d, i) {
return (i * 50) + 25;
})
.attr("cy", h / 2)
.attr("r", function(d) {
return d;
})
// we define "mouseover" handler, here we change tooltip
// visibility to "visible" and add appropriate test
.on("mouseover", function(d) {
return tooltip.style("visibility", "visible").text(''radius = '' + d);
})
// we move tooltip during of "mousemove"
.on("mousemove", function() {
return tooltip.style("top", (event.pageY - 30) + "px")
.style("left", event.pageX + "px");
})
// we hide our tooltip on "mouseout"
.on("mouseout", function() {
return tooltip.style("visibility", "hidden");
});
.tooltip {
position: absolute;
z-index: 10;
visibility: hidden;
background-color: lightblue;
text-align: center;
padding: 4px;
border-radius: 4px;
font-weight: bold;
color: orange;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.11.0/d3.min.js"></script>
Tengo un conjunto de datos que estoy trazando de forma dispersa. Cuando toco uno de los círculos, me gustaría que aparezca con datos (como valores x, y, tal vez más). Esto es lo que intenté usar:
vis.selectAll("circle")
.data(datafiltered).enter().append("svg:circle")
.attr("cx", function(d) { return x(d.x);})
.attr("cy", function(d) {return y(d.y)})
.attr("fill", "red").attr("r", 15)
.on("mouseover", function() {
d3.select(this).enter().append("text")
.text(function(d) {return d.x;})
.attr("x", function(d) {return x(d.x);})
.attr("y", function (d) {return y(d.y);}); });
Sospecho que necesito ser más informativo sobre qué datos ingresar?
Hay una biblioteca increíble para hacer eso que descubrí recientemente. Es simple de usar y el resultado es bastante limpio: d3-tip.
Puedes ver un ejemplo bl.ocks.org/Caged/6476579 :
Básicamente, todo lo que tienes que hacer es descargar ( index.js ), incluir el script:
<script src="index.js"></script>
y luego siga las instrucciones desde bl.ocks.org/Caged/6476579 (mismo enlace como ejemplo)
Pero para su código, sería algo así como:
define el método:
var tip = d3.tip()
.attr(''class'', ''d3-tip'')
.offset([-10, 0])
.html(function(d) {
return "<strong>Frequency:</strong> <span style=''color:red''>" + d.frequency + "</span>";
})
crea tu svg (como ya lo haces)
var svg = ...
llamar al método:
svg.call(tip);
agrega consejo a tu objeto:
vis.selectAll("circle")
.data(datafiltered).enter().append("svg:circle")
...
.on(''mouseover'', tip.show)
.on(''mouseout'', tip.hide)
No olvides agregar el CSS:
<style>
.d3-tip {
line-height: 1;
font-weight: bold;
padding: 12px;
background: rgba(0, 0, 0, 0.8);
color: #fff;
border-radius: 2px;
}
/* Creates a small triangle extender for the tooltip */
.d3-tip:after {
box-sizing: border-box;
display: inline;
font-size: 10px;
width: 100%;
line-height: 1;
color: rgba(0, 0, 0, 0.8);
content: "/25BC";
position: absolute;
text-align: center;
}
/* Style northward tooltips differently */
.d3-tip.n:after {
margin: -1px 0 0 0;
top: 100%;
left: 0;
}
</style>
Puede pasar los datos que se utilizarán en el mouseover de esta manera: el evento mouseover usa una función con sus datos ingresados previamente como argumento (y el índice como segundo argumento) para que no necesite usar enter()
por segunda vez.
vis.selectAll("circle")
.data(datafiltered).enter().append("svg:circle")
.attr("cx", function(d) { return x(d.x);})
.attr("cy", function(d) {return y(d.y)})
.attr("fill", "red").attr("r", 15)
.on("mouseover", function(d,i) {
d3.select(this).append("text")
.text( d.x)
.attr("x", x(d.x))
.attr("y", y(d.y));
});
Supongo que lo que quieres es una información sobre herramientas. La forma más sencilla de hacerlo es agregar un elemento svg:title
a cada círculo, ya que el navegador se encargará de mostrar la información sobre herramientas y no necesitará el manejador de mouse. El código sería algo así como
vis.selectAll("circle")
.data(datafiltered).enter().append("svg:circle")
...
.append("svg:title")
.text(function(d) { return d.x; });
Si quieres información sobre herramientas más elegante, podrías utilizar tipsy por ejemplo. Vea here para un ejemplo.
Una forma realmente buena de hacer una sugerencia de herramienta se describe aquí: Ejemplo simple de ayuda sobre herramientas D3
Tienes que agregar un div
var tooltip = d3.select("body")
.append("div")
.style("position", "absolute")
.style("z-index", "10")
.style("visibility", "hidden")
.text("a simple tooltip");
Entonces solo puedes alternar usando
.on("mouseover", function(){return tooltip.style("visibility", "visible");})
.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");});
d3.event.pageX
/ d3.event.pageY
es la coordenada actual del mouse.
Si desea cambiar el texto, puede usar tooltip.text("my tooltip text");