Select & delete edges
This commit is contained in:
parent
1c5f7e017e
commit
a507e1a6c3
|
@ -16,6 +16,10 @@ module.exports = createActionCreators({
|
|||
MOVE_SOURCE_OUTPUT: (sourceOutputIndex, destSourceIndex) => ({ sourceOutputIndex, destSourceIndex }),
|
||||
|
||||
KILL_CLIENT_BY_INDEX: clientIndex => ({ clientIndex }),
|
||||
|
||||
KILL_SINK_INPUT_BY_INDEX: sinkInputIndex => ({ sinkInputIndex }),
|
||||
KILL_SOURCE_OUTPUT_BY_INDEX: sourceOutputIndex => ({ sourceOutputIndex }),
|
||||
|
||||
UNLOAD_MODULE_BY_INDEX: moduleIndex => ({ moduleIndex }),
|
||||
},
|
||||
});
|
||||
|
|
|
@ -101,7 +101,7 @@ class Edge extends EdgeBase {
|
|||
});
|
||||
|
||||
return r.g({
|
||||
className: 'edge-container',
|
||||
className: 'edge-container ' + (this.props.className || ''),
|
||||
'data-source': data.source,
|
||||
'data-target': data.target,
|
||||
}, [
|
||||
|
|
|
@ -148,6 +148,19 @@ const Module = Client;
|
|||
|
||||
const gridDotSize = 2;
|
||||
const gridSpacing = 36;
|
||||
|
||||
const Marker = ({ id, d }) => r('marker', {
|
||||
id,
|
||||
viewBox: '0 -8 16 16',
|
||||
refX: '16',
|
||||
markerWidth: '16',
|
||||
markerHeight: '16',
|
||||
orient: 'auto',
|
||||
}, r.path({
|
||||
className: 'arrow',
|
||||
d,
|
||||
}));
|
||||
|
||||
const renderDefs = () => r(React.Fragment, [
|
||||
r.pattern({
|
||||
id: 'background-pattern',
|
||||
|
@ -162,29 +175,26 @@ const renderDefs = () => r(React.Fragment, [
|
|||
r: gridDotSize,
|
||||
})),
|
||||
|
||||
r('marker', {
|
||||
r(Marker, {
|
||||
id: 'my-source-arrow',
|
||||
viewBox: '0 -8 16 16',
|
||||
refX: '16',
|
||||
markerWidth: '16',
|
||||
markerHeight: '16',
|
||||
orient: 'auto',
|
||||
}, r.path({
|
||||
className: 'arrow',
|
||||
d: 'M 16,-8 L 0,0 L 16,8',
|
||||
})),
|
||||
}),
|
||||
|
||||
r('marker', {
|
||||
r(Marker, {
|
||||
id: 'my-sink-arrow',
|
||||
viewBox: '0 -8 16 16',
|
||||
refX: '16',
|
||||
markerWidth: '16',
|
||||
markerHeight: '16',
|
||||
orient: 'auto',
|
||||
}, r.path({
|
||||
className: 'arrow',
|
||||
d: 'M 0,-8 L 16,0 L 0,8',
|
||||
})),
|
||||
}),
|
||||
|
||||
// WORKAROUND: `context-fill` did not work
|
||||
r(Marker, {
|
||||
id: 'my-source-arrow-selected',
|
||||
d: 'M 16,-8 L 0,0 L 16,8',
|
||||
}),
|
||||
|
||||
r(Marker, {
|
||||
id: 'my-sink-arrow-selected',
|
||||
d: 'M 0,-8 L 16,0 L 0,8',
|
||||
}),
|
||||
]);
|
||||
|
||||
const renderNode = (nodeRef, data, key, selected, hovered) => r({
|
||||
|
@ -262,13 +272,12 @@ const renderNodeText = state => dgo => r('foreignObject', {
|
|||
state,
|
||||
})));
|
||||
|
||||
const afterRenderEdge = (id, element, edge, edgeContainer) => {
|
||||
if (edge.type) {
|
||||
edgeContainer.classList.add(edge.type);
|
||||
}
|
||||
};
|
||||
|
||||
const renderEdge = edgeProps => r(Edge, edgeProps);
|
||||
const renderEdge = props => r(Edge, {
|
||||
classSet: {
|
||||
[props.data.type]: true,
|
||||
},
|
||||
...props,
|
||||
});
|
||||
|
||||
const renderEdgeText = state => ({ data, transform }) => r('foreignObject', {
|
||||
transform,
|
||||
|
@ -361,7 +370,8 @@ class Graph extends React.Component {
|
|||
}
|
||||
}
|
||||
|
||||
onSelectEdge() {
|
||||
onSelectEdge(selected) {
|
||||
this.setState({ selected });
|
||||
}
|
||||
|
||||
onCreateEdge() {
|
||||
|
@ -375,7 +385,12 @@ class Graph extends React.Component {
|
|||
}
|
||||
}
|
||||
|
||||
onDeleteEdge() {
|
||||
onDeleteEdge(selected) {
|
||||
if (selected.type === 'sinkInput') {
|
||||
this.props.killSinkInputByIndex(selected.index);
|
||||
} else if (selected.type === 'sourceOutput') {
|
||||
this.props.killSourceOutputByIndex(selected.index);
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
|
@ -488,7 +503,7 @@ class Graph extends React.Component {
|
|||
|
||||
showGraphControls: false,
|
||||
|
||||
edgeArrowSize: 128,
|
||||
edgeArrowSize: 64,
|
||||
|
||||
backgroundFillId: '#background-pattern',
|
||||
|
||||
|
@ -499,8 +514,6 @@ class Graph extends React.Component {
|
|||
|
||||
renderEdge,
|
||||
renderEdgeText: renderEdgeText(this.props),
|
||||
|
||||
afterRenderEdge,
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,6 +43,8 @@ class GraphView extends React.Component {
|
|||
onSwapEdge: this.onSwapEdge.bind(this),
|
||||
onNodeMove: this.onNodeMove.bind(this),
|
||||
|
||||
onSelectEdge: this.onSelectEdge.bind(this),
|
||||
|
||||
renderNode: this.renderNode.bind(this),
|
||||
renderNodeText: this.renderNodeText.bind(this),
|
||||
|
||||
|
@ -96,6 +98,11 @@ class GraphView extends React.Component {
|
|||
}
|
||||
}
|
||||
|
||||
onSelectEdge(edge) {
|
||||
const originalEdge = satelliteEdgeToOriginalEdge.get(edge);
|
||||
this.props.onSelectEdge(originalEdge);
|
||||
}
|
||||
|
||||
renderNode(nodeRef, dgo, key, selected, hovered) {
|
||||
if (dgo.type !== 'satellite') {
|
||||
return this.props.renderNode(nodeRef, dgo, key, selected, hovered);
|
||||
|
@ -127,6 +134,8 @@ class GraphView extends React.Component {
|
|||
return satelliteNodes.concat(node);
|
||||
}, this.props.nodes));
|
||||
|
||||
let { selected } = this.props;
|
||||
|
||||
const edges = flatten(values(mapObjIndexed((edges, target) => mapIndexed((edge, i) => {
|
||||
const satelliteEdge = {
|
||||
id: edge.id,
|
||||
|
@ -136,6 +145,11 @@ class GraphView extends React.Component {
|
|||
index: edge.index,
|
||||
type: edge.type,
|
||||
};
|
||||
|
||||
if (edge === selected) {
|
||||
selected = satelliteEdge;
|
||||
}
|
||||
|
||||
satelliteEdgeToOriginalEdge.set(satelliteEdge, edge);
|
||||
return satelliteEdge;
|
||||
}, edges), edgesByTargetNodeKey)));
|
||||
|
@ -143,6 +157,8 @@ class GraphView extends React.Component {
|
|||
return r(GraphViewBase, {
|
||||
...this.props,
|
||||
|
||||
selected,
|
||||
|
||||
ref: this.graph,
|
||||
|
||||
nodes,
|
||||
|
@ -151,10 +167,12 @@ class GraphView extends React.Component {
|
|||
onSwapEdge: this.onSwapEdge,
|
||||
onNodeMove: this.onNodeMove,
|
||||
|
||||
onSelectEdge: this.onSelectEdge,
|
||||
|
||||
renderNode: this.renderNode,
|
||||
renderNodeText: this.renderNodeText,
|
||||
|
||||
afterRenderEdge: this.afterRenderEdge,
|
||||
afterRenderEdge: this.props.afterRenderEdge && this.afterRenderEdge,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
16
index.css
16
index.css
|
@ -63,15 +63,27 @@ button:active {
|
|||
color: var(--themeSelectedFgColor);
|
||||
}
|
||||
|
||||
.view-wrapper .graph .edge.selected {
|
||||
stroke: var(--themeSelectedBgColor);
|
||||
}
|
||||
|
||||
#my-source-arrow-selected > .arrow, #my-sink-arrow-selected > .arrow {
|
||||
fill: var(--themeSelectedBgColor);
|
||||
}
|
||||
|
||||
.view-wrapper .sourceOutput .edge {
|
||||
/* marker-end: none; */
|
||||
/* marker-start: url(#start-arrow); */
|
||||
marker-end: url(#my-source-arrow);
|
||||
}
|
||||
.view-wrapper .sourceOutput .edge.selected {
|
||||
marker-end: url(#my-source-arrow-selected);
|
||||
}
|
||||
|
||||
.view-wrapper .sinkInput .edge {
|
||||
marker-end: url(#my-sink-arrow);
|
||||
}
|
||||
.view-wrapper .sinkInput .edge.selected {
|
||||
marker-end: url(#my-sink-arrow-selected);
|
||||
}
|
||||
|
||||
#edge-custom-container .edge {
|
||||
marker-end: none;
|
||||
|
|
|
@ -109,10 +109,21 @@ module.exports = store => {
|
|||
pa.moveSourceOutput(sourceOutputIndex, destSourceIndex, rethrow);
|
||||
return state;
|
||||
},
|
||||
|
||||
[pulseActions.killClientByIndex]: (state, { payload: { clientIndex } }) => {
|
||||
pa.killClientByIndex(clientIndex, rethrow);
|
||||
return state;
|
||||
},
|
||||
|
||||
[pulseActions.killSinkInputByIndex]: (state, { payload: { sinkInputIndex } }) => {
|
||||
pa.killSinkInputByIndex(sinkInputIndex, rethrow);
|
||||
return state;
|
||||
},
|
||||
[pulseActions.killSourceOutputByIndex]: (state, { payload: { sourceOutputIndex } }) => {
|
||||
pa.killSourceOutputByIndex(sourceOutputIndex, rethrow);
|
||||
return state;
|
||||
},
|
||||
|
||||
[pulseActions.unloadModuleByIndex]: (state, { payload: { moduleIndex } }) => {
|
||||
pa.unloadModuleByIndex(moduleIndex, rethrow);
|
||||
return state;
|
||||
|
|
Loading…
Reference in New Issue
Block a user