How to save (preserve) the zoom state of flot graphs on Update with AJAX

289 views
Skip to first unread message

Ozan Kaya

unread,
May 12, 2010, 6:45:06 AM5/12/10
to Flot graphs
I have a simple application which polls database for data every
minute. When new data is fetched, I am updating the graph using ajax.
However, whenever I update the graph (re-plot it with new values added
to plot data) the current state of zoom is lost. Before updating the
graph, I want to preserve the latest zoom position. After updating the
graph, I want to zoom the graph to its saved position. This is
important because re-zooming every minute is irritating. Is this
possible?

Joshua Varner

unread,
May 12, 2010, 4:01:27 PM5/12/10
to flot-...@googlegroups.com
When you get your new data before you re plot get the current zoom and
add it to the options on update.

// Get the current zoom
var zoom = plot.getAxes();

// Add the zoom to standard options
var zoomed = {};
$.extend(zoomed,options);
zoomed.xaxis.min = zoom.xaxis.min;
zoomed.xaxis.max = zoom.xaxis.max;
zoomed.yaxis.min = zoom.yaxis.min;
zoomed.yaxis.max = zoom.yaxis.max;

// draw/save the plot
plot = $.plot($("#graph"), d, zoomed);

Josh

George Roberts

unread,
May 12, 2010, 5:05:18 PM5/12/10
to flot-...@googlegroups.com
Joshua's suggestion is very nice but I had the same problem and resolved it by
blocking ajax update polls until the user unzoomed again. I set a flag
(bZoomed=true) which gets cleared when they hit the "zoomout" button. Ajax
queries don't query the server if bZoomed==true. Also my ajax code always knows
to ask for all new data from the server but in your case that might not work as
the server might only store the latest data.

- George Roberts
http://gr5.org
----- Original Message -----
From: "Joshua Varner" <jlva...@gmail.com>
To: <flot-...@googlegroups.com>
Sent: Wednesday, May 12, 2010 4:01 PM
Subject: Re: How to save (preserve) the zoom state of flot graphs on Update with
AJAX


> When you get your new data before you re plot get the current zoom and
> add it to the options on update.
>
> // Get the current zoom
> var zoom = plot.getAxes();
>
> // Add the zoom to standard options
> var zoomed = {};
> $.extend(zoomed,options);
> zoomed.xaxis.min = zoom.xaxis.min;
> zoomed.xaxis.max = zoom.xaxis.max;
> zoomed.yaxis.min = zoom.yaxis.min;
> zoomed.yaxis.max = zoom.yaxis.max;
>
> // draw/save the plot
> plot = $.plot($("#graph"), d, zoomed);
>
> Josh
>
> On Wed, May 12, 2010 at 5:45 AM, Ozan Kaya <oza...@gmail.com> wrote:

Spencer Aloysius

unread,
May 18, 2010, 9:23:33 AM5/18/10
to Flot graphs
Will this work with persisting zoom when selections are unchecked?

Spencer

Joshua Varner

unread,
May 18, 2010, 10:56:03 AM5/18/10
to flot-...@googlegroups.com
Short answer yes.

This is really independent of zooming per se. All you are doing is
grabbing the existing settings for the axis (which had previously been
zoomed) and then passing them in as new options for the next time you
plot the graph. The axis are global options so individual series
presence won't affect them.

Josh

Spencer Aloysius

unread,
May 18, 2010, 12:58:52 PM5/18/10
to Flot graphs

I'm going to try this. For some reason when I tried getSelection() to
solve this problem thinking that the axes would stay the same because
they were a global value and not dependent on the zoom level. Not
surprisingly getSelection() did not work.

Thanks for the tip.

Spencer

On May 18, 9:56 am, Joshua Varner <jlvar...@gmail.com> wrote:
> Short answer yes.
>
> This is really independent of zooming per se. All you are doing is
> grabbing the existing settings for the axis (which had previously been
> zoomed) and then passing them in as new options for the next time you
> plot the graph. The axis are global options so individual series
> presence won't affect them.
>
> Josh
>
> On Tue, May 18, 2010 at 8:23 AM, Spencer Aloysius
>

Spencer Aloysius

unread,
May 18, 2010, 3:14:04 PM5/18/10
to Flot graphs
I'm having trouble implementing this over two functions. I have a
page where the user can choose a bunch of different options (call them
1-12) which then plots a bunch of different series (call them A - Z).
So I divided my plotting and the series selection into two different
functions like this:

function makeplot(options, series, result) {
var placeholder = $("#placeholder");
var plot = $.plot(placeholder, result, options);

if ((series == "wavelength" || series == "energy") &&
(result.toSource().toString().search("xaxis") != -1 )) {
placeholder.unbind("plotselected")
placeholder.bind("plotselected", function (event, ranges) {
plot = $.plot(placeholder, result,
$.extend(true, {}, options, {
xaxis: { min: ranges.xaxis.from, max:
ranges.xaxis.to },
x2axis: { min: ranges.x2axis.from, max:
ranges.x2axis.to },
yaxis: { min: ranges.yaxis.from, max:
ranges.yaxis.to }
}));
});
}
else {
placeholder.unbind("plotselected");
placeholder.bind("plotselected", function (event, ranges) {
plot = $.plot(placeholder, result,
$.extend(true, {}, options, {
xaxis: { min: ranges.xaxis.from, max:
ranges.xaxis.to },
yaxis: { min: ranges.yaxis.from, max:
ranges.yaxis.to }
}));
});
}

placeholder.live("plotunselected", function (event) {
plot = $.plot(placeholder, result, options)
});


};

function makeCheckboxes (options, series, result) {
// insert checkboxes
$("#choices").html(" ");
var choiceContainer = $("#choices");
$.each(result, function(key, val) {
choiceContainer.append('<br/><input type="checkbox" name="' +
key +
'" checked="checked" id="id' + key +
'">' +
'<label for="id' + key + '">'
+ val.label + '</label>');
});
choiceContainer.find("input").click(plotAccordingToChoices);

function plotAccordingToChoices() {
var data = [];
choiceContainer.find("input:checked").each(function () {
var key = $(this).attr("name");
if (key && result[key])
data.push(result[key]);
});

if (data.length > 0) {
makeplot(options, series, data);
};
};
};


For example, right now when a user chooses option 1, an Ajax call to a
MySQL db is fired off and if successful, this calls the makeplot
function. If I give plot a global scope, calculate the zoom level in
plotAccordingtoChoices, pass zoomed to makeplot, then if a user zooms
and then unchecks a series, the plot no longer unzooms to the original
size because the original options for xaxis and yaxis have changed.
However options are individually defined for choice 1, 2, 3 and so on
because they all have different xaxis & yaxis restrictions.

I am stuck. How can I pass the zoom level around while maintaining
the limited scope of the options variable?

Spencer

On May 18, 9:56 am, Joshua Varner <jlvar...@gmail.com> wrote:
> Short answer yes.
>
> This is really independent of zooming per se. All you are doing is
> grabbing the existing settings for the axis (which had previously been
> zoomed) and then passing them in as new options for the next time you
> plot the graph. The axis are global options so individual series
> presence won't affect them.
>
> Josh
>
> On Tue, May 18, 2010 at 8:23 AM, Spencer Aloysius
>

Joshua Varner

unread,
May 18, 2010, 3:37:42 PM5/18/10
to flot-...@googlegroups.com
Assuming I understand your use case:

Select Option -> Select Series -> Zoom -> Change Series
Maintain zoom level

Select Option -> Select Series -> Zoom -> Change Option
Clear zoom level

Then you'll need to have a secondFunction like clearZoomThenPlot that
would clear out where you are saving the current zoom level and then
call plotAccordingToChoices. I don't see where the ranges variable is
being updated, so I assume the zooming code is doing that, you can
either null it out and put a check on draw, or just have some defaults
to which you would reset.

Use that one on controls that should reset the graph, and
plotAccordingToChoices on the ones that should maintain it.

Josh
Reply all
Reply to author
Forward
0 new messages