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