summaryrefslogtreecommitdiff
path: root/js/dojo/dojox/charting/action2d/MouseZoomAndPan.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/dojo/dojox/charting/action2d/MouseZoomAndPan.js')
-rw-r--r--js/dojo/dojox/charting/action2d/MouseZoomAndPan.js246
1 files changed, 246 insertions, 0 deletions
diff --git a/js/dojo/dojox/charting/action2d/MouseZoomAndPan.js b/js/dojo/dojox/charting/action2d/MouseZoomAndPan.js
new file mode 100644
index 0000000..eea708b
--- /dev/null
+++ b/js/dojo/dojox/charting/action2d/MouseZoomAndPan.js
@@ -0,0 +1,246 @@
+//>>built
+define("dojox/charting/action2d/MouseZoomAndPan", ["dojo/_base/html", "dojo/_base/declare", "dojo/_base/window", "dojo/_base/array", "dojo/_base/event",
+ "dojo/_base/connect", "./ChartAction", "dojo/_base/sniff", "dojo/dom-prop", "dojo/keys"],
+ function(html, declare, win, arr, eventUtil, connect, ChartAction, has, domProp, keys){
+
+ /*=====
+ dojo.declare("dojox.charting.action2d.__MouseZoomAndPanCtorArgs", null, {
+ // summary:
+ // Additional arguments for mouse zoom and pan actions.
+
+ // axis: String?
+ // Target axis name for this action. Default is "x".
+ axis: "x",
+ // scaleFactor: Number?
+ // The scale factor applied on mouse wheel zoom. Default is 1.2.
+ scaleFactor: 1.2,
+ // maxScale: Number?
+ // The max scale factor accepted by this chart action. Default is 100.
+ maxScale: 100,
+ // enableScroll: Boolean?
+ // Whether mouse drag gesture should scroll the chart. Default is true.
+ enableScroll: true,
+ // enableDoubleClickZoom: Boolean?
+ // Whether a double click gesture should toggle between fit and zoom on the chart. Default is true.
+ enableDoubleClickZoom: true,
+ // enableKeyZoom: Boolean?
+ // Whether a keyZoomModifier + + or keyZoomModifier + - key press should zoom in our out on the chart. Default is true.
+ enableKeyZoom: true,
+ // keyZoomModifier: String?
+ // Which keyboard modifier should used for keyboard zoom in and out. This should be one of "alt", "ctrl", "shift" or "none" for no modifier. Default is "ctrl".
+ keyZoomModifier: "ctrl"
+ });
+ var ChartAction = dojox.charting.action2d.ChartAction;
+ =====*/
+
+ var sUnit = has("mozilla") ? -3 : 120;
+ var keyTests = {
+ none: function(event){
+ return !event.ctrlKey && !event.altKey && !event.shiftKey;
+ },
+ ctrl: function(event){
+ return event.ctrlKey && !event.altKey && !event.shiftKey;
+ },
+ alt: function(event){
+ return !event.ctrlKey && event.altKey && !event.shiftKey;
+ },
+ shift: function(event){
+ return !event.ctrlKey && !event.altKey && event.shiftKey;
+ }
+ };
+
+ return declare("dojox.charting.action2d.MouseZoomAndPan", ChartAction, {
+ // summary:
+ // Create an mouse zoom and pan action.
+ // You can zoom in or out the data window with mouse wheel. You can scroll using mouse drag gesture.
+ // You can toggle between zoom and fit view using double click on the chart.
+
+ // the data description block for the widget parser
+ defaultParams: {
+ axis: "x",
+ scaleFactor: 1.2,
+ maxScale: 100,
+ enableScroll: true,
+ enableDoubleClickZoom: true,
+ enableKeyZoom: true,
+ keyZoomModifier: "ctrl"
+ },
+ optionalParams: {}, // no optional parameters
+
+ constructor: function(chart, plot, kwArgs){
+ // summary:
+ // Create an mouse zoom and pan action and connect it.
+ // chart: dojox.charting.Chart
+ // The chart this action applies to.
+ // kwArgs: dojox.charting.action2d.__MouseZoomAndPanCtorArgs?
+ // Optional arguments for the chart action.
+ this._listeners = [{eventName: !has("mozilla") ? "onmousewheel" : "DOMMouseScroll", methodName: "onMouseWheel"}];
+ if(!kwArgs){ kwArgs = {}; }
+ this.axis = kwArgs.axis ? kwArgs.axis : "x";
+ this.scaleFactor = kwArgs.scaleFactor ? kwArgs.scaleFactor : 1.2;
+ this.maxScale = kwArgs.maxScale ? kwArgs.maxScale : 100;
+ this.enableScroll = kwArgs.enableScroll != undefined ? kwArgs.enableScroll : true;
+ this.enableDoubleClickZoom = kwArgs.enableDoubleClickZoom != undefined ? kwArgs.enableDoubleClickZoom : true;
+ this.enableKeyZoom = kwArgs.enableKeyZoom != undefined ? kwArgs.enableKeyZoom : true;
+ this.keyZoomModifier = kwArgs.keyZoomModifier ? kwArgs.keyZoomModifier : "ctrl";
+ if(this.enableScroll){
+ this._listeners.push({eventName: "onmousedown", methodName: "onMouseDown"});
+ }
+ if(this.enableDoubleClickZoom){
+ this._listeners.push({eventName: "ondblclick", methodName: "onDoubleClick"});
+ }
+ if(this.enableKeyZoom){
+ this._listeners.push({eventName: "keypress", methodName: "onKeyPress"});
+ }
+ this._handles = [];
+ this.connect();
+ },
+
+ _disconnectHandles: function(){
+ if(has("ie")){
+ this.chart.node.releaseCapture();
+ }
+ arr.forEach(this._handles, connect.disconnect);
+ this._handles = [];
+ },
+
+ connect: function(){
+ // summary:
+ // Connect this action to the chart.
+ this.inherited(arguments);
+ if(this.enableKeyZoom){
+ // we want to be able to get focus to receive key events
+ domProp.set(this.chart.node, "tabindex", "0");
+ // if one doesn't want a focus border he can do something like
+ // dojo.style(this.chart.node, "outline", "none");
+ }
+ },
+
+ disconnect: function(){
+ // summary:
+ // Disconnect this action from the chart.
+ this.inherited(arguments);
+ if(this.enableKeyZoom){
+ // we don't need anymore to be able to get focus to receive key events
+ domProp.set(this.chart.node, "tabindex", "-1");
+ }
+ // in case we disconnect before the end of the action
+ this._disconnectHandles();
+ },
+
+ onMouseDown: function(event){
+ // summary:
+ // Called when mouse is down on the chart.
+ var chart = this.chart, axis = chart.getAxis(this.axis);
+ if(!axis.vertical){
+ this._startCoord = event.pageX;
+ }else{
+ this._startCoord = event.pageY;
+ }
+ this._startOffset = axis.getWindowOffset();
+ this._isPanning = true;
+ // we now want to capture mouse move events everywhere to avoid
+ // stop scrolling when going out of the chart window
+ if(has("ie")){
+ this._handles.push(connect.connect(this.chart.node, "onmousemove", this, "onMouseMove"));
+ this._handles.push(connect.connect(this.chart.node, "onmouseup", this, "onMouseUp"));
+ this.chart.node.setCapture();
+ }else{
+ this._handles.push(connect.connect(win.doc, "onmousemove", this, "onMouseMove"));
+ this._handles.push(connect.connect(win.doc, "onmouseup", this, "onMouseUp"));
+ }
+ chart.node.focus();
+ // prevent the browser from trying the drag on the "image"
+ eventUtil.stop(event);
+ },
+
+ onMouseMove: function(event){
+ // summary:
+ // Called when mouse is moved on the chart.
+ if(this._isPanning){
+ var chart = this.chart, axis = chart.getAxis(this.axis);
+ var delta = axis.vertical?(this._startCoord- event.pageY):(event.pageX - this._startCoord);
+
+ var bounds = axis.getScaler().bounds,
+ s = bounds.span / (bounds.upper - bounds.lower);
+
+ var scale = axis.getWindowScale();
+
+ chart.setAxisWindow(this.axis, scale, this._startOffset - delta / s / scale);
+ chart.render();
+ }
+ },
+
+ onMouseUp: function(event){
+ // summary:
+ // Called when mouse is up on the chart.
+ this._isPanning = false;
+ this._disconnectHandles();
+ },
+
+ onMouseWheel: function(event){
+ // summary:
+ // Called when mouse wheel is used on the chart.
+ var scroll = event[(has("mozilla") ? "detail" : "wheelDelta")] / sUnit;
+ // on Mozilla the sUnit might actually not always be 3
+ // make sure we never have -1 < scroll < 1
+ if(scroll > -1 && scroll < 0){
+ scroll = -1;
+ }else if(scroll > 0 && scroll < 1){
+ scroll = 1;
+ }
+ this._onZoom(scroll, event);
+ },
+
+ onKeyPress: function(event){
+ // summary:
+ // Called when a key is pressed on the chart.
+ if(keyTests[this.keyZoomModifier](event)){
+ if(event.keyChar == "+" || event.keyCode == keys.NUMPAD_PLUS){
+ this._onZoom(1, event);
+ }else if(event.keyChar == "-" || event.keyCode == keys.NUMPAD_MINUS){
+ this._onZoom(-1, event);
+ }
+ }
+ },
+
+ onDoubleClick: function(event){
+ // summary:
+ // Called when the mouse is double is double clicked on the chart. Toggle between zoom and fit chart.
+ var chart = this.chart, axis = chart.getAxis(this.axis);
+ var scale = 1 / this.scaleFactor;
+ // are we fit?
+ if(axis.getWindowScale()==1){
+ // fit => zoom
+ var scaler = axis.getScaler(), start = scaler.bounds.from, end = scaler.bounds.to,
+ oldMiddle = (start + end) / 2, newMiddle = this.plot.toData({x: event.pageX, y: event.pageY})[this.axis],
+ newStart = scale * (start - oldMiddle) + newMiddle, newEnd = scale * (end - oldMiddle) + newMiddle;
+ chart.zoomIn(this.axis, [newStart, newEnd]);
+ }else{
+ // non fit => fit
+ chart.setAxisWindow(this.axis, 1, 0);
+ chart.render();
+ }
+ eventUtil.stop(event);
+ },
+
+ _onZoom: function(scroll, event){
+ var scale = (scroll < 0 ? Math.abs(scroll)*this.scaleFactor :
+ 1 / (Math.abs(scroll)*this.scaleFactor));
+ var chart = this.chart, axis = chart.getAxis(this.axis);
+ // after wheel reset event position exactly if we could start a new scroll action
+ var cscale = axis.getWindowScale();
+ if(cscale / scale > this.maxScale){
+ return;
+ }
+ var scaler = axis.getScaler(), start = scaler.bounds.from, end = scaler.bounds.to;
+ // keep mouse pointer as transformation center if available otherwise center
+ var middle = (event.type == "keypress") ? (start + end) / 2 :
+ this.plot.toData({x: event.pageX, y: event.pageY})[this.axis];
+ var newStart = scale * (start - middle) + middle, newEnd = scale * (end - middle) + middle;
+ chart.zoomIn(this.axis, [newStart, newEnd]);
+ // do not scroll browser
+ eventUtil.stop(event);
+ }
+ });
+});