| | |
| | | "react": "^18.2.0", |
| | | "react-dom": "^18.2.0", |
| | | "react-helmet-async": "^1.3.0", |
| | | "react-syntax-highlighter": "^15.5.0", |
| | | "tweedle.js": "^2.1.0" |
| | | }, |
| | | "devDependencies": { |
| | |
| | | "jest-environment-jsdom": "^29.7.0", |
| | | "lint-staged": "^10.5.4", |
| | | "mockjs": "^1.1.0", |
| | | "prettier": "^2.8.8", |
| | | "react-dev-inspector": "^1.9.0", |
| | | "swagger-ui-dist": "^4.19.1", |
| | | "ts-node": "^10.9.2", |
New file |
| | |
| | | .graphDrawerContainer { |
| | | margin-top: 10px; |
| | | margin-bottom: 10px; |
| | | } |
| | | |
| | | .graphDrawerContainer>div { |
| | | margin-top: 10px; |
| | | } |
| | |
| | | import { Stencil } from '@antv/x6-plugin-stencil'; |
| | | import { History } from '@antv/x6-plugin-history' |
| | | import { Transform } from '@antv/x6-plugin-transform' |
| | | import { commonGraphPorts, commonGraphAttrs, initGraphConnecting } from "./GraphConfig"; |
| | | import { commonGraphPorts, commonGraphAttrs, initGraphConnecting, initNodeData } from "./GraphConfig"; |
| | | |
| | | export const GraphComponent = React.forwardRef((props, ref) => { |
| | | const container = useRef(null); |
| | |
| | | label: '订单管理', |
| | | ports: commonGraphPorts, |
| | | attrs: commonGraphAttrs, |
| | | data: initNodeData, |
| | | }); |
| | | |
| | | const rect2 = graph.addNode({ |
| | |
| | | label: '库存管理', |
| | | ports: commonGraphPorts, |
| | | attrs: commonGraphAttrs, |
| | | data: initNodeData, |
| | | }); |
| | | |
| | | graph.use( |
| | |
| | | |
| | | graph.use( |
| | | new Transform({ |
| | | resizing: { |
| | | enabled: true |
| | | }, |
| | | resizing: { |
| | | enabled: true |
| | | }, |
| | | }), |
| | | ) |
| | | ) |
| | | |
| | | |
| | | graph.fromJSON({ |
| | | "cells": [ |
| | | { |
| | | "shape": "edge", |
| | | "attrs": { |
| | | "line": { |
| | | "stroke": "#A2B1C3", |
| | | "targetMarker": { |
| | | "name": "block", |
| | | "width": 12, |
| | | "height": 8 |
| | | } |
| | | } |
| | | }, |
| | | "id": "2475ea4f-f0e3-4b44-add4-7d4950ddea45", |
| | | "zIndex": 0, |
| | | "source": { |
| | | "cell": "71d8bc90-558f-489f-b432-a03d7af27cdc", |
| | | "port": "port2" |
| | | }, |
| | | "target": { |
| | | "cell": "c5798537-a8a0-4d79-bd76-a4f663492126", |
| | | "port": "port1" |
| | | }, |
| | | "data": { |
| | | "codeContent": null, |
| | | "root": false, |
| | | "isLogic": false, |
| | | "logicBool": false, |
| | | "searchLogicId": 1, |
| | | "searchLogicBool": true, |
| | | "searchIndex": 0 |
| | | }, |
| | | "labels": [ |
| | | { |
| | | "attrs": { |
| | | "label": { |
| | | "text": "" |
| | | } |
| | | } |
| | | } |
| | | ] |
| | | }, |
| | | { |
| | | "shape": "edge", |
| | | "attrs": { |
| | | "line": { |
| | | "stroke": "#A2B1C3", |
| | | "targetMarker": { |
| | | "name": "block", |
| | | "width": 12, |
| | | "height": 8 |
| | | } |
| | | } |
| | | }, |
| | | "id": "2c3744b4-45ce-44a6-b169-402eaec24174", |
| | | "zIndex": 0, |
| | | "source": { |
| | | "cell": "c5798537-a8a0-4d79-bd76-a4f663492126", |
| | | "port": "port2" |
| | | }, |
| | | "target": { |
| | | "cell": "3ca188b2-9ffe-4528-ba6e-c1568b6d7fe6", |
| | | "port": "port1" |
| | | }, |
| | | "data": { |
| | | "codeContent": null, |
| | | "root": false, |
| | | "isLogic": false, |
| | | "logicBool": false, |
| | | "searchLogicId": 1, |
| | | "searchLogicBool": true, |
| | | "searchIndex": 0 |
| | | }, |
| | | "labels": [ |
| | | { |
| | | "attrs": { |
| | | "label": { |
| | | "text": "" |
| | | } |
| | | } |
| | | } |
| | | ] |
| | | }, |
| | | { |
| | | "shape": "edge", |
| | | "attrs": { |
| | | "line": { |
| | | "stroke": "#A2B1C3", |
| | | "targetMarker": { |
| | | "name": "block", |
| | | "width": 12, |
| | | "height": 8 |
| | | } |
| | | } |
| | | }, |
| | | "id": "56181ccf-a41c-4cd8-82d6-e2a4bde31ba9", |
| | | "zIndex": 0, |
| | | "source": { |
| | | "cell": "3ca188b2-9ffe-4528-ba6e-c1568b6d7fe6", |
| | | "port": "port2" |
| | | }, |
| | | "target": { |
| | | "cell": "63db5ce0-b916-44e4-a924-a79b35afe1d1", |
| | | "port": "port1" |
| | | }, |
| | | "data": { |
| | | "codeContent": null, |
| | | "root": false, |
| | | "isLogic": false, |
| | | "logicBool": true, |
| | | "searchLogicId": 1, |
| | | "searchLogicBool": true, |
| | | "searchIndex": 0 |
| | | }, |
| | | "labels": [ |
| | | { |
| | | "attrs": { |
| | | "label": { |
| | | "text": "true" |
| | | } |
| | | } |
| | | } |
| | | ] |
| | | }, |
| | | { |
| | | "shape": "edge", |
| | | "attrs": { |
| | | "line": { |
| | | "stroke": "#A2B1C3", |
| | | "targetMarker": { |
| | | "name": "block", |
| | | "width": 12, |
| | | "height": 8 |
| | | } |
| | | } |
| | | }, |
| | | "id": "73ca24ef-e9d4-4f18-9f06-ca49ac65962a", |
| | | "zIndex": 0, |
| | | "source": { |
| | | "cell": "cc993d9b-ce11-409d-92c6-7208682dcc8b", |
| | | "port": "port4" |
| | | }, |
| | | "target": { |
| | | "cell": "06d450fc-474e-4b23-b40d-c89fde446b28", |
| | | "port": "port3" |
| | | }, |
| | | "data": { |
| | | "codeContent": null, |
| | | "root": false, |
| | | "isLogic": false, |
| | | "logicBool": false, |
| | | "searchLogicId": 1, |
| | | "searchLogicBool": true, |
| | | "searchIndex": 0 |
| | | }, |
| | | "labels": [ |
| | | { |
| | | "attrs": { |
| | | "label": { |
| | | "text": "false" |
| | | } |
| | | } |
| | | } |
| | | ] |
| | | }, |
| | | { |
| | | "shape": "edge", |
| | | "attrs": { |
| | | "line": { |
| | | "stroke": "#A2B1C3", |
| | | "targetMarker": { |
| | | "name": "block", |
| | | "width": 12, |
| | | "height": 8 |
| | | } |
| | | } |
| | | }, |
| | | "id": "84a3a77c-79e8-4cf8-9bab-a72bbfc77f1d", |
| | | "zIndex": 0, |
| | | "source": { |
| | | "cell": "cc993d9b-ce11-409d-92c6-7208682dcc8b", |
| | | "port": "port2" |
| | | }, |
| | | "target": { |
| | | "cell": "cd9da0a4-5c2d-4f1b-9c51-403b32f1ad51", |
| | | "port": "port1" |
| | | }, |
| | | "data": { |
| | | "codeContent": null, |
| | | "root": false, |
| | | "isLogic": false, |
| | | "logicBool": true, |
| | | "searchLogicId": 1, |
| | | "searchLogicBool": true, |
| | | "searchIndex": 0 |
| | | }, |
| | | "labels": [ |
| | | { |
| | | "attrs": { |
| | | "label": { |
| | | "text": "true" |
| | | } |
| | | } |
| | | } |
| | | ] |
| | | }, |
| | | { |
| | | "shape": "edge", |
| | | "attrs": { |
| | | "line": { |
| | | "stroke": "#A2B1C3", |
| | | "targetMarker": { |
| | | "name": "block", |
| | | "width": 12, |
| | | "height": 8 |
| | | } |
| | | } |
| | | }, |
| | | "id": "93d65ae7-f170-466a-92ea-f69614002800", |
| | | "zIndex": 0, |
| | | "source": { |
| | | "cell": "c844f3d1-02a3-47d3-bcb9-51027c1deb1c", |
| | | "port": "port2" |
| | | }, |
| | | "target": { |
| | | "cell": "cc993d9b-ce11-409d-92c6-7208682dcc8b", |
| | | "port": "port1" |
| | | }, |
| | | "data": { |
| | | "codeContent": null, |
| | | "root": false, |
| | | "isLogic": false, |
| | | "logicBool": false, |
| | | "searchLogicId": 1, |
| | | "searchLogicBool": true, |
| | | "searchIndex": 0 |
| | | }, |
| | | "labels": [ |
| | | { |
| | | "attrs": { |
| | | "label": { |
| | | "text": "" |
| | | } |
| | | } |
| | | } |
| | | ] |
| | | }, |
| | | { |
| | | "shape": "edge", |
| | | "attrs": { |
| | | "line": { |
| | | "stroke": "#A2B1C3", |
| | | "targetMarker": { |
| | | "name": "block", |
| | | "width": 12, |
| | | "height": 8 |
| | | } |
| | | } |
| | | }, |
| | | "id": "de85103e-80ac-4c88-92de-5bb1a131788c", |
| | | "zIndex": 0, |
| | | "source": { |
| | | "cell": "63db5ce0-b916-44e4-a924-a79b35afe1d1", |
| | | "port": "port2" |
| | | }, |
| | | "target": { |
| | | "cell": "c844f3d1-02a3-47d3-bcb9-51027c1deb1c", |
| | | "port": "port1" |
| | | }, |
| | | "data": { |
| | | "codeContent": null, |
| | | "root": false, |
| | | "isLogic": false, |
| | | "logicBool": false, |
| | | "searchLogicId": 1, |
| | | "searchLogicBool": true, |
| | | "searchIndex": 0 |
| | | }, |
| | | "labels": [ |
| | | { |
| | | "attrs": { |
| | | "label": { |
| | | "text": "" |
| | | } |
| | | } |
| | | } |
| | | ] |
| | | }, |
| | | { |
| | | "position": { |
| | | "x": 60, |
| | | "y": 60 |
| | | }, |
| | | "size": { |
| | | "width": 120, |
| | | "height": 40 |
| | | }, |
| | | "attrs": { |
| | | "text": { |
| | | "text": "订单管理" |
| | | }, |
| | | "body": { |
| | | "fill": "#efefef", |
| | | "stroke": "#4d4d4d", |
| | | "strokeWidth": 2, |
| | | "refD": "M 50 0 L 100 50 L 50 100 L 0 50 Z" |
| | | } |
| | | }, |
| | | "visible": true, |
| | | "shape": "rect", |
| | | "id": "a4962b5d-6ef0-4217-bbf8-742652ffc0ee", |
| | | "data": { |
| | | "codeContent": null, |
| | | "root": false, |
| | | "isLogic": false, |
| | | "logicBool": false, |
| | | "searchLogicId": 1, |
| | | "searchLogicBool": true, |
| | | "searchIndex": 0 |
| | | }, |
| | | "zIndex": 1, |
| | | "ports": { |
| | | "groups": { |
| | | "top": { |
| | | "position": "top", |
| | | "attrs": { |
| | | "circle": { |
| | | "r": 5, |
| | | "magnet": true, |
| | | "stroke": "#5F95FF", |
| | | "strokeWidth": 1, |
| | | "fill": "#fff", |
| | | "style": { |
| | | "visibility": "hidden" |
| | | } |
| | | } |
| | | } |
| | | }, |
| | | "bottom": { |
| | | "position": "bottom", |
| | | "attrs": { |
| | | "circle": { |
| | | "r": 5, |
| | | "magnet": true, |
| | | "stroke": "#5F95FF", |
| | | "strokeWidth": 1, |
| | | "fill": "#fff", |
| | | "style": { |
| | | "visibility": "hidden" |
| | | } |
| | | } |
| | | } |
| | | }, |
| | | "left": { |
| | | "position": "left", |
| | | "attrs": { |
| | | "circle": { |
| | | "r": 5, |
| | | "magnet": true, |
| | | "stroke": "#5F95FF", |
| | | "strokeWidth": 1, |
| | | "fill": "#fff", |
| | | "style": { |
| | | "visibility": "hidden" |
| | | } |
| | | } |
| | | } |
| | | }, |
| | | "right": { |
| | | "position": "right", |
| | | "attrs": { |
| | | "circle": { |
| | | "r": 5, |
| | | "magnet": true, |
| | | "stroke": "#5F95FF", |
| | | "strokeWidth": 1, |
| | | "fill": "#fff", |
| | | "style": { |
| | | "visibility": "hidden" |
| | | } |
| | | } |
| | | } |
| | | } |
| | | }, |
| | | "items": [ |
| | | { |
| | | "id": "port1", |
| | | "group": "top" |
| | | }, |
| | | { |
| | | "id": "port2", |
| | | "group": "bottom" |
| | | }, |
| | | { |
| | | "id": "port3", |
| | | "group": "left" |
| | | }, |
| | | { |
| | | "id": "port4", |
| | | "group": "right" |
| | | } |
| | | ] |
| | | } |
| | | }, |
| | | { |
| | | "position": { |
| | | "x": 260, |
| | | "y": 390 |
| | | }, |
| | | "size": { |
| | | "width": 120, |
| | | "height": 40 |
| | | }, |
| | | "attrs": { |
| | | "text": { |
| | | "text": "库存管理" |
| | | }, |
| | | "body": { |
| | | "fill": "#efefef", |
| | | "stroke": "#4d4d4d", |
| | | "strokeWidth": 2, |
| | | "refD": "M 50 0 L 100 50 L 50 100 L 0 50 Z" |
| | | } |
| | | }, |
| | | "visible": true, |
| | | "shape": "rect", |
| | | "id": "63db5ce0-b916-44e4-a924-a79b35afe1d1", |
| | | "data": { |
| | | "codeContent": "2222", |
| | | "root": false, |
| | | "isLogic": false, |
| | | "logicBool": false, |
| | | "searchLogicId": 1, |
| | | "searchLogicBool": true, |
| | | "searchIndex": 0 |
| | | }, |
| | | "zIndex": 2, |
| | | "ports": { |
| | | "groups": { |
| | | "top": { |
| | | "position": "top", |
| | | "attrs": { |
| | | "circle": { |
| | | "r": 5, |
| | | "magnet": true, |
| | | "stroke": "#5F95FF", |
| | | "strokeWidth": 1, |
| | | "fill": "#fff", |
| | | "style": { |
| | | "visibility": "hidden" |
| | | } |
| | | } |
| | | } |
| | | }, |
| | | "bottom": { |
| | | "position": "bottom", |
| | | "attrs": { |
| | | "circle": { |
| | | "r": 5, |
| | | "magnet": true, |
| | | "stroke": "#5F95FF", |
| | | "strokeWidth": 1, |
| | | "fill": "#fff", |
| | | "style": { |
| | | "visibility": "hidden" |
| | | } |
| | | } |
| | | } |
| | | }, |
| | | "left": { |
| | | "position": "left", |
| | | "attrs": { |
| | | "circle": { |
| | | "r": 5, |
| | | "magnet": true, |
| | | "stroke": "#5F95FF", |
| | | "strokeWidth": 1, |
| | | "fill": "#fff", |
| | | "style": { |
| | | "visibility": "hidden" |
| | | } |
| | | } |
| | | } |
| | | }, |
| | | "right": { |
| | | "position": "right", |
| | | "attrs": { |
| | | "circle": { |
| | | "r": 5, |
| | | "magnet": true, |
| | | "stroke": "#5F95FF", |
| | | "strokeWidth": 1, |
| | | "fill": "#fff", |
| | | "style": { |
| | | "visibility": "hidden" |
| | | } |
| | | } |
| | | } |
| | | } |
| | | }, |
| | | "items": [ |
| | | { |
| | | "id": "port1", |
| | | "group": "top" |
| | | }, |
| | | { |
| | | "id": "port2", |
| | | "group": "bottom" |
| | | }, |
| | | { |
| | | "id": "port3", |
| | | "group": "left" |
| | | }, |
| | | { |
| | | "id": "port4", |
| | | "group": "right" |
| | | } |
| | | ] |
| | | } |
| | | }, |
| | | { |
| | | "position": { |
| | | "x": 270, |
| | | "y": 265 |
| | | }, |
| | | "size": { |
| | | "width": 100, |
| | | "height": 60 |
| | | }, |
| | | "attrs": { |
| | | "text": { |
| | | "text": "逻辑判断1" |
| | | }, |
| | | "body": { |
| | | "fill": "#efefef", |
| | | "stroke": "#4d4d4d", |
| | | "refD": "M 50 0 L 100 50 L 50 100 L 0 50 Z" |
| | | } |
| | | }, |
| | | "visible": true, |
| | | "shape": "path", |
| | | "id": "3ca188b2-9ffe-4528-ba6e-c1568b6d7fe6", |
| | | "data": { |
| | | "codeContent": "逻辑判断1", |
| | | "root": false, |
| | | "isLogic": true, |
| | | "logicBool": false, |
| | | "searchLogicId": 1, |
| | | "searchLogicBool": true, |
| | | "searchIndex": 0 |
| | | }, |
| | | "zIndex": 3, |
| | | "ports": { |
| | | "groups": { |
| | | "top": { |
| | | "position": "top", |
| | | "attrs": { |
| | | "circle": { |
| | | "r": 5, |
| | | "magnet": true, |
| | | "stroke": "#5F95FF", |
| | | "strokeWidth": 1, |
| | | "fill": "#fff", |
| | | "style": { |
| | | "visibility": "hidden" |
| | | } |
| | | } |
| | | } |
| | | }, |
| | | "bottom": { |
| | | "position": "bottom", |
| | | "attrs": { |
| | | "circle": { |
| | | "r": 5, |
| | | "magnet": true, |
| | | "stroke": "#5F95FF", |
| | | "strokeWidth": 1, |
| | | "fill": "#fff", |
| | | "style": { |
| | | "visibility": "hidden" |
| | | } |
| | | } |
| | | } |
| | | }, |
| | | "left": { |
| | | "position": "left", |
| | | "attrs": { |
| | | "circle": { |
| | | "r": 5, |
| | | "magnet": true, |
| | | "stroke": "#5F95FF", |
| | | "strokeWidth": 1, |
| | | "fill": "#fff", |
| | | "style": { |
| | | "visibility": "hidden" |
| | | } |
| | | } |
| | | } |
| | | }, |
| | | "right": { |
| | | "position": "right", |
| | | "attrs": { |
| | | "circle": { |
| | | "r": 5, |
| | | "magnet": true, |
| | | "stroke": "#5F95FF", |
| | | "strokeWidth": 1, |
| | | "fill": "#fff", |
| | | "style": { |
| | | "visibility": "hidden" |
| | | } |
| | | } |
| | | } |
| | | } |
| | | }, |
| | | "items": [ |
| | | { |
| | | "id": "port1", |
| | | "group": "top" |
| | | }, |
| | | { |
| | | "id": "port2", |
| | | "group": "bottom" |
| | | }, |
| | | { |
| | | "id": "port3", |
| | | "group": "left" |
| | | }, |
| | | { |
| | | "id": "port4", |
| | | "group": "right" |
| | | } |
| | | ] |
| | | } |
| | | }, |
| | | { |
| | | "position": { |
| | | "x": 300, |
| | | "y": 30 |
| | | }, |
| | | "size": { |
| | | "width": 80, |
| | | "height": 40 |
| | | }, |
| | | "attrs": { |
| | | "text": { |
| | | "text": "程序入口" |
| | | }, |
| | | "body": { |
| | | "fill": "#efefef", |
| | | "stroke": "#4d4d4d", |
| | | "strokeWidth": 2, |
| | | "refD": "M 50 0 L 100 50 L 50 100 L 0 50 Z" |
| | | } |
| | | }, |
| | | "visible": true, |
| | | "shape": "rect", |
| | | "id": "71d8bc90-558f-489f-b432-a03d7af27cdc", |
| | | "data": { |
| | | "codeContent": null, |
| | | "root": true, |
| | | "isLogic": false, |
| | | "logicBool": false, |
| | | "searchLogicId": 1, |
| | | "searchLogicBool": true, |
| | | "searchIndex": 0 |
| | | }, |
| | | "zIndex": 4, |
| | | "ports": { |
| | | "groups": { |
| | | "top": { |
| | | "position": "top", |
| | | "attrs": { |
| | | "circle": { |
| | | "r": 5, |
| | | "magnet": true, |
| | | "stroke": "#5F95FF", |
| | | "strokeWidth": 1, |
| | | "fill": "#fff", |
| | | "style": { |
| | | "visibility": "hidden" |
| | | } |
| | | } |
| | | } |
| | | }, |
| | | "bottom": { |
| | | "position": "bottom", |
| | | "attrs": { |
| | | "circle": { |
| | | "r": 5, |
| | | "magnet": true, |
| | | "stroke": "#5F95FF", |
| | | "strokeWidth": 1, |
| | | "fill": "#fff", |
| | | "style": { |
| | | "visibility": "hidden" |
| | | } |
| | | } |
| | | } |
| | | }, |
| | | "left": { |
| | | "position": "left", |
| | | "attrs": { |
| | | "circle": { |
| | | "r": 5, |
| | | "magnet": true, |
| | | "stroke": "#5F95FF", |
| | | "strokeWidth": 1, |
| | | "fill": "#fff", |
| | | "style": { |
| | | "visibility": "hidden" |
| | | } |
| | | } |
| | | } |
| | | }, |
| | | "right": { |
| | | "position": "right", |
| | | "attrs": { |
| | | "circle": { |
| | | "r": 5, |
| | | "magnet": true, |
| | | "stroke": "#5F95FF", |
| | | "strokeWidth": 1, |
| | | "fill": "#fff", |
| | | "style": { |
| | | "visibility": "hidden" |
| | | } |
| | | } |
| | | } |
| | | } |
| | | }, |
| | | "items": [ |
| | | { |
| | | "id": "port1", |
| | | "group": "top" |
| | | }, |
| | | { |
| | | "id": "port2", |
| | | "group": "bottom" |
| | | }, |
| | | { |
| | | "id": "port3", |
| | | "group": "left" |
| | | }, |
| | | { |
| | | "id": "port4", |
| | | "group": "right" |
| | | } |
| | | ] |
| | | } |
| | | }, |
| | | { |
| | | "position": { |
| | | "x": 300, |
| | | "y": 110 |
| | | }, |
| | | "size": { |
| | | "width": 80, |
| | | "height": 40 |
| | | }, |
| | | "attrs": { |
| | | "text": { |
| | | "text": "常用组件" |
| | | }, |
| | | "body": { |
| | | "fill": "#efefef", |
| | | "stroke": "#4d4d4d", |
| | | "strokeWidth": 2, |
| | | "refD": "M 50 0 L 100 50 L 50 100 L 0 50 Z" |
| | | } |
| | | }, |
| | | "visible": true, |
| | | "shape": "rect", |
| | | "id": "c5798537-a8a0-4d79-bd76-a4f663492126", |
| | | "data": { |
| | | "codeContent": "1111", |
| | | "root": false, |
| | | "isLogic": false, |
| | | "logicBool": false, |
| | | "searchLogicId": 1, |
| | | "searchLogicBool": true, |
| | | "searchIndex": 0 |
| | | }, |
| | | "zIndex": 5, |
| | | "ports": { |
| | | "groups": { |
| | | "top": { |
| | | "position": "top", |
| | | "attrs": { |
| | | "circle": { |
| | | "r": 5, |
| | | "magnet": true, |
| | | "stroke": "#5F95FF", |
| | | "strokeWidth": 1, |
| | | "fill": "#fff", |
| | | "style": { |
| | | "visibility": "hidden" |
| | | } |
| | | } |
| | | } |
| | | }, |
| | | "bottom": { |
| | | "position": "bottom", |
| | | "attrs": { |
| | | "circle": { |
| | | "r": 5, |
| | | "magnet": true, |
| | | "stroke": "#5F95FF", |
| | | "strokeWidth": 1, |
| | | "fill": "#fff", |
| | | "style": { |
| | | "visibility": "hidden" |
| | | } |
| | | } |
| | | } |
| | | }, |
| | | "left": { |
| | | "position": "left", |
| | | "attrs": { |
| | | "circle": { |
| | | "r": 5, |
| | | "magnet": true, |
| | | "stroke": "#5F95FF", |
| | | "strokeWidth": 1, |
| | | "fill": "#fff", |
| | | "style": { |
| | | "visibility": "hidden" |
| | | } |
| | | } |
| | | } |
| | | }, |
| | | "right": { |
| | | "position": "right", |
| | | "attrs": { |
| | | "circle": { |
| | | "r": 5, |
| | | "magnet": true, |
| | | "stroke": "#5F95FF", |
| | | "strokeWidth": 1, |
| | | "fill": "#fff", |
| | | "style": { |
| | | "visibility": "hidden" |
| | | } |
| | | } |
| | | } |
| | | } |
| | | }, |
| | | "items": [ |
| | | { |
| | | "id": "port1", |
| | | "group": "top" |
| | | }, |
| | | { |
| | | "id": "port2", |
| | | "group": "bottom" |
| | | }, |
| | | { |
| | | "id": "port3", |
| | | "group": "left" |
| | | }, |
| | | { |
| | | "id": "port4", |
| | | "group": "right" |
| | | } |
| | | ] |
| | | } |
| | | }, |
| | | { |
| | | "position": { |
| | | "x": 280, |
| | | "y": 511 |
| | | }, |
| | | "size": { |
| | | "width": 80, |
| | | "height": 40 |
| | | }, |
| | | "attrs": { |
| | | "text": { |
| | | "text": "常用组件2" |
| | | }, |
| | | "body": { |
| | | "fill": "#efefef", |
| | | "stroke": "#4d4d4d", |
| | | "strokeWidth": 2, |
| | | "refD": "M 50 0 L 100 50 L 50 100 L 0 50 Z" |
| | | } |
| | | }, |
| | | "visible": true, |
| | | "shape": "rect", |
| | | "id": "c844f3d1-02a3-47d3-bcb9-51027c1deb1c", |
| | | "data": { |
| | | "codeContent": "常用组件2", |
| | | "root": false, |
| | | "isLogic": false, |
| | | "logicBool": false, |
| | | "searchLogicId": 1, |
| | | "searchLogicBool": true, |
| | | "searchIndex": 0 |
| | | }, |
| | | "zIndex": 6, |
| | | "ports": { |
| | | "groups": { |
| | | "top": { |
| | | "position": "top", |
| | | "attrs": { |
| | | "circle": { |
| | | "r": 5, |
| | | "magnet": true, |
| | | "stroke": "#5F95FF", |
| | | "strokeWidth": 1, |
| | | "fill": "#fff", |
| | | "style": { |
| | | "visibility": "hidden" |
| | | } |
| | | } |
| | | } |
| | | }, |
| | | "bottom": { |
| | | "position": "bottom", |
| | | "attrs": { |
| | | "circle": { |
| | | "r": 5, |
| | | "magnet": true, |
| | | "stroke": "#5F95FF", |
| | | "strokeWidth": 1, |
| | | "fill": "#fff", |
| | | "style": { |
| | | "visibility": "hidden" |
| | | } |
| | | } |
| | | } |
| | | }, |
| | | "left": { |
| | | "position": "left", |
| | | "attrs": { |
| | | "circle": { |
| | | "r": 5, |
| | | "magnet": true, |
| | | "stroke": "#5F95FF", |
| | | "strokeWidth": 1, |
| | | "fill": "#fff", |
| | | "style": { |
| | | "visibility": "hidden" |
| | | } |
| | | } |
| | | } |
| | | }, |
| | | "right": { |
| | | "position": "right", |
| | | "attrs": { |
| | | "circle": { |
| | | "r": 5, |
| | | "magnet": true, |
| | | "stroke": "#5F95FF", |
| | | "strokeWidth": 1, |
| | | "fill": "#fff", |
| | | "style": { |
| | | "visibility": "hidden" |
| | | } |
| | | } |
| | | } |
| | | } |
| | | }, |
| | | "items": [ |
| | | { |
| | | "id": "port1", |
| | | "group": "top" |
| | | }, |
| | | { |
| | | "id": "port2", |
| | | "group": "bottom" |
| | | }, |
| | | { |
| | | "id": "port3", |
| | | "group": "left" |
| | | }, |
| | | { |
| | | "id": "port4", |
| | | "group": "right" |
| | | } |
| | | ] |
| | | } |
| | | }, |
| | | { |
| | | "position": { |
| | | "x": 270, |
| | | "y": 620 |
| | | }, |
| | | "size": { |
| | | "width": 100, |
| | | "height": 60 |
| | | }, |
| | | "attrs": { |
| | | "text": { |
| | | "text": "逻辑判断2" |
| | | }, |
| | | "body": { |
| | | "fill": "#efefef", |
| | | "stroke": "#4d4d4d", |
| | | "refD": "M 50 0 L 100 50 L 50 100 L 0 50 Z" |
| | | } |
| | | }, |
| | | "visible": true, |
| | | "shape": "path", |
| | | "id": "cc993d9b-ce11-409d-92c6-7208682dcc8b", |
| | | "data": { |
| | | "codeContent": "逻辑判断2", |
| | | "root": false, |
| | | "isLogic": true, |
| | | "logicBool": false, |
| | | "searchLogicId": 1, |
| | | "searchLogicBool": true, |
| | | "searchIndex": 0 |
| | | }, |
| | | "zIndex": 7, |
| | | "ports": { |
| | | "groups": { |
| | | "top": { |
| | | "position": "top", |
| | | "attrs": { |
| | | "circle": { |
| | | "r": 5, |
| | | "magnet": true, |
| | | "stroke": "#5F95FF", |
| | | "strokeWidth": 1, |
| | | "fill": "#fff", |
| | | "style": { |
| | | "visibility": "hidden" |
| | | } |
| | | } |
| | | } |
| | | }, |
| | | "bottom": { |
| | | "position": "bottom", |
| | | "attrs": { |
| | | "circle": { |
| | | "r": 5, |
| | | "magnet": true, |
| | | "stroke": "#5F95FF", |
| | | "strokeWidth": 1, |
| | | "fill": "#fff", |
| | | "style": { |
| | | "visibility": "hidden" |
| | | } |
| | | } |
| | | } |
| | | }, |
| | | "left": { |
| | | "position": "left", |
| | | "attrs": { |
| | | "circle": { |
| | | "r": 5, |
| | | "magnet": true, |
| | | "stroke": "#5F95FF", |
| | | "strokeWidth": 1, |
| | | "fill": "#fff", |
| | | "style": { |
| | | "visibility": "hidden" |
| | | } |
| | | } |
| | | } |
| | | }, |
| | | "right": { |
| | | "position": "right", |
| | | "attrs": { |
| | | "circle": { |
| | | "r": 5, |
| | | "magnet": true, |
| | | "stroke": "#5F95FF", |
| | | "strokeWidth": 1, |
| | | "fill": "#fff", |
| | | "style": { |
| | | "visibility": "hidden" |
| | | } |
| | | } |
| | | } |
| | | } |
| | | }, |
| | | "items": [ |
| | | { |
| | | "id": "port1", |
| | | "group": "top" |
| | | }, |
| | | { |
| | | "id": "port2", |
| | | "group": "bottom" |
| | | }, |
| | | { |
| | | "id": "port3", |
| | | "group": "left" |
| | | }, |
| | | { |
| | | "id": "port4", |
| | | "group": "right" |
| | | } |
| | | ] |
| | | } |
| | | }, |
| | | { |
| | | "position": { |
| | | "x": 280, |
| | | "y": 781 |
| | | }, |
| | | "size": { |
| | | "width": 80, |
| | | "height": 40 |
| | | }, |
| | | "attrs": { |
| | | "text": { |
| | | "text": "常用组件3" |
| | | }, |
| | | "body": { |
| | | "fill": "#efefef", |
| | | "stroke": "#4d4d4d", |
| | | "strokeWidth": 2, |
| | | "refD": "M 50 0 L 100 50 L 50 100 L 0 50 Z" |
| | | } |
| | | }, |
| | | "visible": true, |
| | | "shape": "rect", |
| | | "id": "cd9da0a4-5c2d-4f1b-9c51-403b32f1ad51", |
| | | "data": { |
| | | "codeContent": "常用组件3", |
| | | "root": false, |
| | | "isLogic": false, |
| | | "logicBool": false, |
| | | "searchLogicId": 1, |
| | | "searchLogicBool": true, |
| | | "searchIndex": 0 |
| | | }, |
| | | "zIndex": 8, |
| | | "ports": { |
| | | "groups": { |
| | | "top": { |
| | | "position": "top", |
| | | "attrs": { |
| | | "circle": { |
| | | "r": 5, |
| | | "magnet": true, |
| | | "stroke": "#5F95FF", |
| | | "strokeWidth": 1, |
| | | "fill": "#fff", |
| | | "style": { |
| | | "visibility": "hidden" |
| | | } |
| | | } |
| | | } |
| | | }, |
| | | "bottom": { |
| | | "position": "bottom", |
| | | "attrs": { |
| | | "circle": { |
| | | "r": 5, |
| | | "magnet": true, |
| | | "stroke": "#5F95FF", |
| | | "strokeWidth": 1, |
| | | "fill": "#fff", |
| | | "style": { |
| | | "visibility": "hidden" |
| | | } |
| | | } |
| | | } |
| | | }, |
| | | "left": { |
| | | "position": "left", |
| | | "attrs": { |
| | | "circle": { |
| | | "r": 5, |
| | | "magnet": true, |
| | | "stroke": "#5F95FF", |
| | | "strokeWidth": 1, |
| | | "fill": "#fff", |
| | | "style": { |
| | | "visibility": "hidden" |
| | | } |
| | | } |
| | | } |
| | | }, |
| | | "right": { |
| | | "position": "right", |
| | | "attrs": { |
| | | "circle": { |
| | | "r": 5, |
| | | "magnet": true, |
| | | "stroke": "#5F95FF", |
| | | "strokeWidth": 1, |
| | | "fill": "#fff", |
| | | "style": { |
| | | "visibility": "hidden" |
| | | } |
| | | } |
| | | } |
| | | } |
| | | }, |
| | | "items": [ |
| | | { |
| | | "id": "port1", |
| | | "group": "top" |
| | | }, |
| | | { |
| | | "id": "port2", |
| | | "group": "bottom" |
| | | }, |
| | | { |
| | | "id": "port3", |
| | | "group": "left" |
| | | }, |
| | | { |
| | | "id": "port4", |
| | | "group": "right" |
| | | } |
| | | ] |
| | | } |
| | | }, |
| | | { |
| | | "position": { |
| | | "x": 472, |
| | | "y": 640 |
| | | }, |
| | | "size": { |
| | | "width": 80, |
| | | "height": 40 |
| | | }, |
| | | "attrs": { |
| | | "text": { |
| | | "text": "常用组件4" |
| | | }, |
| | | "body": { |
| | | "fill": "#efefef", |
| | | "stroke": "#4d4d4d", |
| | | "strokeWidth": 2, |
| | | "refD": "M 50 0 L 100 50 L 50 100 L 0 50 Z" |
| | | } |
| | | }, |
| | | "visible": true, |
| | | "shape": "rect", |
| | | "id": "06d450fc-474e-4b23-b40d-c89fde446b28", |
| | | "data": { |
| | | "codeContent": "常用组件4", |
| | | "root": false, |
| | | "isLogic": false, |
| | | "logicBool": false, |
| | | "searchLogicId": 1, |
| | | "searchLogicBool": true, |
| | | "searchIndex": 0 |
| | | }, |
| | | "zIndex": 9, |
| | | "ports": { |
| | | "groups": { |
| | | "top": { |
| | | "position": "top", |
| | | "attrs": { |
| | | "circle": { |
| | | "r": 5, |
| | | "magnet": true, |
| | | "stroke": "#5F95FF", |
| | | "strokeWidth": 1, |
| | | "fill": "#fff", |
| | | "style": { |
| | | "visibility": "hidden" |
| | | } |
| | | } |
| | | } |
| | | }, |
| | | "bottom": { |
| | | "position": "bottom", |
| | | "attrs": { |
| | | "circle": { |
| | | "r": 5, |
| | | "magnet": true, |
| | | "stroke": "#5F95FF", |
| | | "strokeWidth": 1, |
| | | "fill": "#fff", |
| | | "style": { |
| | | "visibility": "hidden" |
| | | } |
| | | } |
| | | } |
| | | }, |
| | | "left": { |
| | | "position": "left", |
| | | "attrs": { |
| | | "circle": { |
| | | "r": 5, |
| | | "magnet": true, |
| | | "stroke": "#5F95FF", |
| | | "strokeWidth": 1, |
| | | "fill": "#fff", |
| | | "style": { |
| | | "visibility": "hidden" |
| | | } |
| | | } |
| | | } |
| | | }, |
| | | "right": { |
| | | "position": "right", |
| | | "attrs": { |
| | | "circle": { |
| | | "r": 5, |
| | | "magnet": true, |
| | | "stroke": "#5F95FF", |
| | | "strokeWidth": 1, |
| | | "fill": "#fff", |
| | | "style": { |
| | | "visibility": "hidden" |
| | | } |
| | | } |
| | | } |
| | | } |
| | | }, |
| | | "items": [ |
| | | { |
| | | "id": "port1", |
| | | "group": "top" |
| | | }, |
| | | { |
| | | "id": "port2", |
| | | "group": "bottom" |
| | | }, |
| | | { |
| | | "id": "port3", |
| | | "group": "left" |
| | | }, |
| | | { |
| | | "id": "port4", |
| | | "group": "right" |
| | | } |
| | | ] |
| | | } |
| | | } |
| | | ] |
| | | }) |
| | | |
| | | |
| | | props.initHandle();//通知父组件初始化完成 |
| | | return graph; |
| | |
| | | |
| | | stencilContainer.current.appendChild(stencil.container) |
| | | |
| | | const n1Data = JSON.parse(JSON.stringify(initNodeData)) |
| | | n1Data.root = true;//设置为根节点 |
| | | const n1 = graph.createNode({ |
| | | shape: "rect", |
| | | width: 80, |
| | | height: 40, |
| | | label: "默认组件", |
| | | label: "程序入口", |
| | | attrs: commonGraphAttrs, |
| | | ports: commonGraphPorts |
| | | ports: commonGraphPorts, |
| | | data: n1Data, |
| | | }) |
| | | |
| | | const n2 = graph.createNode({ |
| | | shape: "rect", |
| | | width: 80, |
| | | height: 40, |
| | | label: "测试组件", |
| | | label: "常用组件", |
| | | attrs: commonGraphAttrs, |
| | | ports: commonGraphPorts |
| | | ports: commonGraphPorts, |
| | | data: initNodeData, |
| | | }) |
| | | |
| | | stencil.load([n1, n2], 'group1') |
| | | const n3Data = JSON.parse(JSON.stringify(initNodeData)) |
| | | n3Data.isLogic = true;//逻辑判断 |
| | | const n3 = graph.createNode({ |
| | | shape: 'path', |
| | | width: 100, |
| | | height: 60, |
| | | // https://www.svgrepo.com/svg/13653/like |
| | | path: 'M 50 0 L 100 50 L 50 100 L 0 50 Z', |
| | | attrs: commonGraphAttrs, |
| | | label: '逻辑判断', |
| | | ports: commonGraphPorts, |
| | | data: n3Data, |
| | | }) |
| | | |
| | | stencil.load([n1, n2, n3], 'group1') |
| | | } |
| | | |
| | | function initBind(graph) { |
| | |
| | | }, |
| | | } |
| | | |
| | | export { commonGraphPorts, commonGraphAttrs, initGraphConnecting } |
| | | const initNodeData = { |
| | | codeContent: null, |
| | | root: false,//默认不是根节点 |
| | | isLogic: false,//默认不是逻辑判断 |
| | | logicBool: false,//逻辑判断默认值 |
| | | searchLogicId: 1,//默认逻辑id |
| | | searchLogicBool: true,//默认逻辑id方向 |
| | | searchIndex: 0,//默认执行优先级 |
| | | } |
| | | |
| | | export { commonGraphPorts, commonGraphAttrs, initGraphConnecting, initNodeData } |
| | |
| | | import React, { useRef, useEffect, useState } from "react"; |
| | | import { Button, Drawer, Input } from 'antd'; |
| | | import { Button, Drawer, Input, Switch } from 'antd'; |
| | | import { initNodeData } from "./GraphConfig"; |
| | | import './GrapDrawer.less'; |
| | | |
| | | const { TextArea } = Input; |
| | | |
| | | export const GraphDrawer = ({ graphRef, isReady }) => { |
| | | |
| | | const [open, setOpen] = useState(false); |
| | | |
| | | const [init, setInit] = useState(false); |
| | | |
| | | const [nodeData, setNodeData] = useState(null); |
| | | const [edgeData, setEdgeData] = useState(null); |
| | | const [codeContent, setCodeContent] = useState(null); |
| | | |
| | | const [codeContent,setCodeContent] = useState(null); |
| | | |
| | | const showDrawer = (graph, node) => { |
| | | const showNodeDrawer = (graph, node) => { |
| | | setOpen(true); |
| | | setNodeData(node); |
| | | if (node.data == null) { |
| | | node.data = initNodeData; |
| | | } |
| | | |
| | | if (node.data.codeContent != null) { |
| | | setCodeContent(node.data.codeContent); |
| | | } |
| | | }; |
| | | |
| | | const onClose = (e) => { |
| | | const showEdgeDrawer = (graph, edge) => { |
| | | setOpen(true); |
| | | setEdgeData(edge); |
| | | if (edge.data == null) { |
| | | edge.data = initNodeData; |
| | | } |
| | | |
| | | if (edge.data.codeContent != null) { |
| | | setCodeContent(edge.data.codeContent); |
| | | } |
| | | |
| | | if (edge.labels.length == 0) { |
| | | edge.appendLabel({ |
| | | attrs: { |
| | | label: { |
| | | text: "" |
| | | } |
| | | } |
| | | }) |
| | | } |
| | | |
| | | } |
| | | |
| | | const onNodeClose = (e) => { |
| | | setOpen(false); |
| | | setNodeData(null); |
| | | console.log(codeContent); |
| | | setCodeContent(null); |
| | | }; |
| | | |
| | | const textAreaChange = (e) => { |
| | | const onEdgeClose = (e) => { |
| | | setOpen(false); |
| | | setEdgeData(null); |
| | | setCodeContent(null); |
| | | }; |
| | | |
| | | const nodeTextAreaChange = (e) => { |
| | | setCodeContent(e.target.value); |
| | | nodeData.data.codeContent = e.target.value; |
| | | } |
| | | |
| | | const edgeTextAreaChange = (e) => { |
| | | setCodeContent(e.target.value); |
| | | edgeData.data.codeContent = e.target.value; |
| | | } |
| | | |
| | | const nodeDataInputChange = (e) => { |
| | | nodeData.label = e.target.value; |
| | | } |
| | | |
| | | const edgeDataInputChange = (e) => { |
| | | edgeData.removeLabelAt(0); |
| | | edgeData.appendLabel({ |
| | | attrs: { |
| | | label: { |
| | | text: e.target.value |
| | | } |
| | | } |
| | | }) |
| | | edgeData.data.logicBool = e.target.value == 'true' ? true : false; |
| | | } |
| | | |
| | | useEffect(() => { |
| | |
| | | |
| | | if (!init) { |
| | | graph.on("node:dblclick", ({ node }) => { |
| | | console.log(node); |
| | | showDrawer(graph, node); |
| | | showNodeDrawer(graph, node); |
| | | }) |
| | | graph.on("edge:dblclick", ({ edge }) => { |
| | | showEdgeDrawer(graph, edge); |
| | | }) |
| | | setInit(true); |
| | | } |
| | | } |
| | | }) |
| | | |
| | | if(nodeData){ |
| | | if (nodeData) { |
| | | return ( |
| | | <> |
| | | <Drawer title={nodeData.label} onClose={onClose} open={open} size="large"> |
| | | <p>ID:{nodeData.id}</p> |
| | | <p>可执行代码:</p> |
| | | <TextArea onChange={textAreaChange} rows={10} /> |
| | | <Drawer title={nodeData.label} onClose={onNodeClose} open={open} size="large"> |
| | | <div className="graphDrawerContainer"> |
| | | <div>ID:{nodeData.id}</div> |
| | | <div>组件名:<Input defaultValue={nodeData.label} onChange={nodeDataInputChange} /></div> |
| | | <div>根节点:<Switch checkedChildren="是" unCheckedChildren="否" checked={nodeData.data.root} /></div> |
| | | <div>可执行代码:</div> |
| | | <TextArea value={codeContent} onChange={nodeTextAreaChange} rows={10} /> |
| | | </div> |
| | | </Drawer> |
| | | </> |
| | | ); |
| | | } else if (edgeData) { |
| | | return ( |
| | | <> |
| | | <Drawer title={edgeData.label} onClose={onEdgeClose} open={open} size="large"> |
| | | <div className="graphDrawerContainer"> |
| | | <div>ID:{edgeData.id}</div> |
| | | <div>属性详情:<Input defaultValue={edgeData.labels[0].attrs.label.text} onChange={edgeDataInputChange} /></div> |
| | | <div>根节点:<Switch checkedChildren="是" unCheckedChildren="否" checked={edgeData.data.root} /></div> |
| | | <div>可执行代码:</div> |
| | | <TextArea value={codeContent} onChange={edgeTextAreaChange} rows={10} /> |
| | | </div> |
| | | </Drawer> |
| | | </> |
| | | ); |
New file |
| | |
| | | import React, { useRef, useEffect, useState } from "react"; |
| | | import { Button, message } from 'antd'; |
| | | import { last } from "lodash"; |
| | | |
| | | export const GraphTools = ({ graphRef, isReady }) => { |
| | | |
| | | let codeContent = ""; |
| | | |
| | | const exportData = () => { |
| | | const graph = graphRef.current; |
| | | if (isReady) { |
| | | const data = graph.toJSON(); |
| | | console.log(data); |
| | | // 这里你可以将数据发送到服务器或保存到本地 |
| | | |
| | | const edges = []; |
| | | const nodes = []; |
| | | let rootNode = null; |
| | | data.cells.forEach((item) => { |
| | | if (item.shape == "edge") { |
| | | edges.push(item) |
| | | } else { |
| | | nodes.push(item) |
| | | if (item.data.root) { |
| | | rootNode = item; |
| | | } |
| | | } |
| | | }) |
| | | |
| | | if (rootNode == null) { |
| | | message.warning('请设置程序入口组件'); |
| | | return; |
| | | } |
| | | |
| | | console.log(getDescendants(rootNode, nodes, graph)); |
| | | |
| | | transCode(rootNode, nodes, graph) |
| | | // nodeDFS(rootNode, nodes, graph, codeContent) |
| | | // console.log(codeContent); |
| | | } |
| | | } |
| | | |
| | | const transCode = (rootNode, nodes, graph) => { |
| | | let codeContent = ""; |
| | | const descendants = []; |
| | | let stack = [rootNode]; |
| | | |
| | | let existLogicNode = []; |
| | | let values = nodeDFS(rootNode, nodes, graph); |
| | | |
| | | let cpValues = JSON.parse(JSON.stringify(values)) |
| | | console.log(cpValues); |
| | | |
| | | let groupCode = {}; |
| | | let logicGroupSearch = []; |
| | | let currentLogic = null; |
| | | cpValues.forEach((value) => { |
| | | if (value.data.isLogic) { |
| | | let tmp = {}; |
| | | if (currentLogic == null) { |
| | | tmp = { |
| | | id: value.id, |
| | | parent: null, |
| | | currentCode: "" |
| | | } |
| | | } else { |
| | | tmp = { |
| | | id: value.id, |
| | | parent: currentLogic, |
| | | currentCode: "" |
| | | } |
| | | } |
| | | currentLogic = value.id; |
| | | logicGroupSearch.push(tmp); |
| | | } |
| | | }) |
| | | |
| | | console.log(cpValues); |
| | | console.log(logicGroupSearch); |
| | | |
| | | let codeContentTmp = ""; |
| | | while (values.length > 0) { |
| | | const current = values.pop(); |
| | | const connectedEdges = graph.getConnectedEdges(current);//取边 |
| | | |
| | | connectedEdges.forEach((edge) => { |
| | | //过滤从自身节点出去的边 |
| | | if (edge.source.cell != current.id) { |
| | | //取上一节点 |
| | | let lastNode = null; |
| | | nodes.forEach((node) => { |
| | | if (node.id == edge.source.cell) { |
| | | lastNode = node; |
| | | } |
| | | }) |
| | | |
| | | if (lastNode != null) { |
| | | //判断节点是否逻辑节点 |
| | | if (lastNode.data.isLogic) { |
| | | let nestedCode = ` |
| | | //**********${current.attrs.text.text}-start**********// |
| | | ${current.data.codeContent} |
| | | //**********${current.attrs.text.text}-end**********// |
| | | `; |
| | | codeContentTmp = "\n" + nestedCode + codeContentTmp; |
| | | |
| | | let nestedIfCode = ` |
| | | ${codeContentTmp} |
| | | `; |
| | | |
| | | if (groupCode[lastNode.id] == null) { |
| | | groupCode[lastNode.id] = [{ |
| | | code: nestedIfCode, |
| | | logicBool: edge.data.logicBool, |
| | | condition: lastNode.data.codeContent |
| | | }]; |
| | | } else { |
| | | groupCode[lastNode.id].push({ |
| | | code: nestedIfCode, |
| | | logicBool: edge.data.logicBool, |
| | | condition: lastNode.data.codeContent |
| | | }); |
| | | } |
| | | |
| | | codeContent += nestedIfCode; |
| | | codeContentTmp = ""; |
| | | |
| | | console.log(lastNode, current, true, codeContent); |
| | | } else { |
| | | if (current.data.codeContent != null && !current.data.isLogic) { |
| | | let nestedCode = ` |
| | | //**********${current.attrs.text.text}-start**********// |
| | | ${current.data.codeContent} |
| | | //**********${current.attrs.text.text}-end**********// |
| | | `; |
| | | codeContentTmp = "\n" + nestedCode + codeContentTmp; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | }) |
| | | |
| | | } |
| | | |
| | | for (let i = logicGroupSearch.length - 1; i >= 0; i--) { |
| | | let logic = logicGroupSearch[i]; |
| | | let logicGroup = groupCode[logic.id]; |
| | | |
| | | let logic1 = logicGroup[0]; |
| | | let nestedIfCode = ""; |
| | | |
| | | if (logicGroup.length > 1) { |
| | | let logic2 = logicGroup[0]; |
| | | |
| | | if (logic1.logicBool) { |
| | | nestedIfCode = ` |
| | | if (${logic1.condition}) { |
| | | ${logic1.code} |
| | | }else { |
| | | ${logic2.code} |
| | | } |
| | | `; |
| | | } else { |
| | | nestedIfCode = ` |
| | | if (!(${logic1.condition})) { |
| | | ${logic1.code} |
| | | }else { |
| | | ${logic2.code} |
| | | } |
| | | `; |
| | | } |
| | | } |
| | | |
| | | if (logic.parent != null) { |
| | | logicGroupSearch.forEach((item) => { |
| | | if (item.id == logic.parent) { |
| | | item.currentCode += nestedIfCode; |
| | | } |
| | | }) |
| | | } |
| | | |
| | | console.log(logicGroupSearch,nestedIfCode); |
| | | } |
| | | |
| | | console.log(groupCode); |
| | | console.log(codeContent); |
| | | |
| | | } |
| | | |
| | | // const transCode = (rootNode, nodes, graph) => { |
| | | // let codeContent = ""; |
| | | // const descendants = []; |
| | | // let stack = [rootNode]; |
| | | |
| | | // let count = 0; |
| | | // while (stack.length > 0) { |
| | | // const current = stack.pop(); |
| | | // descendants.push(current); |
| | | |
| | | // const children = getChildren(current, nodes, graph); |
| | | // stack.push(...children); |
| | | |
| | | // // 输出代码 |
| | | // if (!current.data.isLogic) { |
| | | // const connectedEdges = graph.getConnectedEdges(current);//取边 |
| | | // connectedEdges.forEach((edge) => { |
| | | // //过滤从自身节点出去的边 |
| | | // if(edge.source.cell != current.id){ |
| | | // //取上一节点 |
| | | // let lastNode = null; |
| | | // nodes.forEach((node) => { |
| | | // if(node.id == edge.source.cell){ |
| | | // lastNode = node; |
| | | // } |
| | | // }) |
| | | |
| | | // if(lastNode != null) { |
| | | // //判断节点是否逻辑节点 |
| | | // if(lastNode.data.isLogic){ |
| | | // console.log(lastNode); |
| | | // let nestedIfCode = ""; |
| | | // if(lastNode.data.logicBool == 'true') { |
| | | // nestedIfCode = ` |
| | | // if (${lastNode.data.codeContent}) { |
| | | // ${current.data.codeContent} |
| | | // } |
| | | // `; |
| | | // }else{ |
| | | // nestedIfCode = ` |
| | | // if (!(${lastNode.data.codeContent})) { |
| | | // ${current.data.codeContent} |
| | | // } |
| | | // `; |
| | | // } |
| | | |
| | | |
| | | // codeContent += "\n" + nestedIfCode; |
| | | // console.log(codeContent); |
| | | // }else{ |
| | | // if (current.data.codeContent != null) { |
| | | // codeContent += "\n" + current.data.codeContent; |
| | | // } |
| | | // } |
| | | // } |
| | | // } |
| | | // console.log(current); |
| | | // }) |
| | | // } else { |
| | | // // if (current.data.codeContent != null) { |
| | | // // codeContent += "\n" + current.data.codeContent; |
| | | // // } |
| | | |
| | | // // const connectedEdges = graph.getConnectedEdges(current); |
| | | // // console.log(connectedEdges); |
| | | // // stack = [] |
| | | // // let test = [] |
| | | // // connectedEdges.forEach((edge) => { |
| | | // // nodes.forEach((item) => { |
| | | // // if (item.id === edge.target.cell && item.id != current.id) { |
| | | // // test.push(item); |
| | | // // } |
| | | // // }) |
| | | // // }); |
| | | // // console.log(test); |
| | | // // console.log(); |
| | | // // let nestedIfCode = ` |
| | | // // if (true}) { |
| | | // // ${current.data.codeContent} |
| | | // // } |
| | | // // `; |
| | | |
| | | // // codeContent += "\n" + nestedIfCode; |
| | | // // console.log(codeContent); |
| | | // } |
| | | |
| | | // } |
| | | |
| | | // console.log(codeContent); |
| | | // } |
| | | |
| | | const nodeDFS = (node, nodes, graph) => { |
| | | let values = []; |
| | | if (graph) { |
| | | const connectedEdges = graph.getConnectedEdges(node); |
| | | const children = []; |
| | | |
| | | console.log(node); |
| | | connectedEdges.forEach((edge) => { |
| | | nodes.forEach((item) => { |
| | | if (item.id === edge.target.cell && item.id != node.id) { |
| | | children.push(item); |
| | | } |
| | | }) |
| | | }); |
| | | |
| | | console.log(connectedEdges); |
| | | if (children.length != 0) { |
| | | console.log(children); |
| | | children.forEach((node) => { |
| | | console.log(node); |
| | | values.push(node); |
| | | values = values.concat(nodeDFS(node, nodes, graph)) |
| | | }) |
| | | } |
| | | } |
| | | |
| | | return values; |
| | | } |
| | | |
| | | const getChildren = (node, nodes, graph) => { |
| | | const connectedEdges = graph.getConnectedEdges(node); |
| | | const children = []; |
| | | |
| | | connectedEdges.forEach((edge) => { |
| | | nodes.forEach((item) => { |
| | | if (item.id === edge.target.cell && item.id != node.id) { |
| | | children.push(item); |
| | | } |
| | | }) |
| | | }); |
| | | |
| | | return children; |
| | | } |
| | | |
| | | const getDescendants = (node, nodes, graph) => { |
| | | const descendants = []; |
| | | const stack = [node]; |
| | | |
| | | let count = 0; |
| | | while (stack.length > 0) { |
| | | const current = stack.pop(); |
| | | descendants.push(current); |
| | | |
| | | const children = getChildren(current, nodes, graph); |
| | | stack.push(...children); |
| | | } |
| | | |
| | | return descendants; |
| | | } |
| | | |
| | | return ( |
| | | <> |
| | | <Button type="primary" onClick={exportData}> |
| | | 导出数据 |
| | | </Button> |
| | | </> |
| | | ); |
| | | } |
| | |
| | | import React, { useRef, useEffect, useState } from "react"; |
| | | import { Button } from 'antd'; |
| | | import { Button, message, Modal } from 'antd'; |
| | | import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter'; |
| | | import { solarizedlight } from 'react-syntax-highlighter/dist/esm/styles/prism'; |
| | | import './GraphTools.less' |
| | | |
| | | export const GraphTools = ({ graphRef, isReady }) => { |
| | | |
| | | const [isModalOpen, setIsModalOpen] = useState(false); |
| | | const [preCode, setPreCode] = useState(null); |
| | | |
| | | const handleOk = () => { |
| | | setIsModalOpen(false); |
| | | }; |
| | | |
| | | const handleCancel = () => { |
| | | setIsModalOpen(false); |
| | | }; |
| | | |
| | | //预览代码 |
| | | const prewCode = () => { |
| | | const graph = graphRef.current; |
| | | if (isReady) { |
| | | const data = graph.toJSON(); |
| | | |
| | | const edges = []; |
| | | const nodes = []; |
| | | let rootNode = null; |
| | | data.cells.forEach((item) => { |
| | | if (item.shape == "edge") { |
| | | edges.push(item) |
| | | } else { |
| | | nodes.push(item) |
| | | if (item.data.root) { |
| | | rootNode = item; |
| | | } |
| | | } |
| | | }) |
| | | |
| | | if (rootNode == null) { |
| | | message.warning('请设置程序入口组件'); |
| | | return; |
| | | } |
| | | |
| | | const codeContent = transCode(rootNode, nodes, graph) |
| | | console.log(codeContent); |
| | | |
| | | setPreCode(codeContent); |
| | | setIsModalOpen(true); |
| | | } |
| | | } |
| | | |
| | | const exportData = () => { |
| | | const graph = graphRef.current; |
| | |
| | | const data = graph.toJSON(); |
| | | console.log(data); |
| | | // 这里你可以将数据发送到服务器或保存到本地 |
| | | |
| | | const edges = []; |
| | | const nodes = []; |
| | | let rootNode = null; |
| | | data.cells.forEach((item) => { |
| | | if (item.shape == "edge") { |
| | | edges.push(item) |
| | | } else { |
| | | nodes.push(item) |
| | | if (item.data.root) { |
| | | rootNode = item; |
| | | } |
| | | } |
| | | }) |
| | | |
| | | if (rootNode == null) { |
| | | message.warning('请设置程序入口组件'); |
| | | return; |
| | | } |
| | | |
| | | console.log(getDescendants(rootNode, nodes, graph)); |
| | | |
| | | const codeContent = transCode(rootNode, nodes, graph) |
| | | console.log(codeContent); |
| | | } |
| | | } |
| | | |
| | | const transCode = (rootNode, nodes, graph) => { |
| | | let codeContent = ""; |
| | | let values = nodeDFS(rootNode, nodes, graph); |
| | | const searchNode = { |
| | | id: 1, |
| | | parent: null, |
| | | logicBool: true |
| | | }; |
| | | |
| | | let cpValues = JSON.parse(JSON.stringify(values)) |
| | | console.log(cpValues); |
| | | |
| | | let searchIndex = 0; |
| | | cpValues.forEach((value) => { |
| | | if (value.data.isLogic) { |
| | | value.data.searchLogicId = searchNode.id; |
| | | value.data.searchLogicBool = searchNode.logicBool; |
| | | value.data.searchIndex = searchIndex++; |
| | | |
| | | let tmpSearchNode = JSON.parse(JSON.stringify(searchNode)) |
| | | searchNode.parent = tmpSearchNode; |
| | | searchNode.id = value.id; |
| | | searchNode.logicBool = null; |
| | | searchIndex = 0; |
| | | } else { |
| | | let id = searchNode.id; |
| | | let logicBool = searchNode.logicBool; |
| | | |
| | | const connectedEdges = graph.getConnectedEdges(value);//取边 |
| | | connectedEdges.forEach((edge) => { |
| | | let tmpSearchNode = JSON.parse(JSON.stringify(searchNode)); |
| | | while (tmpSearchNode.parent != null) { |
| | | if (edge.source.cell == tmpSearchNode.id) { |
| | | logicBool = edge.data.logicBool;//更新方向 |
| | | searchNode.logicBool = edge.data.logicBool; |
| | | id = tmpSearchNode.id; |
| | | break; |
| | | } |
| | | tmpSearchNode = tmpSearchNode.parent; |
| | | } |
| | | }) |
| | | |
| | | value.data.searchLogicId = id; |
| | | value.data.searchLogicBool = logicBool; |
| | | value.data.searchIndex = searchIndex++; |
| | | } |
| | | }) |
| | | |
| | | console.log(cpValues); |
| | | console.log(searchNode); |
| | | |
| | | let tmp = {} |
| | | let tmpList = [] |
| | | let tmpIndex = 0; |
| | | for (let i = cpValues.length - 1; i >= 0; i--) { |
| | | let item = cpValues[i]; |
| | | if (tmp[item.data.searchLogicId] == null) { |
| | | tmpList[tmpIndex] = [item]; |
| | | tmp[item.data.searchLogicId] = { |
| | | index: tmpIndex, |
| | | code: "", |
| | | codeTrue: "", |
| | | codeFalse: "", |
| | | condition: "" |
| | | }; |
| | | tmpIndex++; |
| | | } else { |
| | | tmpList[tmp[item.data.searchLogicId].index].push(item); |
| | | } |
| | | } |
| | | |
| | | console.log(tmp, tmpList); |
| | | |
| | | tmpList.forEach((item) => { |
| | | item.forEach((val) => { |
| | | let originCode = tmp[val.data.searchLogicId].codeTrue; |
| | | if (!val.data.searchLogicBool) { |
| | | originCode = tmp[val.data.searchLogicId].codeFalse; |
| | | } |
| | | |
| | | let codeContent = val.data.codeContent; |
| | | |
| | | if (val.data.isLogic) { |
| | | codeContent = val.id + "_logic_tag"; |
| | | console.log(val.data); |
| | | tmp[val.id].condition = val.data.codeContent; |
| | | } else { |
| | | codeContent = ` |
| | | //**********${val.attrs.text.text}-start**********// |
| | | ${codeContent} |
| | | //**********${val.attrs.text.text}-start**********// |
| | | `; |
| | | } |
| | | let newCode = ` |
| | | ${codeContent} |
| | | |
| | | ${originCode} |
| | | `; |
| | | |
| | | console.log(newCode); |
| | | if (val.data.searchLogicBool) { |
| | | tmp[val.data.searchLogicId].codeTrue = newCode; |
| | | } else { |
| | | tmp[val.data.searchLogicId].codeFalse = newCode; |
| | | } |
| | | }) |
| | | }) |
| | | |
| | | let sortTmp = []; |
| | | for (var key in tmp) { |
| | | let obj = tmp[key]; |
| | | obj.id = key; |
| | | sortTmp[tmp[key].index] = obj; |
| | | } |
| | | |
| | | // 合并True和False |
| | | sortTmp.forEach((item) => { |
| | | let nestedIfCode = ""; |
| | | if (item.condition == "") { |
| | | nestedIfCode = ` |
| | | ${item.codeTrue} |
| | | ${item.codeFalse} |
| | | `; |
| | | } else { |
| | | nestedIfCode = ` |
| | | if(${item.condition}){ |
| | | // 逻辑TRUE |
| | | ${item.codeTrue} |
| | | }else { |
| | | // 逻辑FALSE |
| | | ${item.codeFalse} |
| | | } |
| | | `; |
| | | } |
| | | |
| | | item.code = nestedIfCode; |
| | | }) |
| | | |
| | | console.log(sortTmp); |
| | | |
| | | let finalTmp = {}; |
| | | let sortTmpCopy = JSON.parse(JSON.stringify(sortTmp)); |
| | | sortTmpCopy.forEach((item) => { |
| | | if (item.id != "1") { |
| | | let codeContent = item.code; |
| | | sortTmp.forEach((val) => { |
| | | codeContent = codeContent.replace(val.id + "_logic_tag", val.code); |
| | | console.log(item, val.id, codeContent); |
| | | }) |
| | | finalTmp[item.id] = { |
| | | code: codeContent |
| | | } |
| | | } |
| | | }) |
| | | |
| | | console.log(sortTmpCopy); |
| | | console.log(finalTmp); |
| | | |
| | | sortTmpCopy.forEach((item) => { |
| | | if (item.id == "1") { |
| | | let finalCode = item.code; |
| | | for (var key in finalTmp) { |
| | | let obj = finalTmp[key]; |
| | | finalCode = finalCode.replace(key + "_logic_tag", obj.code); |
| | | } |
| | | |
| | | codeContent = finalCode; |
| | | } |
| | | }) |
| | | |
| | | codeContent = formatJavaCode(codeContent) |
| | | return codeContent; |
| | | } |
| | | |
| | | const formatJavaCode = (codeString) => { |
| | | let baseIndentation = " "; //用四个空格表示一个缩进 |
| | | let indentationLevel = 0; //增加这行代码来初始化indentationLevel |
| | | |
| | | let formattedCode = codeString |
| | | .replace(/^\s+/mg, '') // 移除每行前面的空白 |
| | | .replace(/(\{|\})/g, ' $& ') // 让大括号周围都有空格 |
| | | // 上面的.replace(/^\s+/mg, '')可能会在括号周围插入多余的空格,所以下面这行代码会移除开头或末尾的空格 |
| | | .replace(/^\s+|\s+$/mg, '') |
| | | // 用了.split('\n')后,每一行都是数组中的一个元素,所以可以通过减少或增加行开头的空格数来添加或删除缩进 |
| | | .split('\n').reduce((formattedCode, currentLine) => { |
| | | if (currentLine.includes('}')) { |
| | | // 如果一行中包含右大括号,我们要减少一个缩进 |
| | | indentationLevel--; |
| | | } |
| | | |
| | | let indentation = baseIndentation.repeat(indentationLevel); |
| | | let indentedLine = indentation + currentLine; |
| | | |
| | | if (currentLine.includes('{')) { |
| | | // 如果一行中包含左大括号,那个大括号后面的代码需要额外的一个缩进 |
| | | indentationLevel++; |
| | | } |
| | | |
| | | return formattedCode + '\n' + indentedLine; |
| | | }, ''); |
| | | |
| | | return formattedCode; |
| | | } |
| | | |
| | | // const transCode = (rootNode, nodes, graph) => { |
| | | // let codeContent = ""; |
| | | // const descendants = []; |
| | | // let stack = [rootNode]; |
| | | |
| | | // let count = 0; |
| | | // while (stack.length > 0) { |
| | | // const current = stack.pop(); |
| | | // descendants.push(current); |
| | | |
| | | // const children = getChildren(current, nodes, graph); |
| | | // stack.push(...children); |
| | | |
| | | // // 输出代码 |
| | | // if (!current.data.isLogic) { |
| | | // const connectedEdges = graph.getConnectedEdges(current);//取边 |
| | | // connectedEdges.forEach((edge) => { |
| | | // //过滤从自身节点出去的边 |
| | | // if(edge.source.cell != current.id){ |
| | | // //取上一节点 |
| | | // let lastNode = null; |
| | | // nodes.forEach((node) => { |
| | | // if(node.id == edge.source.cell){ |
| | | // lastNode = node; |
| | | // } |
| | | // }) |
| | | |
| | | // if(lastNode != null) { |
| | | // //判断节点是否逻辑节点 |
| | | // if(lastNode.data.isLogic){ |
| | | // console.log(lastNode); |
| | | // let nestedIfCode = ""; |
| | | // if(lastNode.data.logicBool == 'true') { |
| | | // nestedIfCode = ` |
| | | // if (${lastNode.data.codeContent}) { |
| | | // ${current.data.codeContent} |
| | | // } |
| | | // `; |
| | | // }else{ |
| | | // nestedIfCode = ` |
| | | // if (!(${lastNode.data.codeContent})) { |
| | | // ${current.data.codeContent} |
| | | // } |
| | | // `; |
| | | // } |
| | | |
| | | |
| | | // codeContent += "\n" + nestedIfCode; |
| | | // console.log(codeContent); |
| | | // }else{ |
| | | // if (current.data.codeContent != null) { |
| | | // codeContent += "\n" + current.data.codeContent; |
| | | // } |
| | | // } |
| | | // } |
| | | // } |
| | | // console.log(current); |
| | | // }) |
| | | // } else { |
| | | // // if (current.data.codeContent != null) { |
| | | // // codeContent += "\n" + current.data.codeContent; |
| | | // // } |
| | | |
| | | // // const connectedEdges = graph.getConnectedEdges(current); |
| | | // // console.log(connectedEdges); |
| | | // // stack = [] |
| | | // // let test = [] |
| | | // // connectedEdges.forEach((edge) => { |
| | | // // nodes.forEach((item) => { |
| | | // // if (item.id === edge.target.cell && item.id != current.id) { |
| | | // // test.push(item); |
| | | // // } |
| | | // // }) |
| | | // // }); |
| | | // // console.log(test); |
| | | // // console.log(); |
| | | // // let nestedIfCode = ` |
| | | // // if (true}) { |
| | | // // ${current.data.codeContent} |
| | | // // } |
| | | // // `; |
| | | |
| | | // // codeContent += "\n" + nestedIfCode; |
| | | // // console.log(codeContent); |
| | | // } |
| | | |
| | | // } |
| | | |
| | | // console.log(codeContent); |
| | | // } |
| | | |
| | | const nodeDFS = (node, nodes, graph) => { |
| | | let values = []; |
| | | if (graph) { |
| | | const connectedEdges = graph.getConnectedEdges(node); |
| | | const children = []; |
| | | |
| | | console.log(node); |
| | | connectedEdges.forEach((edge) => { |
| | | nodes.forEach((item) => { |
| | | if (item.id === edge.target.cell && item.id != node.id) { |
| | | children.push(item); |
| | | } |
| | | }) |
| | | }); |
| | | |
| | | console.log(connectedEdges); |
| | | if (children.length != 0) { |
| | | console.log(children); |
| | | children.forEach((node) => { |
| | | console.log(node); |
| | | values.push(node); |
| | | values = values.concat(nodeDFS(node, nodes, graph)) |
| | | }) |
| | | } |
| | | } |
| | | |
| | | return values; |
| | | } |
| | | |
| | | const getChildren = (node, nodes, graph) => { |
| | | const connectedEdges = graph.getConnectedEdges(node); |
| | | const children = []; |
| | | |
| | | connectedEdges.forEach((edge) => { |
| | | nodes.forEach((item) => { |
| | | if (item.id === edge.target.cell && item.id != node.id) { |
| | | children.push(item); |
| | | } |
| | | }) |
| | | }); |
| | | |
| | | return children; |
| | | } |
| | | |
| | | const getDescendants = (node, nodes, graph) => { |
| | | const descendants = []; |
| | | const stack = [node]; |
| | | |
| | | let count = 0; |
| | | while (stack.length > 0) { |
| | | const current = stack.pop(); |
| | | descendants.push(current); |
| | | |
| | | const children = getChildren(current, nodes, graph); |
| | | stack.push(...children); |
| | | } |
| | | |
| | | return descendants; |
| | | } |
| | | |
| | | return ( |
| | | <> |
| | | <Button type="primary" onClick={exportData}> |
| | | 导出数据 |
| | | </Button> |
| | | <div className="container"> |
| | | <Button type="primary" onClick={exportData}> |
| | | 导出数据 |
| | | </Button> |
| | | |
| | | <Button type="primary" onClick={prewCode}> |
| | | 预览代码 |
| | | </Button> |
| | | </div> |
| | | |
| | | <Modal title="Basic Modal" open={isModalOpen} onOk={handleOk} onCancel={handleCancel}> |
| | | <SyntaxHighlighter language="java" style={solarizedlight}> |
| | | {preCode} |
| | | </SyntaxHighlighter> |
| | | </Modal> |
| | | </> |
| | | ); |
| | | } |
New file |
| | |
| | | .container { |
| | | width: 200px; |
| | | display: flex; |
| | | justify-content: space-around; |
| | | margin-top: 10px; |
| | | } |
New file |
| | |
| | | import React, { useRef, useEffect, useState } from "react"; |
| | | import { Button, message } from 'antd'; |
| | | import { last } from "lodash"; |
| | | |
| | | export const GraphTools = ({ graphRef, isReady }) => { |
| | | |
| | | let codeContent = ""; |
| | | |
| | | const exportData = () => { |
| | | const graph = graphRef.current; |
| | | if (isReady) { |
| | | const data = graph.toJSON(); |
| | | console.log(data); |
| | | // 这里你可以将数据发送到服务器或保存到本地 |
| | | |
| | | const edges = []; |
| | | const nodes = []; |
| | | let rootNode = null; |
| | | data.cells.forEach((item) => { |
| | | if (item.shape == "edge") { |
| | | edges.push(item) |
| | | } else { |
| | | nodes.push(item) |
| | | if (item.data.root) { |
| | | rootNode = item; |
| | | } |
| | | } |
| | | }) |
| | | |
| | | if (rootNode == null) { |
| | | message.warning('请设置程序入口组件'); |
| | | return; |
| | | } |
| | | |
| | | console.log(getDescendants(rootNode, nodes, graph)); |
| | | |
| | | transCode(rootNode, nodes, graph) |
| | | // nodeDFS(rootNode, nodes, graph, codeContent) |
| | | // console.log(codeContent); |
| | | } |
| | | } |
| | | |
| | | const transCode = (rootNode, nodes, graph) => { |
| | | let codeContent = ""; |
| | | const descendants = []; |
| | | let stack = [rootNode]; |
| | | |
| | | let existLogicNode = []; |
| | | let values = nodeDFS(rootNode, nodes, graph); |
| | | |
| | | let cpValues = JSON.parse(JSON.stringify(values)) |
| | | console.log(cpValues); |
| | | |
| | | let groupCode = {}; |
| | | let logicGroupSearch = {}; |
| | | let currentLogic = null; |
| | | cpValues.forEach((value) => { |
| | | if(value.data.isLogic) { |
| | | let tmp = {}; |
| | | if(currentLogic == null) { |
| | | tmp = { |
| | | id: value.id, |
| | | parent: null |
| | | } |
| | | }else{ |
| | | tmp = { |
| | | id: value.id, |
| | | parent: currentLogic |
| | | } |
| | | } |
| | | currentLogic = value.id; |
| | | logicGroupSearch[value.id] = tmp; |
| | | } |
| | | }) |
| | | |
| | | console.log(logicGroupSearch); |
| | | |
| | | let codeContentTmp = ""; |
| | | while (values.length > 0) { |
| | | const current = values.pop(); |
| | | const connectedEdges = graph.getConnectedEdges(current);//取边 |
| | | |
| | | connectedEdges.forEach((edge) => { |
| | | //过滤从自身节点出去的边 |
| | | if (edge.source.cell != current.id) { |
| | | //取上一节点 |
| | | let lastNode = null; |
| | | nodes.forEach((node) => { |
| | | if (node.id == edge.source.cell) { |
| | | lastNode = node; |
| | | } |
| | | }) |
| | | |
| | | if (lastNode != null) { |
| | | //判断节点是否逻辑节点 |
| | | if (lastNode.data.isLogic) { |
| | | let nestedCode = ` |
| | | //**********${current.attrs.text.text}-start**********// |
| | | ${current.data.codeContent} |
| | | //**********${current.attrs.text.text}-end**********// |
| | | `; |
| | | codeContentTmp = "\n" + nestedCode + codeContentTmp; |
| | | |
| | | let nestedIfCode = ""; |
| | | if (existLogicNode.indexOf(lastNode.id) == -1) { |
| | | //判断边逻辑值 |
| | | if (edge.data.logicBool == true) { |
| | | nestedIfCode = ` |
| | | //**********逻辑判断-${lastNode.attrs.text.text}-start**********// |
| | | if (${lastNode.data.codeContent}) { |
| | | ${codeContentTmp} |
| | | // } |
| | | // //**********逻辑判断-${lastNode.attrs.text.text}-end**********// |
| | | `; |
| | | } else { |
| | | nestedIfCode = ` |
| | | //**********逻辑判断-${lastNode.attrs.text.text}-start**********// |
| | | if (!(${lastNode.data.codeContent})) { |
| | | ${codeContentTmp} |
| | | // } |
| | | // //**********逻辑判断-${lastNode.attrs.text.text}-end**********// |
| | | `; |
| | | } |
| | | existLogicNode.push(lastNode.id); |
| | | |
| | | groupCode[lastNode.id + "-true"] = nestedIfCode; |
| | | } else { |
| | | nestedIfCode = ` |
| | | //**********逻辑判断-${lastNode.attrs.text.text}-start**********// |
| | | else { |
| | | ${codeContentTmp} |
| | | // } |
| | | // //**********逻辑判断-${lastNode.attrs.text.text}-end**********// |
| | | `; |
| | | |
| | | groupCode[lastNode.id + "-false"] = nestedIfCode; |
| | | } |
| | | |
| | | |
| | | codeContent += nestedIfCode; |
| | | codeContentTmp = ""; |
| | | |
| | | console.log(lastNode, current, true, codeContent); |
| | | } else { |
| | | if (current.data.codeContent != null && !current.data.isLogic) { |
| | | let nestedCode = ` |
| | | //**********${current.attrs.text.text}-start**********// |
| | | ${current.data.codeContent} |
| | | //**********${current.attrs.text.text}-end**********// |
| | | `; |
| | | codeContentTmp = "\n" + nestedCode + codeContentTmp; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | }) |
| | | |
| | | } |
| | | |
| | | console.log(groupCode); |
| | | console.log(codeContent); |
| | | |
| | | } |
| | | |
| | | // const transCode = (rootNode, nodes, graph) => { |
| | | // let codeContent = ""; |
| | | // const descendants = []; |
| | | // let stack = [rootNode]; |
| | | |
| | | // let count = 0; |
| | | // while (stack.length > 0) { |
| | | // const current = stack.pop(); |
| | | // descendants.push(current); |
| | | |
| | | // const children = getChildren(current, nodes, graph); |
| | | // stack.push(...children); |
| | | |
| | | // // 输出代码 |
| | | // if (!current.data.isLogic) { |
| | | // const connectedEdges = graph.getConnectedEdges(current);//取边 |
| | | // connectedEdges.forEach((edge) => { |
| | | // //过滤从自身节点出去的边 |
| | | // if(edge.source.cell != current.id){ |
| | | // //取上一节点 |
| | | // let lastNode = null; |
| | | // nodes.forEach((node) => { |
| | | // if(node.id == edge.source.cell){ |
| | | // lastNode = node; |
| | | // } |
| | | // }) |
| | | |
| | | // if(lastNode != null) { |
| | | // //判断节点是否逻辑节点 |
| | | // if(lastNode.data.isLogic){ |
| | | // console.log(lastNode); |
| | | // let nestedIfCode = ""; |
| | | // if(lastNode.data.logicBool == 'true') { |
| | | // nestedIfCode = ` |
| | | // if (${lastNode.data.codeContent}) { |
| | | // ${current.data.codeContent} |
| | | // } |
| | | // `; |
| | | // }else{ |
| | | // nestedIfCode = ` |
| | | // if (!(${lastNode.data.codeContent})) { |
| | | // ${current.data.codeContent} |
| | | // } |
| | | // `; |
| | | // } |
| | | |
| | | |
| | | // codeContent += "\n" + nestedIfCode; |
| | | // console.log(codeContent); |
| | | // }else{ |
| | | // if (current.data.codeContent != null) { |
| | | // codeContent += "\n" + current.data.codeContent; |
| | | // } |
| | | // } |
| | | // } |
| | | // } |
| | | // console.log(current); |
| | | // }) |
| | | // } else { |
| | | // // if (current.data.codeContent != null) { |
| | | // // codeContent += "\n" + current.data.codeContent; |
| | | // // } |
| | | |
| | | // // const connectedEdges = graph.getConnectedEdges(current); |
| | | // // console.log(connectedEdges); |
| | | // // stack = [] |
| | | // // let test = [] |
| | | // // connectedEdges.forEach((edge) => { |
| | | // // nodes.forEach((item) => { |
| | | // // if (item.id === edge.target.cell && item.id != current.id) { |
| | | // // test.push(item); |
| | | // // } |
| | | // // }) |
| | | // // }); |
| | | // // console.log(test); |
| | | // // console.log(); |
| | | // // let nestedIfCode = ` |
| | | // // if (true}) { |
| | | // // ${current.data.codeContent} |
| | | // // } |
| | | // // `; |
| | | |
| | | // // codeContent += "\n" + nestedIfCode; |
| | | // // console.log(codeContent); |
| | | // } |
| | | |
| | | // } |
| | | |
| | | // console.log(codeContent); |
| | | // } |
| | | |
| | | const nodeDFS = (node, nodes, graph) => { |
| | | let values = []; |
| | | if (graph) { |
| | | const connectedEdges = graph.getConnectedEdges(node); |
| | | const children = []; |
| | | |
| | | console.log(node); |
| | | connectedEdges.forEach((edge) => { |
| | | nodes.forEach((item) => { |
| | | if (item.id === edge.target.cell && item.id != node.id) { |
| | | children.push(item); |
| | | } |
| | | }) |
| | | }); |
| | | |
| | | console.log(connectedEdges); |
| | | if (children.length != 0) { |
| | | console.log(children); |
| | | children.forEach((node) => { |
| | | console.log(node); |
| | | values.push(node); |
| | | values = values.concat(nodeDFS(node, nodes, graph)) |
| | | }) |
| | | } |
| | | } |
| | | |
| | | return values; |
| | | } |
| | | |
| | | const getChildren = (node, nodes, graph) => { |
| | | const connectedEdges = graph.getConnectedEdges(node); |
| | | const children = []; |
| | | |
| | | connectedEdges.forEach((edge) => { |
| | | nodes.forEach((item) => { |
| | | if (item.id === edge.target.cell && item.id != node.id) { |
| | | children.push(item); |
| | | } |
| | | }) |
| | | }); |
| | | |
| | | return children; |
| | | } |
| | | |
| | | const getDescendants = (node, nodes, graph) => { |
| | | const descendants = []; |
| | | const stack = [node]; |
| | | |
| | | let count = 0; |
| | | while (stack.length > 0) { |
| | | const current = stack.pop(); |
| | | descendants.push(current); |
| | | |
| | | const children = getChildren(current, nodes, graph); |
| | | stack.push(...children); |
| | | } |
| | | |
| | | return descendants; |
| | | } |
| | | |
| | | return ( |
| | | <> |
| | | <Button type="primary" onClick={exportData}> |
| | | 导出数据 |
| | | </Button> |
| | | </> |
| | | ); |
| | | } |
| | |
| | | // 接口地址 |
| | | export const API_BASE_URL: string = 'http://127.0.0.1:9090/wcs'; |
| | | export const API_BASE_URL: string = 'http://192.168.4.113:9090/wcs'; |
| | | |
| | | // 项目名称 |
| | | export const PROJECT_NAME: string = 'admin'; |