Browse Source

feat: add label to edge when imove-branch node is connected and remove label from edge when the edge is deleted

master
smallstonesk 4 years ago
parent
commit
796a0dfa45
  1. 2
      packages/core/package.json
  2. 21
      packages/core/src/common/shortcuts.ts
  3. 17
      packages/core/src/index.tsx
  4. 61
      packages/core/src/mods/flowChart/createFlowChart.ts
  5. 4
      packages/core/src/mods/flowChart/index.tsx
  6. 2
      packages/core/src/utils/index.ts

2
packages/core/package.json

@ -37,7 +37,7 @@
},
"dependencies": {
"@ant-design/icons": "^4.0.6",
"@antv/x6": "^0.10.59",
"@antv/x6": "^0.10.63",
"ace-builds": "^1.4.12",
"antd": "^4.5.3",
"react-ace": "^9.1.3",

21
packages/core/src/common/shortcuts.ts

@ -1,6 +1,6 @@
import {Graph} from '@antv/x6';
import {safeGet} from '../utils';
import {localSave} from '../api';
import {Cell, Edge, Graph, Node} from '@antv/x6';
interface Shortcut {
keys: string | string[];
@ -73,6 +73,25 @@ const shortcuts: {[key: string]: Shortcut} = {
delete: {
keys: ['backspace', 'del'],
handler(flowChart: Graph) {
const toDelCells = flowChart.getSelectedCells();
const onEdgeDel = (edge: Edge) => {
const srcNode = edge.getSourceNode() as Node;
const isSrcNodeInDelCells = !!toDelCells.find(c => c === srcNode);
if(srcNode && srcNode.shape === 'imove-branch' && !isSrcNodeInDelCells) {
const portId = edge.getSourcePortId();
if(portId === 'right' || portId === 'bottom') {
const edgeLabel = safeGet(edge.getLabelAt(0), 'attrs.label.text', '');
srcNode.setPortProp(portId, 'attrs/text/text', edgeLabel);
}
}
};
toDelCells.forEach((cell: Cell) => {
if(cell.isEdge()) {
onEdgeDel(cell);
} else {
flowChart.getConnectedEdges(cell).forEach(onEdgeDel);
}
});
flowChart.removeCells(flowChart.getSelectedCells());
flowChart.trigger('toolBar:forceUpdate');
return false;

17
packages/core/src/index.tsx

@ -15,22 +15,9 @@ interface IProps {
}
const Core: React.FC<IProps> = props => {
const {onSave} = props;
const [flowChart, setGraph] = useState<Graph>();
const onFlowChartReady = (flowChart: Graph): void => {
setGraph(flowChart);
flowChart.on('node:added', (args) => {
flowChart.cleanSelection();
flowChart.select(args.cell);
});
flowChart.on('selection:changed', () => {
flowChart.trigger('toolBar:forceUpdate');
flowChart.trigger('settingBar:forceUpdate');
});
};
const [flowChart, setFlowChart] = useState<Graph>();
const onFlowChartReady = (flowChart: Graph): void => setFlowChart(flowChart);
return (
<Layout
flowChart={flowChart}

61
packages/core/src/utils/createGraph.ts → packages/core/src/mods/flowChart/createFlowChart.ts

@ -1,8 +1,8 @@
import {Graph, Cell} from '@antv/x6';
import shortcuts from '../common/shortcuts';
import baseCellSchemaMap from '../common/baseCell';
import previewCellSchemaMap from '../common/previewCell';
import MiniMapSimpleNode from '../components/miniMapSimpleNode';
import shortcuts from '../../common/shortcuts';
import {Cell, Edge, Graph, Node} from '@antv/x6';
import baseCellSchemaMap from '../../common/baseCell';
import previewCellSchemaMap from '../../common/previewCell';
import MiniMapSimpleNode from '../../components/miniMapSimpleNode';
// X6 register base/preview cell shape
[baseCellSchemaMap, previewCellSchemaMap]
@ -11,13 +11,37 @@ import MiniMapSimpleNode from '../components/miniMapSimpleNode';
base.define(rest);
}));
const createGraph = (container: HTMLDivElement, miniMapContainer: HTMLDivElement): Graph => {
const registerEvents = (flowChart: Graph): void => {
flowChart.on('node:added', (args) => {
flowChart.cleanSelection();
flowChart.select(args.cell);
});
flowChart.on('selection:changed', () => {
flowChart.trigger('toolBar:forceUpdate');
flowChart.trigger('settingBar:forceUpdate');
});
flowChart.on("edge:connected", (args) => {
const edge = args.edge as Edge;
const sourceNode = edge.getSourceNode() as Node;
if(sourceNode && sourceNode.shape === 'imove-branch') {
const portId = edge.getSourcePortId();
if(portId === 'right' || portId === 'bottom') {
edge.setLabelAt(0, sourceNode.getPortProp(portId, 'attrs/text/text'));
sourceNode.setPortProp(portId, 'attrs/text/text', '');
}
}
});
};
// NOTE: calculate the width/height ratio of flowchart
const ratio = container.offsetWidth / container.offsetHeight;
const registerShortcuts = (flowChart: Graph): void => {
Object.values(shortcuts).forEach(shortcut => {
const {keys, handler} = shortcut;
flowChart.bindKey(keys, () => handler(flowChart));
});
};
// create graph instance
const graph = new Graph({
const createFlowChart = (container: HTMLDivElement, miniMapContainer: HTMLDivElement): Graph => {
const flowChart = new Graph({
container,
rotating: false,
resizing: true,
@ -66,7 +90,7 @@ const createGraph = (container: HTMLDivElement, miniMapContainer: HTMLDivElement
},
// https://x6.antv.vision/zh/docs/tutorial/basic/minimap
minimap: {
width: 150 * ratio,
width: 150 * container.offsetWidth / container.offsetHeight,
height: 150,
minScale: 0.5,
maxScale: 1.5,
@ -92,14 +116,9 @@ const createGraph = (container: HTMLDivElement, miniMapContainer: HTMLDivElement
enabled: true
}
});
registerEvents(flowChart);
registerShortcuts(flowChart);
return flowChart;
};
// register shortcuts
Object.values(shortcuts).forEach(shortcut => {
const {keys, handler} = shortcut;
graph.bindKey(keys, () => handler(graph));
});
return graph;
}
export default createGraph;
export default createFlowChart;

4
packages/core/src/mods/flowChart/index.tsx

@ -3,7 +3,7 @@ import React, {useRef, useEffect} from 'react';
import styles from './index.module.less';
import {Graph} from '@antv/x6';
import createGraph from '../../utils/createGraph';
import createFlowChart from './createFlowChart';
interface IProps {
onReady: (graph: Graph) => void;
@ -15,7 +15,7 @@ const FlowChart: React.FC<IProps> = props => {
const miniMapRef = useRef<HTMLDivElement>(null);
useEffect(() => {
if(graphRef.current && miniMapRef.current) {
const graph = createGraph(graphRef.current, miniMapRef.current);
const graph = createFlowChart(graphRef.current, miniMapRef.current);
onReady(graph);
}
}, []);

2
packages/core/src/utils/index.ts

@ -6,7 +6,7 @@ export const safeParse = (json: string): Object => {
}
};
export const safeGet = (obj: any, keyChain: string, defaultVal: any): any => {
export const safeGet = (obj: any, keyChain: string, defaultVal?: any): any => {
if(typeof obj !== 'object' || obj === null) {
return defaultVal;

Loading…
Cancel
Save