summaryrefslogtreecommitdiffstats
path: root/catalog-ui/src/app/ng2/pages/composition/graph/common/common-graph-utils.ts
diff options
context:
space:
mode:
Diffstat (limited to 'catalog-ui/src/app/ng2/pages/composition/graph/common/common-graph-utils.ts')
-rw-r--r--catalog-ui/src/app/ng2/pages/composition/graph/common/common-graph-utils.ts304
1 files changed, 304 insertions, 0 deletions
diff --git a/catalog-ui/src/app/ng2/pages/composition/graph/common/common-graph-utils.ts b/catalog-ui/src/app/ng2/pages/composition/graph/common/common-graph-utils.ts
new file mode 100644
index 0000000000..bfc540e97e
--- /dev/null
+++ b/catalog-ui/src/app/ng2/pages/composition/graph/common/common-graph-utils.ts
@@ -0,0 +1,304 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 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 * as _ from "lodash";
+import {
+ CommonNodeBase,
+ Relationship,
+ CompositionCiNodeBase
+} from "app/models";
+import {CompositionCiServicePathLink} from "app/models/graph/graph-links/composition-graph-links/composition-ci-service-path-link";
+import {Requirement, Capability} from "app/models";
+import {Injectable} from "@angular/core";
+
+
+
+@Injectable()
+export class CommonGraphUtils {
+
+ constructor() {
+
+ }
+
+ public safeApply = (scope:ng.IScope, fn:any) => { //todo remove to general utils
+ let phase = scope.$root.$$phase;
+ if (phase == '$apply' || phase == '$digest') {
+ if (fn && (typeof(fn) === 'function')) {
+ fn();
+ }
+ } else {
+ scope.$apply(fn);
+ }
+ };
+
+ /**
+ * Draw node on the graph
+ * @param cy
+ * @param compositionGraphNode
+ * @param position
+ * @returns {CollectionElements}
+ */
+ public addNodeToGraph(cy:Cy.Instance, compositionGraphNode:CommonNodeBase, position?:Cy.Position):Cy.CollectionElements {
+
+ let node = cy.add(<Cy.ElementDefinition> {
+ group: 'nodes',
+ position: position,
+ data: compositionGraphNode,
+ classes: compositionGraphNode.classes
+ });
+
+ this.initNodeTooltip(node);
+ return node;
+ };
+
+ /**
+ * The function will create a component instance node by the componentInstance position.
+ * If the node is UCPE the function will create all cp lan&wan for the ucpe
+ * @param cy
+ * @param compositionGraphNode
+ * @returns {Cy.CollectionElements}
+ */
+ public addComponentInstanceNodeToGraph(cy:Cy.Instance, compositionGraphNode:CompositionCiNodeBase):Cy.CollectionElements {
+
+ let nodePosition = {
+ x: +compositionGraphNode.componentInstance.posX,
+ y: +compositionGraphNode.componentInstance.posY
+ };
+
+ let node = this.addNodeToGraph(cy, compositionGraphNode, nodePosition);
+ return node;
+ };
+
+ /**
+ * Add service path link to graph - only draw the link
+ * @param cy
+ * @param link
+ */
+ public insertServicePathLinkToGraph = (cy:Cy.Instance, link:CompositionCiServicePathLink) => {
+ let linkElement = cy.add({
+ group: 'edges',
+ data: link,
+ classes: link.classes
+ });
+ this.initServicePathTooltip(linkElement, link);
+ };
+
+ /**
+ * Returns function for the link tooltip content
+ * @param {Relationship} linkRelation
+ * @param {Requirement} requirement
+ * @param {Capability} capability
+ * @returns {() => string}
+ * @private
+ */
+ private _getLinkTooltipContent(linkRelation:Relationship, requirement?:Requirement, capability?:Capability):string {
+ return '<div class="line">' +
+ '<span class="req-cap-label">R: </span>' +
+ '<span>' + (requirement ? requirement.getTitle() : linkRelation.relation.requirement) + '</span>' +
+ '</div>' +
+ '<div class="line">' +
+ '<div class="sprite-new link-tooltip-arrow"></div>' +
+ '<span class="req-cap-label">C: </span>' +
+ '<span>' + (capability ? capability.getTitle() : linkRelation.relation.capability) + '</span>' +
+ '</div>';
+ }
+
+ /**
+ * This function will init qtip tooltip on the link
+ * @param linkElement - the link we want the tooltip to apply on,
+ * @param link
+ * @param getLinkRequirementCapability
+ * link - the link obj
+ */
+ public initLinkTooltip(linkElement:Cy.CollectionElements, link:Relationship, getLinkRequirementCapability:Function) {
+ const content = () => this._getLinkTooltipContent(link); // base tooltip content without owner names
+ const render = (event, api) => {
+ // on render (called once at first show), get the link requirement and capability and change to full tooltip content (with owner names)
+ getLinkRequirementCapability().then((linkReqCap) => {
+ const fullContent = () => this._getLinkTooltipContent(link, linkReqCap.requirement, linkReqCap.capability);
+ api.set('content.text', fullContent);
+ });
+ };
+ linkElement.qtip(this.prepareInitTooltipData({content, events: {render}}));
+ };
+
+ /**
+ *
+ * @param linkElement
+ * @param link
+ */
+ public initServicePathTooltip(linkElement:Cy.CollectionElements, link:CompositionCiServicePathLink) {
+ let content = function () {
+ return '<div class="line">' +
+ '<div>' + link.pathName + '</div>' +
+ '</div>';
+ };
+ linkElement.qtip(this.prepareInitTooltipData({content}));
+ };
+
+ private prepareInitTooltipData(options?:Object) {
+ return _.merge({
+ position: {
+ my: 'top center',
+ at: 'bottom center',
+ adjust: {x: 0, y: 0},
+ effect: false
+ },
+ style: {
+ classes: 'qtip-dark qtip-rounded qtip-custom link-qtip',
+ tip: {
+ width: 16,
+ height: 8
+ }
+ },
+ show: {
+ event: 'mouseover',
+ delay: 1000
+ },
+ hide: {event: 'mouseout mousedown'},
+ includeLabels: true,
+ events: {}
+ }, options);
+ }
+
+ public HTMLCoordsToCytoscapeCoords(cytoscapeBoundingBox:Cy.Extent, mousePos:Cy.Position):Cy.Position {
+ return {x: mousePos.x + cytoscapeBoundingBox.x1, y: mousePos.y + cytoscapeBoundingBox.y1}
+ };
+
+
+ public getCytoscapeNodePosition = (cy:Cy.Instance, event:DragEvent | MouseEvent):Cy.Position => {
+ let targetOffset = $(event.target).offset();
+ if(event instanceof DragEvent) {
+ targetOffset = $('canvas').offset();
+ }
+
+ let x = (event.pageX - targetOffset.left) / cy.zoom();
+ let y = (event.pageY - targetOffset.top) / cy.zoom();
+
+ return this.HTMLCoordsToCytoscapeCoords(cy.extent(), {
+ x: x,
+ y: y
+ });
+ };
+
+
+ public getNodePosition(node:Cy.CollectionFirstNode):Cy.Position {
+ let nodePosition = node.relativePoint();
+ if (node.data().isUcpe) { //UCPEs use bounding box and not relative point.
+ nodePosition = {x: node.boundingbox().x1, y: node.boundingbox().y1};
+ }
+
+ return nodePosition;
+ }
+
+ /**
+ * Generic function that can be used for any html elements overlaid on canvas
+ * Returns the html position of a node on canvas, including left palette and header offsets. Option to pass in additional offset to add to return position.
+ * @param node
+ * @param additionalOffset
+ * @returns {Cy.Position}
+
+ public getNodePositionWithOffset = (node:Cy.CollectionFirstNode, additionalOffset?:Cy.Position): Cy.Position => {
+ if(!additionalOffset) additionalOffset = {x: 0, y:0};
+
+ let nodePosition = node.renderedPosition();
+ let posWithOffset:Cy.Position = {
+ x: nodePosition.x + GraphUIObjects.DIAGRAM_PALETTE_WIDTH_OFFSET + additionalOffset.x,
+ y: nodePosition.y + GraphUIObjects.COMPOSITION_HEADER_OFFSET + additionalOffset.y
+ };
+ return posWithOffset;
+ };*/
+
+ /**
+ * return true/false if first node contains in second - this used in order to verify is node is entirely inside ucpe
+ * @param firstBox
+ * @param secondBox
+ * @returns {boolean}
+ */
+ public isFirstBoxContainsInSecondBox(firstBox:Cy.BoundingBox, secondBox:Cy.BoundingBox) {
+
+ return firstBox.x1 > secondBox.x1 && firstBox.x2 < secondBox.x2 && firstBox.y1 > secondBox.y1 && firstBox.y2 < secondBox.y2;
+
+ };
+
+ /**
+ *
+ * @param cy
+ * @param node
+ * @returns {Array}
+ */
+ public getLinkableNodes(cy:Cy.Instance, node:Cy.CollectionFirstNode):Array<CompositionCiNodeBase> {
+ let compatibleNodes = [];
+ _.each(cy.nodes(), (tempNode)=> {
+ if (this.nodeLocationsCompatible(node, tempNode)) {
+ compatibleNodes.push(tempNode.data());
+ }
+ });
+ return compatibleNodes;
+ }
+
+ /**
+ * Checks whether node locations are compatible in reference to UCPEs.
+ * Returns true if both nodes are in UCPE or both nodes out, or one node is UCPEpart.
+ * @param node1
+ * @param node2
+ */
+ public nodeLocationsCompatible(node1:Cy.CollectionFirstNode, node2:Cy.CollectionFirstNode) {
+ return (this.isFirstBoxContainsInSecondBox(node1.boundingbox(), node2.boundingbox()));
+ }
+
+ /**
+ * This function will init qtip tooltip on the node
+ * @param node - the node we want the tooltip to apply on
+ */
+ public initNodeTooltip(node:Cy.CollectionNodes) {
+
+ let opts = {
+ content: function () {
+ return this.data('name');
+ },
+ position: {
+ my: 'top center',
+ at: 'bottom center',
+ adjust: {x: 0, y: -5}
+ },
+ style: {
+ classes: 'qtip-dark qtip-rounded qtip-custom',
+ tip: {
+ width: 16,
+ height: 8
+ }
+ },
+ show: {
+ event: 'mouseover',
+ delay: 1000
+ },
+ hide: {event: 'mouseout mousedown'},
+ includeLabels: true
+ };
+
+ if (node.data().isUcpePart) { //fix tooltip positioning for UCPE-cps
+ opts.position.adjust = {x: 0, y: 20};
+ }
+
+ node.qtip(opts);
+ };
+}
+