Tengo un gráfico hecho con d3.js y tengo los siguientes atributos y propiedades para los nodos:
// Enter any new nodes at the parent's previous position var nodeEnter = node.enter().append("g") .attr("class", "node") .attr("transform", function(d) { return "rotate(" + (dx - 90) + ")translate(" + dy + ")"; }) .on("click", click) .on("dblclick", dblclick)Me gustaría agregar la capacidad de subrayar el título del nodo al pasar el mouse sobre él. Algo como esto que desafortunadamente no funciona:
var nodeEnter = node.enter().append("g") .on("mouseover").style("text-decoration","underline") .on("mouseout").style("text-decoration","none")EDITAR: preferiría poner una condición para que esto suceda solo para algunos nodos del gráfico.
No está utilizando el método selection.on() correctamente. Para hacer algo en un evento, debe proporcionar al método un segundo parámetro: una función que describa la acción realizada en el evento:
D3v6+
.on("mouseover", function(event, datum) { ... })D3v5 y antes
.on("mouseover", function(datum, index, nodes) { ... }) En todas las versiones de D3, this será el elemento de destino (a menos que se utilice la notación de flecha ). El dato son los datos vinculados al elemento de destino, un elemento de la matriz que se pasa a selection.data().
Si solo proporciona un parámetro, devuelve la función de manejo de eventos actual asignada a ese evento. En su caso, es probable que aún no haya hecho esto (porque está intentando hacerlo), por lo que .on("mouseover").style(...) devolverá un error como "No se puede encontrar el estilo de propiedad de nulo" porque .on("mouseover") devolverá nulo: no hay una función de manejo de eventos asignada a este evento para devolver.
Entonces, para resaltar los nodos al pasar el mouse con algo de lógica para que podamos tener diferentes resultados para diferentes nodos, podemos usar algo como:
selection.on("mouseover", function(event, datum) { if(datum.property == "someValue") { d3.select(this).style("text-decoration","underline"); } }) .on("mouseout", function(event,datum) { d3.select(this).style("text-decoration","none"); })Donde la declaración if se puede reemplazar con la lógica que prefiera.
Veo que probablemente esté utilizando un generador de diseño jerárquico, los generadores de diseño jerárquico de D3 anidan las propiedades del dato original en una propiedad de datos para que las propiedades de diseño y las propiedades que no son de diseño no colisionen, por lo que datum.property puede residir en datum.data.property (registro el dato si tiene problemas).
var svg = d3.select("body") .append("svg"); var data = [ "Underline on mouse", "Never underline" ]; svg.selectAll("text") .data(data) .enter() .append("text") .attr("x", 20) .attr("y", (d,i)=>i*50+40) .text(d=>d) .on("mouseover", function(event, datum) { if(datum == "Underline on mouse") { d3.select(this).style("text-decoration","underline"); } }) .on("mouseout", function(event,datum) { d3.select(this).style("text-decoration","none"); }) <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.0.0/d3.min.js"></script>Puede agregar un subrayado al pasar el mouse usando CSS
.node:hover{ text-decoration: underline; }