J'ai un ensemble de données que je trace dans un scatter. Lorsque je passe la souris sur l’un des cercles, je souhaite qu’il apparaisse avec des données (comme les valeurs x, y, peut-être plus). Voici ce que j'ai essayé d'utiliser:
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);}); });
Je soupçonne d’être plus informatif sur les données à saisir?
Je suppose que ce que vous voulez, c'est une info-bulle. Pour ce faire, le moyen le plus simple consiste à ajouter un élément svg:title
à chaque cercle, car le navigateur se chargera d'afficher l'info-bulle et vous n'aurez pas besoin du gestionnaire de souris. Le code serait quelque chose comme
vis.selectAll("circle")
.data(datafiltered).enter().append("svg:circle")
...
.append("svg:title")
.text(function(d) { return d.x; });
Si vous voulez des info-bulles plus sophistiquées, vous pouvez utiliser tipy par exemple. Voir ici pour un exemple.
Un très bon moyen de créer une info-bulle est décrit ici: Exemple d'infobulle simple D
Vous devez ajouter une div
var tooltip = d3.select("body")
.append("div")
.style("position", "absolute")
.style("z-index", "10")
.style("visibility", "hidden")
.text("a simple tooltip");
Ensuite, vous pouvez simplement basculer en utilisant
.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
est la coordonnée actuelle de la souris.
Si vous voulez changer le texte, vous pouvez utiliser tooltip.text("my tooltip text");
Il existe une bibliothèque géniale pour ce faire que j'ai récemment découverte. C'est simple à utiliser et le résultat est plutôt soigné: d3-tip.
Vous pouvez voir un exemple ici :
En gros, tout ce que vous avez à faire est de télécharger ( index.js ), inclure le script:
<script src="index.js"></script>
puis suivez les instructions de ici (même lien que l'exemple)
Mais pour votre code, ce serait quelque chose comme:
définir la méthode:
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>";
})
créez votre svg (comme vous le faites déjà)
var svg = ...
appelez la méthode:
svg.call(tip);
ajouter une astuce à votre objet:
vis.selectAll("circle")
.data(datafiltered).enter().append("svg:circle")
...
.on('mouseover', tip.show)
.on('mouseout', tip.hide)
N'oubliez pas d'ajouter le 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>
Vous pouvez transmettre les données à utiliser dans le survol de la manière suivante: l'événement mouseover utilise une fonction avec vos données précédemment enter
ed en tant qu'argument (et l'index en tant que second argument); vous n'avez donc pas besoin de l'utiliser. enter()
une seconde fois.
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));
});
Cet exemple concis montre comment créer une info-bulle personnalisée dans 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>