ensuring node can only be dragged within constraints

This commit is contained in:
Alex Windett 2017-03-20 12:40:03 +00:00 committed by Sérgio Ramos
parent 7a2a1f95a6
commit 5459220c77
2 changed files with 64 additions and 42 deletions

View File

@ -5,6 +5,7 @@ import Constants from './constants';
import GraphNode from './graph-node'; import GraphNode from './graph-node';
import GraphLink from './graph-link'; import GraphLink from './graph-link';
import React from 'react'; import React from 'react';
import { triggerMouseEvent } from '../../shared/functions';
const StyledSvg = styled.svg` const StyledSvg = styled.svg`
width: 100%; width: 100%;
@ -42,7 +43,7 @@ class TopologyGraph extends React.Component {
const n = Math.ceil( const n = Math.ceil(
Math.log( Math.log(
simulation.alphaMin()) / Math.log( simulation.alphaMin()) / Math.log(
1 - simulation.alphaDecay())); 1 - simulation.alphaDecay()));
for (var i = 0; i < n; ++i) { for (var i = 0; i < n; ++i) {
simulation.tick(); simulation.tick();
} }
@ -88,7 +89,7 @@ class TopologyGraph extends React.Component {
const n = Math.ceil( const n = Math.ceil(
Math.log( Math.log(
nextSimulation.alphaMin()) / Math.log( nextSimulation.alphaMin()) / Math.log(
1 - nextSimulation.alphaDecay())); 1 - nextSimulation.alphaDecay()));
for (var i = 0; i < n; ++i) { for (var i = 0; i < n; ++i) {
nextSimulation.tick(); nextSimulation.tick();
} }
@ -102,6 +103,28 @@ class TopologyGraph extends React.Component {
} }
} }
isWithinSVGBounds(target, x, y) {
const svgBounds = document
.getElementsByClassName('topology-svg')[0]
.getBoundingClientRect();
const nodeHeight = target.getBoundingClientRect().height;
const nodeWidth = target.getBoundingClientRect().width;
const constraints = {
top: svgBounds.top + (nodeHeight / 2),
left: svgBounds.left + (nodeWidth / 2),
bottom: svgBounds.bottom - (nodeHeight / 2),
right: svgBounds.right - (nodeWidth / 2)
};
if ( x > constraints.right || x < constraints.left ) return false;
if ( y < constraints.top || y > constraints.bottom ) return false;
return true;
}
render() { render() {
const { const {
@ -123,6 +146,7 @@ class TopologyGraph extends React.Component {
x: svgSize.width - Constants.nodeSize.width, x: svgSize.width - Constants.nodeSize.width,
y: 0 y: 0
} : simNode(service.uuid); } : simNode(service.uuid);
return ({ return ({
...service, ...service,
...sNode ...sNode
@ -143,40 +167,38 @@ class TopologyGraph extends React.Component {
// it's this node's position that we'll need to update // it's this node's position that we'll need to update
dragInfo.dragging = true; dragInfo.dragging = true;
dragInfo.nodeId = nodeId; dragInfo.nodeId = nodeId;
if(evt.changedTouches) {
dragInfo.position = { const x = evt.changedTouches ? evt.changedTouches[0].pageX : evt.clientX;
x: evt.changedTouches[0].pageX, const y = evt.changedTouches ? evt.changedTouches[0].pageY : evt.clientY;
y: evt.changedTouches[0].pageY
}; dragInfo.position = {
} x,
else { y
dragInfo.position = { };
x: evt.clientX,
y: evt.clientY
};
}
}; };
const onDragMove = (evt) => { const onDragMove = (evt) => {
if(dragInfo.dragging) { if ( dragInfo.dragging ) {
let offset = {}; const x = evt.changedTouches
if(evt.changedTouches) { ? evt.changedTouches[0].pageX
offset = { : evt.clientX;
x: evt.changedTouches[0].pageX - dragInfo.position.x, const y = evt.changedTouches
y: evt.changedTouches[0].pageY - dragInfo.position.y ? evt.changedTouches[0].pageY
}; : evt.clientY;
}
else { if ( !this.isWithinSVGBounds(evt.target, x, y) ) {
offset = { triggerMouseEvent(evt.target, 'mouseup');
x: evt.clientX - dragInfo.position.x,
y: evt.clientY - dragInfo.position.y
};
} }
const offset = {
x: x - dragInfo.position.x,
y: y - dragInfo.position.y
};
const dragNodes = nodes.map((simNode, index) => { const dragNodes = nodes.map((simNode, index) => {
if(simNode.id === dragInfo.nodeId) { if ( simNode.id === dragInfo.nodeId ) {
return ({ return ({
...simNode, ...simNode,
x: simNode.x + offset.x, x: simNode.x + offset.x,
@ -192,18 +214,10 @@ class TopologyGraph extends React.Component {
nodes: dragNodes nodes: dragNodes
}); });
if(evt.changedTouches) { dragInfo.position = {
dragInfo.position = { x,
x: evt.changedTouches[0].pageX, y
y: evt.changedTouches[0].pageY };
};
}
else {
dragInfo.position = {
x: evt.clientX,
y: evt.clientY
};
}
} }
}; };
@ -211,7 +225,7 @@ class TopologyGraph extends React.Component {
dragInfo = { dragInfo = {
dragging: false, dragging: false,
nodeId: null, nodeId: null,
position: null position: {}
}; };
}; };
@ -241,6 +255,7 @@ class TopologyGraph extends React.Component {
onMouseUp={onDragEnd} onMouseUp={onDragEnd}
onTouchEnd={onDragEnd} onTouchEnd={onDragEnd}
onTouchCancel={onDragEnd} onTouchCancel={onDragEnd}
className='topology-svg'
> >
<g> <g>
{renderedNodes} {renderedNodes}

View File

@ -51,6 +51,12 @@ const isAnd = (...names) =>
? css(...args) ? css(...args)
: css``; : css``;
const triggerMouseEvent = (trg, ev) => {
const clickEvent = document.createEvent('MouseEvents');
clickEvent.initEvent(ev, true, true);
trg.dispatchEvent(clickEvent);
};
export { export {
unitcalc, unitcalc,
remcalc, remcalc,
@ -58,5 +64,6 @@ export {
rndId, rndId,
is, is,
isNot, isNot,
isAnd isAnd,
triggerMouseEvent
}; };