d3-drag.js 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. // https://d3js.org/d3-drag/ v1.2.5 Copyright 2019 Mike Bostock
  2. (function (global, factory) {
  3. typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('d3-dispatch'), require('d3-selection')) :
  4. typeof define === 'function' && define.amd ? define(['exports', 'd3-dispatch', 'd3-selection'], factory) :
  5. (global = global || self, factory(global.d3 = global.d3 || {}, global.d3, global.d3));
  6. }(this, function (exports, d3Dispatch, d3Selection) { 'use strict';
  7. function nopropagation() {
  8. d3Selection.event.stopImmediatePropagation();
  9. }
  10. function noevent() {
  11. d3Selection.event.preventDefault();
  12. d3Selection.event.stopImmediatePropagation();
  13. }
  14. function nodrag(view) {
  15. var root = view.document.documentElement,
  16. selection = d3Selection.select(view).on("dragstart.drag", noevent, true);
  17. if ("onselectstart" in root) {
  18. selection.on("selectstart.drag", noevent, true);
  19. } else {
  20. root.__noselect = root.style.MozUserSelect;
  21. root.style.MozUserSelect = "none";
  22. }
  23. }
  24. function yesdrag(view, noclick) {
  25. var root = view.document.documentElement,
  26. selection = d3Selection.select(view).on("dragstart.drag", null);
  27. if (noclick) {
  28. selection.on("click.drag", noevent, true);
  29. setTimeout(function() { selection.on("click.drag", null); }, 0);
  30. }
  31. if ("onselectstart" in root) {
  32. selection.on("selectstart.drag", null);
  33. } else {
  34. root.style.MozUserSelect = root.__noselect;
  35. delete root.__noselect;
  36. }
  37. }
  38. function constant(x) {
  39. return function() {
  40. return x;
  41. };
  42. }
  43. function DragEvent(target, type, subject, id, active, x, y, dx, dy, dispatch) {
  44. this.target = target;
  45. this.type = type;
  46. this.subject = subject;
  47. this.identifier = id;
  48. this.active = active;
  49. this.x = x;
  50. this.y = y;
  51. this.dx = dx;
  52. this.dy = dy;
  53. this._ = dispatch;
  54. }
  55. DragEvent.prototype.on = function() {
  56. var value = this._.on.apply(this._, arguments);
  57. return value === this._ ? this : value;
  58. };
  59. // Ignore right-click, since that should open the context menu.
  60. function defaultFilter() {
  61. return !d3Selection.event.ctrlKey && !d3Selection.event.button;
  62. }
  63. function defaultContainer() {
  64. return this.parentNode;
  65. }
  66. function defaultSubject(d) {
  67. return d == null ? {x: d3Selection.event.x, y: d3Selection.event.y} : d;
  68. }
  69. function defaultTouchable() {
  70. return navigator.maxTouchPoints || ("ontouchstart" in this);
  71. }
  72. function drag() {
  73. var filter = defaultFilter,
  74. container = defaultContainer,
  75. subject = defaultSubject,
  76. touchable = defaultTouchable,
  77. gestures = {},
  78. listeners = d3Dispatch.dispatch("start", "drag", "end"),
  79. active = 0,
  80. mousedownx,
  81. mousedowny,
  82. mousemoving,
  83. touchending,
  84. clickDistance2 = 0;
  85. function drag(selection) {
  86. selection
  87. .on("mousedown.drag", mousedowned)
  88. .filter(touchable)
  89. .on("touchstart.drag", touchstarted)
  90. .on("touchmove.drag", touchmoved)
  91. .on("touchend.drag touchcancel.drag", touchended)
  92. .style("touch-action", "none")
  93. .style("-webkit-tap-highlight-color", "rgba(0,0,0,0)");
  94. }
  95. function mousedowned() {
  96. if (touchending || !filter.apply(this, arguments)) return;
  97. var gesture = beforestart("mouse", container.apply(this, arguments), d3Selection.mouse, this, arguments);
  98. if (!gesture) return;
  99. d3Selection.select(d3Selection.event.view).on("mousemove.drag", mousemoved, true).on("mouseup.drag", mouseupped, true);
  100. nodrag(d3Selection.event.view);
  101. nopropagation();
  102. mousemoving = false;
  103. mousedownx = d3Selection.event.clientX;
  104. mousedowny = d3Selection.event.clientY;
  105. gesture("start");
  106. }
  107. function mousemoved() {
  108. noevent();
  109. if (!mousemoving) {
  110. var dx = d3Selection.event.clientX - mousedownx, dy = d3Selection.event.clientY - mousedowny;
  111. mousemoving = dx * dx + dy * dy > clickDistance2;
  112. }
  113. gestures.mouse("drag");
  114. }
  115. function mouseupped() {
  116. d3Selection.select(d3Selection.event.view).on("mousemove.drag mouseup.drag", null);
  117. yesdrag(d3Selection.event.view, mousemoving);
  118. noevent();
  119. gestures.mouse("end");
  120. }
  121. function touchstarted() {
  122. if (!filter.apply(this, arguments)) return;
  123. var touches = d3Selection.event.changedTouches,
  124. c = container.apply(this, arguments),
  125. n = touches.length, i, gesture;
  126. for (i = 0; i < n; ++i) {
  127. if (gesture = beforestart(touches[i].identifier, c, d3Selection.touch, this, arguments)) {
  128. nopropagation();
  129. gesture("start");
  130. }
  131. }
  132. }
  133. function touchmoved() {
  134. var touches = d3Selection.event.changedTouches,
  135. n = touches.length, i, gesture;
  136. for (i = 0; i < n; ++i) {
  137. if (gesture = gestures[touches[i].identifier]) {
  138. noevent();
  139. gesture("drag");
  140. }
  141. }
  142. }
  143. function touchended() {
  144. var touches = d3Selection.event.changedTouches,
  145. n = touches.length, i, gesture;
  146. if (touchending) clearTimeout(touchending);
  147. touchending = setTimeout(function() { touchending = null; }, 500); // Ghost clicks are delayed!
  148. for (i = 0; i < n; ++i) {
  149. if (gesture = gestures[touches[i].identifier]) {
  150. nopropagation();
  151. gesture("end");
  152. }
  153. }
  154. }
  155. function beforestart(id, container, point, that, args) {
  156. var p = point(container, id), s, dx, dy,
  157. sublisteners = listeners.copy();
  158. if (!d3Selection.customEvent(new DragEvent(drag, "beforestart", s, id, active, p[0], p[1], 0, 0, sublisteners), function() {
  159. if ((d3Selection.event.subject = s = subject.apply(that, args)) == null) return false;
  160. dx = s.x - p[0] || 0;
  161. dy = s.y - p[1] || 0;
  162. return true;
  163. })) return;
  164. return function gesture(type) {
  165. var p0 = p, n;
  166. switch (type) {
  167. case "start": gestures[id] = gesture, n = active++; break;
  168. case "end": delete gestures[id], --active; // nobreak
  169. case "drag": p = point(container, id), n = active; break;
  170. }
  171. d3Selection.customEvent(new DragEvent(drag, type, s, id, n, p[0] + dx, p[1] + dy, p[0] - p0[0], p[1] - p0[1], sublisteners), sublisteners.apply, sublisteners, [type, that, args]);
  172. };
  173. }
  174. drag.filter = function(_) {
  175. return arguments.length ? (filter = typeof _ === "function" ? _ : constant(!!_), drag) : filter;
  176. };
  177. drag.container = function(_) {
  178. return arguments.length ? (container = typeof _ === "function" ? _ : constant(_), drag) : container;
  179. };
  180. drag.subject = function(_) {
  181. return arguments.length ? (subject = typeof _ === "function" ? _ : constant(_), drag) : subject;
  182. };
  183. drag.touchable = function(_) {
  184. return arguments.length ? (touchable = typeof _ === "function" ? _ : constant(!!_), drag) : touchable;
  185. };
  186. drag.on = function() {
  187. var value = listeners.on.apply(listeners, arguments);
  188. return value === listeners ? drag : value;
  189. };
  190. drag.clickDistance = function(_) {
  191. return arguments.length ? (clickDistance2 = (_ = +_) * _, drag) : Math.sqrt(clickDistance2);
  192. };
  193. return drag;
  194. }
  195. exports.drag = drag;
  196. exports.dragDisable = nodrag;
  197. exports.dragEnable = yesdrag;
  198. Object.defineProperty(exports, '__esModule', { value: true });
  199. }));