Attacher l'événement 'onclick' à L'arrière-plan du graphique D3
J'ai un diagramme d'histogramme D3, sur lequel j'ai attaché un événement 'onclick' aux barres:
...
var bar = svg.selectAll(".bar")
.data(data)
.enter().append("g")
.attr("class", "bar")
.attr("transform", function(d) { return "translate(" + x(d.x) + "," + y(d.y) + ")"; })
.on('mouseover', tip.show)
.on('mouseout', tip.hide)
.on('click', function(d,i){ //do stuff });
...
Cela fonctionne exactement comme prévu. Je voudrais également attacher un événement 'onclick' à l'arrière-plan du graphique (ie. partout dans le graphique qui n'est pas une barre), mais j'ai des problèmes avec cela. J'ai essayé d'attacher l'événement de deux façons, mais dans tous les cas, ce nouvel événement semble remplacer mon bar-click:
Quelques tentatives:
$("svg:not('.bar')").on("click", function(){ //do stuff });
$("g:not('.bar')").on("click", function(){ //do stuff });
var svg = d3.select("#histogram_block").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
.on("click", function(d,i){
if (d) { //do stuff}
else { //do stuff }
};
Je suppose qu'il y a un façon d'ajouter le gestionnaire d'événements à L'objet SVG lorsqu'il est initialisé, mais je ne connais pas la bonne façon de procéder.
2 réponses
L'événement n'est pas réellement remplacé, mais les deux sont déclenchés - le gestionnaire onclick
pour le SVG et pour la barre. Pour éviter cela, utilisez la .stopPropagation()
méthode (voir la documentation). Le code ressemble à ceci:
rect.on("click", function() {
console.log("rect");
d3.event.stopPropagation();
});
Exemple Complet ici. Comparer avec le comportement avec l'arrêt de la propagation de l'événement ici.
Dans cet exemple (Ligne 246: http://tributary.io/inlet/8361294 ) j'ajoute un nouveau rect avec une largeur et une hauteur égales à la surface totale du graphique, puis j'attache Mes événements de souris (ou de clic).
svg.append("rect")
.attr({"class": "overlay" , "width": width , "height": height})
.on({
"mouseover": function() { /* do stuff */ },
"mouseout": function() { /* do stuff */ },
"click": function() { /* do stuff */ },
});