Skip to content Skip to sidebar Skip to footer

D3: Finding Graph Y-coordinate With Mouseover

I am making an interactive area chart using D3. While mousing over the area-chart, I'd like to have a dot rolling along the top of the chart, as in the following example: http://hc

Solution 1:

It's actually relatively easy to create your own lookup table:

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

This is a viable solution if you have enough data points, but it's likely that you will probably need to use some sort of rounding or interpolator to fill in the intermediate x-values. For instance, if there is a fixed spacing between your points, you can use a linear interpolator and do the following calculations to get the coordinates for your circle on 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];
}

Here is the code in action: http://jsfiddle.net/Wexcode/KGxHF/

Here is another example of how you could do this from Mike Bostock: http://bl.ocks.org/3025699


Solution 2:

mbostock (D3.js author) implement this here

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

Solution 3:

I use this code to see value X and Y of each point and draw a circle on my curve on mouse event : exemple on jsFiddle here

Y_value is a global !

var Y_value; 

i define my axes rage

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

i define the circle cursor

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

i add a tooltip on my circle

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

and i have my event code

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

Post a Comment for "D3: Finding Graph Y-coordinate With Mouseover"