web-dev-qa-db-fra.com

Comment appeler un événement "click" par programme dans d3?

J'essaie comme ça (aussi à https://Gist.github.com/1703994 ):

<!DOCTYPE html>
<html>
  <head>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script type="text/javascript" src="http://mbostock.github.com/d3/d3.js?1.27.2"></script>
    <script type="text/javascript" src="http://mbostock.github.com/d3/d3.time.js?1.27.2"></script>

    <script type="text/javascript" src="js-libs/jquery-1.7.js"></script>

    <style>
      <!--
      #test {
      width: 400px;
      height: 500px;
      }
      -->
    </style>
  </head>

  <body>

    <script type="text/javascript">
      $(function() {
        var w = 600,
            h = 350;

        var vis = d3.select("#test").append("svg:svg")
        .attr("width", w)
        .attr("height", h)
        .append("svg:g")
        .attr("transform", "translate(" + w / 2 + "," + h / 2 + ")");

        var g = vis.selectAll("g")
        .data([ { x:1 , y: 2} ])
        .enter().append("svg:g");

        g.append("svg:path")
        .attr("fill", "red")
        .attr("stroke", "red")
        .attr("stroke-width", "10")
        .attr("d", "M 100 350 l 150 -300")

        g.select("path")
        .on("click", function() { console.log("Hello"); });

        // XXX: how to execute click programmaticaly?
      })
    </script>

    <div id="test"></div>
  </body>
</html>

Mais ne fonctionne pas

Je pense que nous pouvons utiliser https://github.com/mbostock/d3/wiki/Internals#wiki-dispatch_on

Mais comment le faire?

53
mad

je ne sais pas pourquoi, mais il semble y avoir un écart entre la façon dont jQuery et d3 gèrent les événements qui entraînent la non-distribution par un événement de clic induit par $("#some-d3-element").click() à l'élément d3.

une solution de contournement:

jQuery.fn.d3Click = function () {
  this.each(function (i, e) {
    var evt = new MouseEvent("click");
    e.dispatchEvent(evt);
  });
};

puis appelez ça:

$("#some-d3-element").d3Click();
82
handler

Appelez simplement la méthode .on en tant que getter pour la valeur enregistrée (c'est-à-dire votre fonction de gestionnaire), puis appelez le résultat correspondant:

g.select("path").on("click")();

Cela devient un peu plus compliqué si votre gestionnaire utilise les champs de données et/ou d'événements liés, ou si vous avez plusieurs écouteurs d'événements liés (par exemple, "click.thing1" et "click.thing2"). Dans ce cas, vous feriez probablement mieux de déclencher un faux événement à l'aide des méthodes standard DOM :

var e = document.createEvent('UIEvents');
e.initUIEvent('click', true, true, /* ... */);
g.select("path").node().dispatchEvent(e);
67
natevw

Cela marche. J'utilise des graphiques à secteurs, je sélectionne donc toutes les tranches de camembert "sélectionnées" et, pour chacune d'entre elles, récupère le rappel "clic" attaché (que j'ai joint à une autre partie de code non incluse ici, à l'aide de d3. on ()) puis en appelant avec les paramètres attendus dans le bon contexte.

d3.selectAll("g.selected").each(function(d, i) {
    var onClickFunc = d3.select(this).on("click");
    onClickFunc.apply(this, [d, i]);
});                
14
Andrew Plank

Avec D3 v4, vous voudrez probablement ceci:

d3.select('#some-id').dispatch('click');

Réf .: https://github.com/d3/d3-selection#selection_dispatch

6
Jonatas Walker

Je suis venu par ce fil à la recherche d'un événement d3 mousemove pour les tests unitaires angulaires. 

@natevw answer

g.select("path").on("click")();

beaucoup aidé sur l'événement mouseover. Mais appliquer cela à mousemove donnait une erreur e.source nulle. 

La solution consistait à définir l'événement d3 par programmation.

d3.event = document.createEvent('MouseEvent');
d3.event.initMouseEvent("mousemove");
d3.select(Elm[0]).select("rect").on("mousemove")();

J'espère que cela t'aides.

4
massanishi

Cette réponse est peut-être quelque peu indépendante - mais, espérons-le, utile pour une personne cherchant comment appeler un événement de clic d'un élément SVG - car jQuery $ (mySvgElement) .trigger ("clic") ne fonctionne pas.

Voici comment déclencher/invoquer/déclencher un événement click pour un élément SVG par programme:

var ev = document.createEvent("SVGEvents");
ev.initEvent("click",true,true);

var target = $("svg>g>path[fill='#0011cc']").get(0); // get the SVG element here
target.dispatchEvent(ev);  // like $(target).trigger('click') - but working!
3
Fredrik Johansson

Vous pouvez passer en mode super manuel en récupérant l'événement mouse et en lui transmettant les arguments que d3 vous fournirait autrement. Cela vous donne un moyen assez propre de le faire tout en utilisant les constructions d3. Pour un seul élément, utilisez ce qui suit:

var path = g.select('path');
path.on('click').call(path.node(), path.datum());

Pour plusieurs éléments, vous pouvez déclencher chacun d’eux à tour de rôle:

g.selectAll('path').each(function(d, i) {
  d3.select(this).on('click').apply(this, arguments);
});

Ce dernier peut également être utilisé pour un seul élément si votre sélecteur est suffisamment spécifique ou si vous utilisez .select() au lieu de .selectAll() pour ne renvoyer que le premier élément.

1
Yony

La réponse de @handler n'a pas fonctionné entièrement pour moi. Il cliquerait sur l'élément svg mais des événements simulés supplémentaires ne seraient pas enregistrés. C'est ce qui a fonctionné pour moi: 

function eventFire(el, etype){
  if (el.fireEvent) {
    el.fireEvent('on' + etype);
  } else {
    var evObj = document.createEvent('Events');
    evObj.initEvent(etype, true, false);
    el.dispatchEvent(evObj);
  }
}

Usage: 

eventFire(document.getElementById(element_id), 'click');
0
Cybernetic