feat(nodes): add extent option

This commit is contained in:
moklick
2021-11-04 21:43:47 +01:00
parent fefcc441af
commit fdf2571402
7 changed files with 36 additions and 25 deletions
+1
View File
@@ -36,6 +36,7 @@ const initialNodes: Node[] = [
position: { x: 15, y: 15 },
className: 'light',
parentNode: '4',
extent: 'parent',
},
{
id: '4b',
+2 -2
View File
@@ -10,7 +10,7 @@ import ReactFlow, {
Node,
Connection,
Edge,
NodeExtent,
CoordinateExtent,
Position,
} from 'react-flow-renderer';
import dagre from 'dagre';
@@ -22,7 +22,7 @@ import './layouting.css';
const dagreGraph = new dagre.graphlib.Graph();
dagreGraph.setDefaultEdgeLabel(() => ({}));
const nodeExtent: NodeExtent = [
const nodeExtent: CoordinateExtent = [
[0, 0],
[1000, 1000],
];
+3 -4
View File
@@ -10,12 +10,11 @@ import {
OnConnectStartFunc,
OnConnectStopFunc,
OnConnectEndFunc,
NodeExtent,
CoordinateExtent,
OnNodesChange,
OnEdgesChange,
ConnectionMode,
SnapGrid,
TranslateExtent,
} from '../../types';
interface StoreUpdaterProps {
@@ -29,14 +28,14 @@ interface StoreUpdaterProps {
nodesConnectable?: boolean;
minZoom?: number;
maxZoom?: number;
nodeExtent?: NodeExtent;
nodeExtent?: CoordinateExtent;
onNodesChange?: OnNodesChange;
onEdgesChange?: OnEdgesChange;
elementsSelectable?: boolean;
connectionMode?: ConnectionMode;
snapToGrid?: boolean;
snapGrid?: SnapGrid;
translateExtent?: TranslateExtent;
translateExtent?: CoordinateExtent;
}
const selector = (s: ReactFlowState) => ({
+3 -4
View File
@@ -33,11 +33,10 @@ import {
OnConnectStopFunc,
OnConnectEndFunc,
OnConnectFunc,
TranslateExtent,
CoordinateExtent,
KeyCode,
PanOnScrollMode,
OnEdgeUpdateFunc,
NodeExtent,
NodeChange,
EdgeChange,
} from '../../types';
@@ -111,9 +110,9 @@ export interface ReactFlowProps extends Omit<HTMLAttributes<HTMLDivElement>, 'on
maxZoom?: number;
defaultZoom?: number;
defaultPosition?: [number, number];
translateExtent?: TranslateExtent;
translateExtent?: CoordinateExtent;
preventScrolling?: boolean;
nodeExtent?: NodeExtent;
nodeExtent?: CoordinateExtent;
defaultMarkerColor?: string;
zoomOnScroll?: boolean;
zoomOnPinch?: boolean;
+19 -7
View File
@@ -11,8 +11,7 @@ import {
NodeDiffUpdate,
XYPosition,
InitD3ZoomPayload,
TranslateExtent,
NodeExtent,
CoordinateExtent,
Transform,
Dimensions,
OnConnectFunc,
@@ -143,7 +142,7 @@ const createStore = () =>
onNodesChange?.(nodesToChange);
},
updateNodePosition: ({ id, diff, isDragging }: NodeDiffUpdate) => {
const { onNodesChange, nodes, nodeExtent } = get();
const { onNodesChange, nodes, nodeExtent, nodeInternals } = get();
if (onNodesChange) {
const matchingNodes = nodes.filter((n) => !!(n.isSelected || n.id === id));
@@ -158,13 +157,26 @@ const createStore = () =>
};
if (diff) {
change.position = nodeExtent
let currentExtent = nodeExtent || node.extent;
if (node.extent === 'parent' && node.parentNode && node.width && node.height) {
const parent = nodeInternals.get(node.parentNode);
currentExtent =
parent?.width && parent?.height
? [
[0, 0],
[parent.width - node.width, parent.height - node.height],
]
: currentExtent;
}
change.position = currentExtent
? clampPosition(
{
x: node.position.x + diff.x,
y: node.position.y + diff.y,
},
nodeExtent
currentExtent
)
: { x: node.position.x + diff.x, y: node.position.y + diff.y };
}
@@ -300,7 +312,7 @@ const createStore = () =>
set({ maxZoom });
},
setTranslateExtent: (translateExtent: TranslateExtent) => {
setTranslateExtent: (translateExtent: CoordinateExtent) => {
const { d3Zoom } = get();
d3Zoom?.translateExtent(translateExtent);
@@ -320,7 +332,7 @@ const createStore = () =>
onEdgesChange?.(edgesToUnselect as EdgeChange[]);
}
},
setNodeExtent: (nodeExtent: NodeExtent) =>
setNodeExtent: (nodeExtent: CoordinateExtent) =>
set({
nodeExtent,
nodes: get().nodes.map((node) => {
+6 -6
View File
@@ -84,6 +84,7 @@ export interface Node<T = any> {
height?: number | null;
parentNode?: ElementId;
zIndex?: number;
extent?: 'parent' | CoordinateExtent;
}
export enum ArrowHeadType {
@@ -416,8 +417,7 @@ export type FlowTransform = {
zoom: number;
};
export type TranslateExtent = [[number, number], [number, number]];
export type NodeExtent = TranslateExtent;
export type CoordinateExtent = [[number, number], [number, number]];
export type KeyCode = string | Array<string>;
@@ -486,8 +486,8 @@ export interface ReactFlowState {
d3ZoomHandler: ((this: Element, event: any, d: unknown) => void) | undefined;
minZoom: number;
maxZoom: number;
translateExtent: TranslateExtent;
nodeExtent: NodeExtent;
translateExtent: CoordinateExtent;
nodeExtent: CoordinateExtent;
nodesSelectionActive: boolean;
selectionActive: boolean;
@@ -527,8 +527,8 @@ export interface ReactFlowState {
initD3Zoom: (payload: InitD3ZoomPayload) => void;
setMinZoom: (minZoom: number) => void;
setMaxZoom: (maxZoom: number) => void;
setTranslateExtent: (translateExtent: TranslateExtent) => void;
setNodeExtent: (nodeExtent: NodeExtent) => void;
setTranslateExtent: (translateExtent: CoordinateExtent) => void;
setNodeExtent: (nodeExtent: CoordinateExtent) => void;
setOnConnect: (onConnectFunction: OnConnectFunc) => void;
setOnConnectStart: (onConnectFunction: OnConnectStartFunc) => void;
setOnConnectStop: (onConnectFunction: OnConnectStopFunc) => void;
+2 -2
View File
@@ -1,4 +1,4 @@
import { Dimensions, XYPosition, NodeExtent, Box, Rect } from '../types';
import { Dimensions, XYPosition, CoordinateExtent, Box, Rect } from '../types';
export const getDimensions = (node: HTMLDivElement): Dimensions => ({
width: node.offsetWidth,
@@ -7,7 +7,7 @@ export const getDimensions = (node: HTMLDivElement): Dimensions => ({
export const clamp = (val: number, min: number = 0, max: number = 1): number => Math.min(Math.max(val, min), max);
export const clampPosition = (position: XYPosition, extent: NodeExtent) => ({
export const clampPosition = (position: XYPosition, extent: CoordinateExtent) => ({
x: clamp(position.x, extent[0][0], extent[1][0]),
y: clamp(position.y, extent[0][1], extent[1][1]),
});