Skip to content

Commit

Permalink
Merge pull request #247 from ajbogh/type_updates
Browse files Browse the repository at this point in the history
Updated types, function definitions,  and optional properties.
  • Loading branch information
ajbogh authored Aug 5, 2020
2 parents 07f2e04 + ad4a23a commit 88a77f3
Show file tree
Hide file tree
Showing 7 changed files with 115 additions and 51 deletions.
4 changes: 2 additions & 2 deletions __tests__/components/graph-util.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ describe('GraphUtils class', () => {
},
};

jest.spyOn(document, 'getElementById').mockReturnValue(fakeElement);
jest.spyOn(document, 'querySelector').mockReturnValue(fakeElement);
const result = GraphUtils.removeElementFromDom('fake');

expect(fakeElement.parentNode.removeChild).toHaveBeenCalledWith(
Expand All @@ -140,7 +140,7 @@ describe('GraphUtils class', () => {
});

it("does nothing when it can't find the element", () => {
jest.spyOn(document, 'getElementById').mockReturnValue(undefined);
jest.spyOn(document, 'querySelector').mockReturnValue(undefined);
const result = GraphUtils.removeElementFromDom('fake');

expect(result).toEqual(false);
Expand Down
21 changes: 21 additions & 0 deletions __tests__/components/graph-view.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -838,6 +838,13 @@ describe('GraphView component', () => {

it('drags an edge', () => {
instance.canSwap.mockReturnValue(true);
instance.viewWrapper = {
current: {
querySelector: jest.fn().mockImplementation(selector => {
return {};
}),
},
};
const draggedEdge = {
source: 'a',
target: 'b',
Expand All @@ -858,6 +865,13 @@ describe('GraphView component', () => {

it('handles swapping the edge to a different node', () => {
instance.canSwap.mockReturnValue(true);
instance.viewWrapper = {
current: {
querySelector: jest.fn().mockImplementation(selector => {
return {};
}),
},
};
const draggedEdge = {
source: 'a',
target: 'b',
Expand Down Expand Up @@ -1040,6 +1054,13 @@ describe('GraphView component', () => {
});

it('drags the edge', () => {
instance.viewWrapper = {
current: {
querySelector: jest.fn().mockImplementation(selector => {
return {};
}),
},
};
event.sourceEvent.buttons = 2;
instance.handleZoomStart(event);
expect(output.state().draggedEdge).toEqual(edge);
Expand Down
2 changes: 1 addition & 1 deletion src/components/edge.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import { EdgeLabelText } from './edge-label-text';
export type IEdge = {
source: string,
target: string,
type?: string,
type?: null | string,
handleText?: string,
handleTooltipText?: string,
label_from?: string,
Expand Down
30 changes: 19 additions & 11 deletions src/components/graph-view-props.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,26 +48,34 @@ export type IGraphViewProps = {
nodeSubtypes: any,
nodeTypes: any,
readOnly?: boolean,
selected: any,
selected?: null | any,
showGraphControls?: boolean,
zoomDelay?: number,
zoomDur?: number,
canCreateEdge?: (startNode?: INode, endNode?: INode) => boolean,
canDeleteEdge?: (selected: any) => boolean,
canDeleteNode?: (selected: any) => boolean,
canSwapEdge?: (
sourceNode: INode,
hoveredNode: INode | null,
swapEdge: IEdge
) => boolean,
onBackgroundClick?: (x: number, y: number, event: any) => void,
onCopySelected?: () => void,
onCreateEdge: (sourceNode: INode, targetNode: INode) => void,
onCreateNode: (x: number, y: number, event: any) => void,
onContextMenu: (x: number, y: number, event: any) => void,
onDeleteEdge: (selectedEdge: IEdge, edges: IEdge[]) => void,
onDeleteNode: (selected: any, nodeId: string, nodes: any[]) => void,
onPasteSelected?: () => void,
onSelectEdge: (selectedEdge: IEdge) => void,
onSelectNode: (node: INode | null, event: any) => void,
onSwapEdge: (sourceNode: INode, targetNode: INode, edge: IEdge) => void,
onCreateEdge?: (sourceNode: INode, targetNode: INode) => void,
onCreateNode?: (x: number, y: number, event: any) => void,
onContextMenu?: (x: number, y: number, event: any) => void,
onDeleteEdge?: (selectedEdge: IEdge, edges: IEdge[]) => void,
onDeleteNode?: (selected: any, nodeId: string, nodes: any[]) => void,
onPasteSelected?: (
selectedNode: INode,
xyCoords?: { x: number, y: number }
) => void,
onSelectEdge?: (selectedEdge: IEdge) => void,
onSelectNode?: (node: INode | null, event: any) => void,
onSwapEdge?: (sourceNode: INode, targetNode: INode, edge: IEdge) => void,
onUndo?: () => void,
onUpdateNode: (node: INode) => void,
onUpdateNode?: (node: INode) => void,
renderBackground?: (gridSize?: number) => any,
renderDefs?: () => any,
renderNode?: (
Expand Down
75 changes: 51 additions & 24 deletions src/components/graph-view.js
Original file line number Diff line number Diff line change
Expand Up @@ -383,15 +383,17 @@ class GraphView extends React.Component<IGraphViewProps, IGraphViewState> {

const prevNodeMapNode = this.getNodeById(nodeId, prevNodesMap);

// remove all outgoing edges
prevNodeMapNode.outgoingEdges.forEach(edge => {
this.removeEdgeElement(edge.source, edge.target);
});
if (prevNodeMapNode) {
// remove all outgoing edges
prevNodeMapNode.outgoingEdges.forEach(edge => {
this.removeEdgeElement(edge.source, edge.target);
});

// remove all incoming edges
prevNodeMapNode.incomingEdges.forEach(edge => {
this.removeEdgeElement(edge.source, edge.target);
});
// remove all incoming edges
prevNodeMapNode.incomingEdges.forEach(edge => {
this.removeEdgeElement(edge.source, edge.target);
});
}

// remove node
const timeoutId = `nodes-${nodeId}`;
Expand Down Expand Up @@ -476,12 +478,13 @@ class GraphView extends React.Component<IGraphViewProps, IGraphViewState> {
sourceNode !== hoveredNode &&
(swapEdge.source !== sourceNode[this.props.nodeKey] ||
swapEdge.target !== hoveredNode[this.props.nodeKey]) &&
canSwapEdge &&
canSwapEdge(sourceNode, hoveredNode, swapEdge)
);
}

deleteNode(selectedNode: INode) {
const { nodeKey } = this.props;
const { nodeKey, onSelectNode, onDeleteNode } = this.props;
const { nodes } = this.state;
const nodeId = selectedNode[nodeKey];

Expand All @@ -500,12 +503,18 @@ class GraphView extends React.Component<IGraphViewProps, IGraphViewState> {
);

// inform consumer
this.props.onSelectNode(null);
this.props.onDeleteNode(selectedNode, nodeId, newNodesArr);
if (onSelectNode) {
onSelectNode(null);
}

if (onDeleteNode) {
onDeleteNode(selectedNode, nodeId, newNodesArr);
}
}

deleteEdge(selectedEdge: IEdge) {
const { edges } = this.state;
const { onDeleteEdge } = this.props;

if (selectedEdge.source == null || selectedEdge.target == null) {
return;
Expand Down Expand Up @@ -541,7 +550,9 @@ class GraphView extends React.Component<IGraphViewProps, IGraphViewState> {
}

// inform consumer
this.props.onDeleteEdge(selectedEdge, newEdgesArr);
if (onDeleteEdge) {
onDeleteEdge(selectedEdge, newEdgesArr);
}
}

handleDelete = (selected: IEdge | INode) => {
Expand Down Expand Up @@ -603,7 +614,7 @@ class GraphView extends React.Component<IGraphViewProps, IGraphViewState> {
selectedNodeObj.node &&
onPasteSelected
) {
onPasteSelected();
onPasteSelected(selectedNodeObj.node);
}

break;
Expand All @@ -614,6 +625,7 @@ class GraphView extends React.Component<IGraphViewProps, IGraphViewState> {

handleEdgeSelected = (e: any) => {
const { source, target } = e.target.dataset;
const { onSelectEdge } = this.props;
let newState = {
svgClicked: true,
focused: true,
Expand All @@ -637,7 +649,10 @@ class GraphView extends React.Component<IGraphViewProps, IGraphViewState> {
},
};
this.setState(newState);
this.props.onSelectEdge(this.state.edges[originalArrIndex]);

if (onSelectEdge) {
onSelectEdge(this.state.edges[originalArrIndex]);
}
} else {
this.setState(newState);
}
Expand Down Expand Up @@ -698,13 +713,16 @@ class GraphView extends React.Component<IGraphViewProps, IGraphViewState> {
focused: true,
svgClicked: true,
});
onSelectNode(null);

if (onSelectNode) {
onSelectNode(null);
}

if (previousSelection) {
this.syncRenderNode(previousSelection);
}

if (!readOnly && d3.event.shiftKey) {
if (!readOnly && d3.event.shiftKey && onCreateNode) {
const xycoords = d3.mouse(d3.event.target);

onCreateNode(xycoords[0], xycoords[1], d3.event);
Expand Down Expand Up @@ -767,7 +785,7 @@ class GraphView extends React.Component<IGraphViewProps, IGraphViewState> {
this.renderConnectedEdgesFromNode(nodeMapNode, true);
this.asyncRenderNode(node);
} else if (
(canCreateEdge && canCreateEdge(nodeId)) ||
(canCreateEdge && canCreateEdge(node)) ||
this.state.draggingEdge
) {
// render new edge
Expand Down Expand Up @@ -808,7 +826,9 @@ class GraphView extends React.Component<IGraphViewProps, IGraphViewState> {
});

// we expect the parent website to set the selected property to the new edge when it's created
onCreateEdge(hoveredNodeData, edgeEndNode);
if (onCreateEdge) {
onCreateEdge(hoveredNodeData, edgeEndNode);
}
} else {
// make the system understand that the edge creation process is done even though it didn't work.
this.setState({
Expand All @@ -835,7 +855,10 @@ class GraphView extends React.Component<IGraphViewProps, IGraphViewState> {

if (nodeMap) {
Object.assign(nodeMap.node, position);
onUpdateNode(nodeMap.node);

if (onUpdateNode) {
onUpdateNode(nodeMap.node);
}
}
}

Expand Down Expand Up @@ -899,6 +922,7 @@ class GraphView extends React.Component<IGraphViewProps, IGraphViewState> {
creatingEdge: boolean,
event?: any
) => {
const { onSelectNode } = this.props;
const newState = {
componentUpToDate: false,
selectedNodeObj: {
Expand All @@ -909,8 +933,8 @@ class GraphView extends React.Component<IGraphViewProps, IGraphViewState> {

this.setState(newState);

if (!creatingEdge) {
this.props.onSelectNode(node, event);
if (!creatingEdge && onSelectNode) {
onSelectNode(node, event);
}
};

Expand Down Expand Up @@ -1076,7 +1100,7 @@ class GraphView extends React.Component<IGraphViewProps, IGraphViewState> {
handleZoomEnd = () => {
const { draggingEdge, draggedEdge, edgeEndNode } = this.state;

const { nodeKey } = this.props;
const { nodeKey, onSwapEdge } = this.props;

if (!draggingEdge || !draggedEdge) {
if (draggingEdge && !draggedEdge) {
Expand Down Expand Up @@ -1127,7 +1151,10 @@ class GraphView extends React.Component<IGraphViewProps, IGraphViewState> {
// determine the target node and update the edge
draggedEdgeCopy.target = edgeEndNode[nodeKey];
this.syncRenderEdge(draggedEdgeCopy);
this.props.onSwapEdge(sourceNodeById.node, edgeEndNode, draggedEdge);

if (onSwapEdge) {
onSwapEdge(sourceNodeById.node, edgeEndNode, draggedEdge);
}
} else {
// this resets the dragged edge back to its original position.
this.syncRenderEdge(draggedEdge);
Expand Down Expand Up @@ -1601,7 +1628,7 @@ class GraphView extends React.Component<IGraphViewProps, IGraphViewState> {
const height = parent.clientHeight;

const next = {
k: viewTransform.k,
k: viewTransform ? viewTransform.k : 0,
x: 0,
y: 0,
};
Expand Down
6 changes: 3 additions & 3 deletions src/examples/graph.js
Original file line number Diff line number Diff line change
Expand Up @@ -465,14 +465,14 @@ class Graph extends React.Component<IGraphProps, IGraphState> {
};

// Pastes the selected node to mouse position
onPasteSelected = (node: INode, mousePosition: [number, number]) => {
onPasteSelected = (node: INode, mousePosition?: [number, number]) => {
const graph = this.state.graph;

const newNode = {
...node,
id: Date.now(),
x: mousePosition[0],
y: mousePosition[1],
x: mousePosition ? mousePosition[0] : node.x,
y: mousePosition ? mousePosition[1] : node.y,
};

graph.nodes = [...graph.nodes, newNode];
Expand Down
28 changes: 18 additions & 10 deletions typings/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,25 +118,33 @@ declare module 'react-digraph' {
nodeSubtypes: any;
nodeTypes: any;
readOnly?: boolean;
selected: any;
selected?: null | any;
showGraphControls?: boolean;
zoomDelay?: number;
zoomDur?: number;
canCreateEdge?: (startNode?: INode, endNode?: INode) => boolean;
canDeleteEdge?: (selected: any) => boolean;
canDeleteNode?: (selected: any) => boolean;
canSwapEdge?: (
sourceNode: INode,
hoveredNode: INode | null,
swapEdge: IEdge
) => boolean,
onBackgroundClick?: (x: number, y: number, event: any) => void,
onCopySelected?: () => void;
onCreateEdge: (sourceNode: INode, targetNode: INode) => void;
onCreateNode: (x: number, y: number, event: any) => void;
onDeleteEdge: (selectedEdge: IEdge, edges: IEdge[]) => void;
onDeleteNode: (selected: any, nodeId: string, nodes: any[]) => void;
onPasteSelected?: () => void;
onSelectEdge: (selectedEdge: IEdge) => void;
onSelectNode: (node: INode | null, event: any) => void;
onSwapEdge: (sourceNode: INode, targetNode: INode, edge: IEdge) => void;
onCreateEdge?: (sourceNode: INode, targetNode: INode) => void;
onCreateNode?: (x: number, y: number, event: any) => void;
onDeleteEdge?: (selectedEdge: IEdge, edges: IEdge[]) => void;
onDeleteNode?: (selected: any, nodeId: string, nodes: any[]) => void;
onPasteSelected?: (
selectedNode: INode,
xyCoords?: { x: number, y: number }
) => void,
onSelectEdge?: (selectedEdge: IEdge) => void;
onSelectNode?: (node: INode | null, event: any) => void;
onSwapEdge?: (sourceNode: INode, targetNode: INode, edge: IEdge) => void;
onUndo?: () => void;
onUpdateNode: (node: INode) => void;
onUpdateNode?: (node: INode) => void;
renderBackground?: (gridSize?: number) => any;
renderDefs?: () => any;
renderNode?: (
Expand Down

0 comments on commit 88a77f3

Please sign in to comment.