feat(keyhandler): add onNodeRemove callback
This commit is contained in:
Vendored
+92
-33
@@ -29798,6 +29798,8 @@
|
|||||||
var UPDATE_SELECTION = 'UPDATE_SELECTION';
|
var UPDATE_SELECTION = 'UPDATE_SELECTION';
|
||||||
var SET_SELECTION = 'SET_SELECTION';
|
var SET_SELECTION = 'SET_SELECTION';
|
||||||
var SET_NODES_SELECTION = 'SET_NODES_SELECTION';
|
var SET_NODES_SELECTION = 'SET_NODES_SELECTION';
|
||||||
|
var SET_SELECTED_NODES_IDS = 'SET_SELECTED_NODES_IDS';
|
||||||
|
var REMOVE_NODES = 'REMOVE_NODES';
|
||||||
var initialState = {
|
var initialState = {
|
||||||
width: 0,
|
width: 0,
|
||||||
height: 0,
|
height: 0,
|
||||||
@@ -29894,12 +29896,31 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case REMOVE_NODES:
|
||||||
|
{
|
||||||
|
var ids = action.payload.ids;
|
||||||
|
var nextEdges = state.edges.filter(function (e) {
|
||||||
|
return !ids.includes(e.data.target) && !ids.includes(e.data.source);
|
||||||
|
});
|
||||||
|
var nextNodes = state.nodes.filter(function (n) {
|
||||||
|
return !ids.includes(n.data.id);
|
||||||
|
});
|
||||||
|
console.log(ids);
|
||||||
|
console.log(state.edges, nextEdges);
|
||||||
|
console.log(state.nodes, nextNodes);
|
||||||
|
return _objectSpread2({}, state, {
|
||||||
|
nodes: nextNodes,
|
||||||
|
edges: nextEdges
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
case SET_NODES:
|
case SET_NODES:
|
||||||
case SET_EDGES:
|
case SET_EDGES:
|
||||||
case UPDATE_TRANSFORM:
|
case UPDATE_TRANSFORM:
|
||||||
case INIT_D3:
|
case INIT_D3:
|
||||||
case UPDATE_SIZE:
|
case UPDATE_SIZE:
|
||||||
case SET_SELECTION:
|
case SET_SELECTION:
|
||||||
|
case SET_SELECTED_NODES_IDS:
|
||||||
return _objectSpread2({}, state, {}, action.payload);
|
return _objectSpread2({}, state, {}, action.payload);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -29991,6 +30012,15 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
var setSelectedNodesIds = function setSelectedNodesIds(ids) {
|
||||||
|
var idArray = Array.isArray(ids) ? ids : [ids];
|
||||||
|
return {
|
||||||
|
type: SET_SELECTED_NODES_IDS,
|
||||||
|
payload: {
|
||||||
|
selectedNodeIds: idArray
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
var updateSelection = function updateSelection(selection) {
|
var updateSelection = function updateSelection(selection) {
|
||||||
return {
|
return {
|
||||||
type: UPDATE_SELECTION,
|
type: UPDATE_SELECTION,
|
||||||
@@ -30001,6 +30031,7 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
var GraphContext = React.createContext({});
|
var GraphContext = React.createContext({});
|
||||||
|
|
||||||
var Provider = function Provider(props) {
|
var Provider = function Provider(props) {
|
||||||
var onNodeClick = props.onNodeClick,
|
var onNodeClick = props.onNodeClick,
|
||||||
children = props.children;
|
children = props.children;
|
||||||
@@ -30284,17 +30315,11 @@
|
|||||||
|
|
||||||
var NodesSelection = (function () {
|
var NodesSelection = (function () {
|
||||||
var graphContext = React.useContext(GraphContext);
|
var graphContext = React.useContext(GraphContext);
|
||||||
var state = graphContext.state,
|
var state = graphContext.state;
|
||||||
dispatch = graphContext.dispatch;
|
|
||||||
return React__default.createElement("div", {
|
return React__default.createElement("div", {
|
||||||
className: "react-graph__nodesselection",
|
className: "react-graph__nodesselection",
|
||||||
style: {
|
style: {
|
||||||
transform: "translate(".concat(state.transform[0], "px,").concat(state.transform[1], "px) scale(").concat(state.transform[2], ")")
|
transform: "translate(".concat(state.transform[0], "px,").concat(state.transform[1], "px) scale(").concat(state.transform[2], ")")
|
||||||
},
|
|
||||||
onClick: function onClick() {
|
|
||||||
return dispatch(setNodesSelection({
|
|
||||||
isActive: false
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
}, React__default.createElement("div", {
|
}, React__default.createElement("div", {
|
||||||
className: "react-graph__nodesselection-rect",
|
className: "react-graph__nodesselection-rect",
|
||||||
@@ -30344,11 +30369,15 @@
|
|||||||
|
|
||||||
var GraphView = function GraphView(props) {
|
var GraphView = function GraphView(props) {
|
||||||
var zoomPane = React.useRef(null);
|
var zoomPane = React.useRef(null);
|
||||||
var graphContext = React.useContext(GraphContext);
|
|
||||||
|
var _useContext = React.useContext(GraphContext),
|
||||||
|
state = _useContext.state,
|
||||||
|
dispatch = _useContext.dispatch;
|
||||||
|
|
||||||
var shiftPressed = useKeyPress('Shift');
|
var shiftPressed = useKeyPress('Shift');
|
||||||
React.useEffect(function () {
|
React.useEffect(function () {
|
||||||
var selection = select(zoomPane.current).call(d3ZoomInstance);
|
var selection = select(zoomPane.current).call(d3ZoomInstance);
|
||||||
graphContext.dispatch(initD3({
|
dispatch(initD3({
|
||||||
zoom: d3ZoomInstance,
|
zoom: d3ZoomInstance,
|
||||||
selection: selection
|
selection: selection
|
||||||
}));
|
}));
|
||||||
@@ -30362,35 +30391,35 @@
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
graphContext.dispatch(updateTransform(event.transform));
|
dispatch(updateTransform(event.transform));
|
||||||
props.onMove();
|
props.onMove();
|
||||||
});
|
});
|
||||||
|
|
||||||
if (graphContext.state.d3Selection) {
|
if (state.d3Selection) {
|
||||||
// we need to restore the graph transform otherwise d3 zoom transform and graph transform are not synced
|
// we need to restore the graph transform otherwise d3 zoom transform and graph transform are not synced
|
||||||
var graphTransform = identity$1.translate(graphContext.state.transform[0], graphContext.state.transform[1]).scale(graphContext.state.transform[2]);
|
var graphTransform = identity$1.translate(state.transform[0], state.transform[1]).scale(state.transform[2]);
|
||||||
graphContext.state.d3Selection.call(graphContext.state.d3Zoom.transform, graphTransform);
|
state.d3Selection.call(state.d3Zoom.transform, graphTransform);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [shiftPressed]);
|
}, [shiftPressed]);
|
||||||
React.useEffect(function () {
|
React.useEffect(function () {
|
||||||
return graphContext.dispatch(updateSize(props.size));
|
return dispatch(updateSize(props.size));
|
||||||
}, [props.size.width, props.size.height]);
|
}, [props.size.width, props.size.height]);
|
||||||
React.useEffect(function () {
|
React.useEffect(function () {
|
||||||
if (graphContext.state.d3Initialised) {
|
if (state.d3Initialised) {
|
||||||
props.onLoad({
|
props.onLoad({
|
||||||
nodes: graphContext.state.nodes,
|
nodes: state.nodes,
|
||||||
edges: graphContext.state.edges,
|
edges: state.edges,
|
||||||
fitView: function fitView$1() {
|
fitView: function fitView$1() {
|
||||||
return graphContext.dispatch(fitView());
|
return dispatch(fitView());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, [graphContext.state.d3Initialised]);
|
}, [state.d3Initialised]);
|
||||||
React.useEffect(function () {
|
React.useEffect(function () {
|
||||||
props.onChange({
|
props.onChange({
|
||||||
nodes: graphContext.state.nodes,
|
nodes: state.nodes,
|
||||||
edges: graphContext.state.edges
|
edges: state.edges
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
return React__default.createElement("div", {
|
return React__default.createElement("div", {
|
||||||
@@ -30398,10 +30427,15 @@
|
|||||||
}, React__default.createElement(NodeRenderer, {
|
}, React__default.createElement(NodeRenderer, {
|
||||||
nodeTypes: props.nodeTypes
|
nodeTypes: props.nodeTypes
|
||||||
}), React__default.createElement(EdgeRenderer, {
|
}), React__default.createElement(EdgeRenderer, {
|
||||||
width: graphContext.state.width,
|
width: state.width,
|
||||||
height: graphContext.state.height
|
height: state.height
|
||||||
}), shiftPressed && React__default.createElement(UserSelection, null), graphContext.state.nodesSelectionActive && React__default.createElement(NodesSelection, null), React__default.createElement("div", {
|
}), shiftPressed && React__default.createElement(UserSelection, null), state.nodesSelectionActive && React__default.createElement(NodesSelection, null), React__default.createElement("div", {
|
||||||
className: "react-graph__zoompane",
|
className: "react-graph__zoompane",
|
||||||
|
onClick: function onClick() {
|
||||||
|
return dispatch(setNodesSelection({
|
||||||
|
isActive: false
|
||||||
|
}));
|
||||||
|
},
|
||||||
ref: zoomPane
|
ref: zoomPane
|
||||||
}));
|
}));
|
||||||
};
|
};
|
||||||
@@ -30410,6 +30444,23 @@
|
|||||||
monitorHeight: true
|
monitorHeight: true
|
||||||
})(GraphView);
|
})(GraphView);
|
||||||
|
|
||||||
|
var GlobalKeyHandler = (function (props) {
|
||||||
|
var _useContext = React.useContext(GraphContext),
|
||||||
|
state = _useContext.state,
|
||||||
|
dispatch = _useContext.dispatch;
|
||||||
|
|
||||||
|
var removePressed = useKeyPress('Backspace');
|
||||||
|
React.useEffect(function () {
|
||||||
|
if (removePressed && state.selectedNodeIds.length) {
|
||||||
|
props.onNodeRemove(state.selectedNodeIds);
|
||||||
|
dispatch(setNodesSelection({
|
||||||
|
isActive: false
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}, [removePressed]);
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
|
||||||
var Handle = (function (props) {
|
var Handle = (function (props) {
|
||||||
return React__default.createElement("div", _extends({
|
return React__default.createElement("div", _extends({
|
||||||
className: "react-graph__handle"
|
className: "react-graph__handle"
|
||||||
@@ -32747,7 +32798,10 @@
|
|||||||
var wrapNode = (function (NodeComponent) {
|
var wrapNode = (function (NodeComponent) {
|
||||||
return function (props) {
|
return function (props) {
|
||||||
var nodeElement = React.useRef(null);
|
var nodeElement = React.useRef(null);
|
||||||
var graphContext = React.useContext(GraphContext);
|
|
||||||
|
var _useContext = React.useContext(GraphContext),
|
||||||
|
state = _useContext.state,
|
||||||
|
dispatch = _useContext.dispatch;
|
||||||
|
|
||||||
var _useState = React.useState({
|
var _useState = React.useState({
|
||||||
x: 0,
|
x: 0,
|
||||||
@@ -32763,12 +32817,12 @@
|
|||||||
var position = __rg.position;
|
var position = __rg.position;
|
||||||
var id = data.id;
|
var id = data.id;
|
||||||
|
|
||||||
var _graphContext$state$t = _slicedToArray(graphContext.state.transform, 3),
|
var _state$transform = _slicedToArray(state.transform, 3),
|
||||||
x = _graphContext$state$t[0],
|
x = _state$transform[0],
|
||||||
y = _graphContext$state$t[1],
|
y = _state$transform[1],
|
||||||
k = _graphContext$state$t[2];
|
k = _state$transform[2];
|
||||||
|
|
||||||
var selected = graphContext.state.selectedNodeIds.includes(id);
|
var selected = state.selectedNodeIds.includes(id);
|
||||||
var nodeClasses = classnames('react-graph__node', {
|
var nodeClasses = classnames('react-graph__node', {
|
||||||
selected: selected
|
selected: selected
|
||||||
});
|
});
|
||||||
@@ -32776,7 +32830,7 @@
|
|||||||
var bounds = nodeElement.current.getBoundingClientRect();
|
var bounds = nodeElement.current.getBoundingClientRect();
|
||||||
var unscaledWith = Math.round(bounds.width * (1 / k));
|
var unscaledWith = Math.round(bounds.width * (1 / k));
|
||||||
var unscaledHeight = Math.round(bounds.height * (1 / k));
|
var unscaledHeight = Math.round(bounds.height * (1 / k));
|
||||||
graphContext.dispatch(updateNodeData(id, {
|
dispatch(updateNodeData(id, {
|
||||||
width: unscaledWith,
|
width: unscaledWith,
|
||||||
height: unscaledHeight
|
height: unscaledHeight
|
||||||
}));
|
}));
|
||||||
@@ -32804,7 +32858,7 @@
|
|||||||
x: e.clientX * (1 / k),
|
x: e.clientX * (1 / k),
|
||||||
y: e.clientY * (1 / k)
|
y: e.clientY * (1 / k)
|
||||||
};
|
};
|
||||||
graphContext.dispatch(updateNodePos(id, {
|
dispatch(updateNodePos(id, {
|
||||||
x: unscaledPos.x - x - offset.x,
|
x: unscaledPos.x - x - offset.x,
|
||||||
y: unscaledPos.y - y - offset.y
|
y: unscaledPos.y - y - offset.y
|
||||||
}));
|
}));
|
||||||
@@ -32821,6 +32875,7 @@
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dispatch(setSelectedNodesIds(id));
|
||||||
onNodeClick({
|
onNodeClick({
|
||||||
data: data,
|
data: data,
|
||||||
position: position
|
position: position
|
||||||
@@ -32900,7 +32955,8 @@
|
|||||||
onLoad = _this$props.onLoad,
|
onLoad = _this$props.onLoad,
|
||||||
onMove = _this$props.onMove,
|
onMove = _this$props.onMove,
|
||||||
onChange = _this$props.onChange,
|
onChange = _this$props.onChange,
|
||||||
elements = _this$props.elements;
|
elements = _this$props.elements,
|
||||||
|
onNodeRemove = _this$props.onNodeRemove;
|
||||||
|
|
||||||
var _elements$map$reduce = elements.map(parseElements).reduce(separateElements, {}),
|
var _elements$map$reduce = elements.map(parseElements).reduce(separateElements, {}),
|
||||||
nodes = _elements$map$reduce.nodes,
|
nodes = _elements$map$reduce.nodes,
|
||||||
@@ -32918,6 +32974,8 @@
|
|||||||
onMove: onMove,
|
onMove: onMove,
|
||||||
onChange: onChange,
|
onChange: onChange,
|
||||||
nodeTypes: this.nodeTypes
|
nodeTypes: this.nodeTypes
|
||||||
|
}), React__default.createElement(GlobalKeyHandler, {
|
||||||
|
onNodeRemove: onNodeRemove
|
||||||
}), children));
|
}), children));
|
||||||
}
|
}
|
||||||
}]);
|
}]);
|
||||||
@@ -32927,6 +32985,7 @@
|
|||||||
|
|
||||||
ReactGraph.defaultProps = {
|
ReactGraph.defaultProps = {
|
||||||
onNodeClick: function onNodeClick() {},
|
onNodeClick: function onNodeClick() {},
|
||||||
|
onNodeRemove: function onNodeRemove() {},
|
||||||
onLoad: function onLoad() {},
|
onLoad: function onLoad() {},
|
||||||
onMove: function onMove() {},
|
onMove: function onMove() {},
|
||||||
onChange: function onChange() {},
|
onChange: function onChange() {},
|
||||||
|
|||||||
@@ -86,6 +86,7 @@ class App extends PureComponent {
|
|||||||
<Graph
|
<Graph
|
||||||
elements={this.state.elements}
|
elements={this.state.elements}
|
||||||
onNodeClick={node => console.log(node)}
|
onNodeClick={node => console.log(node)}
|
||||||
|
onNodeRemove={nodeIds => console.log('remove', nodeIds)}
|
||||||
style={{ width: '100%', height: '100%' }}
|
style={{ width: '100%', height: '100%' }}
|
||||||
onLoad={graphInstance => this.onLoad(graphInstance)}
|
onLoad={graphInstance => this.onLoad(graphInstance)}
|
||||||
onChange={(elements) => this.onChange(elements)}
|
onChange={(elements) => this.onChange(elements)}
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
import { useEffect, useContext } from 'react';
|
||||||
|
|
||||||
|
import { useKeyPress } from '../hooks';
|
||||||
|
import { setNodesSelection } from '../state/actions';
|
||||||
|
import { GraphContext } from '../GraphContext';
|
||||||
|
|
||||||
|
export default (props) => {
|
||||||
|
const { state, dispatch } = useContext(GraphContext);
|
||||||
|
const removePressed = useKeyPress('Backspace');
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (removePressed && state.selectedNodeIds.length) {
|
||||||
|
props.onNodeRemove(state.selectedNodeIds);
|
||||||
|
dispatch(setNodesSelection({ isActive: false }));
|
||||||
|
}
|
||||||
|
}, [removePressed])
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import React, { createContext, useEffect, useReducer } from 'react';
|
import React, { createContext, useEffect, useReducer, useRef } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import isEqual from 'lodash.isequal';
|
import isEqual from 'lodash.isequal';
|
||||||
|
|
||||||
@@ -7,6 +7,16 @@ import { setNodes, setEdges } from '../state/actions';
|
|||||||
|
|
||||||
export const GraphContext = createContext({});
|
export const GraphContext = createContext({});
|
||||||
|
|
||||||
|
function usePrevious(value) {
|
||||||
|
const ref = useRef();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
ref.current = value;
|
||||||
|
});
|
||||||
|
|
||||||
|
return ref.current;
|
||||||
|
}
|
||||||
|
|
||||||
export const Provider = (props) => {
|
export const Provider = (props) => {
|
||||||
const {
|
const {
|
||||||
onNodeClick,
|
onNodeClick,
|
||||||
|
|||||||
@@ -3,20 +3,20 @@ import ReactDraggable from 'react-draggable';
|
|||||||
import cx from 'classnames';
|
import cx from 'classnames';
|
||||||
|
|
||||||
import { GraphContext } from '../../GraphContext';
|
import { GraphContext } from '../../GraphContext';
|
||||||
import { updateNodeData, updateNodePos } from '../../state/actions';
|
import { updateNodeData, updateNodePos, setSelectedNodesIds } from '../../state/actions';
|
||||||
|
|
||||||
const isInputTarget = (e) => ['INPUT', 'SELECT', 'TEXTAREA'].includes(e.target.nodeName);
|
const isInputTarget = (e) => ['INPUT', 'SELECT', 'TEXTAREA'].includes(e.target.nodeName);
|
||||||
|
|
||||||
export default NodeComponent => (props) => {
|
export default NodeComponent => (props) => {
|
||||||
const nodeElement = useRef(null);
|
const nodeElement = useRef(null);
|
||||||
const graphContext = useContext(GraphContext);
|
const { state, dispatch } = useContext(GraphContext);
|
||||||
const [offset, setOffset] = useState({ x: 0, y: 0 });
|
const [offset, setOffset] = useState({ x: 0, y: 0 });
|
||||||
|
|
||||||
const { data, onNodeClick, __rg } = props;
|
const { data, onNodeClick, __rg } = props;
|
||||||
const { position } = __rg;
|
const { position } = __rg;
|
||||||
const { id } = data;
|
const { id } = data;
|
||||||
const [ x, y, k ] = graphContext.state.transform;
|
const [ x, y, k ] = state.transform;
|
||||||
const selected = graphContext.state.selectedNodeIds.includes(id);
|
const selected = state.selectedNodeIds.includes(id);
|
||||||
const nodeClasses = cx('react-graph__node', { selected });
|
const nodeClasses = cx('react-graph__node', { selected });
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -24,7 +24,7 @@ export default NodeComponent => (props) => {
|
|||||||
const unscaledWith = Math.round(bounds.width * (1 / k));
|
const unscaledWith = Math.round(bounds.width * (1 / k));
|
||||||
const unscaledHeight = Math.round(bounds.height * (1 / k));
|
const unscaledHeight = Math.round(bounds.height * (1 / k));
|
||||||
|
|
||||||
graphContext.dispatch(updateNodeData(id, { width: unscaledWith, height: unscaledHeight }));
|
dispatch(updateNodeData(id, { width: unscaledWith, height: unscaledHeight }));
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -50,7 +50,7 @@ export default NodeComponent => (props) => {
|
|||||||
y: e.clientY * (1 / k)
|
y: e.clientY * (1 / k)
|
||||||
}
|
}
|
||||||
|
|
||||||
graphContext.dispatch(updateNodePos(id, {
|
dispatch(updateNodePos(id, {
|
||||||
x: unscaledPos.x - x - offset.x,
|
x: unscaledPos.x - x - offset.x,
|
||||||
y: unscaledPos.y - y - offset.y
|
y: unscaledPos.y - y - offset.y
|
||||||
}));
|
}));
|
||||||
@@ -65,6 +65,8 @@ export default NodeComponent => (props) => {
|
|||||||
if (isInputTarget(e)) {
|
if (isInputTarget(e)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dispatch(setSelectedNodesIds(id));
|
||||||
onNodeClick({ data, position });
|
onNodeClick({ data, position });
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|||||||
+7
-2
@@ -2,6 +2,7 @@ import React, { PureComponent } from 'react';
|
|||||||
|
|
||||||
import { parseElements, separateElements } from './graph-utils';
|
import { parseElements, separateElements } from './graph-utils';
|
||||||
import GraphView from './GraphView';
|
import GraphView from './GraphView';
|
||||||
|
import GlobalKeyHandler from './GlobalKeyHandler';
|
||||||
import { Provider } from './GraphContext';
|
import { Provider } from './GraphContext';
|
||||||
import { createNodeTypes } from './NodeRenderer/utils';
|
import { createNodeTypes } from './NodeRenderer/utils';
|
||||||
|
|
||||||
@@ -20,7 +21,7 @@ class ReactGraph extends PureComponent {
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
style, onNodeClick, children, onLoad, onMove, onChange, elements
|
style, onNodeClick, children, onLoad, onMove, onChange, elements, onNodeRemove
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
const { nodes, edges } = elements
|
const { nodes, edges } = elements
|
||||||
@@ -36,6 +37,9 @@ class ReactGraph extends PureComponent {
|
|||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
nodeTypes={this.nodeTypes}
|
nodeTypes={this.nodeTypes}
|
||||||
/>
|
/>
|
||||||
|
<GlobalKeyHandler
|
||||||
|
onNodeRemove={onNodeRemove}
|
||||||
|
/>
|
||||||
{children}
|
{children}
|
||||||
</Provider>
|
</Provider>
|
||||||
</div>
|
</div>
|
||||||
@@ -44,7 +48,8 @@ class ReactGraph extends PureComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ReactGraph.defaultProps = {
|
ReactGraph.defaultProps = {
|
||||||
onNodeClick: () => {},
|
onNodeClick: () => {},
|
||||||
|
onNodeRemove: () => {},
|
||||||
onLoad: () => {},
|
onLoad: () => {},
|
||||||
onMove: () => {},
|
onMove: () => {},
|
||||||
onChange: () => {},
|
onChange: () => {},
|
||||||
|
|||||||
+14
-1
@@ -1,7 +1,8 @@
|
|||||||
import {
|
import {
|
||||||
UPDATE_TRANSFORM, UPDATE_SIZE, SET_NODES, SET_EDGES,
|
UPDATE_TRANSFORM, UPDATE_SIZE, SET_NODES, SET_EDGES,
|
||||||
UPDATE_NODE_DATA, UPDATE_NODE_POS, INIT_D3, FIT_VIEW,
|
UPDATE_NODE_DATA, UPDATE_NODE_POS, INIT_D3, FIT_VIEW,
|
||||||
UPDATE_SELECTION, SET_SELECTION, SET_NODES_SELECTION
|
UPDATE_SELECTION, SET_SELECTION, SET_NODES_SELECTION,
|
||||||
|
SET_SELECTED_NODES_IDS, REMOVE_NODES
|
||||||
} from './index';
|
} from './index';
|
||||||
|
|
||||||
export const updateTransform = (transform) => {
|
export const updateTransform = (transform) => {
|
||||||
@@ -65,6 +66,18 @@ export const setNodesSelection = ({ isActive, selection }) => {
|
|||||||
return { type: SET_NODES_SELECTION, payload: { nodesSelectionActive: isActive, selection } };
|
return { type: SET_NODES_SELECTION, payload: { nodesSelectionActive: isActive, selection } };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const setSelectedNodesIds = (ids) => {
|
||||||
|
const idArray = Array.isArray(ids) ? ids : [ids];
|
||||||
|
|
||||||
|
return { type: SET_SELECTED_NODES_IDS, payload: { selectedNodeIds: idArray } };
|
||||||
|
};
|
||||||
|
|
||||||
|
export const removeNodes = (ids) => {
|
||||||
|
const idArray = Array.isArray(ids) ? ids : [ids];
|
||||||
|
|
||||||
|
return { type: REMOVE_NODES, payload: { ids: idArray } };
|
||||||
|
}
|
||||||
|
|
||||||
export const updateSelection = (selection) => {
|
export const updateSelection = (selection) => {
|
||||||
return {
|
return {
|
||||||
type: UPDATE_SELECTION,
|
type: UPDATE_SELECTION,
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ export const FIT_VIEW = 'FIT_VIEW';
|
|||||||
export const UPDATE_SELECTION = 'UPDATE_SELECTION';
|
export const UPDATE_SELECTION = 'UPDATE_SELECTION';
|
||||||
export const SET_SELECTION = 'SET_SELECTION';
|
export const SET_SELECTION = 'SET_SELECTION';
|
||||||
export const SET_NODES_SELECTION = 'SET_NODES_SELECTION';
|
export const SET_NODES_SELECTION = 'SET_NODES_SELECTION';
|
||||||
|
export const SET_SELECTED_NODES_IDS = 'SET_SELECTED_NODES_IDS';
|
||||||
|
export const REMOVE_NODES = 'REMOVE_NODES';
|
||||||
|
|
||||||
export const initialState = {
|
export const initialState = {
|
||||||
width: 0,
|
width: 0,
|
||||||
@@ -98,12 +100,24 @@ export const reducer = (state, action) => {
|
|||||||
|
|
||||||
return { ...state, ...action.payload, selectedNodesBbox };
|
return { ...state, ...action.payload, selectedNodesBbox };
|
||||||
}
|
}
|
||||||
|
case REMOVE_NODES: {
|
||||||
|
const { ids } = action.payload;
|
||||||
|
const nextEdges = state.edges.filter(e => !ids.includes(e.data.target) && !ids.includes(e.data.source));
|
||||||
|
const nextNodes = state.nodes.filter(n => !ids.includes(n.data.id));
|
||||||
|
|
||||||
|
console.log(ids,);
|
||||||
|
console.log( state.edges, nextEdges, );
|
||||||
|
console.log(state.nodes, nextNodes);
|
||||||
|
|
||||||
|
return { ...state, nodes: nextNodes, edges: nextEdges };
|
||||||
|
}
|
||||||
case SET_NODES:
|
case SET_NODES:
|
||||||
case SET_EDGES:
|
case SET_EDGES:
|
||||||
case UPDATE_TRANSFORM:
|
case UPDATE_TRANSFORM:
|
||||||
case INIT_D3:
|
case INIT_D3:
|
||||||
case UPDATE_SIZE:
|
case UPDATE_SIZE:
|
||||||
case SET_SELECTION:
|
case SET_SELECTION:
|
||||||
|
case SET_SELECTED_NODES_IDS:
|
||||||
return { ...state, ...action.payload };
|
return { ...state, ...action.payload };
|
||||||
default:
|
default:
|
||||||
return state;
|
return state;
|
||||||
|
|||||||
Reference in New Issue
Block a user