From 0c5bb75fcd6018f99eb1bcf23af7113ed6eaf939 Mon Sep 17 00:00:00 2001 From: "olau@iola.dk" Date: Sun, 5 Jul 2009 19:10:21 +0000 Subject: [PATCH] Added navigate plugin for panning and zooming git-svn-id: https://flot.googlecode.com/svn/trunk@186 1e0a6537-2640-0410-bfb7-f154510ff394 --- NEWS.txt | 2 + examples/index.html | 1 + examples/navigate.html | 117 ++++++++++++++++++++ jquery.flot.navigate.js | 235 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 355 insertions(+) create mode 100644 examples/navigate.html create mode 100644 jquery.flot.navigate.js diff --git a/NEWS.txt b/NEWS.txt index 2e9f6fd..05da1dd 100644 --- a/NEWS.txt +++ b/NEWS.txt @@ -107,6 +107,8 @@ Changes: - Image plugin: plot prerendered images. +- Navigation plugin for panning and zooming a plot. + Bug fixes: diff --git a/examples/index.html b/examples/index.html index 8d881de..0df5776 100644 --- a/examples/index.html +++ b/examples/index.html @@ -26,6 +26,7 @@
  • Turning series on/off
  • Selection support and zooming and zooming with overview
  • Interacting with the data points
  • +
  • Panning and zooming (with plugin)
  • Some more esoteric features:

    diff --git a/examples/navigate.html b/examples/navigate.html new file mode 100644 index 0000000..31eda6f --- /dev/null +++ b/examples/navigate.html @@ -0,0 +1,117 @@ + + + + + Flot Examples + + + + + + + + +

    Flot Examples

    + +
    + +

    + +

    With the navigate plugin it is easy to add panning and + zooming. Drag to pan, double click to zoom. The plugin fires + events (useful for synchronizing several plots) and adds a + couple of public methods so you can easily build + a little user interface around it, like the little buttons + at the top right in the plot.

    + + + + + + diff --git a/jquery.flot.navigate.js b/jquery.flot.navigate.js new file mode 100644 index 0000000..d683da7 --- /dev/null +++ b/jquery.flot.navigate.js @@ -0,0 +1,235 @@ +/* +Flot plugin for adding panning and zooming capabilities to a plot. + +The default behaviour is double click to zoom in, drag to pan. The +plugin defines plot.zoom({ center }), plot.zoomOut() and +plot.pan(offset) so you easily can add custom controls. It also fires +a "plotpan" and "plotzoom" event when something happens, useful for +synchronizing plots. + +Example usage: + + plot = $.plot(...); + + // zoom default amount in on the pixel (100, 200) + plot.zoom({ center: { left: 10, top: 20 } }); + + // zoom out again + plot.zoomOut(); + + // pan 100 pixels to the left and 20 down + plot.pan({ left: -100, top: 20 }) + + +Options: + + zoom: { + interactive: false + trigger: "dblclick" // or "click" for single click + amount: 1.5 // 2 = 200% (zoom in), 0.5 = 50% (zoom out) + } + + pan: { + interactive: false + } + + xaxis, yaxis, x2axis, y2axis: { + zoomRange: null // or [number, number] (min range, max range) + panRange: null // or [number, number] (min, max) + } + +"interactive" enables the built-in drag/click behaviour. "amount" is +the amount to zoom the viewport relative to the current range, so 1 is +100% (i.e. no change), 1.5 is 150% (zoom in), 0.7 is 70% (zoom out). + +"zoomRange" is the interval in which zooming can happen, e.g. with +zoomRange: [1, 100] the zoom will never scale the axis so that the +difference between min and max is smaller than 1 or larger than 100. +You can set either of them to null to ignore. + +"panRange" confines the panning to stay within a range, e.g. with +panRange: [-10, 20] panning stops at -10 in one end and at 20 in the +other. Either can be null. +*/ + +/* +First an inline dependency: +jquery.event.drag.js ~ v1.5 ~ Copyright (c) 2008, Three Dub Media (http://threedubmedia.com) +Licensed under the MIT License ~ http://threedubmedia.googlecode.com/files/MIT-LICENSE.txt +*/ +(function(E){E.fn.drag=function(L,K,J){if(K){this.bind("dragstart",L)}if(J){this.bind("dragend",J)}return !L?this.trigger("drag"):this.bind("drag",K?K:L)};var A=E.event,B=A.special,F=B.drag={not:":input",distance:0,which:1,dragging:false,setup:function(J){J=E.extend({distance:F.distance,which:F.which,not:F.not},J||{});J.distance=I(J.distance);A.add(this,"mousedown",H,J);if(this.attachEvent){this.attachEvent("ondragstart",D)}},teardown:function(){A.remove(this,"mousedown",H);if(this===F.dragging){F.dragging=F.proxy=false}G(this,true);if(this.detachEvent){this.detachEvent("ondragstart",D)}}};B.dragstart=B.dragend={setup:function(){},teardown:function(){}};function H(L){var K=this,J,M=L.data||{};if(M.elem){K=L.dragTarget=M.elem;L.dragProxy=F.proxy||K;L.cursorOffsetX=M.pageX-M.left;L.cursorOffsetY=M.pageY-M.top;L.offsetX=L.pageX-L.cursorOffsetX;L.offsetY=L.pageY-L.cursorOffsetY}else{if(F.dragging||(M.which>0&&L.which!=M.which)||E(L.target).is(M.not)){return }}switch(L.type){case"mousedown":E.extend(M,E(K).offset(),{elem:K,target:L.target,pageX:L.pageX,pageY:L.pageY});A.add(document,"mousemove mouseup",H,M);G(K,false);F.dragging=null;return false;case !F.dragging&&"mousemove":if(I(L.pageX-M.pageX)+I(L.pageY-M.pageY) zr[1]))) + return; + + axisOptions.min = min; + axisOptions.max = max; + } + + scaleAxis(x1, x2, 'xaxis'); + scaleAxis(x1, x2, 'x2axis'); + scaleAxis(y1, y2, 'yaxis'); + scaleAxis(y1, y2, 'y2axis'); + + plot.setupGrid(); + plot.draw(); + + if (!args.preventEvent) + plot.getPlaceholder().trigger("plotzoom", [ plot ]); + } + + plot.pan = function (args) { + var l = +args.left, t = +args.top, + axes = plot.getAxes(), options = plot.getOptions(); + + if (isNaN(l)) + l = 0; + if (isNaN(t)) + t = 0; + + function panAxis(delta, name) { + var axis = axes[name], + axisOptions = options[name], + min, max; + + if (!axis.used) + return; + + min = axis.c2p(axis.p2c(axis.min) + delta), + max = axis.c2p(axis.p2c(axis.max) + delta); + + var pr = axisOptions.panRange; + if (pr) { + // check whether we hit the wall + if (pr[0] != null && pr[0] > min) { + delta = pr[0] - min; + min += delta; + max += delta; + } + + if (pr[1] != null && pr[1] < max) { + delta = pr[1] - max; + min += delta; + max += delta; + } + } + + axisOptions.min = min; + axisOptions.max = max; + } + + panAxis(l, 'xaxis'); + panAxis(l, 'x2axis'); + panAxis(t, 'yaxis'); + panAxis(t, 'y2axis'); + + plot.setupGrid(); + plot.draw(); + + if (!args.preventEvent) + plot.getPlaceholder().trigger("plotpan", [ plot ]); + } + + plot.hooks.bindEvents.push(bindEvents); + } + + $.plot.plugins.push({ + init: init, + options: options, + name: 'navigate', + version: '1.0' + }); +})(jQuery);