Javascript 如何在 d3 中以编程方式调用“click”事件?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9063383/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 08:33:18  来源:igfitidea点击:

How to invoke "click" event programmatically in d3?

javascriptd3.js

提问by mad

I'm trying like that (also at https://gist.github.com/1703994):

我正在尝试这样(也在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>

But doesn't work

但不起作用

I think we may use https://github.com/mbostock/d3/wiki/Internals#wiki-dispatch_on

我想我们可以使用https://github.com/mbostock/d3/wiki/Internals#wiki-dispatch_on

But how to do it?

但是怎么做呢?

回答by handler

not sure why, but there appears to be a discrepancy with the way jQuery and d3 handle events that causes a jQuery induced click event $("#some-d3-element").click()to not dispatch to the d3 element.

不知道为什么,但 jQuery 和 d3 处理事件的方式似乎存在差异,导致 jQuery 引发的点击事件$("#some-d3-element").click()无法分派到 d3 元素。

a workaround:

解决方法:

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

and then call it:

然后调用它:

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

回答by natevw

Simply call the .onmethod as a getter for the registered value (i.e. your handler function), then call the result of that:

只需将该.on方法作为注册值的 getter调用(即您的处理程序函数),然后调用其结果:

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

It gets a little more complicated if your handler uses the bound data and/or event fields, or if you've got multiple event listeners bound (e.g "click.thing1" and "click.thing2"). In that case, you're probably best off just firing a fake event using the standard DOM methods:

如果您的处理程序使用绑定数据和/或事件字段,或者如果您绑定了多个事件侦听器(例如“click.thing1”和“click.thing2”),它会变得更加复杂。在这种情况下,您可能最好只使用标准 DOM 方法触发一个假事件:

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

回答by Jonatas Walker

With D3 v4you will likely want this:

使用D3 v4,您可能需要:

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

Ref.: https://github.com/d3/d3-selection#selection_dispatch

参考:https: //github.com/d3/d3-selection#selection_dispatch

回答by Andrew Plank

This works. I'm using pie charts, so I'm selecting all the "selected" pie slices, and for each of them, retrieving the attached "click" callback (that I have attached in another portion of code not included here, using d3's .on() method) and then invoking with the expected parameters in the correct context.

这有效。我正在使用饼图,所以我选择了所有“选定的”饼图,并为每个饼图检索附加的“点击”回调(我已附加到此处未包含的另一部分代码中,使用 d3 的 . on() 方法),然后在正确的上下文中使用预期的参数进行调用。

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

回答by massanishi

I came this thread looking for a d3 mousemove event for angular unit testing.

我来到这个线程寻找用于角度单元测试的 d3 mousemove 事件。

@natevw answer

@natevw 回答

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

helped a lot on mouseover event. But, applying that to mousemove was giving an e.source null error.

对鼠标悬停事件有很大帮助。但是,将其应用于 mousemove 会产生 e.source null 错误。

The work around was to set the d3 event programmatically.

解决方法是以编程方式设置 d3 事件。

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

Hope this helps.

希望这可以帮助。

回答by Fredrik Johansson

This answer might be somewhat unrelated - but hopefully useful to someone searching for how to invoke a click event of a SVG element - since jQuery $(mySvgElement).trigger("click") won't work.

这个答案可能有点无关 - 但希望对搜索如何调用 SVG 元素的点击事件的人有用 - 因为 jQuery $(mySvgElement).trigger("click") 将不起作用。

This is how you would programmatically trigger/invoke/raise a click event for a SVG element:

这是您以编程方式触发/调用/引发 SVG 元素的点击事件的方式:

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!

回答by Yony

You can go super manual by getting the mouse event and passing it the arguments that d3 would otherwise provide for you. This gives you a fairly clean way to do it while still using d3 constructs. For a single element use the following:

您可以通过获取鼠标事件并向其传递 d3 否则会为您提供的参数来进行超级手动操作。这为您提供了一种相当干净的方法,同时仍然使用 d3 结构。对于单个元素,请使用以下内容:

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

For multiple elements, you can trigger each one in turn:

对于多个元素,可以依次触发每一个:

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

The latter can also be used for a single element if your selector is specific enough, or if you use .select()instead of .selectAll()to only return the first element.

如果您的选择器足够具体,或者如果您使用.select()而不是.selectAll()仅返回第一个元素,后者也可以用于单个元素。

回答by Cybernetic

@handler answer did not work for me entirely. It would click the svg element but additional simulated events would not register. This is what worked for me:

@handler 的回答完全不适合我。它会单击 svg 元素,但不会注册其他模拟事件。这对我有用:

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');

回答by user1410605

This is how I do it.

我就是这样做的。

g.selectAll("path").on("click", function(d, i){
                                    my_function(d, i);
                                });

I've found the the callbacks work with anonymous functions. So for the code above, any path that is clicked will call my_functionand pass in the current datum dand index iof the path that was clicked.

我发现回调可以使用匿名函数。所以对于上面的代码,任何被点击的路径都会调用my_function并传入被点击路径的当前数据d和索引i

回答by mad

I find next workaround:

我找到下一个解决方法:

d3.selectAll("path").each(function(d, i) {
                    onClickFunc.apply(this, [d, i]);
                });

Where dis data and iis index this data

d数据在哪里,i是索引这个数据