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