Create SVG in UI
[clamp.git] / ui-react / src / components / loop_viewer / svg / SvgGenerator.js
diff --git a/ui-react/src/components/loop_viewer/svg/SvgGenerator.js b/ui-react/src/components/loop_viewer/svg/SvgGenerator.js
new file mode 100644 (file)
index 0000000..d718c2e
--- /dev/null
@@ -0,0 +1,240 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ *
+ */
+
+import React from 'react'
+import styled from 'styled-components';
+import { withRouter } from "react-router-dom";
+import LoopCache from '../../../api/LoopCache';
+import OnapConstant from '../../../utils/OnapConstants';
+
+const DivStyled = styled.div`
+       overflow-x: scroll;
+    width: 100%;
+    height: 100%;
+`
+
+const emptySvg = (<svg> <text x="20" y="40">No LOOP (SVG)</text> </svg>);
+
+class SvgGenerator extends React.Component {
+    boxWidth = 200;
+    boxHeight = 100;
+    boxSpace = 50;
+
+    static GENERATED_FROM_INSTANCE = "INSTANCE";
+    static GENERATED_FROM_TEMPLATE = "TEMPLATE";
+
+       state = {
+               loopCache: new LoopCache({}),
+               clickable: false,
+               generatedFrom: SvgGenerator.GENERATED_FROM_INSTANCE, // INSTANCE / TEMPLATE
+       }
+
+       constructor(props) {
+               super(props);
+               this.state.loopCache = props.loopCache;
+               this.state.clickable = props.clickable;
+               this.state.generatedFrom = props.generatedFrom;
+               this.handleSvgClick = this.handleSvgClick.bind(this);
+               this.renderSvg = this.renderSvg.bind(this);
+       }
+
+       shouldComponentUpdate(nextProps, nextState) {
+               return this.state.loopCache !== nextState.loopCache;
+       }
+
+       componentWillReceiveProps(newProps) {
+               if (this.state.loopCache !== newProps.loopCache) {
+                       this.setState({
+                               loopCache: newProps.loopCache,
+                       });
+               }
+       }
+
+       handleSvgClick(event) {
+           if (this.state.clickable) {
+            console.debug("svg click event received");
+            var elementName = event.target.parentNode.getAttribute('policyId');
+            console.info("SVG element clicked", elementName);
+            if (elementName !== null) {
+                this.props.history.push("/policyModal/"+event.target.parentNode.getAttribute('policyType')+"/"+elementName);
+            }
+               }
+       }
+
+    createVesBox (xPos) {
+        return this.createOneBox(xPos,null,null,'VES Collector','VES',null);
+    }
+
+    createOneArrow(xPos) {
+        return (
+         <svg width={this.boxSpace} height={this.boxHeight} x={xPos}>
+           <defs>
+                       <marker viewBox="0 0 20 20" markerWidth="20" markerHeight="20" orient="auto" refX="8.5" refY="5" id="arrow">
+                               <path d="m 1 5 l 0 -3 l 7 3 l -7 3 z"
+                                       stroke-width= "1" stroke-linecap= "butt" stroke-dasharray= "10000, 1"
+                                       fill="#000000" stroke="#000000" />
+                       </marker>
+           </defs>
+           <line x1="0" y1="50%" x2="100%" y2="50%" stroke-width="2" color="black" stroke="black" marker-end="url(#arrow)"/>
+         </svg>
+        );
+    }
+
+    createBeginCircle(xPos, text) {
+            return (
+            <svg width={this.boxWidth} height={this.boxHeight} x={xPos}>
+                <circle cx={this.boxWidth-30} cy="50%" r="30" stroke-width="1" color="black" stroke="black" fill="#27ae60"/>
+                <text x={this.boxWidth-30} y="50%" text-anchor="middle" dominant-baseline="middle" textLength="20%" lengthAdjust="spacingAndGlyphs" >{text}</text>
+            </svg>
+            );
+    }
+
+    createEndCircle(xPos, text) {
+            return (
+            <svg width={this.boxWidth} height={this.boxHeight} x={xPos}>
+                <circle cx={30} cy="50%" r="30" stroke-width="2" color="black" stroke="black" fill="#27ae60"/>
+                <text x={30} y="50%" text-anchor="middle" dominant-baseline="middle" textLength="20%" lengthAdjust="spacingAndGlyphs" >{text}</text>
+            </svg>
+            );
+    }
+
+    createOneBox(xPos, policyId, loopElementModelId , name, title, policyType) {
+        return (
+        <svg width={this.boxWidth} height={this.boxHeight} x={xPos} title="test">
+            <g policyId={policyId} loopElementModelId={loopElementModelId} policyType={policyType}>
+                <rect width="100%" height="100%" stroke-width="2" color="black" stroke="black" fill="#1abc9c"/>
+                <text x="50%" y="15%" color="white" fill="white" dominant-baseline="middle" text-anchor="middle" textLength="50%" lengthAdjust="spacingAndGlyphs">{title}</text>
+                <text x="50%" y="50%" text-anchor="middle" dominant-baseline="middle" textLength="80%" lengthAdjust="spacingAndGlyphs" >{name}</text>
+                <text x="50%" y="80%" text-anchor="middle" dominant-baseline="middle" textLength="110%" lengthAdjust="spacingAndGlyphs" >{policyId}</text>
+            </g>
+        </svg>
+        );
+    }
+
+    createSvgFromTemplate() {
+        const allElements = [];
+        var xPos = 0;
+
+        allElements.push(this.createBeginCircle(xPos,"Start"))
+        xPos+=(this.boxWidth+this.boxSpace);
+
+        allElements.push(this.createOneArrow(xPos-this.boxSpace));
+
+        allElements.push(this.createVesBox(xPos));
+        xPos+=(this.boxWidth+this.boxSpace);
+
+        allElements.push(this.createOneArrow(xPos-this.boxSpace));
+        //createOneBox(xPos, policyId, loopElementModelId , name, title, policyType)
+        for (var loopElement of this.state.loopCache.getAllLoopElementModels()) {
+
+            allElements.push(this.createOneBox(xPos,
+                loopElement['name'],
+                loopElement['name'],
+                loopElement['shortName'],
+                loopElement['loopElementType'],
+                loopElement['loopElementType']))
+            xPos+=(this.boxWidth+this.boxSpace);
+            allElements.push(this.createOneArrow(xPos-this.boxSpace));
+        }
+
+        allElements.push(this.createEndCircle(xPos, "End"))
+        xPos+=(this.boxWidth+this.boxSpace);
+
+        return allElements;
+    }
+
+    createSvgFromInstance() {
+        const allElements = [];
+        var xPos = 0;
+
+        allElements.push(this.createBeginCircle(xPos,"Start"))
+        xPos+=(this.boxWidth+this.boxSpace);
+
+        allElements.push(this.createOneArrow(xPos-this.boxSpace));
+
+        allElements.push(this.createVesBox(xPos));
+        xPos+=(this.boxWidth+this.boxSpace);
+
+        allElements.push(this.createOneArrow(xPos-this.boxSpace));
+
+        for (var msPolicy in this.state.loopCache.getMicroServicePolicies()) {
+            var loopElementModelName =  this.state.loopCache.getMicroServicePolicies()[msPolicy]['loopElementModel'];
+            if (loopElementModelName !== undefined) {
+                loopElementModelName = loopElementModelName['name'];
+            }
+            allElements.push(this.createOneBox(xPos,
+                this.state.loopCache.getMicroServicePolicies()[msPolicy]['name'],
+                loopElementModelName,
+                this.state.loopCache.getMicroServicePolicies()[msPolicy]['policyModel']['policyAcronym'],
+                'microservice',
+                OnapConstant.microServiceType))
+            xPos+=(this.boxWidth+this.boxSpace);
+            allElements.push(this.createOneArrow(xPos-this.boxSpace));
+        }
+
+        for (var opPolicy in this.state.loopCache.getOperationalPolicies()) {
+            loopElementModelName =  this.state.loopCache.getOperationalPolicies()[opPolicy]['loopElementModel'];
+            if (loopElementModelName !== undefined) {
+                loopElementModelName = loopElementModelName['name'];
+            }
+            allElements.push(this.createOneBox(xPos,
+                this.state.loopCache.getOperationalPolicies()[opPolicy]['name'],
+                loopElementModelName,
+                this.state.loopCache.getOperationalPolicies()[opPolicy]['policyModel']['policyAcronym'],
+                'operational',
+                OnapConstant.operationalPolicyType))
+            xPos+=(this.boxWidth+this.boxSpace);
+            allElements.push(this.createOneArrow(xPos-this.boxSpace));
+        }
+
+        allElements.push(this.createEndCircle(xPos, "End"))
+        xPos+=(this.boxWidth+this.boxSpace);
+
+        return allElements;
+    }
+
+    renderSvg() {
+        if (this.state.loopCache.getLoopName() === undefined) {
+            return [emptySvg];
+        }
+        if (this.state.generatedFrom === SvgGenerator.GENERATED_FROM_INSTANCE) {
+            return this.createSvgFromInstance();
+        } else if (this.state.generatedFrom === SvgGenerator.GENERATED_FROM_TEMPLATE) {
+            return this.createSvgFromTemplate();
+        }
+    }
+
+    render() {
+        var allTheElements = this.renderSvg();
+        var svgWidth = this.boxWidth*allTheElements.length;
+        var svgHeight = this.boxHeight+100;
+        return (
+            <DivStyled onClick={this.handleSvgClick} >
+                <svg height={svgHeight} width={svgWidth}  preserveAspectRatio="none">
+                    {allTheElements}
+                </svg>
+            </DivStyled>
+        );
+    }
+}
+
+export default withRouter(SvgGenerator);