feat(snap): snap initial nodes to grid

This commit is contained in:
moklick
2019-10-21 21:27:00 +02:00
parent 0fccc63601
commit 99dcc775b4
7 changed files with 89 additions and 36 deletions
+23 -11
View File
@@ -5890,17 +5890,23 @@ var addEdge = function (edgeParams, elements) {
? edgeParams.id ? edgeParams.id
: getEdgeId(edgeParams) })); : getEdgeId(edgeParams) }));
}; };
var pointToRendererPoint = function (_a, transform) { var pointToRendererPoint = function (_a, transform, snapToGrid, snapGrid) {
var x = _a.x, y = _a.y; var x = _a.x, y = _a.y;
var rendererX = (x - transform[0]) * (1 / transform[2]); var position = {
var rendererY = (y - transform[1]) * (1 / transform[2]); x: (x - transform[0]) * (1 / transform[2]),
return { y: (y - transform[1]) * (1 / transform[2]),
x: rendererX,
y: rendererY,
}; };
if (snapToGrid) {
var transformedGridSizeX = snapGrid[0] * transform[2];
var transformedGridSizeY = snapGrid[1] * transform[2];
position = {
x: transformedGridSizeX * Math.round(position.x / transformedGridSizeX),
y: transformedGridSizeY * Math.round(position.y / transformedGridSizeY),
};
}
return position;
}; };
var parseElement = function (element, transform) { var parseElement = function (element, transform, snapToGrid, snapGrid) {
if (transform === void 0) { transform = [0, 0, 1]; }
if (!element.id) { if (!element.id) {
throw new Error('All elements (nodes and edges) need to have an id.'); throw new Error('All elements (nodes and edges) need to have an id.');
} }
@@ -5909,7 +5915,7 @@ var parseElement = function (element, transform) {
} }
var nodeElement = element; var nodeElement = element;
return __assign(__assign({}, nodeElement), { id: nodeElement.id.toString(), type: nodeElement.type || 'default', __rg: { return __assign(__assign({}, nodeElement), { id: nodeElement.id.toString(), type: nodeElement.type || 'default', __rg: {
position: pointToRendererPoint(nodeElement.position, transform), position: pointToRendererPoint(nodeElement.position, transform, snapToGrid, snapGrid),
width: null, width: null,
height: null, height: null,
handleBounds: {}, handleBounds: {},
@@ -8242,12 +8248,18 @@ var useElementUpdater = function (elements) {
nodes: s.nodes, nodes: s.nodes,
edges: s.edges, edges: s.edges,
transform: s.transform, transform: s.transform,
snapToGrid: s.snapToGrid,
snapGrid: s.snapGrid,
}); }); }); });
var setNodes = useStoreActions$1(function (a) { return a.setNodes; }); var setNodes = useStoreActions$1(function (a) { return a.setNodes; });
var setEdges = useStoreActions$1(function (a) { return a.setEdges; }); var setEdges = useStoreActions$1(function (a) { return a.setEdges; });
useEffect(function () { useEffect(function () {
var nodes = elements.filter(isNode); var nodes = elements.filter(isNode);
var edges = elements.filter(isEdge).map(function (e) { return parseElement(e); }); var edges = elements
.filter(isEdge)
.map(function (e) {
return parseElement(e, state.transform, state.snapToGrid, state.snapGrid);
});
var nextNodes = nodes.map(function (propNode) { var nextNodes = nodes.map(function (propNode) {
var existingNode = state.nodes.find(function (n) { return n.id === propNode.id; }); var existingNode = state.nodes.find(function (n) { return n.id === propNode.id; });
if (existingNode) { if (existingNode) {
@@ -8255,7 +8267,7 @@ var useElementUpdater = function (elements) {
? __assign(__assign({}, existingNode.data), propNode.data) : existingNode.data; ? __assign(__assign({}, existingNode.data), propNode.data) : existingNode.data;
return __assign(__assign({}, existingNode), { data: data }); return __assign(__assign({}, existingNode), { data: data });
} }
return parseElement(propNode, state.transform); return parseElement(propNode, state.transform, state.snapToGrid, state.snapGrid);
}); });
var nodesChanged = !fastDeepEqual(state.nodes, nextNodes); var nodesChanged = !fastDeepEqual(state.nodes, nextNodes);
var edgesChanged = !fastDeepEqual(state.edges, edges); var edgesChanged = !fastDeepEqual(state.edges, edges);
+1 -1
View File
File diff suppressed because one or more lines are too long
+23 -11
View File
@@ -5897,17 +5897,23 @@ var addEdge = function (edgeParams, elements) {
? edgeParams.id ? edgeParams.id
: getEdgeId(edgeParams) })); : getEdgeId(edgeParams) }));
}; };
var pointToRendererPoint = function (_a, transform) { var pointToRendererPoint = function (_a, transform, snapToGrid, snapGrid) {
var x = _a.x, y = _a.y; var x = _a.x, y = _a.y;
var rendererX = (x - transform[0]) * (1 / transform[2]); var position = {
var rendererY = (y - transform[1]) * (1 / transform[2]); x: (x - transform[0]) * (1 / transform[2]),
return { y: (y - transform[1]) * (1 / transform[2]),
x: rendererX,
y: rendererY,
}; };
if (snapToGrid) {
var transformedGridSizeX = snapGrid[0] * transform[2];
var transformedGridSizeY = snapGrid[1] * transform[2];
position = {
x: transformedGridSizeX * Math.round(position.x / transformedGridSizeX),
y: transformedGridSizeY * Math.round(position.y / transformedGridSizeY),
};
}
return position;
}; };
var parseElement = function (element, transform) { var parseElement = function (element, transform, snapToGrid, snapGrid) {
if (transform === void 0) { transform = [0, 0, 1]; }
if (!element.id) { if (!element.id) {
throw new Error('All elements (nodes and edges) need to have an id.'); throw new Error('All elements (nodes and edges) need to have an id.');
} }
@@ -5916,7 +5922,7 @@ var parseElement = function (element, transform) {
} }
var nodeElement = element; var nodeElement = element;
return __assign(__assign({}, nodeElement), { id: nodeElement.id.toString(), type: nodeElement.type || 'default', __rg: { return __assign(__assign({}, nodeElement), { id: nodeElement.id.toString(), type: nodeElement.type || 'default', __rg: {
position: pointToRendererPoint(nodeElement.position, transform), position: pointToRendererPoint(nodeElement.position, transform, snapToGrid, snapGrid),
width: null, width: null,
height: null, height: null,
handleBounds: {}, handleBounds: {},
@@ -8249,12 +8255,18 @@ var useElementUpdater = function (elements) {
nodes: s.nodes, nodes: s.nodes,
edges: s.edges, edges: s.edges,
transform: s.transform, transform: s.transform,
snapToGrid: s.snapToGrid,
snapGrid: s.snapGrid,
}); }); }); });
var setNodes = useStoreActions$1(function (a) { return a.setNodes; }); var setNodes = useStoreActions$1(function (a) { return a.setNodes; });
var setEdges = useStoreActions$1(function (a) { return a.setEdges; }); var setEdges = useStoreActions$1(function (a) { return a.setEdges; });
React.useEffect(function () { React.useEffect(function () {
var nodes = elements.filter(isNode); var nodes = elements.filter(isNode);
var edges = elements.filter(isEdge).map(function (e) { return parseElement(e); }); var edges = elements
.filter(isEdge)
.map(function (e) {
return parseElement(e, state.transform, state.snapToGrid, state.snapGrid);
});
var nextNodes = nodes.map(function (propNode) { var nextNodes = nodes.map(function (propNode) {
var existingNode = state.nodes.find(function (n) { return n.id === propNode.id; }); var existingNode = state.nodes.find(function (n) { return n.id === propNode.id; });
if (existingNode) { if (existingNode) {
@@ -8262,7 +8274,7 @@ var useElementUpdater = function (elements) {
? __assign(__assign({}, existingNode.data), propNode.data) : existingNode.data; ? __assign(__assign({}, existingNode.data), propNode.data) : existingNode.data;
return __assign(__assign({}, existingNode), { data: data }); return __assign(__assign({}, existingNode), { data: data });
} }
return parseElement(propNode, state.transform); return parseElement(propNode, state.transform, state.snapToGrid, state.snapGrid);
}); });
var nodesChanged = !fastDeepEqual(state.nodes, nextNodes); var nodesChanged = !fastDeepEqual(state.nodes, nextNodes);
var edgesChanged = !fastDeepEqual(state.edges, edges); var edgesChanged = !fastDeepEqual(state.edges, edges);
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -4,7 +4,7 @@ export declare const isNode: (element: Node | Edge) => boolean;
export declare const getOutgoers: (node: Node, elements: (Node | Edge)[]) => (Node | Edge)[]; export declare const getOutgoers: (node: Node, elements: (Node | Edge)[]) => (Node | Edge)[];
export declare const removeElements: (elementsToRemove: (Node | Edge)[], elements: (Node | Edge)[]) => (Node | Edge)[]; export declare const removeElements: (elementsToRemove: (Node | Edge)[], elements: (Node | Edge)[]) => (Node | Edge)[];
export declare const addEdge: (edgeParams: Edge, elements: (Node | Edge)[]) => (Node | Edge)[]; export declare const addEdge: (edgeParams: Edge, elements: (Node | Edge)[]) => (Node | Edge)[];
export declare const parseElement: (element: Node | Edge, transform?: [number, number, number]) => Node | Edge; export declare const parseElement: (element: Node | Edge, transform: [number, number, number], snapToGrid: boolean, snapGrid: [number, number]) => Node | Edge;
export declare const getBoundingBox: (nodes: Node[]) => Rect; export declare const getBoundingBox: (nodes: Node[]) => Rect;
export declare const graphPosToZoomedPos: (pos: XYPosition, transform: [number, number, number]) => XYPosition; export declare const graphPosToZoomedPos: (pos: XYPosition, transform: [number, number, number]) => XYPosition;
export declare const getNodesInside: (nodes: Node[], bbox: Rect, transform?: [number, number, number], partially?: boolean) => Node[]; export declare const getNodesInside: (nodes: Node[], bbox: Rect, transform?: [number, number, number], partially?: boolean) => Node[];
+13 -2
View File
@@ -10,6 +10,8 @@ const useElementUpdater = (elements: Elements): void => {
nodes: s.nodes, nodes: s.nodes,
edges: s.edges, edges: s.edges,
transform: s.transform, transform: s.transform,
snapToGrid: s.snapToGrid,
snapGrid: s.snapGrid,
})); }));
const setNodes = useStoreActions(a => a.setNodes); const setNodes = useStoreActions(a => a.setNodes);
@@ -17,7 +19,11 @@ const useElementUpdater = (elements: Elements): void => {
useEffect(() => { useEffect(() => {
const nodes = elements.filter(isNode) as Node[]; const nodes = elements.filter(isNode) as Node[];
const edges = elements.filter(isEdge).map(e => parseElement(e)) as Edge[]; const edges = elements
.filter(isEdge)
.map(e =>
parseElement(e, state.transform, state.snapToGrid, state.snapGrid)
) as Edge[];
const nextNodes = nodes.map(propNode => { const nextNodes = nodes.map(propNode => {
const existingNode = state.nodes.find(n => n.id === propNode.id); const existingNode = state.nodes.find(n => n.id === propNode.id);
@@ -33,7 +39,12 @@ const useElementUpdater = (elements: Elements): void => {
}; };
} }
return parseElement(propNode, state.transform); return parseElement(
propNode,
state.transform,
state.snapToGrid,
state.snapGrid
);
}) as Node[]; }) as Node[];
const nodesChanged: boolean = !isEqual(state.nodes, nextNodes); const nodesChanged: boolean = !isEqual(state.nodes, nextNodes);
+27 -9
View File
@@ -65,20 +65,33 @@ export const addEdge = (edgeParams: Edge, elements: Elements): Elements => {
const pointToRendererPoint = ( const pointToRendererPoint = (
{ x, y }: XYPosition, { x, y }: XYPosition,
transform: Transform transform: Transform,
snapToGrid: boolean,
snapGrid: [number, number]
): XYPosition => { ): XYPosition => {
const rendererX = (x - transform[0]) * (1 / transform[2]); let position: XYPosition = {
const rendererY = (y - transform[1]) * (1 / transform[2]); x: (x - transform[0]) * (1 / transform[2]),
y: (y - transform[1]) * (1 / transform[2]),
return {
x: rendererX,
y: rendererY,
}; };
if (snapToGrid) {
const transformedGridSizeX = snapGrid[0] * transform[2];
const transformedGridSizeY = snapGrid[1] * transform[2];
position = {
x: transformedGridSizeX * Math.round(position.x / transformedGridSizeX),
y: transformedGridSizeY * Math.round(position.y / transformedGridSizeY),
};
}
return position;
}; };
export const parseElement = ( export const parseElement = (
element: Node | Edge, element: Node | Edge,
transform: Transform = [0, 0, 1] transform: Transform,
snapToGrid: boolean,
snapGrid: [number, number]
): Node | Edge => { ): Node | Edge => {
if (!element.id) { if (!element.id) {
throw new Error('All elements (nodes and edges) need to have an id.'); throw new Error('All elements (nodes and edges) need to have an id.');
@@ -99,7 +112,12 @@ export const parseElement = (
id: nodeElement.id.toString(), id: nodeElement.id.toString(),
type: nodeElement.type || 'default', type: nodeElement.type || 'default',
__rg: { __rg: {
position: pointToRendererPoint(nodeElement.position, transform), position: pointToRendererPoint(
nodeElement.position,
transform,
snapToGrid,
snapGrid
),
width: null, width: null,
height: null, height: null,
handleBounds: {}, handleBounds: {},