refactor: remove passing props to reactive obj instead use props directly again (sort of breaks reactivity in some cases...)
fix: node selection not displaying correct rect after mouseup
This commit is contained in:
@@ -29,7 +29,6 @@ const nodeTypes = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const CustomNodeFlow = defineComponent({
|
const CustomNodeFlow = defineComponent({
|
||||||
components: { RevueFlow, MiniMap, Controls },
|
|
||||||
setup() {
|
setup() {
|
||||||
const elements = ref<Elements>([]);
|
const elements = ref<Elements>([]);
|
||||||
const bgColor = ref(initBgColor);
|
const bgColor = ref(initBgColor);
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
*/
|
*/
|
||||||
import { isNode } from '../../utils/graph';
|
import { isNode } from '../../utils/graph';
|
||||||
import { Node, RevueFlowStore } from '../../types';
|
import { Node, RevueFlowStore } from '../../types';
|
||||||
import { computed, inject, ref } from 'vue';
|
import { computed, defineComponent, inject, PropType, ref } from 'vue';
|
||||||
import Draggable, { DraggableEventHandler } from '@braks/revue-draggable';
|
import Draggable, { DraggableEventHandler } from '@braks/revue-draggable';
|
||||||
|
|
||||||
export interface NodesSelectionProps {
|
export interface NodesSelectionProps {
|
||||||
@@ -14,89 +14,104 @@ export interface NodesSelectionProps {
|
|||||||
onSelectionContextMenu?: (event: MouseEvent, nodes: Node[]) => void;
|
onSelectionContextMenu?: (event: MouseEvent, nodes: Node[]) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const NodesSelection = ({
|
const NodesSelection = defineComponent({
|
||||||
onSelectionDragStart,
|
props: {
|
||||||
onSelectionDrag,
|
onSelectionDragStart: {
|
||||||
onSelectionDragStop,
|
type: Function as unknown as PropType<NodesSelectionProps['onSelectionDragStart']>,
|
||||||
onSelectionContextMenu
|
required: false,
|
||||||
}: NodesSelectionProps) => {
|
default: undefined
|
||||||
const store = inject<RevueFlowStore>('store');
|
},
|
||||||
console.log('nodesSelection');
|
onSelectionDrag: {
|
||||||
|
type: Function as unknown as PropType<NodesSelectionProps['onSelectionDrag']>,
|
||||||
const nodeRef = ref<HTMLElement | undefined>();
|
required: false,
|
||||||
|
default: undefined
|
||||||
const grid = computed(() => (store?.snapToGrid ? store?.snapGrid : [1, 1])! as [number, number]);
|
},
|
||||||
|
onSelectionDragStop: {
|
||||||
const selectedNodes = computed(() =>
|
type: Function as unknown as PropType<NodesSelectionProps['onSelectionDragStop']>,
|
||||||
store?.selectedElements
|
required: false,
|
||||||
? store?.selectedElements.filter(isNode).map((selectedNode) => {
|
default: undefined
|
||||||
const matchingNode = store?.nodes.find((node) => node.id === selectedNode.id);
|
},
|
||||||
|
onSelectionContextMenu: {
|
||||||
return {
|
type: Function as unknown as PropType<NodesSelectionProps['onSelectionContextMenu']>,
|
||||||
...matchingNode,
|
required: false,
|
||||||
position: matchingNode?.__rf.position
|
default: undefined
|
||||||
} as Node;
|
|
||||||
})
|
|
||||||
: []
|
|
||||||
);
|
|
||||||
|
|
||||||
const style = computed(() => ({
|
|
||||||
transform: `translate(${store?.transform[0]}px,${store?.transform[1]}px) scale(${store?.transform[2]})`
|
|
||||||
}));
|
|
||||||
|
|
||||||
const innerStyle = computed(() => ({
|
|
||||||
width: store?.selectedNodesBbox.width,
|
|
||||||
height: store?.selectedNodesBbox.height,
|
|
||||||
top: store?.selectedNodesBbox.y,
|
|
||||||
left: store?.selectedNodesBbox.x
|
|
||||||
}));
|
|
||||||
|
|
||||||
const onStart: DraggableEventHandler = (event: MouseEvent) => {
|
|
||||||
onSelectionDragStart?.(event, selectedNodes.value);
|
|
||||||
};
|
|
||||||
|
|
||||||
const onDrag: DraggableEventHandler = (event, data) => {
|
|
||||||
if (onSelectionDrag) {
|
|
||||||
onSelectionDrag(event, selectedNodes.value);
|
|
||||||
}
|
}
|
||||||
console.log('dragging', data);
|
},
|
||||||
};
|
setup(props) {
|
||||||
|
const store = inject<RevueFlowStore>('store')!;
|
||||||
|
const nodeRef = ref<HTMLElement | undefined>();
|
||||||
|
const grid = computed(() => (store.snapToGrid ? store.snapGrid : [1, 1])! as [number, number]);
|
||||||
|
|
||||||
const onStop: DraggableEventHandler = (event: MouseEvent) => {
|
const selectedNodes = computed(() =>
|
||||||
store?.updateNodePosDiff({
|
store.selectedElements
|
||||||
isDragging: false
|
? store.selectedElements.filter(isNode).map((selectedNode) => {
|
||||||
});
|
const matchingNode = store.nodes.find((node) => node.id === selectedNode.id);
|
||||||
|
|
||||||
onSelectionDragStop?.(event, selectedNodes.value);
|
return {
|
||||||
};
|
...matchingNode,
|
||||||
|
position: matchingNode?.__rf.position
|
||||||
|
} as Node;
|
||||||
|
})
|
||||||
|
: []
|
||||||
|
);
|
||||||
|
|
||||||
const onContextMenu = (event: MouseEvent) => {
|
const style = computed(() => ({
|
||||||
const selectedNodes = store?.selectedElements
|
transform: `translate(${store.transform[0]}px,${store.transform[1]}px) scale(${store.transform[2]})`
|
||||||
? store?.selectedElements.filter(isNode).map((selectedNode) => store?.nodes.find((node) => node.id === selectedNode.id))
|
}));
|
||||||
: [];
|
|
||||||
|
|
||||||
onSelectionContextMenu?.(event, selectedNodes as any);
|
const innerStyle = computed(() => ({
|
||||||
};
|
width: `${store.selectedNodesBbox.width}px`,
|
||||||
|
height: `${store.selectedNodesBbox.height}px`,
|
||||||
|
top: `${store.selectedNodesBbox.y}px`,
|
||||||
|
left: `${store.selectedNodesBbox.x}px`
|
||||||
|
}));
|
||||||
|
|
||||||
if (!store?.selectedElements || store?.selectionActive) {
|
const onStart: DraggableEventHandler = (event: MouseEvent) => {
|
||||||
return null;
|
props.onSelectionDragStart?.(event, selectedNodes.value);
|
||||||
|
};
|
||||||
|
|
||||||
|
const onDrag: DraggableEventHandler = (event) => {
|
||||||
|
if (props.onSelectionDrag) {
|
||||||
|
props.onSelectionDrag(event, selectedNodes.value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const onStop: DraggableEventHandler = (event: MouseEvent) => {
|
||||||
|
store.updateNodePosDiff({
|
||||||
|
isDragging: false
|
||||||
|
});
|
||||||
|
|
||||||
|
props.onSelectionDragStop?.(event, selectedNodes.value);
|
||||||
|
};
|
||||||
|
|
||||||
|
const onContextMenu = (event: MouseEvent) => {
|
||||||
|
const selectedNodes = store.selectedElements
|
||||||
|
? store.selectedElements.filter(isNode).map((selectedNode) => store.nodes.find((node) => node.id === selectedNode.id))
|
||||||
|
: [];
|
||||||
|
|
||||||
|
props.onSelectionContextMenu?.(event, selectedNodes as any);
|
||||||
|
};
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
return !store.selectedElements || store.selectionActive ? (
|
||||||
|
''
|
||||||
|
) : (
|
||||||
|
<div class="revue-flow__nodesselection" style={style.value}>
|
||||||
|
<Draggable
|
||||||
|
scale={store.transform[2]}
|
||||||
|
grid={grid.value}
|
||||||
|
onStart={onStart}
|
||||||
|
onDrag={onDrag}
|
||||||
|
onStop={onStop}
|
||||||
|
enableUserSelectHack={false}
|
||||||
|
nodeRef={nodeRef.value}
|
||||||
|
>
|
||||||
|
<div ref={nodeRef} class="revue-flow__nodesselection-rect" onContextmenu={onContextMenu} style={innerStyle.value} />
|
||||||
|
</Draggable>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
});
|
||||||
return (
|
|
||||||
<div class="revue-flow__nodesselection" style={style.value}>
|
|
||||||
<Draggable
|
|
||||||
scale={store?.transform[2]}
|
|
||||||
grid={grid.value}
|
|
||||||
onStart={onStart}
|
|
||||||
onDrag={onDrag}
|
|
||||||
onStop={onStop}
|
|
||||||
enableUserSelectHack={false}
|
|
||||||
nodeRef={nodeRef.value}
|
|
||||||
>
|
|
||||||
<div ref={nodeRef} class="revue-flow__nodesselection-rect" onContextmenu={onContextMenu} style={innerStyle.value} />
|
|
||||||
</Draggable>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default NodesSelection;
|
export default NodesSelection;
|
||||||
|
|||||||
+100
-171
@@ -1,4 +1,4 @@
|
|||||||
import { defineComponent, inject, onBeforeMount, onMounted, ref, reactive, PropType, CSSProperties } from 'vue';
|
import { defineComponent, inject, onBeforeMount, onMounted, ref, PropType, CSSProperties } from 'vue';
|
||||||
import FlowRenderer from '../FlowRenderer';
|
import FlowRenderer from '../FlowRenderer';
|
||||||
import NodeRenderer from '../NodeRenderer';
|
import NodeRenderer from '../NodeRenderer';
|
||||||
import EdgeRenderer from '../EdgeRenderer';
|
import EdgeRenderer from '../EdgeRenderer';
|
||||||
@@ -359,74 +359,6 @@ const GraphView = defineComponent({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
setup(props) {
|
setup(props) {
|
||||||
const {
|
|
||||||
nodeTypes,
|
|
||||||
edgeTypes,
|
|
||||||
onMove,
|
|
||||||
onMoveStart,
|
|
||||||
onMoveEnd,
|
|
||||||
onLoad,
|
|
||||||
onElementClick,
|
|
||||||
onNodeDoubleClick,
|
|
||||||
onEdgeDoubleClick,
|
|
||||||
onNodeMouseEnter,
|
|
||||||
onNodeMouseMove,
|
|
||||||
onNodeMouseLeave,
|
|
||||||
onNodeContextMenu,
|
|
||||||
onNodeDragStart,
|
|
||||||
onNodeDrag,
|
|
||||||
onNodeDragStop,
|
|
||||||
onSelectionDragStart,
|
|
||||||
onSelectionDrag,
|
|
||||||
onSelectionDragStop,
|
|
||||||
onSelectionContextMenu,
|
|
||||||
connectionMode,
|
|
||||||
connectionLineType,
|
|
||||||
connectionLineStyle,
|
|
||||||
connectionLineComponent,
|
|
||||||
selectionKeyCode,
|
|
||||||
multiSelectionKeyCode,
|
|
||||||
zoomActivationKeyCode,
|
|
||||||
onElementsRemove,
|
|
||||||
deleteKeyCode,
|
|
||||||
onConnect,
|
|
||||||
onConnectStart,
|
|
||||||
onConnectStop,
|
|
||||||
onConnectEnd,
|
|
||||||
snapToGrid,
|
|
||||||
snapGrid,
|
|
||||||
onlyRenderVisibleElements,
|
|
||||||
nodesDraggable,
|
|
||||||
nodesConnectable,
|
|
||||||
elementsSelectable,
|
|
||||||
selectNodesOnDrag,
|
|
||||||
minZoom,
|
|
||||||
maxZoom,
|
|
||||||
defaultZoom,
|
|
||||||
defaultPosition,
|
|
||||||
translateExtent,
|
|
||||||
nodeExtent,
|
|
||||||
arrowHeadColor,
|
|
||||||
markerEndId,
|
|
||||||
zoomOnScroll,
|
|
||||||
zoomOnPinch,
|
|
||||||
panOnScroll,
|
|
||||||
panOnScrollSpeed,
|
|
||||||
panOnScrollMode,
|
|
||||||
zoomOnDoubleClick,
|
|
||||||
paneMoveable,
|
|
||||||
onPaneClick,
|
|
||||||
onPaneScroll,
|
|
||||||
onPaneContextMenu,
|
|
||||||
onEdgeUpdate,
|
|
||||||
onEdgeContextMenu,
|
|
||||||
onEdgeMouseEnter,
|
|
||||||
onEdgeMouseMove,
|
|
||||||
onEdgeMouseLeave,
|
|
||||||
edgeUpdaterRadius,
|
|
||||||
onEdgeUpdateStart,
|
|
||||||
onEdgeUpdateEnd
|
|
||||||
} = reactive(props);
|
|
||||||
const store = inject<RevueFlowStore>('store');
|
const store = inject<RevueFlowStore>('store');
|
||||||
const isInitialized = ref<boolean>(false);
|
const isInitialized = ref<boolean>(false);
|
||||||
|
|
||||||
@@ -434,8 +366,8 @@ const GraphView = defineComponent({
|
|||||||
const { zoomIn, zoomOut, zoomTo, transform, fitView, initialized } = useZoomPanHelper();
|
const { zoomIn, zoomOut, zoomTo, transform, fitView, initialized } = useZoomPanHelper();
|
||||||
|
|
||||||
if (!isInitialized.value && initialized) {
|
if (!isInitialized.value && initialized) {
|
||||||
if (onLoad && store) {
|
if (props.onLoad && store) {
|
||||||
onLoad({
|
props.onLoad({
|
||||||
fitView: (params = { padding: 0.1 }) => fitView(params),
|
fitView: (params = { padding: 0.1 }) => fitView(params),
|
||||||
zoomIn,
|
zoomIn,
|
||||||
zoomOut,
|
zoomOut,
|
||||||
@@ -450,140 +382,137 @@ const GraphView = defineComponent({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
if (typeof props.nodesConnectable !== 'undefined') {
|
||||||
|
store?.setNodesConnectable(!!props.nodesConnectable);
|
||||||
|
}
|
||||||
|
if (typeof props.elementsSelectable !== 'undefined') {
|
||||||
|
store?.setElementsSelectable(!!props.elementsSelectable);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof props.connectionMode !== 'undefined') {
|
||||||
|
store?.setConnectionMode(props.connectionMode);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
onBeforeMount(() => {
|
onBeforeMount(() => {
|
||||||
if (onConnect) {
|
if (props.onConnect) {
|
||||||
store?.setOnConnect(onConnect);
|
store?.setOnConnect(props.onConnect);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (onConnectStart) {
|
if (props.onConnectStart) {
|
||||||
store?.setOnConnectStart(onConnectStart);
|
store?.setOnConnectStart(props.onConnectStart);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (onConnectStop) {
|
if (props.onConnectStop) {
|
||||||
store?.setOnConnectStop(onConnectStop);
|
store?.setOnConnectStop(props.onConnectStop);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (onConnectEnd) {
|
if (props.onConnectEnd) {
|
||||||
store?.setOnConnectEnd(onConnectEnd);
|
store?.setOnConnectEnd(props.onConnectEnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof snapToGrid !== 'undefined') {
|
if (typeof props.snapToGrid !== 'undefined') {
|
||||||
store?.setSnapToGrid(snapToGrid);
|
store?.setSnapToGrid(props.snapToGrid);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof snapGrid !== 'undefined') {
|
if (typeof props.snapGrid !== 'undefined') {
|
||||||
store?.setSnapGrid(snapGrid);
|
store?.setSnapGrid(props.snapGrid);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof nodesDraggable !== 'undefined') {
|
if (typeof props.nodesDraggable !== 'undefined') {
|
||||||
store?.setNodesDraggable(!!nodesDraggable);
|
store?.setNodesDraggable(!!props.nodesDraggable);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof nodesConnectable !== 'undefined') {
|
if (typeof props.nodesConnectable !== 'undefined') {
|
||||||
store?.setNodesConnectable(!!nodesConnectable);
|
store?.setNodesConnectable(!!props.nodesConnectable);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof elementsSelectable !== 'undefined') {
|
if (typeof props.elementsSelectable !== 'undefined') {
|
||||||
store?.setElementsSelectable(!!elementsSelectable);
|
store?.setElementsSelectable(!!props.elementsSelectable);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof minZoom !== 'undefined') {
|
if (typeof props.minZoom !== 'undefined') {
|
||||||
store?.setMinZoom(minZoom);
|
store?.setMinZoom(props.minZoom);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof maxZoom !== 'undefined') {
|
if (typeof props.maxZoom !== 'undefined') {
|
||||||
store?.setMaxZoom(maxZoom);
|
store?.setMaxZoom(props.maxZoom);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof translateExtent !== 'undefined') {
|
if (typeof props.translateExtent !== 'undefined') {
|
||||||
store?.setTranslateExtent(translateExtent);
|
store?.setTranslateExtent(props.translateExtent);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof nodeExtent !== 'undefined') {
|
if (typeof props.nodeExtent !== 'undefined') {
|
||||||
store?.setNodeExtent(nodeExtent);
|
store?.setNodeExtent(props.nodeExtent);
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
if (typeof nodesConnectable !== 'undefined') {
|
|
||||||
store?.setNodesConnectable(!!nodesConnectable);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
if (typeof elementsSelectable !== 'undefined') {
|
|
||||||
store?.setElementsSelectable(!!elementsSelectable);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof connectionMode !== 'undefined') {
|
|
||||||
store?.setConnectionMode(connectionMode);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return () => (
|
return () => (
|
||||||
<FlowRenderer
|
<FlowRenderer
|
||||||
onPaneClick={onPaneClick}
|
onPaneClick={props.onPaneClick}
|
||||||
onPaneContextMenu={onPaneContextMenu}
|
onPaneContextMenu={props.onPaneContextMenu}
|
||||||
onPaneScroll={onPaneScroll}
|
onPaneScroll={props.onPaneScroll}
|
||||||
onElementsRemove={onElementsRemove}
|
onElementsRemove={props.onElementsRemove}
|
||||||
deleteKeyCode={deleteKeyCode}
|
deleteKeyCode={props.deleteKeyCode}
|
||||||
selectionKeyCode={selectionKeyCode}
|
selectionKeyCode={props.selectionKeyCode}
|
||||||
multiSelectionKeyCode={multiSelectionKeyCode}
|
multiSelectionKeyCode={props.multiSelectionKeyCode}
|
||||||
zoomActivationKeyCode={zoomActivationKeyCode}
|
zoomActivationKeyCode={props.zoomActivationKeyCode}
|
||||||
elementsSelectable={elementsSelectable}
|
elementsSelectable={props.elementsSelectable}
|
||||||
onMove={onMove}
|
onMove={props.onMove}
|
||||||
onMoveStart={onMoveStart}
|
onMoveStart={props.onMoveStart}
|
||||||
onMoveEnd={onMoveEnd}
|
onMoveEnd={props.onMoveEnd}
|
||||||
zoomOnScroll={zoomOnScroll}
|
zoomOnScroll={props.zoomOnScroll}
|
||||||
zoomOnPinch={zoomOnPinch}
|
zoomOnPinch={props.zoomOnPinch}
|
||||||
zoomOnDoubleClick={zoomOnDoubleClick}
|
zoomOnDoubleClick={props.zoomOnDoubleClick}
|
||||||
panOnScroll={panOnScroll}
|
panOnScroll={props.panOnScroll}
|
||||||
panOnScrollSpeed={panOnScrollSpeed}
|
panOnScrollSpeed={props.panOnScrollSpeed}
|
||||||
panOnScrollMode={panOnScrollMode}
|
panOnScrollMode={props.panOnScrollMode}
|
||||||
paneMoveable={paneMoveable}
|
paneMoveable={props.paneMoveable}
|
||||||
defaultPosition={defaultPosition}
|
defaultPosition={props.defaultPosition}
|
||||||
defaultZoom={defaultZoom}
|
defaultZoom={props.defaultZoom}
|
||||||
translateExtent={translateExtent}
|
translateExtent={props.translateExtent}
|
||||||
onSelectionDragStart={onSelectionDragStart}
|
onSelectionDragStart={props.onSelectionDragStart}
|
||||||
onSelectionDrag={onSelectionDrag}
|
onSelectionDrag={props.onSelectionDrag}
|
||||||
onSelectionDragStop={onSelectionDragStop}
|
onSelectionDragStop={props.onSelectionDragStop}
|
||||||
onSelectionContextMenu={onSelectionContextMenu}
|
onSelectionContextMenu={props.onSelectionContextMenu}
|
||||||
>
|
>
|
||||||
<NodeRenderer
|
<NodeRenderer
|
||||||
nodeTypes={nodeTypes}
|
nodeTypes={props.nodeTypes}
|
||||||
onElementClick={onElementClick}
|
onElementClick={props.onElementClick}
|
||||||
onNodeDoubleClick={onNodeDoubleClick}
|
onNodeDoubleClick={props.onNodeDoubleClick}
|
||||||
onNodeMouseEnter={onNodeMouseEnter}
|
onNodeMouseEnter={props.onNodeMouseEnter}
|
||||||
onNodeMouseMove={onNodeMouseMove}
|
onNodeMouseMove={props.onNodeMouseMove}
|
||||||
onNodeMouseLeave={onNodeMouseLeave}
|
onNodeMouseLeave={props.onNodeMouseLeave}
|
||||||
onNodeContextMenu={onNodeContextMenu}
|
onNodeContextMenu={props.onNodeContextMenu}
|
||||||
onNodeDragStop={onNodeDragStop}
|
onNodeDragStop={props.onNodeDragStop}
|
||||||
onNodeDrag={onNodeDrag}
|
onNodeDrag={props.onNodeDrag}
|
||||||
onNodeDragStart={onNodeDragStart}
|
onNodeDragStart={props.onNodeDragStart}
|
||||||
selectNodesOnDrag={selectNodesOnDrag}
|
selectNodesOnDrag={props.selectNodesOnDrag}
|
||||||
snapToGrid={snapToGrid}
|
snapToGrid={props.snapToGrid}
|
||||||
snapGrid={snapGrid}
|
snapGrid={props.snapGrid}
|
||||||
onlyRenderVisibleElements={onlyRenderVisibleElements}
|
onlyRenderVisibleElements={props.onlyRenderVisibleElements}
|
||||||
/>
|
/>
|
||||||
<EdgeRenderer
|
<EdgeRenderer
|
||||||
edgeTypes={edgeTypes}
|
edgeTypes={props.edgeTypes}
|
||||||
onElementClick={onElementClick}
|
onElementClick={props.onElementClick}
|
||||||
onEdgeDoubleClick={onEdgeDoubleClick}
|
onEdgeDoubleClick={props.onEdgeDoubleClick}
|
||||||
connectionLineType={connectionLineType}
|
connectionLineType={props.connectionLineType}
|
||||||
connectionLineStyle={connectionLineStyle}
|
connectionLineStyle={props.connectionLineStyle}
|
||||||
connectionLineComponent={connectionLineComponent}
|
connectionLineComponent={props.connectionLineComponent}
|
||||||
connectionMode={connectionMode}
|
connectionMode={props.connectionMode}
|
||||||
arrowHeadColor={arrowHeadColor}
|
arrowHeadColor={props.arrowHeadColor}
|
||||||
markerEndId={markerEndId}
|
markerEndId={props.markerEndId}
|
||||||
onEdgeUpdate={onEdgeUpdate}
|
onEdgeUpdate={props.onEdgeUpdate}
|
||||||
onlyRenderVisibleElements={onlyRenderVisibleElements}
|
onlyRenderVisibleElements={props.onlyRenderVisibleElements}
|
||||||
onEdgeContextMenu={onEdgeContextMenu}
|
onEdgeContextMenu={props.onEdgeContextMenu}
|
||||||
onEdgeMouseEnter={onEdgeMouseEnter}
|
onEdgeMouseEnter={props.onEdgeMouseEnter}
|
||||||
onEdgeMouseMove={onEdgeMouseMove}
|
onEdgeMouseMove={props.onEdgeMouseMove}
|
||||||
onEdgeMouseLeave={onEdgeMouseLeave}
|
onEdgeMouseLeave={props.onEdgeMouseLeave}
|
||||||
onEdgeUpdateStart={onEdgeUpdateStart}
|
onEdgeUpdateStart={props.onEdgeUpdateStart}
|
||||||
onEdgeUpdateEnd={onEdgeUpdateEnd}
|
onEdgeUpdateEnd={props.onEdgeUpdateEnd}
|
||||||
edgeUpdaterRadius={edgeUpdaterRadius}
|
edgeUpdaterRadius={props.edgeUpdaterRadius}
|
||||||
/>
|
/>
|
||||||
</FlowRenderer>
|
</FlowRenderer>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -94,27 +94,27 @@ const NodeRenderer = defineComponent({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
setup(props) {
|
setup(props) {
|
||||||
const store = inject<RevueFlowStore>('store');
|
const store = inject<RevueFlowStore>('store')!;
|
||||||
|
|
||||||
const visibleNodes = computed(() => {
|
const visibleNodes = computed(() => {
|
||||||
return props.onlyRenderVisibleElements
|
return props.onlyRenderVisibleElements
|
||||||
? store?.nodes &&
|
? store.nodes &&
|
||||||
getNodesInside(
|
getNodesInside(
|
||||||
store?.nodes,
|
store.nodes,
|
||||||
{
|
{
|
||||||
x: 0,
|
x: 0,
|
||||||
y: 0,
|
y: 0,
|
||||||
width: store?.width,
|
width: store?.width,
|
||||||
height: store?.height
|
height: store?.height
|
||||||
},
|
},
|
||||||
store?.transform,
|
store.transform,
|
||||||
true
|
true
|
||||||
)
|
)
|
||||||
: store?.nodes;
|
: store.nodes;
|
||||||
});
|
});
|
||||||
|
|
||||||
const transformStyle = computed(() => ({
|
const transformStyle = computed(() => ({
|
||||||
transform: `translate(${store?.transform[0]}px,${store?.transform[1]}px) scale(${store?.transform[2]})`
|
transform: `translate(${store.transform[0]}px,${store.transform[1]}px) scale(${store.transform[2]})`
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const resizeObserver = computed(() => {
|
const resizeObserver = computed(() => {
|
||||||
@@ -128,7 +128,7 @@ const NodeRenderer = defineComponent({
|
|||||||
nodeElement: entry.target as HTMLDivElement
|
nodeElement: entry.target as HTMLDivElement
|
||||||
}));
|
}));
|
||||||
|
|
||||||
store?.updateNodeDimensions(updates);
|
store.updateNodeDimensions(updates);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,14 +1,4 @@
|
|||||||
import {
|
import { computed, CSSProperties, defineComponent, HTMLAttributes, onBeforeUnmount, PropType, provide, watchEffect } from 'vue';
|
||||||
computed,
|
|
||||||
CSSProperties,
|
|
||||||
defineComponent,
|
|
||||||
HTMLAttributes,
|
|
||||||
onBeforeUnmount,
|
|
||||||
PropType,
|
|
||||||
provide,
|
|
||||||
reactive,
|
|
||||||
watchEffect
|
|
||||||
} from 'vue';
|
|
||||||
import GraphView from '../GraphView';
|
import GraphView from '../GraphView';
|
||||||
import DefaultNode from '../../components/Nodes/DefaultNode';
|
import DefaultNode from '../../components/Nodes/DefaultNode';
|
||||||
import InputNode from '../../components/Nodes/InputNode';
|
import InputNode from '../../components/Nodes/InputNode';
|
||||||
@@ -548,164 +538,92 @@ const RevueFlow = defineComponent({
|
|||||||
*/
|
*/
|
||||||
},
|
},
|
||||||
setup(props, { slots }) {
|
setup(props, { slots }) {
|
||||||
const {
|
|
||||||
elements = [],
|
|
||||||
nodeTypes = defaultNodeTypes,
|
|
||||||
edgeTypes = defaultEdgeTypes,
|
|
||||||
onElementClick,
|
|
||||||
onLoad,
|
|
||||||
onMove,
|
|
||||||
onMoveStart,
|
|
||||||
onMoveEnd,
|
|
||||||
onElementsRemove,
|
|
||||||
onConnect,
|
|
||||||
onConnectStart,
|
|
||||||
onConnectStop,
|
|
||||||
onConnectEnd,
|
|
||||||
onNodeMouseEnter,
|
|
||||||
onNodeMouseMove,
|
|
||||||
onNodeMouseLeave,
|
|
||||||
onNodeContextMenu,
|
|
||||||
onNodeDoubleClick,
|
|
||||||
onNodeDragStart,
|
|
||||||
onNodeDrag,
|
|
||||||
onNodeDragStop,
|
|
||||||
onSelectionChange,
|
|
||||||
onSelectionDragStart,
|
|
||||||
onSelectionDrag,
|
|
||||||
onSelectionDragStop,
|
|
||||||
onSelectionContextMenu,
|
|
||||||
connectionMode = ConnectionMode.Strict,
|
|
||||||
connectionLineType = ConnectionLineType.Bezier,
|
|
||||||
connectionLineStyle,
|
|
||||||
connectionLineComponent,
|
|
||||||
deleteKeyCode = 'Backspace',
|
|
||||||
selectionKeyCode = 'Shift',
|
|
||||||
multiSelectionKeyCode = 'Meta',
|
|
||||||
zoomActivationKeyCode = 'Meta',
|
|
||||||
snapToGrid = false,
|
|
||||||
snapGrid = [15, 15],
|
|
||||||
onlyRenderVisibleElements = false,
|
|
||||||
selectNodesOnDrag = true,
|
|
||||||
nodesDraggable,
|
|
||||||
nodesConnectable,
|
|
||||||
elementsSelectable,
|
|
||||||
minZoom,
|
|
||||||
maxZoom,
|
|
||||||
defaultZoom = 1,
|
|
||||||
defaultPosition = [0, 0],
|
|
||||||
translateExtent,
|
|
||||||
nodeExtent,
|
|
||||||
arrowHeadColor = '#b1b1b7',
|
|
||||||
markerEndId,
|
|
||||||
zoomOnScroll = true,
|
|
||||||
zoomOnPinch = true,
|
|
||||||
panOnScroll = false,
|
|
||||||
panOnScrollSpeed = 0.5,
|
|
||||||
panOnScrollMode = PanOnScrollMode.Free,
|
|
||||||
zoomOnDoubleClick = true,
|
|
||||||
paneMoveable = true,
|
|
||||||
onPaneClick,
|
|
||||||
onPaneScroll,
|
|
||||||
onPaneContextMenu,
|
|
||||||
onEdgeUpdate,
|
|
||||||
onEdgeContextMenu,
|
|
||||||
onEdgeDoubleClick,
|
|
||||||
onEdgeMouseEnter,
|
|
||||||
onEdgeMouseMove,
|
|
||||||
onEdgeMouseLeave,
|
|
||||||
onEdgeUpdateStart,
|
|
||||||
onEdgeUpdateEnd,
|
|
||||||
edgeUpdaterRadius = 10,
|
|
||||||
nodeTypesId = '1',
|
|
||||||
edgeTypesId = '1',
|
|
||||||
...rest
|
|
||||||
} = reactive(props);
|
|
||||||
const store = configureStore(initialState)();
|
const store = configureStore(initialState)();
|
||||||
provide<RevueFlowStore>('store', store);
|
provide<RevueFlowStore>('store', store);
|
||||||
store.setElements(elements);
|
store.setElements(props.elements);
|
||||||
|
|
||||||
watchEffect(() => {
|
watchEffect(() => {
|
||||||
store.setElements(elements);
|
store.setElements(props.elements);
|
||||||
onSelectionChange?.(store.selectedElements);
|
props.onSelectionChange?.(store.selectedElements);
|
||||||
});
|
});
|
||||||
|
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
store.$reset();
|
store.$reset();
|
||||||
store.setElements([]);
|
store.setElements([]);
|
||||||
});
|
});
|
||||||
|
|
||||||
const nodeTypesParsed = computed(() => nodeTypes && createNodeTypes(nodeTypes));
|
const nodeTypesParsed = computed(() => props.nodeTypes && createNodeTypes(props.nodeTypes));
|
||||||
const edgeTypesParsed = computed(() => edgeTypes && createEdgeTypes(edgeTypes));
|
const edgeTypesParsed = computed(() => props.edgeTypes && createEdgeTypes(props.edgeTypes));
|
||||||
|
|
||||||
return () => (
|
return () => (
|
||||||
<div {...rest} class="revue-flow">
|
<div onDrop={props.onDrop} onDragover={props.onDragover} class="revue-flow">
|
||||||
<GraphView
|
<GraphView
|
||||||
onLoad={onLoad}
|
onLoad={props.onLoad}
|
||||||
onMove={onMove}
|
onMove={props.onMove}
|
||||||
onMoveStart={onMoveStart}
|
onMoveStart={props.onMoveStart}
|
||||||
onMoveEnd={onMoveEnd}
|
onMoveEnd={props.onMoveEnd}
|
||||||
onElementClick={onElementClick}
|
onElementClick={props.onElementClick}
|
||||||
onNodeMouseEnter={onNodeMouseEnter}
|
onNodeMouseEnter={props.onNodeMouseEnter}
|
||||||
onNodeMouseMove={onNodeMouseMove}
|
onNodeMouseMove={props.onNodeMouseMove}
|
||||||
onNodeMouseLeave={onNodeMouseLeave}
|
onNodeMouseLeave={props.onNodeMouseLeave}
|
||||||
onNodeContextMenu={onNodeContextMenu}
|
onNodeContextMenu={props.onNodeContextMenu}
|
||||||
onNodeDoubleClick={onNodeDoubleClick}
|
onNodeDoubleClick={props.onNodeDoubleClick}
|
||||||
onNodeDragStart={onNodeDragStart}
|
onNodeDragStart={props.onNodeDragStart}
|
||||||
onNodeDrag={onNodeDrag}
|
onNodeDrag={props.onNodeDrag}
|
||||||
onNodeDragStop={onNodeDragStop}
|
onNodeDragStop={props.onNodeDragStop}
|
||||||
nodeTypes={nodeTypesParsed.value}
|
nodeTypes={nodeTypesParsed.value}
|
||||||
edgeTypes={edgeTypesParsed.value}
|
edgeTypes={edgeTypesParsed.value}
|
||||||
connectionMode={connectionMode}
|
connectionMode={props.connectionMode}
|
||||||
connectionLineType={connectionLineType}
|
connectionLineType={props.connectionLineType}
|
||||||
connectionLineStyle={connectionLineStyle}
|
connectionLineStyle={props.connectionLineStyle}
|
||||||
connectionLineComponent={connectionLineComponent}
|
connectionLineComponent={props.connectionLineComponent}
|
||||||
selectionKeyCode={selectionKeyCode}
|
selectionKeyCode={props.selectionKeyCode}
|
||||||
onElementsRemove={onElementsRemove}
|
onElementsRemove={props.onElementsRemove}
|
||||||
deleteKeyCode={deleteKeyCode}
|
deleteKeyCode={props.deleteKeyCode}
|
||||||
multiSelectionKeyCode={multiSelectionKeyCode}
|
multiSelectionKeyCode={props.multiSelectionKeyCode}
|
||||||
zoomActivationKeyCode={zoomActivationKeyCode}
|
zoomActivationKeyCode={props.zoomActivationKeyCode}
|
||||||
onConnect={onConnect}
|
onConnect={props.onConnect}
|
||||||
onConnectStart={onConnectStart}
|
onConnectStart={props.onConnectStart}
|
||||||
onConnectStop={onConnectStop}
|
onConnectStop={props.onConnectStop}
|
||||||
onConnectEnd={onConnectEnd}
|
onConnectEnd={props.onConnectEnd}
|
||||||
snapToGrid={snapToGrid}
|
snapToGrid={props.snapToGrid}
|
||||||
snapGrid={snapGrid}
|
snapGrid={props.snapGrid}
|
||||||
onlyRenderVisibleElements={onlyRenderVisibleElements}
|
onlyRenderVisibleElements={props.onlyRenderVisibleElements}
|
||||||
nodesDraggable={nodesDraggable}
|
nodesDraggable={props.nodesDraggable}
|
||||||
nodesConnectable={nodesConnectable}
|
nodesConnectable={props.nodesConnectable}
|
||||||
elementsSelectable={elementsSelectable}
|
elementsSelectable={props.elementsSelectable}
|
||||||
selectNodesOnDrag={selectNodesOnDrag}
|
selectNodesOnDrag={props.selectNodesOnDrag}
|
||||||
minZoom={minZoom}
|
minZoom={props.minZoom}
|
||||||
maxZoom={maxZoom}
|
maxZoom={props.maxZoom}
|
||||||
defaultZoom={defaultZoom}
|
defaultZoom={props.defaultZoom}
|
||||||
defaultPosition={defaultPosition}
|
defaultPosition={props.defaultPosition}
|
||||||
translateExtent={translateExtent}
|
translateExtent={props.translateExtent}
|
||||||
nodeExtent={nodeExtent}
|
nodeExtent={props.nodeExtent}
|
||||||
arrowHeadColor={arrowHeadColor}
|
arrowHeadColor={props.arrowHeadColor}
|
||||||
markerEndId={markerEndId}
|
markerEndId={props.markerEndId}
|
||||||
zoomOnScroll={zoomOnScroll}
|
zoomOnScroll={props.zoomOnScroll}
|
||||||
zoomOnPinch={zoomOnPinch}
|
zoomOnPinch={props.zoomOnPinch}
|
||||||
zoomOnDoubleClick={zoomOnDoubleClick}
|
zoomOnDoubleClick={props.zoomOnDoubleClick}
|
||||||
panOnScroll={panOnScroll}
|
panOnScroll={props.panOnScroll}
|
||||||
panOnScrollSpeed={panOnScrollSpeed}
|
panOnScrollSpeed={props.panOnScrollSpeed}
|
||||||
panOnScrollMode={panOnScrollMode}
|
panOnScrollMode={props.panOnScrollMode}
|
||||||
paneMoveable={paneMoveable}
|
paneMoveable={props.paneMoveable}
|
||||||
onPaneClick={onPaneClick}
|
onPaneClick={props.onPaneClick}
|
||||||
onPaneScroll={onPaneScroll}
|
onPaneScroll={props.onPaneScroll}
|
||||||
onPaneContextMenu={onPaneContextMenu}
|
onPaneContextMenu={props.onPaneContextMenu}
|
||||||
onSelectionDragStart={onSelectionDragStart}
|
onSelectionDragStart={props.onSelectionDragStart}
|
||||||
onSelectionDrag={onSelectionDrag}
|
onSelectionDrag={props.onSelectionDrag}
|
||||||
onSelectionDragStop={onSelectionDragStop}
|
onSelectionDragStop={props.onSelectionDragStop}
|
||||||
onSelectionContextMenu={onSelectionContextMenu}
|
onSelectionContextMenu={props.onSelectionContextMenu}
|
||||||
onEdgeUpdate={onEdgeUpdate}
|
onEdgeUpdate={props.onEdgeUpdate}
|
||||||
onEdgeContextMenu={onEdgeContextMenu}
|
onEdgeContextMenu={props.onEdgeContextMenu}
|
||||||
onEdgeDoubleClick={onEdgeDoubleClick}
|
onEdgeDoubleClick={props.onEdgeDoubleClick}
|
||||||
onEdgeMouseEnter={onEdgeMouseEnter}
|
onEdgeMouseEnter={props.onEdgeMouseEnter}
|
||||||
onEdgeMouseMove={onEdgeMouseMove}
|
onEdgeMouseMove={props.onEdgeMouseMove}
|
||||||
onEdgeMouseLeave={onEdgeMouseLeave}
|
onEdgeMouseLeave={props.onEdgeMouseLeave}
|
||||||
onEdgeUpdateStart={onEdgeUpdateStart}
|
onEdgeUpdateStart={props.onEdgeUpdateStart}
|
||||||
onEdgeUpdateEnd={onEdgeUpdateEnd}
|
onEdgeUpdateEnd={props.onEdgeUpdateEnd}
|
||||||
edgeUpdaterRadius={edgeUpdaterRadius}
|
edgeUpdaterRadius={props.edgeUpdaterRadius}
|
||||||
/>
|
/>
|
||||||
{slots.default ? slots.default() : ''}
|
{slots.default ? slots.default() : ''}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { select, pointer } from 'd3-selection';
|
|||||||
|
|
||||||
import { clamp } from '../../utils';
|
import { clamp } from '../../utils';
|
||||||
import { FlowTransform, TranslateExtent, PanOnScrollMode, KeyCode } from '../../types';
|
import { FlowTransform, TranslateExtent, PanOnScrollMode, KeyCode } from '../../types';
|
||||||
import { defineComponent, onMounted, PropType, ref, watch, watchEffect } from 'vue';
|
import { defineComponent, PropType, ref, watch, watchEffect } from 'vue';
|
||||||
import store from '../../store';
|
import store from '../../store';
|
||||||
import useKeyPress from '../../hooks/useKeyPress';
|
import useKeyPress from '../../hooks/useKeyPress';
|
||||||
import useResizeHandler from '../../hooks/useResizeHandler';
|
import useResizeHandler from '../../hooks/useResizeHandler';
|
||||||
@@ -129,7 +129,7 @@ const ZoomPane = defineComponent({
|
|||||||
if (zoomPane.value) useResizeHandler(zoomPane.value);
|
if (zoomPane.value) useResizeHandler(zoomPane.value);
|
||||||
});
|
});
|
||||||
|
|
||||||
onMounted(() => {
|
watchEffect(() => {
|
||||||
if (zoomPane.value && props.defaultPosition && props.defaultZoom) {
|
if (zoomPane.value && props.defaultPosition && props.defaultZoom) {
|
||||||
const currentTranslateExtent =
|
const currentTranslateExtent =
|
||||||
typeof props.translateExtent !== 'undefined' ? props.translateExtent : pinia.translateExtent;
|
typeof props.translateExtent !== 'undefined' ? props.translateExtent : pinia.translateExtent;
|
||||||
@@ -153,7 +153,7 @@ const ZoomPane = defineComponent({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
onMounted(() => {
|
watchEffect(() => {
|
||||||
if (pinia.d3Selection && pinia.d3Zoom) {
|
if (pinia.d3Selection && pinia.d3Zoom) {
|
||||||
if (props.panOnScroll && zoomActivationKeyPressed) {
|
if (props.panOnScroll && zoomActivationKeyPressed) {
|
||||||
pinia.d3Selection
|
pinia.d3Selection
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ export default function configureStore(
|
|||||||
setActivePinia(pinia);
|
setActivePinia(pinia);
|
||||||
|
|
||||||
return defineStore({
|
return defineStore({
|
||||||
id: 'revue-flow-' + pinia.state.value.length + 1,
|
id: 'revue-flow-' + Math.random(),
|
||||||
state: () => preloadedState,
|
state: () => preloadedState,
|
||||||
getters: {},
|
getters: {},
|
||||||
actions: {
|
actions: {
|
||||||
|
|||||||
Reference in New Issue
Block a user