ChiMo
ChiMo

Reputation: 601

jquery flot chart highlight dot when near point

I am making a chart using jQuery flot (plot)

https://jsfiddle.net/5gtqwkjg/2/

var updateLegendTimeout = null;
var latestPosition = null;

function updateLegend() {

    updateLegendTimeout = null;

    var pos = latestPosition;

    var axes = plot.getAxes();
    if (pos.x < axes.xaxis.min || pos.x > axes.xaxis.max || pos.y < axes.yaxis.min || pos.y > axes.yaxis.max) {
        return;
    }

    /*
            var o = plot.pointOffset({ x: pos.x, y: -1.25 });
            var ctx = plot.getCanvas().getContext("2d");

            ctx.beginPath();
            ctx.moveTo(o.left, o.top);
            o.top = 0;
            ctx.lineTo(o.left, o.top);
            ctx.stroke();
            */

    var i, j, dataset = plot.getData();
    var halfDist = (dataset[0].data[1][0] - dataset[0].data[0][0]) / 2;

    for (i = 0; i < dataset.length; ++i) {

        var series = dataset[i];

        // Find the nearest points, x-wise

        for (j = 0; j < series.data.length; ++j) {
            if (series.data[j][0] - halfDist > pos.x) {
                break;
            }
        }

        // Now Interpolate

        var y,
        p1 = series.data[j - 1],
            p2 = series.data[j];

        if (p1 == null) y = p2[1];
        else if (p2 == null) y = p1[1];
        else y = p1[1];

        legends.eq(i).text(series.label.replace(/=.*/, "= " + y.toFixed(2)));
        //dataset[i].highlightColor = "#abcdef";
        //plot.highlight(dataset[0].series, dataset[0].datapoint);
    }
}

$("#placeholder").bind("plothover", function (event, pos, item) {
    latestPosition = pos;
    if (!updateLegendTimeout) {
        updateLegendTimeout = setTimeout(updateLegend, 50);
    }
});

I want to add in a functionality that when the user moves the mouse along the x-axis the dot will highlight to indicate what point they are hovering nearest to. I already have the legend reflect the values but how would I highlight the dots?

EDIT: Very helpful answers guys! Here is the finished result if anyone is interested https://jsfiddle.net/5gtqwkjg/4/

Upvotes: 2

Views: 2502

Answers (2)

Raidri
Raidri

Reputation: 17550

Using the highlight() function like Michel de Nijs in his answer, but a simpler version:

1) Put the plot.unhighlight(); at the start of your updateLegend function (you might also want to rename that since it not longer only updates the legend).

2) Add plot.highlight(i, j-1); after your for (j ...) loop.

See this fiddle for the code.

Upvotes: 2

Michel de Nijs
Michel de Nijs

Reputation: 406

You can make use of the highlight and unhighlight functions provided by Flot.

highlight(series, datapoint)

Highlight a specific datapoint in the data series. You can either specify the actual objects, e.g. if you got them from a "plotclick" event, or you can specify the indices, e.g. highlight(1, 3) to highlight the fourth point in the second series (remember, zero-based indexing).

unhighlight(series, datapoint) or unhighlight()

Remove the highlighting of the point, same parameters as highlight.

If you call unhighlight with no parameters, e.g. as plot.unhighlight(), all current highlights are removed.

See https://github.com/flot/flot/blob/master/API.md#plot-methods for reference.


Applying that logic to your question, I think I managed to create the desired result you were looking for.

I first start by unhighlighting everything, just to make sure nothing slips past us when we do highlight points.

for (i = 0; i < dataset.length; ++i) {

        plot.unhighlight(); // Unhighlight everything!

        var series = dataset[i];

Next up we go do the fun part, highlight all the points! (Just the ones we actually want to highlight)

In your "Find the nearest points, x-wise" loop I added another loop!

for (j = 0; j < series.data.length; ++j) {    
    if (series.data[j][0] - halfDist > pos.x) { 
        for(a = 0; a < dataset.length; a++) {  // <-- The added loop

            // You might want to optimize the way this is done
            // The way you were storing the series data didn't seem to work like I..
            // ..wanted it do, so I had to iterate the dataset variable again.
            // The yellow line won't highlight if you change dataset[a] to series. 
            plot.highlight(dataset[a], series.data[j][0]);
        }

        break;
     }
 }

The result https://jsfiddle.net/qj3068zn/6/, for ease of use.

Do note, none of this is optimized. You're probably better off restructuring your code to provide a more general way to approach this and increase reusability and readability.

Upvotes: 2

Related Questions