简体   繁体   English

使用Javascript D3库,如何在mousemove事件中确定区域元素数据集中的鼠标位置?

[英]Using Javascript D3 library, how can I determine mouse position in data set of an area element on mousemove event?

I am trying to setup a tooltip for an area path that I created. 我正在尝试为我创建的区域路径设置工具提示。 I checked all the arguments being passed into the on mousemove event handler, and I'm just getting the full data set, 0, 0. Nothing to indicate my index in the data as far as I can see. 我检查了传递给on mousemove事件处理程序的所有参数,我只是得到完整的数据集,0,0。就我所见,没有任何东西可以指示数据中的索引。 "This" context also is the svg path element. “这个”上下文也是svg路径元素。 Still nothing useful. 仍然没有用。 Even looked at d3.select(this), and I can't find the index anywhere there either. 甚至看了d3.select(this),我也找不到索引。 Is there some way to determine over which data point my mouse is? 有没有办法确定我的鼠标是哪个数据点?

Looking around I found a reference to d3.mouse(this), and that gives me x/y coordinate, but how do I map that back to a data point in the data set? 环顾四周,我找到了对d3.mouse(this)的引用,这给了我x / y坐标,但是如何将它映射回数据集中的数据点呢?

My goal is to have a tooltip to display some meta-data related to that specific data point in the set. 我的目标是使用工具提示来显示与集合中特定数据点相关的一些元数据。

Here is are some code snippets as requested: 以下是一些要求的代码片段:

var area=d3.svg.area()
    .interpolate("monotone")
    .x(function(d){
      return(scale.x(d.date));
    })
    .y0(height-padding.bottom)
    .y1(function(d){
      return(scale.y(d.count));
    });

var path=svg.append('path')
            .datum(data)
            .attr('d',area)
            .attr("clip-path", "url(#clip)")
            .attr('fill','url(#gradient)')
            // .attr('title','path')
            .on('mousemove',function(){
              console.log(arguments);
              console.log(d3.select(this));
              console.log(d3.mouse(this));        
            });          

@nautat has the right answer in his edit, but I'd like to expand on it because for whatever reason the blocks examples rarely have comments and can be like unfolding someone else's origami. @nautat在他的编辑中有正确的答案,但我想扩展它,因为无论出于何种原因,块示例很少有评论,可以像展开其他人的折纸。

This is the relavant part from http://bl.ocks.org/3902569 ... comments along the way are mine 这是来自http://bl.ocks.org/3902569的相关部分...沿途的评论是我的

// define a function for mouse move
// this function is wired up to the visualization elsewhere with .on('mousemove', fn)
function mousemove() {
  // using the x scale, in this case a d3 time scale
  // use the .invert() function to interpolate a date along the scale
  // given the x-coordinates of the mouse
  var x0 = x.invert(d3.mouse(this)[0]),

    // using the interpolated date, find an index in the sorted data
    // this would be the index suitable for insertion
    i = bisectDate(data, x0, 1),

    // now that we know where in the data the interpolated date would "fit"
    // between two values, pull them both back as temporaries
    d0 = data[i - 1],
    d1 = data[i],

    // now, examine which of the two dates we are "closer" to
    // to do this, compare the delta values
    d = x0 - d0.date > d1.date - x0 ? d1 : d0;

    // move the "focus" element into position
    // we find the X and Y values for the new position using the x and y scales
    // using the closest data point to the mouse
    focus.attr("transform", "translate(" + x(d.date) + "," + y(d.close) + ")");

    // set the text of the "focus" element to be the value of the element selected
    focus.select("text").text(formatCurrency(d.close));
}

Your problem is not so much related to the mouseover event listener, but more to the way you bind data to your path; 您的问题与mouseover事件侦听器没有多大关系,但更多的是将数据绑定到路径的方式; you don't do a proper data join. 你没有做正确的数据连接。

Read more about data joins: http://bost.ocks.org/mike/join/ 阅读有关数据连接的更多信息: http//bost.ocks.org/mike/join/

The following example is using divs instead of paths, but the principle is the same. 以下示例使用div而不是路径,但原理是相同的。 See working example at: http://jsfiddle.net/RghQn/ 请参阅以下工作示例: http//jsfiddle.net/RghQn/

var data = ['a', 'b', 'c'];
d3.select("body").selectAll("div")
    .data(data)
  .enter().append("div")
    .text(String)
    .on("mouseover", function(d,i) {
        console.log("mouseover!");
        // d: bound datum to DOM element
        console.log("d: ", d);
        // i: index of the selection
        console.log("i: ", i);
        // this context: the current DOM element
        console.log(d3.select(this).text());
    });
​​​​​​​​​​​​​​​

See also the API docs section about event listeners: https://github.com/mbostock/d3/wiki/Selections#wiki-on 另请参阅有关事件侦听器的API文档部分: https//github.com/mbostock/d3/wiki/Selections#wiki-on

selection.on(type[, listener[, capture]]) selection.on(type [,listener [,capture]])

Adds or removes an event listener to each element in the current selection, for the specified type. 为指定的类型添加或删除当前选择中每个元素的事件侦听器。 The type is a string event type name, such as "click", "mouseover", or "submit". 类型是字符串事件类型名称,例如“click”,“mouseover”或“submit”。 The specified listener is invoked in the same manner as other operator functions, being passed the current datum d and index i, with the this context as the current DOM element. 以与其他运算符函数相同的方式调用指定的侦听器,传递当前数据d和索引i,并将此上下文作为当前DOM元素。 To access the current event, use the global d3.event. 要访问当前事件,请使用全局d3.event。


EDIT 编辑

I know realize I misunderstood your question. 我知道我误解了你的问题。 You have one path and want to get information about the path coordinates at the location of the mouse. 您有一条路径,想要获取有关鼠标位置的路径坐标的信息。

There is not straightforward. 没有直截了当的说法。 You can see how Mike did it in the following example: http://bl.ocks.org/3902569 您可以在以下示例中看到Mike是如何做到的: http//bl.ocks.org/3902569

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM