Initial OpenECOMP policy/engine commit
[policy/engine.git] / ecomp-sdk-app / src / main / webapp / static / fusion / raptor / dy3 / js / interaction.js
1         function moveV3(event, g, context) {
2                 if (context.isPanning) {
3                         Dygraph.movePan(event, g, context);
4                 } else if (context.isZooming) {
5                         Dygraph.moveZoom(event, g, context);
6                 }
7         }
8         
9         function upV3(event, g, context) {
10                 if (context.isPanning) {
11                         Dygraph.endPan(event, g, context);
12                 } else if (context.isZooming) {
13                         Dygraph.endZoom(event, g, context);
14                 }
15         }       
16
17 // Take the offset of a mouse event on the dygraph canvas and
18 // convert it to a pair of percentages from the bottom left. 
19 // (Not top left, bottom is where the lower value is.)
20 function offsetToPercentage(g, offsetX, offsetY) {
21   // This is calculating the pixel offset of the leftmost date.
22   var xOffset = g.toDomCoords(g.xAxisRange()[0], null)[0];
23   var yar0 = g.yAxisRange(0);
24
25   // This is calculating the pixel of the higest value. (Top pixel)
26   var yOffset = g.toDomCoords(null, yar0[1])[1];
27
28   // x y w and h are relative to the corner of the drawing area,
29   // so that the upper corner of the drawing area is (0, 0).
30   var x = offsetX - xOffset;
31   var y = offsetY - yOffset;
32
33   // This is computing the rightmost pixel, effectively defining the
34   // width.
35   var w = g.toDomCoords(g.xAxisRange()[1], null)[0] - xOffset;
36
37   // This is computing the lowest pixel, effectively defining the height.
38   var h = g.toDomCoords(null, yar0[0])[1] - yOffset;
39
40   // Percentage from the left.
41   var xPct = w == 0 ? 0 : (x / w);
42   // Percentage from the top.
43   var yPct = h == 0 ? 0 : (y / h);
44
45   // The (1-) part below changes it from "% distance down from the top"
46   // to "% distance up from the bottom".
47   return [xPct, (1-yPct)];
48 }
49
50 function dblClickV3(event, g, context) {
51   // Reducing by 20% makes it 80% the original size, which means
52   // to restore to original size it must grow by 25%
53   /*
54   if (!(event.offsetX && event.offsetY)){
55     event.offsetX = event.layerX - event.target.offsetLeft;
56     event.offsetY = event.layerY - event.target.offsetTop;
57   }
58
59   var percentages = offsetToPercentage(g, event.offsetX, event.offsetY);
60   var xPct = percentages[0];
61   var yPct = percentages[1];
62
63   if (event.ctrlKey) {
64     zoom(g, -.25, xPct, yPct);
65   } else {
66     zoom(g, +.2, xPct, yPct);
67   }
68   */
69   restorePositioning(g);
70 }
71
72 var lastClickedGraph = null;
73
74 function clickV3(event, g, context) {
75   lastClickedGraph = g;
76   Dygraph.cancelEvent(event);
77 }
78
79 function scrollV3(event, g, context) {
80   if (lastClickedGraph != g) {
81     return;
82   }
83   var normal = event.detail ? event.detail * -1 : event.wheelDelta / 40;
84   // For me the normalized value shows 0.075 for one click. If I took
85   // that verbatim, it would be a 7.5%.
86   var percentage = normal / 50;
87
88   if (!(event.offsetX && event.offsetY)){
89     event.offsetX = event.layerX - event.target.offsetLeft;
90     event.offsetY = event.layerY - event.target.offsetTop;
91   }
92
93   var percentages = offsetToPercentage(g, event.offsetX, event.offsetY);
94   var xPct = percentages[0];
95   var yPct = percentages[1];
96
97   zoom(g, percentage, xPct, yPct);
98   Dygraph.cancelEvent(event);
99 }
100
101 // Adjusts [x, y] toward each other by zoomInPercentage%
102 // Split it so the left/bottom axis gets xBias/yBias of that change and
103 // tight/top gets (1-xBias)/(1-yBias) of that change.
104 //
105 // If a bias is missing it splits it down the middle.
106 function zoom(g, zoomInPercentage, xBias, yBias) {
107   xBias = xBias || 0.5;
108   yBias = yBias || 0.5;
109   function adjustAxis(axis, zoomInPercentage, bias) {
110     var delta = axis[1] - axis[0];
111     var increment = delta * zoomInPercentage;
112     var foo = [increment * bias, increment * (1-bias)];
113     return [ axis[0] + foo[0], axis[1] - foo[1] ];
114   }
115   var yAxes = g.yAxisRanges();
116   var newYAxes = [];
117   for (var i = 0; i < yAxes.length; i++) {
118     newYAxes[i] = adjustAxis(yAxes[i], zoomInPercentage, yBias);
119   }
120
121   g.updateOptions({
122     dateWindow: adjustAxis(g.xAxisRange(), zoomInPercentage, xBias),
123     valueRange: newYAxes[0]
124     });
125 }
126
127 function restorePositioning(g) {
128   g.updateOptions({
129     dateWindow: null,
130     valueRange: null
131   });
132 }       
133
134 function zoom_custom(res) {
135   var w = g.xAxisRange();
136   desired_range = [w[0] - res * 1000, w[0] ];
137   animate();
138 }
139
140 function reset() {
141  desired_range = orig_range;
142  animate();
143 }
144
145 var click = 0;
146 var desired_range = null;
147 function approach_range() {
148         if (!desired_range) return;
149         // go halfway there
150         var range = g.xAxisRange();
151         if (Math.abs(desired_range[0] - range[0]) < 60 &&
152                 Math.abs(desired_range[1] - range[1]) < 60) {
153                 if(desired_range[0]>=orig_range[0])
154                         g.updateOptions({dateWindow: desired_range});
155                 else {
156                         g.updateOptions({dateWindow: orig_range});
157                         click = 8;
158                 }
159                 // (do not set another timeout.)
160         } else {
161                 var new_range;
162         new_range = [0.5 * (desired_range[0] + range[0]),
163                        0.5 * (desired_range[1] + range[1])];
164         g.updateOptions({dateWindow: new_range});
165         animate();
166     }
167 }         
168
169 function animate() {
170   setTimeout(approach_range, 50);
171 }
172
173
174 var v4Active = false;
175 var v4Canvas = null;
176
177 function downV4(event, g, context) {
178   context.initializeMouseDown(event, g, context);
179     
180     Dygraph.Interaction.startTouch(event, g, context);
181   
182     Dygraph.Interaction.moveTouch(event, g, context);
183   
184     Dygraph.Interaction.endTouch(event, g, context);
185   
186   v4Active = true;
187   moveV4(event, g, context); // in case the mouse went down on a data point.
188 }
189
190 var processed = [];
191
192 function moveV4(event, g, context) {
193   var RANGE = 7;
194
195   if (v4Active) {
196     var graphPos = Dygraph.findPos(g.graphDiv);
197     var canvasx = Dygraph.pageX(event) - graphPos.x;
198     var canvasy = Dygraph.pageY(event) - graphPos.y;
199
200     var rows = g.numRows();
201     // Row layout:
202     // [date, [val1, stdev1], [val2, stdev2]]
203     for (var row = 0; row < rows; row++) {
204       var date = g.getValue(row, 0);
205       var x = g.toDomCoords(date, null)[0];
206       var diff = Math.abs(canvasx - x);
207       if (diff < RANGE) {
208         for (var col = 1; col < 3; col++) {
209           // TODO(konigsberg): these will throw exceptions as data is removed.
210           var vals =  g.getValue(row, col);
211           if (vals == null) { continue; }
212           var val = vals[0];
213           var y = g.toDomCoords(null, val)[1];
214           var diff2 = Math.abs(canvasy - y);
215           if (diff2 < RANGE) {
216             var found = false;
217             for (var i in processed) {
218               var stored = processed[i];
219               if(stored[0] == row && stored[1] == col) {
220                 found = true;
221                 break;
222               }
223             }
224             if (!found) {
225               //processed.push([row, col]);
226               //drawV4(x, y);
227             }
228             return;
229           }
230         }
231       }
232     }
233   }
234 }
235
236 function upV4(event, g, context) {
237   if (v4Active) {
238     v4Active = false;
239   }
240 }
241
242 function dblClickV4(event, g, context) {
243   restorePositioning(g);
244 }
245
246 function drawV4(x, y) {
247   var ctx = v4Canvas;
248
249   ctx.strokeStyle = "#000000";
250   //ctx.fillStyle = "#FFFF00";
251   ctx.fillStyle = "#FF0000";
252   ctx.beginPath();
253   ctx.arc(x,y,5,0,Math.PI*2,true);
254   ctx.closePath();
255   ctx.stroke();
256   ctx.fill();
257 }
258
259 function captureCanvas(canvas, area, g) {
260   v4Canvas = canvas;
261 }
262
263 function newDygraphTouchstart(event, g, context) { 
264 // This right here is what prevents IOS from doing its own zoom/touch behavior 
265 // It stops the node from being selected too 
266 event.preventDefault(); // touch browsers are all nice. 
267
268 if (event.touches.length > 1) { 
269 // If the user ever puts two fingers down, it's not a double tap. 
270 context.startTimeForDoubleTapMs = null; 
271
272
273 var touches = []; 
274 for (var i = 0; i < event.touches.length; i++) { 
275 var t = event.touches[i]; 
276 // we dispense with 'dragGetX_' because all touchBrowsers support pageX 
277 touches.push({ 
278 pageX: t.pageX, 
279 pageY: t.pageY, 
280 dataX: g.toDataXCoord(t.pageX), 
281 dataY: g.toDataYCoord(t.pageY) 
282 // identifier: t.identifier 
283 }); 
284
285 context.initialTouches = touches; 
286
287 if (touches.length == 1) { 
288 // This is just a swipe. 
289 context.initialPinchCenter = touches[0]; 
290 context.touchDirections = { x: true, y: true }; 
291
292 // ADDITION - this needs to select the points 
293 //var closestTouchP = g.findClosestPoint(touches[0].pageX,touches[0].pageY); 
294 //if(closestTouchP) { 
295 //var selectionChanged = g.setSelection(closestTouchP.row, closestTouchP.seriesName); 
296 //} 
297 g.mouseMove_(event); 
298
299 } else if (touches.length >= 2) { 
300 // It's become a pinch! 
301 // In case there are 3+ touches, we ignore all but the "first" two. 
302
303 // only screen coordinates can be averaged (data coords could be log scale). 
304 context.initialPinchCenter = { 
305 pageX: 0.5 * (touches[0].pageX + touches[1].pageX), 
306 pageY: 0.5 * (touches[0].pageY + touches[1].pageY), 
307
308 // TODO(danvk): remove 
309 dataX: 0.5 * (touches[0].dataX + touches[1].dataX), 
310 dataY: 0.5 * (touches[0].dataY + touches[1].dataY) 
311 }; 
312
313 // Make pinches in a 45-degree swath around either axis 1-dimensional zooms. 
314 var initialAngle = 180 / Math.PI * Math.atan2( 
315 context.initialPinchCenter.pageY - touches[0].pageY, 
316 touches[0].pageX - context.initialPinchCenter.pageX); 
317
318 // use symmetry to get it into the first quadrant. 
319 initialAngle = Math.abs(initialAngle); 
320 if (initialAngle > 90) initialAngle = 90 - initialAngle; 
321
322 context.touchDirections = { 
323 x: (initialAngle < (90 - 45/2)), 
324 y: (initialAngle > 45/2) 
325 }; 
326
327
328 // save the full x & y ranges. 
329 context.initialRange = { 
330 x: g.xAxisRange(), 
331 y: g.yAxisRange() 
332 }; 
333 };