5

作成したエリア パスのツールチップをセットアップしようとしています。on mousemove イベント ハンドラーに渡されるすべての引数を確認しましたが、完全なデータ セット 0, 0 を取得しています。私が見る限り、データ内のインデックスを示すものは何もありません。「この」コンテキストも svg パス要素です。まだ何も役に立ちません。d3.select(this) を見ても、どこにもインデックスが見つかりません。マウスがどのデータ ポイント上にあるかを判断する方法はありますか?

周りを見回すと、d3.mouse(this) への参照が見つかりました。これにより x/y 座標が得られますが、それをデータ セット内のデータ ポイントにマップするにはどうすればよいでしょうか?

私の目標は、セット内の特定のデータ ポイントに関連するメタデータを表示するためのツールチップを用意することです。

要求されたコード スニペットを次に示します。

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));        
            });          
4

2 に答える 2

6

@nautatは彼の編集で正しい答えを持っていますが、何らかの理由でブロックの例にコメントが含まれることはめったになく、他の人の折り紙を展開するようなものになる可能性があるため、それを拡張したいと思います.

これは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));
}
于 2013-10-15T14:03:54.477 に答える
2

問題は、マウスオーバーイベントリスナーにあまり関係していませんが、データをパスにバインドする方法に関係しています。適切なデータ結合を行いません。

データ結合の詳細については、http://bost.ocks.org/mike/join/をご覧ください。

次の例では、パスの代わりにdivを使用していますが、原則は同じです。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());
    });
​​​​​​​​​​​​​​​

イベントリスナーに関するAPIドキュメントセクションも参照してください:https ://github.com/mbostock/d3/wiki/Selections#wiki-on

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

指定されたタイプについて、現在の選択の各要素にイベントリスナーを追加または削除します。タイプは、「クリック」、「マウスオーバー」、「送信」などの文字列イベントタイプ名です。指定されたリスナーは、他のオペレーター関数と同じ方法で呼び出され、現在のDOM要素としてこのコンテキストを使用して現在のデータムdとインデックスiが渡されます。現在のイベントにアクセスするには、グローバルd3.eventを使用します。


編集

私はあなたの質問を誤解したことを知っています。パスが1つあり、マウスの位置でのパス座標に関する情報を取得したい。

簡単なことはありません。次の例で、マイクがどのようにそれを行ったかを確認できます。http: //bl.ocks.org/3902569

于 2012-11-02T17:28:29.717 に答える