@kevinburke/flot 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/CHANGELOG.md +1814 -0
  2. package/LICENSE.txt +22 -0
  3. package/README.md +119 -0
  4. package/dist/flot.js +9830 -0
  5. package/dist/flot.min.js +2 -0
  6. package/dist/flot.min.js.map +1 -0
  7. package/dist/flot.mjs +9805 -0
  8. package/dist/jquery.flot.js +9869 -0
  9. package/dist/jquery.flot.min.js +2 -0
  10. package/dist/jquery.flot.min.js.map +1 -0
  11. package/dist/plugins/jquery.flot.crosshair.js +207 -0
  12. package/dist/plugins/jquery.flot.crosshair.min.js +2 -0
  13. package/dist/plugins/jquery.flot.crosshair.min.js.map +1 -0
  14. package/dist/plugins/jquery.flot.image.js +261 -0
  15. package/dist/plugins/jquery.flot.image.min.js +2 -0
  16. package/dist/plugins/jquery.flot.image.min.js.map +1 -0
  17. package/dist/plugins/jquery.flot.pie.js +815 -0
  18. package/dist/plugins/jquery.flot.pie.min.js +2 -0
  19. package/dist/plugins/jquery.flot.pie.min.js.map +1 -0
  20. package/dist/plugins/jquery.flot.resize.js +62 -0
  21. package/dist/plugins/jquery.flot.resize.min.js +2 -0
  22. package/dist/plugins/jquery.flot.resize.min.js.map +1 -0
  23. package/dist/plugins/jquery.flot.threshold.js +148 -0
  24. package/dist/plugins/jquery.flot.threshold.min.js +2 -0
  25. package/dist/plugins/jquery.flot.threshold.min.js.map +1 -0
  26. package/docs/API.md +1767 -0
  27. package/docs/PLUGINS.md +143 -0
  28. package/docs/absRelTime.md +42 -0
  29. package/docs/browser.md +24 -0
  30. package/docs/canvaswrapper.md +116 -0
  31. package/docs/composeImages.md +32 -0
  32. package/docs/drawSeries.md +35 -0
  33. package/docs/hover.md +21 -0
  34. package/docs/interactions.md +57 -0
  35. package/docs/logaxis.md +27 -0
  36. package/docs/navigate.md +110 -0
  37. package/package.json +53 -0
  38. package/source/helpers.js +168 -0
  39. package/source/index.js +70 -0
  40. package/source/jquery-adapter.js +83 -0
  41. package/source/jquery.canvaswrapper.js +546 -0
  42. package/source/jquery.colorhelpers.js +198 -0
  43. package/source/jquery.flot.axislabels.js +214 -0
  44. package/source/jquery.flot.browser.js +53 -0
  45. package/source/jquery.flot.categories.js +202 -0
  46. package/source/jquery.flot.composeImages.js +327 -0
  47. package/source/jquery.flot.crosshair.js +203 -0
  48. package/source/jquery.flot.drawSeries.js +699 -0
  49. package/source/jquery.flot.errorbars.js +375 -0
  50. package/source/jquery.flot.fillbetween.js +254 -0
  51. package/source/jquery.flot.flatdata.js +47 -0
  52. package/source/jquery.flot.hover.js +354 -0
  53. package/source/jquery.flot.image.js +252 -0
  54. package/source/jquery.flot.js +2814 -0
  55. package/source/jquery.flot.legend.js +444 -0
  56. package/source/jquery.flot.logaxis.js +299 -0
  57. package/source/jquery.flot.navigate.js +842 -0
  58. package/source/jquery.flot.pie.js +811 -0
  59. package/source/jquery.flot.resize.js +57 -0
  60. package/source/jquery.flot.saturated.js +40 -0
  61. package/source/jquery.flot.selection.js +552 -0
  62. package/source/jquery.flot.stack.js +220 -0
  63. package/source/jquery.flot.symbol.js +98 -0
  64. package/source/jquery.flot.threshold.js +144 -0
  65. package/source/jquery.flot.time.js +584 -0
  66. package/source/jquery.flot.touch.js +320 -0
  67. package/source/jquery.flot.touchNavigate.js +357 -0
  68. package/source/jquery.flot.uiConstants.js +9 -0
  69. package/source/jquery.js +9473 -0
@@ -0,0 +1,320 @@
1
+
2
+ /* global jQuery */
3
+
4
+ import { plugins } from './jquery.flot.js';
5
+
6
+ 'use strict';
7
+
8
+ var options = {
9
+ propagateSupportedGesture: false
10
+ };
11
+
12
+ function init(plot) {
13
+ plot.hooks.processOptions.push(initTouchNavigation);
14
+ }
15
+
16
+ function initTouchNavigation(plot, options) {
17
+ var gestureState = {
18
+ twoTouches: false,
19
+ currentTapStart: { x: 0, y: 0 },
20
+ currentTapEnd: { x: 0, y: 0 },
21
+ prevTap: { x: 0, y: 0 },
22
+ currentTap: { x: 0, y: 0 },
23
+ interceptedLongTap: false,
24
+ isUnsupportedGesture: false,
25
+ prevTapTime: null,
26
+ tapStartTime: null,
27
+ longTapTriggerId: null
28
+ },
29
+ maxDistanceBetweenTaps = 20,
30
+ maxIntervalBetweenTaps = 500,
31
+ maxLongTapDistance = 20,
32
+ minLongTapDuration = 1500,
33
+ pressedTapDuration = 125,
34
+ mainEventHolder;
35
+
36
+ function interpretGestures(e) {
37
+ var o = plot.getOptions();
38
+
39
+ if (!o.pan.active && !o.zoom.active) {
40
+ return;
41
+ }
42
+
43
+ updateOnMultipleTouches(e);
44
+ mainEventHolder.dispatchEvent(new CustomEvent('touchevent', { detail: e }));
45
+
46
+ if (isPinchEvent(e)) {
47
+ executeAction(e, 'pinch');
48
+ } else {
49
+ executeAction(e, 'pan');
50
+ if (!wasPinchEvent(e)) {
51
+ if (isDoubleTap(e)) {
52
+ executeAction(e, 'doubleTap');
53
+ }
54
+ executeAction(e, 'tap');
55
+ executeAction(e, 'longTap');
56
+ }
57
+ }
58
+ }
59
+
60
+ function executeAction(e, gesture) {
61
+ switch (gesture) {
62
+ case 'pan':
63
+ pan[e.type](e);
64
+ break;
65
+ case 'pinch':
66
+ pinch[e.type](e);
67
+ break;
68
+ case 'doubleTap':
69
+ doubleTap.onDoubleTap(e);
70
+ break;
71
+ case 'longTap':
72
+ longTap[e.type](e);
73
+ break;
74
+ case 'tap':
75
+ tap[e.type](e);
76
+ break;
77
+ }
78
+ }
79
+
80
+ function bindEvents(plot, eventHolder) {
81
+ mainEventHolder = eventHolder;
82
+ eventHolder.addEventListener('touchstart', interpretGestures, false);
83
+ eventHolder.addEventListener('touchmove', interpretGestures, false);
84
+ eventHolder.addEventListener('touchend', interpretGestures, false);
85
+ }
86
+
87
+ function shutdown(plot, eventHolder) {
88
+ eventHolder.removeEventListener('touchstart', interpretGestures);
89
+ eventHolder.removeEventListener('touchmove', interpretGestures);
90
+ eventHolder.removeEventListener('touchend', interpretGestures);
91
+ if (gestureState.longTapTriggerId) {
92
+ clearTimeout(gestureState.longTapTriggerId);
93
+ gestureState.longTapTriggerId = null;
94
+ }
95
+ }
96
+
97
+ var pan = {
98
+ touchstart: function(e) {
99
+ updatePrevForDoubleTap();
100
+ updateCurrentForDoubleTap(e);
101
+ updateStateForLongTapStart(e);
102
+
103
+ mainEventHolder.dispatchEvent(new CustomEvent('panstart', { detail: e }));
104
+ },
105
+
106
+ touchmove: function(e) {
107
+ preventEventBehaviors(e);
108
+
109
+ updateCurrentForDoubleTap(e);
110
+ updateStateForLongTapEnd(e);
111
+
112
+ if (!gestureState.isUnsupportedGesture) {
113
+ mainEventHolder.dispatchEvent(new CustomEvent('pandrag', { detail: e }));
114
+ }
115
+ },
116
+
117
+ touchend: function(e) {
118
+ preventEventBehaviors(e);
119
+
120
+ if (wasPinchEvent(e)) {
121
+ mainEventHolder.dispatchEvent(new CustomEvent('pinchend', { detail: e }));
122
+ mainEventHolder.dispatchEvent(new CustomEvent('panstart', { detail: e }));
123
+ } else if (noTouchActive(e)) {
124
+ mainEventHolder.dispatchEvent(new CustomEvent('panend', { detail: e }));
125
+ }
126
+ }
127
+ };
128
+
129
+ var pinch = {
130
+ touchstart: function(e) {
131
+ mainEventHolder.dispatchEvent(new CustomEvent('pinchstart', { detail: e }));
132
+ },
133
+
134
+ touchmove: function(e) {
135
+ preventEventBehaviors(e);
136
+ gestureState.twoTouches = isPinchEvent(e);
137
+ if (!gestureState.isUnsupportedGesture) {
138
+ mainEventHolder.dispatchEvent(new CustomEvent('pinchdrag', { detail: e }));
139
+ }
140
+ },
141
+
142
+ touchend: function(e) {
143
+ preventEventBehaviors(e);
144
+ }
145
+ };
146
+
147
+ var doubleTap = {
148
+ onDoubleTap: function(e) {
149
+ preventEventBehaviors(e);
150
+ mainEventHolder.dispatchEvent(new CustomEvent('doubletap', { detail: e }));
151
+ }
152
+ };
153
+
154
+ var longTap = {
155
+ touchstart: function(e) {
156
+ longTap.waitForLongTap(e);
157
+ },
158
+
159
+ touchmove: function(e) {
160
+ },
161
+
162
+ touchend: function(e) {
163
+ if (gestureState.longTapTriggerId) {
164
+ clearTimeout(gestureState.longTapTriggerId);
165
+ gestureState.longTapTriggerId = null;
166
+ }
167
+ },
168
+
169
+ isLongTap: function(e) {
170
+ var currentTime = new Date().getTime(),
171
+ tapDuration = currentTime - gestureState.tapStartTime;
172
+ if (tapDuration >= minLongTapDuration && !gestureState.interceptedLongTap) {
173
+ if (distance(gestureState.currentTapStart.x, gestureState.currentTapStart.y, gestureState.currentTapEnd.x, gestureState.currentTapEnd.y) < maxLongTapDistance) {
174
+ gestureState.interceptedLongTap = true;
175
+ return true;
176
+ }
177
+ }
178
+ return false;
179
+ },
180
+
181
+ waitForLongTap: function(e) {
182
+ var longTapTrigger = function() {
183
+ if (longTap.isLongTap(e)) {
184
+ mainEventHolder.dispatchEvent(new CustomEvent('longtap', { detail: e }));
185
+ }
186
+ gestureState.longTapTriggerId = null;
187
+ };
188
+ if (!gestureState.longTapTriggerId) {
189
+ gestureState.longTapTriggerId = setTimeout(longTapTrigger, minLongTapDuration);
190
+ }
191
+ }
192
+ };
193
+
194
+ var tap = {
195
+ touchstart: function(e) {
196
+ gestureState.tapStartTime = new Date().getTime();
197
+ },
198
+
199
+ touchmove: function(e) {
200
+ },
201
+
202
+ touchend: function(e) {
203
+ if (tap.isTap(e)) {
204
+ mainEventHolder.dispatchEvent(new CustomEvent('tap', { detail: e }));
205
+ preventEventBehaviors(e);
206
+ }
207
+ },
208
+
209
+ isTap: function(e) {
210
+ var currentTime = new Date().getTime(),
211
+ tapDuration = currentTime - gestureState.tapStartTime;
212
+ if (tapDuration <= pressedTapDuration) {
213
+ if (distance(gestureState.currentTapStart.x, gestureState.currentTapStart.y, gestureState.currentTapEnd.x, gestureState.currentTapEnd.y) < maxLongTapDistance) {
214
+ return true;
215
+ }
216
+ }
217
+ return false;
218
+ }
219
+ };
220
+
221
+ if (options.pan.enableTouch === true || options.zoom.enableTouch) {
222
+ plot.hooks.bindEvents.push(bindEvents);
223
+ plot.hooks.shutdown.push(shutdown);
224
+ };
225
+
226
+ function updatePrevForDoubleTap() {
227
+ gestureState.prevTap = {
228
+ x: gestureState.currentTap.x,
229
+ y: gestureState.currentTap.y
230
+ };
231
+ };
232
+
233
+ function updateCurrentForDoubleTap(e) {
234
+ gestureState.currentTap = {
235
+ x: e.touches[0].pageX,
236
+ y: e.touches[0].pageY
237
+ };
238
+ }
239
+
240
+ function updateStateForLongTapStart(e) {
241
+ gestureState.tapStartTime = new Date().getTime();
242
+ gestureState.interceptedLongTap = false;
243
+ gestureState.currentTapStart = {
244
+ x: e.touches[0].pageX,
245
+ y: e.touches[0].pageY
246
+ };
247
+ gestureState.currentTapEnd = {
248
+ x: e.touches[0].pageX,
249
+ y: e.touches[0].pageY
250
+ };
251
+ };
252
+
253
+ function updateStateForLongTapEnd(e) {
254
+ gestureState.currentTapEnd = {
255
+ x: e.touches[0].pageX,
256
+ y: e.touches[0].pageY
257
+ };
258
+ };
259
+
260
+ function isDoubleTap(e) {
261
+ var currentTime = new Date().getTime(),
262
+ intervalBetweenTaps = currentTime - gestureState.prevTapTime;
263
+
264
+ if (intervalBetweenTaps >= 0 && intervalBetweenTaps < maxIntervalBetweenTaps) {
265
+ if (distance(gestureState.prevTap.x, gestureState.prevTap.y, gestureState.currentTap.x, gestureState.currentTap.y) < maxDistanceBetweenTaps) {
266
+ e.firstTouch = gestureState.prevTap;
267
+ e.secondTouch = gestureState.currentTap;
268
+ return true;
269
+ }
270
+ }
271
+ gestureState.prevTapTime = currentTime;
272
+ return false;
273
+ }
274
+
275
+ function preventEventBehaviors(e) {
276
+ if (!gestureState.isUnsupportedGesture) {
277
+ e.preventDefault();
278
+ if (!plot.getOptions().propagateSupportedGesture) {
279
+ e.stopPropagation();
280
+ }
281
+ }
282
+ }
283
+
284
+ function distance(x1, y1, x2, y2) {
285
+ return Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
286
+ }
287
+
288
+ function noTouchActive(e) {
289
+ return (e.touches && e.touches.length === 0);
290
+ }
291
+
292
+ function wasPinchEvent(e) {
293
+ return (gestureState.twoTouches && e.touches.length === 1);
294
+ }
295
+
296
+ function updateOnMultipleTouches(e) {
297
+ if (e.touches.length >= 3) {
298
+ gestureState.isUnsupportedGesture = true;
299
+ } else {
300
+ gestureState.isUnsupportedGesture = false;
301
+ }
302
+ }
303
+
304
+ function isPinchEvent(e) {
305
+ if (e.touches && e.touches.length >= 2) {
306
+ if (e.touches[0].target === plot.getEventHolder() &&
307
+ e.touches[1].target === plot.getEventHolder()) {
308
+ return true;
309
+ }
310
+ }
311
+ return false;
312
+ }
313
+ }
314
+
315
+ plugins.push({
316
+ init: init,
317
+ options: options,
318
+ name: 'navigateTouch',
319
+ version: '0.3'
320
+ });
@@ -0,0 +1,357 @@
1
+ import { plugins } from './jquery.flot.js';
2
+ import { uiConstants } from './jquery.flot.uiConstants.js';
3
+ import { trigger } from './helpers.js';
4
+
5
+ 'use strict';
6
+
7
+ var options = {
8
+ zoom: {
9
+ enableTouch: false
10
+ },
11
+ pan: {
12
+ enableTouch: false,
13
+ touchMode: 'manual'
14
+ },
15
+ recenter: {
16
+ enableTouch: true
17
+ }
18
+ };
19
+
20
+ var ZOOM_DISTANCE_MARGIN = uiConstants.ZOOM_DISTANCE_MARGIN;
21
+
22
+ function init(plot) {
23
+ plot.hooks.processOptions.push(initTouchNavigation);
24
+ }
25
+
26
+ function initTouchNavigation(plot, options) {
27
+ var gestureState = {
28
+ zoomEnable: false,
29
+ prevDistance: null,
30
+ prevTapTime: 0,
31
+ prevPanPosition: { x: 0, y: 0 },
32
+ prevTapPosition: { x: 0, y: 0 }
33
+ },
34
+ navigationState = {
35
+ prevTouchedAxis: 'none',
36
+ currentTouchedAxis: 'none',
37
+ touchedAxis: null,
38
+ navigationConstraint: 'unconstrained',
39
+ initialState: null
40
+ },
41
+ useManualPan = options.pan.interactive && options.pan.touchMode === 'manual',
42
+ smartPanLock = options.pan.touchMode === 'smartLock',
43
+ useSmartPan = options.pan.interactive && (smartPanLock || options.pan.touchMode === 'smart'),
44
+ pan, pinch, doubleTap;
45
+
46
+ function bindEvents(plot, eventHolder) {
47
+ var o = plot.getOptions();
48
+
49
+ if (o.zoom.interactive && o.zoom.enableTouch) {
50
+ eventHolder.addEventListener('pinchstart', pinch.start, false);
51
+ eventHolder.addEventListener('pinchdrag', pinch.drag, false);
52
+ eventHolder.addEventListener('pinchend', pinch.end, false);
53
+ }
54
+
55
+ if (o.pan.interactive && o.pan.enableTouch) {
56
+ eventHolder.addEventListener('panstart', pan.start, false);
57
+ eventHolder.addEventListener('pandrag', pan.drag, false);
58
+ eventHolder.addEventListener('panend', pan.end, false);
59
+ }
60
+
61
+ if ((o.recenter.interactive && o.recenter.enableTouch)) {
62
+ eventHolder.addEventListener('doubletap', doubleTap.recenterPlot, false);
63
+ }
64
+ }
65
+
66
+ function shutdown(plot, eventHolder) {
67
+ eventHolder.removeEventListener('panstart', pan.start);
68
+ eventHolder.removeEventListener('pandrag', pan.drag);
69
+ eventHolder.removeEventListener('panend', pan.end);
70
+ eventHolder.removeEventListener('pinchstart', pinch.start);
71
+ eventHolder.removeEventListener('pinchdrag', pinch.drag);
72
+ eventHolder.removeEventListener('pinchend', pinch.end);
73
+ eventHolder.removeEventListener('doubletap', doubleTap.recenterPlot);
74
+ }
75
+
76
+ pan = {
77
+ start: function(e) {
78
+ presetNavigationState(e, 'pan', gestureState);
79
+ updateData(e, 'pan', gestureState, navigationState);
80
+
81
+ if (useSmartPan) {
82
+ var point = getPoint(e, 'pan');
83
+ navigationState.initialState = plot.navigationState(point.x, point.y);
84
+ }
85
+ },
86
+
87
+ drag: function(e) {
88
+ presetNavigationState(e, 'pan', gestureState);
89
+
90
+ if (useSmartPan) {
91
+ var point = getPoint(e, 'pan');
92
+ plot.smartPan({
93
+ x: navigationState.initialState.startPageX - point.x,
94
+ y: navigationState.initialState.startPageY - point.y
95
+ }, navigationState.initialState, navigationState.touchedAxis, false, smartPanLock);
96
+ } else if (useManualPan) {
97
+ plot.pan({
98
+ left: -delta(e, 'pan', gestureState).x,
99
+ top: -delta(e, 'pan', gestureState).y,
100
+ axes: navigationState.touchedAxis
101
+ });
102
+ updatePrevPanPosition(e, 'pan', gestureState, navigationState);
103
+ }
104
+ },
105
+
106
+ end: function(e) {
107
+ presetNavigationState(e, 'pan', gestureState);
108
+
109
+ if (useSmartPan) {
110
+ plot.smartPan.end();
111
+ }
112
+
113
+ if (wasPinchEvent(e, gestureState)) {
114
+ updateprevPanPosition(e, 'pan', gestureState, navigationState);
115
+ }
116
+ }
117
+ };
118
+
119
+ var pinchDragTimeout;
120
+ pinch = {
121
+ start: function(e) {
122
+ if (pinchDragTimeout) {
123
+ clearTimeout(pinchDragTimeout);
124
+ pinchDragTimeout = null;
125
+ }
126
+ presetNavigationState(e, 'pinch', gestureState);
127
+ setPrevDistance(e, gestureState);
128
+ updateData(e, 'pinch', gestureState, navigationState);
129
+ },
130
+
131
+ drag: function(e) {
132
+ if (pinchDragTimeout) {
133
+ return;
134
+ }
135
+ pinchDragTimeout = setTimeout(function() {
136
+ presetNavigationState(e, 'pinch', gestureState);
137
+ plot.pan({
138
+ left: -delta(e, 'pinch', gestureState).x,
139
+ top: -delta(e, 'pinch', gestureState).y,
140
+ axes: navigationState.touchedAxis
141
+ });
142
+ updatePrevPanPosition(e, 'pinch', gestureState, navigationState);
143
+
144
+ var dist = pinchDistance(e);
145
+
146
+ if (gestureState.zoomEnable || Math.abs(dist - gestureState.prevDistance) > ZOOM_DISTANCE_MARGIN) {
147
+ zoomPlot(plot, e, gestureState, navigationState);
148
+
149
+ //activate zoom mode
150
+ gestureState.zoomEnable = true;
151
+ }
152
+ pinchDragTimeout = null;
153
+ }, 1000 / 60);
154
+ },
155
+
156
+ end: function(e) {
157
+ if (pinchDragTimeout) {
158
+ clearTimeout(pinchDragTimeout);
159
+ pinchDragTimeout = null;
160
+ }
161
+ presetNavigationState(e, 'pinch', gestureState);
162
+ gestureState.prevDistance = null;
163
+ }
164
+ };
165
+
166
+ doubleTap = {
167
+ recenterPlot: function(e) {
168
+ if (e && e.detail && e.detail.type === 'touchstart') {
169
+ // only do not recenter for touch start;
170
+ recenterPlotOnDoubleTap(plot, e, gestureState, navigationState);
171
+ }
172
+ }
173
+ };
174
+
175
+ if (options.pan.enableTouch === true || options.zoom.enableTouch === true) {
176
+ plot.hooks.bindEvents.push(bindEvents);
177
+ plot.hooks.shutdown.push(shutdown);
178
+ }
179
+
180
+ function presetNavigationState(e, gesture, gestureState) {
181
+ navigationState.touchedAxis = getAxis(plot, e, gesture, navigationState);
182
+ if (noAxisTouched(navigationState)) {
183
+ navigationState.navigationConstraint = 'unconstrained';
184
+ } else {
185
+ navigationState.navigationConstraint = 'axisConstrained';
186
+ }
187
+ }
188
+ }
189
+
190
+ plugins.push({
191
+ init: init,
192
+ options: options,
193
+ name: 'navigateTouch',
194
+ version: '0.3'
195
+ });
196
+
197
+ function recenterPlotOnDoubleTap(plot, e, gestureState, navigationState) {
198
+ checkAxesForDoubleTap(plot, e, navigationState);
199
+ if ((navigationState.currentTouchedAxis === 'x' && navigationState.prevTouchedAxis === 'x') ||
200
+ (navigationState.currentTouchedAxis === 'y' && navigationState.prevTouchedAxis === 'y') ||
201
+ (navigationState.currentTouchedAxis === 'none' && navigationState.prevTouchedAxis === 'none')) {
202
+ plot.recenter({ axes: navigationState.touchedAxis });
203
+
204
+ if (navigationState.touchedAxis) {
205
+ trigger(plot.getPlaceholder(), 're-center', { axisTouched: navigationState.touchedAxis });
206
+ } else {
207
+ trigger(plot.getPlaceholder(), 're-center', e);
208
+ }
209
+ }
210
+ }
211
+
212
+ function checkAxesForDoubleTap(plot, e, navigationState) {
213
+ var axis = plot.getTouchedAxis(e.detail.firstTouch.x, e.detail.firstTouch.y);
214
+ if (axis[0] !== undefined) {
215
+ navigationState.prevTouchedAxis = axis[0].direction;
216
+ }
217
+
218
+ axis = plot.getTouchedAxis(e.detail.secondTouch.x, e.detail.secondTouch.y);
219
+ if (axis[0] !== undefined) {
220
+ navigationState.touchedAxis = axis;
221
+ navigationState.currentTouchedAxis = axis[0].direction;
222
+ }
223
+
224
+ if (noAxisTouched(navigationState)) {
225
+ navigationState.touchedAxis = null;
226
+ navigationState.prevTouchedAxis = 'none';
227
+ navigationState.currentTouchedAxis = 'none';
228
+ }
229
+ }
230
+
231
+ function zoomPlot(plot, e, gestureState, navigationState) {
232
+ var offset = plot.offset(),
233
+ center = {
234
+ left: 0,
235
+ top: 0
236
+ },
237
+ zoomAmount = pinchDistance(e) / gestureState.prevDistance,
238
+ dist = pinchDistance(e);
239
+
240
+ center.left = getPoint(e, 'pinch').x - offset.left;
241
+ center.top = getPoint(e, 'pinch').y - offset.top;
242
+
243
+ // send the computed touched axis to the zoom function so that it only zooms on that one
244
+ plot.zoom({
245
+ center: center,
246
+ amount: zoomAmount,
247
+ axes: navigationState.touchedAxis
248
+ });
249
+ gestureState.prevDistance = dist;
250
+ }
251
+
252
+ function wasPinchEvent(e, gestureState) {
253
+ return (gestureState.zoomEnable && e.detail.touches.length === 1);
254
+ }
255
+
256
+ function getAxis(plot, e, gesture, navigationState) {
257
+ if (e.type === 'pinchstart') {
258
+ var axisTouch1 = plot.getTouchedAxis(e.detail.touches[0].pageX, e.detail.touches[0].pageY);
259
+ var axisTouch2 = plot.getTouchedAxis(e.detail.touches[1].pageX, e.detail.touches[1].pageY);
260
+
261
+ if (axisTouch1.length === axisTouch2.length && axisTouch1.toString() === axisTouch2.toString()) {
262
+ return axisTouch1;
263
+ }
264
+ } else if (e.type === 'panstart') {
265
+ return plot.getTouchedAxis(e.detail.touches[0].pageX, e.detail.touches[0].pageY);
266
+ } else if (e.type === 'pinchend') {
267
+ //update axis since instead on pinch, a pan event is made
268
+ return plot.getTouchedAxis(e.detail.touches[0].pageX, e.detail.touches[0].pageY);
269
+ } else {
270
+ return navigationState.touchedAxis;
271
+ }
272
+ }
273
+
274
+ function noAxisTouched(navigationState) {
275
+ return (!navigationState.touchedAxis || navigationState.touchedAxis.length === 0);
276
+ }
277
+
278
+ function setPrevDistance(e, gestureState) {
279
+ gestureState.prevDistance = pinchDistance(e);
280
+ }
281
+
282
+ function updateData(e, gesture, gestureState, navigationState) {
283
+ var axisDir,
284
+ point = getPoint(e, gesture);
285
+
286
+ switch (navigationState.navigationConstraint) {
287
+ case 'unconstrained':
288
+ navigationState.touchedAxis = null;
289
+ gestureState.prevTapPosition = {
290
+ x: gestureState.prevPanPosition.x,
291
+ y: gestureState.prevPanPosition.y
292
+ };
293
+ gestureState.prevPanPosition = {
294
+ x: point.x,
295
+ y: point.y
296
+ };
297
+ break;
298
+ case 'axisConstrained':
299
+ axisDir = navigationState.touchedAxis[0].direction;
300
+ navigationState.currentTouchedAxis = axisDir;
301
+ gestureState.prevTapPosition[axisDir] = gestureState.prevPanPosition[axisDir];
302
+ gestureState.prevPanPosition[axisDir] = point[axisDir];
303
+ break;
304
+ default:
305
+ break;
306
+ }
307
+ }
308
+
309
+ function distance(x1, y1, x2, y2) {
310
+ return Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
311
+ }
312
+
313
+ function pinchDistance(e) {
314
+ var t1 = e.detail.touches[0],
315
+ t2 = e.detail.touches[1];
316
+ return distance(t1.pageX, t1.pageY, t2.pageX, t2.pageY);
317
+ }
318
+
319
+ function updatePrevPanPosition(e, gesture, gestureState, navigationState) {
320
+ var point = getPoint(e, gesture);
321
+
322
+ switch (navigationState.navigationConstraint) {
323
+ case 'unconstrained':
324
+ gestureState.prevPanPosition.x = point.x;
325
+ gestureState.prevPanPosition.y = point.y;
326
+ break;
327
+ case 'axisConstrained':
328
+ gestureState.prevPanPosition[navigationState.currentTouchedAxis] =
329
+ point[navigationState.currentTouchedAxis];
330
+ break;
331
+ default:
332
+ break;
333
+ }
334
+ }
335
+
336
+ function delta(e, gesture, gestureState) {
337
+ var point = getPoint(e, gesture);
338
+
339
+ return {
340
+ x: point.x - gestureState.prevPanPosition.x,
341
+ y: point.y - gestureState.prevPanPosition.y
342
+ }
343
+ }
344
+
345
+ function getPoint(e, gesture) {
346
+ if (gesture === 'pinch') {
347
+ return {
348
+ x: (e.detail.touches[0].pageX + e.detail.touches[1].pageX) / 2,
349
+ y: (e.detail.touches[0].pageY + e.detail.touches[1].pageY) / 2
350
+ }
351
+ } else {
352
+ return {
353
+ x: e.detail.touches[0].pageX,
354
+ y: e.detail.touches[0].pageY
355
+ }
356
+ }
357
+ }
@@ -0,0 +1,9 @@
1
+ 'use strict';
2
+
3
+ export var uiConstants = {
4
+ SNAPPING_CONSTANT: 20,
5
+ PANHINT_LENGTH_CONSTANT: 10,
6
+ MINOR_TICKS_COUNT_CONSTANT: 4,
7
+ TICK_LENGTH_CONSTANT: 10,
8
+ ZOOM_DISTANCE_MARGIN: 25
9
+ };