merged cont.
[opensuse:yast-rest-service.git] / webservice / public / javascripts / plugin / jqplot.dragable.js
1 /**
2  * Copyright (c) 2009 Chris Leonello
3  * jqPlot is currently available for use in all personal or commercial projects 
4  * under both the MIT and GPL version 2.0 licenses. This means that you can 
5  * choose the license that best suits your project and use it accordingly. 
6  *
7  * The author would appreciate an email letting him know of any substantial
8  * use of jqPlot.  You can reach the author at: chris dot leonello at gmail 
9  * dot com or see http://www.jqplot.com/info.php .  This is, of course, 
10  * not required.
11  *
12  * If you are feeling kind and generous, consider supporting the project by
13  * making a donation at: http://www.jqplot.com/donate.php .
14  *
15  * Thanks for using jqPlot!
16  * 
17  */
18 (function($) {
19     
20     /**
21      * Class: $.jqplot.Dragable
22      * Plugin to make plotted points dragable by the user.
23      */
24     $.jqplot.Dragable = function(options) {
25         // Group: Properties
26         this.markerRenderer = new $.jqplot.MarkerRenderer({shadow:false});
27         this.shapeRenderer = new $.jqplot.ShapeRenderer();
28         this.isDragging = false;
29         this.isOver = false;
30         this._ctx;
31         this._elem;
32         this._point;
33         this._gridData;
34         // prop: color
35         // CSS color spec for the dragged point (and adjacent line segment or bar).
36         this.color;
37         // prop: constrainTo
38         // Constrain dragging motion to an axis or to none.
39         // Allowable values are 'none', 'x', 'y'
40         this.constrainTo = 'none';  // 'x', 'y', or 'none';
41         $.extend(true, this, options);
42     };
43     
44     function DragCanvas() {
45         $.jqplot.GenericCanvas.call(this);
46         this.isDragging = false;
47         this.isOver = false;
48         this._neighbor;
49         this._cursors = [];
50     }
51     
52     DragCanvas.prototype = new $.jqplot.GenericCanvas();
53     DragCanvas.prototype.constructor = DragCanvas;
54     
55     
56     // called within scope of series
57     $.jqplot.Dragable.parseOptions = function (defaults, opts) {
58         var options = opts || {};
59         this.plugins.dragable = new $.jqplot.Dragable(options.dragable);
60         // since this function is called before series options are parsed,
61         // we can set this here and it will be overridden if needed.
62         this.isDragable = $.jqplot.config.enablePlugins;
63     };
64     
65     // called within context of plot
66     // create a canvas which we can draw on.
67     // insert it before the eventCanvas, so eventCanvas will still capture events.
68     // add a new DragCanvas object to the plot plugins to handle drawing on this new canvas.
69     $.jqplot.Dragable.postPlotDraw = function() {
70         this.plugins.dragable = {previousCursor:'auto', isOver:false};
71         this.plugins.dragable.dragCanvas = new DragCanvas();
72         
73         this.eventCanvas._elem.before(this.plugins.dragable.dragCanvas.createElement(this._gridPadding, 'jqplot-dragable-canvas', this._plotDimensions));
74         var dctx = this.plugins.dragable.dragCanvas.setContext();
75     };
76     
77     //$.jqplot.preInitHooks.push($.jqplot.Dragable.init);
78     $.jqplot.preParseSeriesOptionsHooks.push($.jqplot.Dragable.parseOptions);
79     $.jqplot.postDrawHooks.push($.jqplot.Dragable.postPlotDraw);
80     $.jqplot.eventListenerHooks.push(['jqplotMouseMove', handleMove]);
81     $.jqplot.eventListenerHooks.push(['jqplotMouseDown', handleDown]);
82     $.jqplot.eventListenerHooks.push(['jqplotMouseUp', handleUp]);
83
84     
85     function initDragPoint(plot, neighbor) {
86         var s = plot.series[neighbor.seriesIndex];
87         var drag = s.plugins.dragable;
88         
89         // first, init the mark renderer for the dragged point
90         var smr = s.markerRenderer;
91         var mr = drag.markerRenderer;
92         mr.style = smr.style;
93         mr.lineWidth = smr.lineWidth + 2.5;
94         mr.size = smr.size + 5;
95         if (!drag.color) {
96             var rgba = $.jqplot.getColorComponents(smr.color);
97             var newrgb = [rgba[0], rgba[1], rgba[2]];
98             var alpha = (rgba[3] >= 0.6) ? rgba[3]*0.6 : rgba[3]*(2-rgba[3]);
99             drag.color = 'rgba('+newrgb[0]+','+newrgb[1]+','+newrgb[2]+','+alpha+')';
100         }
101         mr.color = drag.color;
102         mr.init();
103
104         var start = (neighbor.pointIndex > 0) ? neighbor.pointIndex - 1 : 0;
105         var end = neighbor.pointIndex+2;
106         drag._gridData = s.gridData.slice(start, end);
107     }
108     
109     function handleMove(ev, gridpos, datapos, neighbor, plot) {
110         if (plot.plugins.dragable.dragCanvas.isDragging) {
111             var dc = plot.plugins.dragable.dragCanvas;
112             var dp = dc._neighbor;
113             var s = plot.series[dp.seriesIndex];
114             var drag = s.plugins.dragable;
115             var gd = s.gridData;
116             
117             // compute the new grid position with any constraints.
118             var x = (drag.constrainTo == 'y') ? dp.gridData[0] : gridpos.x;
119             var y = (drag.constrainTo == 'x') ? dp.gridData[1] : gridpos.y;
120             
121             // compute data values for any listeners.
122             var xu = s._xaxis.series_p2u(x);
123             var yu = s._yaxis.series_p2u(y);
124             
125             // clear the canvas then redraw effect at new position.
126             var ctx = dc._ctx;
127             ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
128             
129             // adjust our gridData for the new mouse position
130             if (dp.pointIndex > 0) {
131                 drag._gridData[1] = [x, y];
132             }
133             else {
134                 drag._gridData[0] = [x, y];
135             }
136             plot.series[dp.seriesIndex].draw(dc._ctx, {gridData:drag._gridData, shadow:false, preventJqPlotSeriesDrawTrigger:true, color:drag.color, markerOptions:{color:drag.color, shadow:false}, trendline:{show:false}});
137             plot.target.trigger('jqplotSeriesPointChange', [dp.seriesIndex, dp.pointIndex, [xu,yu], [x,y]]);
138         }
139         else if (neighbor != null) {
140             var series = plot.series[neighbor.seriesIndex];
141             if (series.isDragable) {
142                 var dc = plot.plugins.dragable.dragCanvas;
143                 if (!dc.isOver) {
144                     dc._cursors.push(ev.target.style.cursor);
145                     ev.target.style.cursor = "pointer";
146                 }
147                 dc.isOver = true;
148             }
149         }
150         else if (neighbor == null) {
151             var dc = plot.plugins.dragable.dragCanvas;
152             if (dc.isOver) {
153                 ev.target.style.cursor = dc._cursors.pop();
154                 dc.isOver = false;
155             }
156         }
157     }
158     
159     function handleDown(ev, gridpos, datapos, neighbor, plot) {
160         var dc = plot.plugins.dragable.dragCanvas;
161         dc._cursors.push(ev.target.style.cursor);
162         if (neighbor != null) {
163             var s = plot.series[neighbor.seriesIndex];
164             var drag = s.plugins.dragable;
165             if (s.isDragable && !dc.isDragging) {
166                 dc._neighbor = neighbor;
167                 dc.isDragging = true;
168                 initDragPoint(plot, neighbor);
169                 drag.markerRenderer.draw(s.gridData[neighbor.pointIndex][0], s.gridData[neighbor.pointIndex][1], dc._ctx);
170                 ev.target.style.cursor = "move";
171             }
172         }
173         // Just in case of a hickup, we'll clear the drag canvas and reset.
174         else {
175            var ctx = dc._ctx;
176            ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
177            dc.isDragging = false;
178         }
179     }
180     
181     function handleUp(ev, gridpos, datapos, neighbor, plot) {
182         if (plot.plugins.dragable.dragCanvas.isDragging) {
183             var dc = plot.plugins.dragable.dragCanvas;
184             // clear the canvas
185             var ctx = dc._ctx;
186             ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
187             dc.isDragging = false;
188             // redraw the series canvas at the new point.
189             var dp = dc._neighbor;
190             var s = plot.series[dp.seriesIndex];
191             var drag = s.plugins.dragable;
192             // compute the new grid position with any constraints.
193             var x = (drag.constrainTo == 'y') ? dp.data[0] : datapos[s.xaxis];
194             var y = (drag.constrainTo == 'x') ? dp.data[1] : datapos[s.yaxis];
195             // var x = datapos[s.xaxis];
196             // var y = datapos[s.yaxis];
197             s.data[dp.pointIndex] = [x,y];
198             plot.drawSeries({preventJqPlotSeriesDrawTrigger:true}, dp.seriesIndex);
199             dc._neighbor = null;
200             ev.target.style.cursor = dc._cursors.pop();
201         }
202     }
203 })(jQuery);