D3.js Multiple Line Plot – Part 5

Working version of the plot, download here.

The D3 function, d3.mouse(), provides a convenient tool for tracking the movement of the mouse as the user interacts with the plot. The nearest time x-value is determined and used to display the corresponding y-values for each time-series displayed. The mousemove() function was initialized in part 1 as follows:

function mousemove() {
    var x0 = x.invert(d3.mouse(d3.select("#svgMain").node())[0]);
    var i = bisectDate(origData, x0, 1);
    d3.selectAll(".index").data().forEach(function(d) {
        var d0 = d.values[i - 1],
            d1 = d.values[i],
            p = x0 - d0.date > d1.date - x0 ? d1 : d0;
        var x_new = x(p.date),
            y_new = y(p.yvalue);
        svg.select("#focus" + d.name).attr("transform", "translate(" + x_new + "," + y_new + ")");
        svg.select("#numtext" + d.name).text(p.yvalue);
				svg.select("#datetext").text(dateDisplayFormat(p.date));
    });
}

The code in part 4 displayed where the mousemove() function is first called.

Next, add html and svg elements which draw circles and append text to the plot display at the location and value of the data points. These objects will follow the movement of the mouse. The location of the nearest Date will be fixed in the top center of the plot; its value will change accordingly as the mouse moves. Each time-series line currently displayed on the plot will need to have a “rect” appended to it, as shown below:

var addMouse = function() {
    focus = svg.selectAll(".index").append("g")
        .attr("id", function(d) {
            return "focus" + d.name;
        })
        .attr("class", function(d) {
            return "focus " + d.name;
        })
        .style("display", "none");
    focus.append("circle")
        .attr("id", function(d) {
            return "circle" + d.name;
        })
        .attr("r", 4.5);
    focus.append("text")
        .attr("id", function(d) {
            return "numtext" + d.name;
        })
        .attr("x", 9)
        .attr("dy", "-0.5em");
    svg.append("text")
        .attr("id", "datetext")
        .attr("x", width / 2);
    svg.selectAll(".index").append("rect")
        .attr("class", function(d) {
            return "overlay " + d.name;
        })
        .attr("width", width)
        .attr("height", height)
        .on("mouseover", function() {
            focus.style("display", null);
        })
        .on("mouseout", function() {
            focus.style("display", "none");
        })
        .on("mousemove", mousemove);
}

The circles that trace the multiple plot lines will appear and disappear as the mouse moves onto and off the plot. This is associated with the following CSS style code:

.overlay {
  fill: none;
  pointer-events: all;
}
.focus circle {
  fill: none;
  stroke: steelblue;
}