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.

42
demandé sur woemler 2014-04-08 19:41:54

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.

52
répondu Lars Kotthoff 2014-04-08 15:49:51

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 */ }, 
        });
1
répondu DeBraid 2014-04-08 17:34:57