From a3798b8bfae35cbb42cf400d78c21f1567a8f120 Mon Sep 17 00:00:00 2001 From: Jayasanka Date: Mon, 6 May 2019 14:57:53 +0530 Subject: [PATCH] created util to auto arrange nodes in LifeCycle --- .../react-app/package.json | 1 + .../src/components/apps/release/LifeCycle.js | 38 ++++++++++++- .../react-app/src/js/utils/dagre-utils.ts | 56 +++++++++++++++++++ 3 files changed, 94 insertions(+), 1 deletion(-) create mode 100644 components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/js/utils/dagre-utils.ts diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/package.json b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/package.json index c8a73873f2..469943d5b7 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/package.json +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/package.json @@ -13,6 +13,7 @@ "acorn": "^6.1.1", "antd": "^3.15.0", "axios": "^0.18.0", + "dagre": "^0.8.4", "keymirror": "^0.1.1", "react": "^16.8.4", "react-dom": "^16.8.4", diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/release/LifeCycle.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/release/LifeCycle.js index 55d9140a3b..fcecc41a77 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/release/LifeCycle.js +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/apps/release/LifeCycle.js @@ -2,9 +2,13 @@ import React from "react"; import * as SRD from "storm-react-diagrams"; import "storm-react-diagrams/dist/style.min.css"; import "./LifeCycle.css"; +import {distributeElements} from "../../../js/utils/dagre-utils.ts"; + class LifeCycle extends React.Component { render() { + const nodes = []; + const engine = new SRD.DiagramEngine(); engine.installDefaultFactories(); @@ -24,9 +28,17 @@ class LifeCycle extends React.Component { const link1 = port1.link(port2); const link2 = port1.link(port3); + + nodes.push(createNode("hi")); + + nodes.forEach((node)=>{ + model.addNode(node); + }); + model.addAll(node1, node2, node3, link1, link2); - engine.setDiagramModel(model); + let distributedModel = getDistributedModel(engine, model); + engine.setDiagramModel(distributedModel); return (
@@ -36,4 +48,28 @@ class LifeCycle extends React.Component { } } +function getDistributedModel(engine, model) { + const serialized = model.serializeDiagram(); + const distributedSerializedDiagram = distributeElements(serialized); + + //deserialize the model + let deSerializedModel = new SRD.DiagramModel(); + deSerializedModel.deSerializeDiagram(distributedSerializedDiagram, engine); + return deSerializedModel; +} + +function createNode(name) { + return new SRD.DefaultNodeModel(name, "rgb(0,192,255)"); +} + +let count = 0; + +function connectNodes(nodeFrom, nodeTo) { + //just to get id-like structure + count++; + const portOut = nodeFrom.addPort(new SRD.DefaultPortModel(true, `${nodeFrom.name}-out-${count}`, "Out")); + const portTo = nodeTo.addPort(new SRD.DefaultPortModel(false, `${nodeFrom.name}-to-${count}`, "IN")); + return portOut.link(portTo); +} + export default LifeCycle; \ No newline at end of file diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/js/utils/dagre-utils.ts b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/js/utils/dagre-utils.ts new file mode 100644 index 0000000000..58a006f9a9 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/js/utils/dagre-utils.ts @@ -0,0 +1,56 @@ +import * as dagre from "dagre"; +import * as _ from "lodash"; + +const size = { + width: 60, + height: 60 +}; + +export function distributeElements(model) { + let clonedModel = _.cloneDeep(model); + let nodes = distributeGraph(clonedModel); + nodes.forEach(node => { + let modelNode = clonedModel.nodes.find(item => item.id === node.id); + modelNode.x = node.x - node.width / 2; + modelNode.y = node.y - node.height / 2; + }); + return clonedModel; +} + +function distributeGraph(model) { + let nodes = mapElements(model); + let edges = mapEdges(model); + let graph = new dagre.graphlib.Graph(); + graph.setGraph({}); + graph.setDefaultEdgeLabel(() => ({})); + //add elements to dagre graph + nodes.forEach(node => { + graph.setNode(node.id, node.metadata); + }); + edges.forEach(edge => { + if (edge.from && edge.to) { + graph.setEdge(edge.from, edge.to); + } + }); + //auto-distribute + dagre.layout(graph); + return graph.nodes().map(node => graph.node(node)); +} + +function mapElements(model) { + // dagre compatible format + return model.nodes.map(node => ({ id: node.id, metadata: { ...size, id: node.id } })); +} + +function mapEdges(model) { + // returns links which connects nodes + // we check are there both from and to nodes in the model. Sometimes links can be detached + return model.links + .map(link => ({ + from: link.source, + to: link.target + })) + .filter( + item => model.nodes.find(node => node.id === item.from) && model.nodes.find(node => node.id === item.to) + ); +} \ No newline at end of file