10

D3 を使用してインタラクティブな面グラフを作成しています。次の例のように、面グラフにマウスを置いている間、グラフの上部に点が転がるようにしたいと思います: http://hci.stanford.edu/jheer/files/zoo/ex/time/ multiples.html

(d3.mouse を使用して) マウスの位置を取得したら、これらの座標を対応するデータに変換するにはどうすればよいですか? x 軸は、x スケールの逆数 (egxinvert) を使用すると簡単です。ただし、グラフに対応する y 座標が見つかりません。理想的には、データの x 座標を「検索」して、対応する y 座標を見つけることができますが、D3 でこれを行う方法がわかりません。ありがとう!

4

3 に答える 3

9

実際、独自のルックアップ テーブルを作成するのは比較的簡単です。

/* Create the lookup table */
var table = {};
data.forEach(function(d) {
    table[d.x] = d.y;
});

十分なデータ ポイントがある場合、これは実行可能なソリューションですが、中間の x 値を埋めるために何らかの丸めまたは補間を使用する必要がある可能性があります。たとえば、ポイント間に固定間隔がある場合、線形補間を使用して次の計算を実行して、円の座標を取得できますmouseover

var x = d3.mouse(this)[0];
var y;

if ( table[x] === undefined ) {
    var lower = x - (x % SPACING);
    var upper = lower + SPACING;
    var between = d3.interpolateNumber(table[lower], table[upper]);
    y = between( (x % SPACING) / SPACING );
} else {
    y = table[x];
}

実際のコードは次のとおりです: http://jsfiddle.net/Wexcode/KGxHF/

Mike Bostockによる別の例を次に示します: http://bl.ocks.org/3025699

于 2012-07-07T20:30:08.947 に答える
2

mbostock (D3.js の作成者) は、ここでこれを実装します

svg.append("rect")
  .attr("class", "overlay")
  .attr("width", width)
  .attr("height", height)
  .on("mouseover", function() { focus.style("display", null); })
  .on("mouseout", function() { focus.style("display", "none"); })
  .on("mousemove", mousemove);

function mousemove() {
  var x0 = x.invert(d3.mouse(this)[0]),
    i = bisectDate(data, x0, 1),
    d0 = data[i - 1],
    d1 = data[i],
    d = x0 - d0.date > d1.date - x0 ? d1 : d0;
  focus.attr("transform", "translate(" + x(d.date) + "," + y(d.close) + ")");
  focus.select("text").text(formatCurrency(d.close));
}
于 2014-11-04T21:50:24.737 に答える
1

このコードを使用して、各ポイントの値XとYを確認し、マウスイベントで曲線上に円を描きます:ここでjsFiddleの例

Y_valueはグローバルです!

var Y_value; 

私は私の軸の怒りを定義します

x = d3.time.scale().range([0, w]);
y = d3.scale.linear().range([h, 0]);

サークルカーソルを定義します

var circle = svg.append("circle")
        .attr("r", 8)
        .attr("cx", 0)
        .attr("cy", 0)
        .style({fill: '#fff', 'fill-opacity': .2, stroke: '#000', "stroke-width": '1px'})
        .attr("opacity", 0);

サークルにツールチップを追加します

var tooltip = circle.append("svg:title");

そして私は私のイベントコードを持っています

mySensitiveArea.on("mousemove", function() {
    var X_pixel = d3.mouse(this)[0],
        X_date = x.invert(X_pixel);
    var Y_pixel = y(Y_value);

    var pathData = curve1.data()[0]; // recupere donnée de la courbe

    pathData.forEach(function(element, index, array) {
            if ((index+1 < array.length) && (array[index].date <= X_date) && (array[index+1].date >= X_date)) {
                if (X_date-array[index].date < array[index+1].date-X_date)  Y_value = array[index].val;
                else Y_value = array[index+1].val;
            }
        });

        circle.attr("opacity", 1)
            .attr("cx", X_px)
            .attr("cy", Math.round(y(Y_value)));

        tooltip.text("X = " + (X_date) + "\nY = " + (Y_value));
    });
于 2013-03-17T19:45:44.013 に答える