refactor(onlyRenderVisible): change from nodes to elements #677
This commit is contained in:
@@ -4,12 +4,11 @@ import { useStoreState } from '../../store/hooks';
|
|||||||
import ConnectionLine from '../../components/ConnectionLine/index';
|
import ConnectionLine from '../../components/ConnectionLine/index';
|
||||||
import { isEdge } from '../../utils/graph';
|
import { isEdge } from '../../utils/graph';
|
||||||
import MarkerDefinitions from './MarkerDefinitions';
|
import MarkerDefinitions from './MarkerDefinitions';
|
||||||
|
import { getHandlePosition, getHandle } from './utils';
|
||||||
import {
|
import {
|
||||||
XYPosition,
|
|
||||||
Position,
|
Position,
|
||||||
Edge,
|
Edge,
|
||||||
Node,
|
Node,
|
||||||
ElementId,
|
|
||||||
HandleElement,
|
HandleElement,
|
||||||
Elements,
|
Elements,
|
||||||
ConnectionLineType,
|
ConnectionLineType,
|
||||||
@@ -33,78 +32,6 @@ interface EdgePositions {
|
|||||||
targetY: number;
|
targetY: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getHandlePosition(position: Position, node: Node, handle: any | null = null): XYPosition {
|
|
||||||
if (!handle) {
|
|
||||||
switch (position) {
|
|
||||||
case Position.Top:
|
|
||||||
return {
|
|
||||||
x: node.__rf.width / 2,
|
|
||||||
y: 0,
|
|
||||||
};
|
|
||||||
case Position.Right:
|
|
||||||
return {
|
|
||||||
x: node.__rf.width,
|
|
||||||
y: node.__rf.height / 2,
|
|
||||||
};
|
|
||||||
case Position.Bottom:
|
|
||||||
return {
|
|
||||||
x: node.__rf.width / 2,
|
|
||||||
y: node.__rf.height,
|
|
||||||
};
|
|
||||||
case Position.Left:
|
|
||||||
return {
|
|
||||||
x: 0,
|
|
||||||
y: node.__rf.height / 2,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (position) {
|
|
||||||
case Position.Top:
|
|
||||||
return {
|
|
||||||
x: handle.x + handle.width / 2,
|
|
||||||
y: handle.y,
|
|
||||||
};
|
|
||||||
case Position.Right:
|
|
||||||
return {
|
|
||||||
x: handle.x + handle.width,
|
|
||||||
y: handle.y + handle.height / 2,
|
|
||||||
};
|
|
||||||
case Position.Bottom:
|
|
||||||
return {
|
|
||||||
x: handle.x + handle.width / 2,
|
|
||||||
y: handle.y + handle.height,
|
|
||||||
};
|
|
||||||
case Position.Left:
|
|
||||||
return {
|
|
||||||
x: handle.x,
|
|
||||||
y: handle.y + handle.height / 2,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function getHandle(bounds: HandleElement[], handleId: ElementId | null): HandleElement | null | undefined {
|
|
||||||
let handle = null;
|
|
||||||
|
|
||||||
if (!bounds) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// there is no handleId when there are no multiple handles/ handles with ids
|
|
||||||
// so we just pick the first one
|
|
||||||
if (bounds.length === 1 || !handleId) {
|
|
||||||
handle = bounds[0];
|
|
||||||
} else if (handleId) {
|
|
||||||
handle = bounds.find((d) => d.id === handleId);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof handle === 'undefined') {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getEdgePositions(
|
function getEdgePositions(
|
||||||
sourceNode: Node,
|
sourceNode: Node,
|
||||||
sourceHandle: HandleElement | unknown,
|
sourceHandle: HandleElement | unknown,
|
||||||
@@ -132,25 +59,29 @@ function getEdgePositions(
|
|||||||
function renderEdge(
|
function renderEdge(
|
||||||
edge: Edge,
|
edge: Edge,
|
||||||
props: EdgeRendererProps,
|
props: EdgeRendererProps,
|
||||||
|
visibleNodes: Node[],
|
||||||
nodes: Node[],
|
nodes: Node[],
|
||||||
selectedElements: Elements | null,
|
selectedElements: Elements | null,
|
||||||
elementsSelectable: boolean
|
elementsSelectable: boolean
|
||||||
) {
|
) {
|
||||||
const sourceId = edge.source;
|
|
||||||
const sourceHandleId = edge.sourceHandle || null;
|
const sourceHandleId = edge.sourceHandle || null;
|
||||||
const targetId = edge.target;
|
|
||||||
const targetHandleId = edge.targetHandle || null;
|
const targetHandleId = edge.targetHandle || null;
|
||||||
|
|
||||||
const sourceNode = nodes.find((n) => n.id === sourceId);
|
const sourceNode = nodes.find((n) => n.id === edge.source);
|
||||||
const targetNode = nodes.find((n) => n.id === targetId);
|
const targetNode = nodes.find((n) => n.id === edge.target);
|
||||||
|
const renderEdge = visibleNodes.some((n) => n.id === edge.source || n.id == edge.target);
|
||||||
|
|
||||||
|
if (!renderEdge) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
if (!sourceNode) {
|
if (!sourceNode) {
|
||||||
console.warn(`couldn't create edge for source id: ${sourceId}`);
|
console.warn(`couldn't create edge for source id: ${edge.source}`);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!targetNode) {
|
if (!targetNode) {
|
||||||
console.warn(`couldn't create edge for target id: ${targetId}`);
|
console.warn(`couldn't create edge for target id: ${edge.target}`);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -224,7 +155,6 @@ function renderEdge(
|
|||||||
const EdgeRenderer = (props: EdgeRendererProps) => {
|
const EdgeRenderer = (props: EdgeRendererProps) => {
|
||||||
const [tX, tY, tScale] = useStoreState((state) => state.transform);
|
const [tX, tY, tScale] = useStoreState((state) => state.transform);
|
||||||
const edges = useStoreState((state) => state.edges);
|
const edges = useStoreState((state) => state.edges);
|
||||||
const nodes = useStoreState((state) => state.nodes);
|
|
||||||
const connectionNodeId = useStoreState((state) => state.connectionNodeId);
|
const connectionNodeId = useStoreState((state) => state.connectionNodeId);
|
||||||
const connectionHandleId = useStoreState((state) => state.connectionHandleId);
|
const connectionHandleId = useStoreState((state) => state.connectionHandleId);
|
||||||
const connectionHandleType = useStoreState((state) => state.connectionHandleType);
|
const connectionHandleType = useStoreState((state) => state.connectionHandleType);
|
||||||
@@ -234,6 +164,8 @@ const EdgeRenderer = (props: EdgeRendererProps) => {
|
|||||||
const elementsSelectable = useStoreState((state) => state.elementsSelectable);
|
const elementsSelectable = useStoreState((state) => state.elementsSelectable);
|
||||||
const width = useStoreState((state) => state.width);
|
const width = useStoreState((state) => state.width);
|
||||||
const height = useStoreState((state) => state.height);
|
const height = useStoreState((state) => state.height);
|
||||||
|
const visibleNodes = useStoreState((state) => state.visibleNodes);
|
||||||
|
const nodes = useStoreState((state) => state.nodes);
|
||||||
|
|
||||||
const { connectionLineType, arrowHeadColor, connectionLineStyle, connectionLineComponent } = props;
|
const { connectionLineType, arrowHeadColor, connectionLineStyle, connectionLineComponent } = props;
|
||||||
|
|
||||||
@@ -248,10 +180,10 @@ const EdgeRenderer = (props: EdgeRendererProps) => {
|
|||||||
<svg width={width} height={height} className="react-flow__edges">
|
<svg width={width} height={height} className="react-flow__edges">
|
||||||
<MarkerDefinitions color={arrowHeadColor} />
|
<MarkerDefinitions color={arrowHeadColor} />
|
||||||
<g transform={transformStyle}>
|
<g transform={transformStyle}>
|
||||||
{edges.map((edge: Edge) => renderEdge(edge, props, nodes, selectedElements, elementsSelectable))}
|
{edges.map((edge: Edge) => renderEdge(edge, props, visibleNodes, nodes, selectedElements, elementsSelectable))}
|
||||||
{renderConnectionLine && (
|
{renderConnectionLine && (
|
||||||
<ConnectionLine
|
<ConnectionLine
|
||||||
nodes={nodes}
|
nodes={visibleNodes}
|
||||||
connectionNodeId={connectionNodeId!}
|
connectionNodeId={connectionNodeId!}
|
||||||
connectionHandleId={connectionHandleId}
|
connectionHandleId={connectionHandleId}
|
||||||
connectionHandleType={connectionHandleType!}
|
connectionHandleType={connectionHandleType!}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { ComponentType } from 'react';
|
|||||||
import { BezierEdge, StepEdge, SmoothStepEdge, StraightEdge } from '../../components/Edges';
|
import { BezierEdge, StepEdge, SmoothStepEdge, StraightEdge } from '../../components/Edges';
|
||||||
import wrapEdge from '../../components/Edges/wrapEdge';
|
import wrapEdge from '../../components/Edges/wrapEdge';
|
||||||
|
|
||||||
import { EdgeTypesType, EdgeProps } from '../../types';
|
import { EdgeTypesType, EdgeProps, Position, Node, XYPosition, ElementId, HandleElement } from '../../types';
|
||||||
|
|
||||||
export function createEdgeTypes(edgeTypes: EdgeTypesType): EdgeTypesType {
|
export function createEdgeTypes(edgeTypes: EdgeTypesType): EdgeTypesType {
|
||||||
const standardTypes: EdgeTypesType = {
|
const standardTypes: EdgeTypesType = {
|
||||||
@@ -27,3 +27,75 @@ export function createEdgeTypes(edgeTypes: EdgeTypesType): EdgeTypesType {
|
|||||||
...specialTypes,
|
...specialTypes,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getHandlePosition(position: Position, node: Node, handle: any | null = null): XYPosition {
|
||||||
|
if (!handle) {
|
||||||
|
switch (position) {
|
||||||
|
case Position.Top:
|
||||||
|
return {
|
||||||
|
x: node.__rf.width / 2,
|
||||||
|
y: 0,
|
||||||
|
};
|
||||||
|
case Position.Right:
|
||||||
|
return {
|
||||||
|
x: node.__rf.width,
|
||||||
|
y: node.__rf.height / 2,
|
||||||
|
};
|
||||||
|
case Position.Bottom:
|
||||||
|
return {
|
||||||
|
x: node.__rf.width / 2,
|
||||||
|
y: node.__rf.height,
|
||||||
|
};
|
||||||
|
case Position.Left:
|
||||||
|
return {
|
||||||
|
x: 0,
|
||||||
|
y: node.__rf.height / 2,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (position) {
|
||||||
|
case Position.Top:
|
||||||
|
return {
|
||||||
|
x: handle.x + handle.width / 2,
|
||||||
|
y: handle.y,
|
||||||
|
};
|
||||||
|
case Position.Right:
|
||||||
|
return {
|
||||||
|
x: handle.x + handle.width,
|
||||||
|
y: handle.y + handle.height / 2,
|
||||||
|
};
|
||||||
|
case Position.Bottom:
|
||||||
|
return {
|
||||||
|
x: handle.x + handle.width / 2,
|
||||||
|
y: handle.y + handle.height,
|
||||||
|
};
|
||||||
|
case Position.Left:
|
||||||
|
return {
|
||||||
|
x: handle.x,
|
||||||
|
y: handle.y + handle.height / 2,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getHandle(bounds: HandleElement[], handleId: ElementId | null): HandleElement | null | undefined {
|
||||||
|
let handle = null;
|
||||||
|
|
||||||
|
if (!bounds) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// there is no handleId when there are no multiple handles/ handles with ids
|
||||||
|
// so we just pick the first one
|
||||||
|
if (bounds.length === 1 || !handleId) {
|
||||||
|
handle = bounds[0];
|
||||||
|
} else if (handleId) {
|
||||||
|
handle = bounds.find((d) => d.id === handleId);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof handle === 'undefined') {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ interface FlowRendererProps
|
|||||||
| 'snapGrid'
|
| 'snapGrid'
|
||||||
| 'connectionLineType'
|
| 'connectionLineType'
|
||||||
| 'arrowHeadColor'
|
| 'arrowHeadColor'
|
||||||
| 'onlyRenderVisibleNodes'
|
| 'onlyRenderVisibleElements'
|
||||||
| 'selectNodesOnDrag'
|
| 'selectNodesOnDrag'
|
||||||
> {
|
> {
|
||||||
children: ReactNode;
|
children: ReactNode;
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ export interface GraphViewProps extends Omit<ReactFlowProps, 'onSelectionChange'
|
|||||||
connectionLineType: ConnectionLineType;
|
connectionLineType: ConnectionLineType;
|
||||||
snapToGrid: boolean;
|
snapToGrid: boolean;
|
||||||
snapGrid: [number, number];
|
snapGrid: [number, number];
|
||||||
onlyRenderVisibleNodes: boolean;
|
onlyRenderVisibleElements: boolean;
|
||||||
defaultZoom: number;
|
defaultZoom: number;
|
||||||
defaultPosition: [number, number];
|
defaultPosition: [number, number];
|
||||||
arrowHeadColor: string;
|
arrowHeadColor: string;
|
||||||
@@ -58,7 +58,7 @@ const GraphView = ({
|
|||||||
onConnectEnd,
|
onConnectEnd,
|
||||||
snapToGrid,
|
snapToGrid,
|
||||||
snapGrid,
|
snapGrid,
|
||||||
onlyRenderVisibleNodes,
|
onlyRenderVisibleElements,
|
||||||
nodesDraggable,
|
nodesDraggable,
|
||||||
nodesConnectable,
|
nodesConnectable,
|
||||||
elementsSelectable,
|
elementsSelectable,
|
||||||
@@ -93,6 +93,7 @@ const GraphView = ({
|
|||||||
const setMinZoom = useStoreActions((actions) => actions.setMinZoom);
|
const setMinZoom = useStoreActions((actions) => actions.setMinZoom);
|
||||||
const setMaxZoom = useStoreActions((actions) => actions.setMaxZoom);
|
const setMaxZoom = useStoreActions((actions) => actions.setMaxZoom);
|
||||||
const setTranslateExtent = useStoreActions((actions) => actions.setTranslateExtent);
|
const setTranslateExtent = useStoreActions((actions) => actions.setTranslateExtent);
|
||||||
|
const setOnlyRenderVisibleElements = useStoreActions((actions) => actions.setOnlyRenderVisibleElements);
|
||||||
const currentStore = useStore();
|
const currentStore = useStore();
|
||||||
const { zoomIn, zoomOut, zoomTo, transform, fitView, initialized } = useZoomPanHelper();
|
const { zoomIn, zoomOut, zoomTo, transform, fitView, initialized } = useZoomPanHelper();
|
||||||
|
|
||||||
@@ -187,6 +188,12 @@ const GraphView = ({
|
|||||||
}
|
}
|
||||||
}, [translateExtent]);
|
}, [translateExtent]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (typeof onlyRenderVisibleElements !== 'undefined') {
|
||||||
|
setOnlyRenderVisibleElements(onlyRenderVisibleElements);
|
||||||
|
}
|
||||||
|
}, [translateExtent]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FlowRenderer
|
<FlowRenderer
|
||||||
onPaneClick={onPaneClick}
|
onPaneClick={onPaneClick}
|
||||||
@@ -223,7 +230,6 @@ const GraphView = ({
|
|||||||
onNodeContextMenu={onNodeContextMenu}
|
onNodeContextMenu={onNodeContextMenu}
|
||||||
onNodeDragStop={onNodeDragStop}
|
onNodeDragStop={onNodeDragStop}
|
||||||
onNodeDragStart={onNodeDragStart}
|
onNodeDragStart={onNodeDragStart}
|
||||||
onlyRenderVisibleNodes={onlyRenderVisibleNodes}
|
|
||||||
selectNodesOnDrag={selectNodesOnDrag}
|
selectNodesOnDrag={selectNodesOnDrag}
|
||||||
snapToGrid={snapToGrid}
|
snapToGrid={snapToGrid}
|
||||||
snapGrid={snapGrid}
|
snapGrid={snapGrid}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import React, { memo, useMemo, ComponentType, MouseEvent } from 'react';
|
import React, { memo, useMemo, ComponentType, MouseEvent } from 'react';
|
||||||
|
|
||||||
import { useStoreState } from '../../store/hooks';
|
import { useStoreState } from '../../store/hooks';
|
||||||
import { getNodesInside } from '../../utils/graph';
|
|
||||||
import { Node, NodeTypesType, WrapNodeProps, Edge } from '../../types';
|
import { Node, NodeTypesType, WrapNodeProps, Edge } from '../../types';
|
||||||
|
|
||||||
interface NodeRendererProps {
|
interface NodeRendererProps {
|
||||||
@@ -14,19 +13,17 @@ interface NodeRendererProps {
|
|||||||
onNodeContextMenu?: (event: MouseEvent, node: Node) => void;
|
onNodeContextMenu?: (event: MouseEvent, node: Node) => void;
|
||||||
onNodeDragStart?: (event: MouseEvent, node: Node) => void;
|
onNodeDragStart?: (event: MouseEvent, node: Node) => void;
|
||||||
onNodeDragStop?: (event: MouseEvent, node: Node) => void;
|
onNodeDragStop?: (event: MouseEvent, node: Node) => void;
|
||||||
onlyRenderVisibleNodes: boolean;
|
|
||||||
snapToGrid: boolean;
|
snapToGrid: boolean;
|
||||||
snapGrid: [number, number];
|
snapGrid: [number, number];
|
||||||
}
|
}
|
||||||
|
|
||||||
const NodeRenderer = (props: NodeRendererProps) => {
|
const NodeRenderer = (props: NodeRendererProps) => {
|
||||||
const nodes = useStoreState((state) => state.nodes);
|
|
||||||
const transform = useStoreState((state) => state.transform);
|
const transform = useStoreState((state) => state.transform);
|
||||||
const selectedElements = useStoreState((state) => state.selectedElements);
|
const selectedElements = useStoreState((state) => state.selectedElements);
|
||||||
const viewportBox = useStoreState((state) => state.viewportBox);
|
|
||||||
const nodesDraggable = useStoreState((state) => state.nodesDraggable);
|
const nodesDraggable = useStoreState((state) => state.nodesDraggable);
|
||||||
const nodesConnectable = useStoreState((state) => state.nodesConnectable);
|
const nodesConnectable = useStoreState((state) => state.nodesConnectable);
|
||||||
const elementsSelectable = useStoreState((state) => state.elementsSelectable);
|
const elementsSelectable = useStoreState((state) => state.elementsSelectable);
|
||||||
|
const visibleNodes = useStoreState((state) => state.visibleNodes);
|
||||||
|
|
||||||
const transformStyle = useMemo(
|
const transformStyle = useMemo(
|
||||||
() => ({
|
() => ({
|
||||||
@@ -35,11 +32,9 @@ const NodeRenderer = (props: NodeRendererProps) => {
|
|||||||
[transform[0], transform[1], transform[2]]
|
[transform[0], transform[1], transform[2]]
|
||||||
);
|
);
|
||||||
|
|
||||||
const nodesToRender = props.onlyRenderVisibleNodes ? getNodesInside(nodes, viewportBox, transform, true) : nodes;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="react-flow__nodes" style={transformStyle}>
|
<div className="react-flow__nodes" style={transformStyle}>
|
||||||
{nodesToRender.map((node) => {
|
{visibleNodes.map((node) => {
|
||||||
const nodeType = node.type || 'default';
|
const nodeType = node.type || 'default';
|
||||||
const NodeComponent = (props.nodeTypes[nodeType] || props.nodeTypes.default) as ComponentType<WrapNodeProps>;
|
const NodeComponent = (props.nodeTypes[nodeType] || props.nodeTypes.default) as ComponentType<WrapNodeProps>;
|
||||||
|
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ export interface ReactFlowProps extends Omit<HTMLAttributes<HTMLDivElement>, 'on
|
|||||||
multiSelectionKeyCode?: KeyCode;
|
multiSelectionKeyCode?: KeyCode;
|
||||||
snapToGrid?: boolean;
|
snapToGrid?: boolean;
|
||||||
snapGrid?: [number, number];
|
snapGrid?: [number, number];
|
||||||
onlyRenderVisibleNodes?: boolean;
|
onlyRenderVisibleElements?: boolean;
|
||||||
nodesDraggable?: boolean;
|
nodesDraggable?: boolean;
|
||||||
nodesConnectable?: boolean;
|
nodesConnectable?: boolean;
|
||||||
elementsSelectable?: boolean;
|
elementsSelectable?: boolean;
|
||||||
@@ -142,7 +142,7 @@ const ReactFlow = ({
|
|||||||
multiSelectionKeyCode = 'Meta',
|
multiSelectionKeyCode = 'Meta',
|
||||||
snapToGrid = false,
|
snapToGrid = false,
|
||||||
snapGrid = [15, 15],
|
snapGrid = [15, 15],
|
||||||
onlyRenderVisibleNodes = true,
|
onlyRenderVisibleElements = true,
|
||||||
selectNodesOnDrag = true,
|
selectNodesOnDrag = true,
|
||||||
nodesDraggable,
|
nodesDraggable,
|
||||||
nodesConnectable,
|
nodesConnectable,
|
||||||
@@ -200,7 +200,7 @@ const ReactFlow = ({
|
|||||||
onConnectEnd={onConnectEnd}
|
onConnectEnd={onConnectEnd}
|
||||||
snapToGrid={snapToGrid}
|
snapToGrid={snapToGrid}
|
||||||
snapGrid={snapGrid}
|
snapGrid={snapGrid}
|
||||||
onlyRenderVisibleNodes={onlyRenderVisibleNodes}
|
onlyRenderVisibleElements={onlyRenderVisibleElements}
|
||||||
nodesDraggable={nodesDraggable}
|
nodesDraggable={nodesDraggable}
|
||||||
nodesConnectable={nodesConnectable}
|
nodesConnectable={nodesConnectable}
|
||||||
elementsSelectable={elementsSelectable}
|
elementsSelectable={elementsSelectable}
|
||||||
|
|||||||
@@ -45,10 +45,12 @@ export interface StoreModel {
|
|||||||
viewportBox: Computed<StoreModel, Rect>;
|
viewportBox: Computed<StoreModel, Rect>;
|
||||||
transform: Transform;
|
transform: Transform;
|
||||||
elements: Elements;
|
elements: Elements;
|
||||||
|
visibleNodes: Computed<StoreModel, Node[]>;
|
||||||
nodes: Computed<StoreModel, Node[]>;
|
nodes: Computed<StoreModel, Node[]>;
|
||||||
edges: Computed<StoreModel, Edge[]>;
|
edges: Computed<StoreModel, Edge[]>;
|
||||||
selectedElements: Elements | null;
|
selectedElements: Elements | null;
|
||||||
selectedNodesBbox: Rect;
|
selectedNodesBbox: Rect;
|
||||||
|
onlyRenderVisibleElements: boolean;
|
||||||
|
|
||||||
d3Zoom: ZoomBehavior<Element, unknown> | null;
|
d3Zoom: ZoomBehavior<Element, unknown> | null;
|
||||||
d3Selection: D3Selection<Element, unknown, null, undefined> | null;
|
d3Selection: D3Selection<Element, unknown, null, undefined> | null;
|
||||||
@@ -131,6 +133,8 @@ export interface StoreModel {
|
|||||||
unsetUserSelection: Action<StoreModel>;
|
unsetUserSelection: Action<StoreModel>;
|
||||||
|
|
||||||
setMultiSelectionActive: Action<StoreModel, boolean>;
|
setMultiSelectionActive: Action<StoreModel, boolean>;
|
||||||
|
|
||||||
|
setOnlyRenderVisibleElements: Action<StoreModel, boolean>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const storeModel: StoreModel = {
|
export const storeModel: StoreModel = {
|
||||||
@@ -140,9 +144,19 @@ export const storeModel: StoreModel = {
|
|||||||
transform: [0, 0, 1],
|
transform: [0, 0, 1],
|
||||||
elements: [],
|
elements: [],
|
||||||
nodes: computed((state) => state.elements.filter(isNode)),
|
nodes: computed((state) => state.elements.filter(isNode)),
|
||||||
|
visibleNodes: computed((state) => {
|
||||||
|
if (!state.onlyRenderVisibleElements) {
|
||||||
|
return state.nodes;
|
||||||
|
}
|
||||||
|
|
||||||
|
const viewportBox = { x: 0, y: 0, width: state.width, height: state.height };
|
||||||
|
|
||||||
|
return getNodesInside(state.nodes, viewportBox, state.transform, true);
|
||||||
|
}),
|
||||||
edges: computed((state) => state.elements.filter(isEdge)),
|
edges: computed((state) => state.elements.filter(isEdge)),
|
||||||
selectedElements: null,
|
selectedElements: null,
|
||||||
selectedNodesBbox: { x: 0, y: 0, width: 0, height: 0 },
|
selectedNodesBbox: { x: 0, y: 0, width: 0, height: 0 },
|
||||||
|
onlyRenderVisibleElements: true,
|
||||||
|
|
||||||
d3Zoom: null,
|
d3Zoom: null,
|
||||||
d3Selection: null,
|
d3Selection: null,
|
||||||
@@ -440,6 +454,10 @@ export const storeModel: StoreModel = {
|
|||||||
setMultiSelectionActive: action((state, isActive) => {
|
setMultiSelectionActive: action((state, isActive) => {
|
||||||
state.multiSelectionActive = isActive;
|
state.multiSelectionActive = isActive;
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
setOnlyRenderVisibleElements: action((state, onlyRenderVisible) => {
|
||||||
|
state.onlyRenderVisibleElements = onlyRenderVisible;
|
||||||
|
}),
|
||||||
};
|
};
|
||||||
|
|
||||||
const nodeEnv: string = (typeof __ENV__ !== 'undefined' && __ENV__) as string;
|
const nodeEnv: string = (typeof __ENV__ !== 'undefined' && __ENV__) as string;
|
||||||
|
|||||||
Reference in New Issue
Block a user