web-dev-qa-db-fra.com

Association d'un événement 'onclick' à l'arrière-plan du diagramme D3

J'ai un 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 (c'est-à-dire partout dans le graphique qui n'est pas une barre), mais j'ai des problèmes avec cela. J'ai essayé d'associer l'événement de plusieurs manières, mais dans tous les cas, ce nouvel événement semble remplacer mon clic sur le bouton à barres:

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 existe un moyen 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.

49
woemler

L'événement n'est pas remplacé, mais les deux sont déclenchés - le gestionnaire onclick pour le SVG et pour la barre. Pour éviter cela, utilisez la méthode .stopPropagation() (voir la documentation ). Le code ressemble à ceci:

rect.on("click", function() {
  console.log("rect");
  d3.event.stopPropagation();
});

Exemple complet ici . Comparez avec le comportement avec l'arrêt de la propagation de l'événement ici .

59
Lars Kotthoff

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 ma souris (ou clique) événements.

svg.append("rect")
        .attr({"class": "overlay" , "width": width , "height": height})
        .on({
          "mouseover": function() { /* do stuff */ },
          "mouseout":  function() { /* do stuff */ }, 
          "click":  function() { /* do stuff */ }, 
        });
1
DeBraid