123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245 |
- 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);
- }
- });
- });
|