diff --git a/openecomp-ui/src/nfvo-components/tree/Tree.jsx b/openecomp-ui/src/nfvo-components/tree/Tree.jsx
index 682f3b6..39434fc 100644
--- a/openecomp-ui/src/nfvo-components/tree/Tree.jsx
+++ b/openecomp-ui/src/nfvo-components/tree/Tree.jsx
@@ -1,16 +1,28 @@
-import React, {Component} from 'react';
+import React, { Component } from 'react';
 import PropTypes from 'prop-types';
-import {select} from 'd3-selection';
-import {tree, stratify} from 'd3-hierarchy';
-
+import { select } from 'd3-selection';
+import { tree, stratify } from 'd3-hierarchy';
 
 function diagonal(d) {
-
-	const offset = 50;
-	return 'M' + d.y + ',' + d.x
-		+ 'C' + (d.parent.y + offset) + ',' + d.x
-		+ ' ' + (d.parent.y + offset) + ',' + d.parent.x
-		+ ' ' + d.parent.y + ',' + d.parent.x;
+    const offset = 50;
+    return (
+        'M' +
+        d.y +
+        ',' +
+        d.x +
+        'C' +
+        (d.parent.y + offset) +
+        ',' +
+        d.x +
+        ' ' +
+        (d.parent.y + offset) +
+        ',' +
+        d.parent.x +
+        ' ' +
+        d.parent.y +
+        ',' +
+        d.parent.x
+    );
 }
 
 const nodeRadius = 8;
@@ -18,164 +30,226 @@
 const NARROW_HORIZONTAL_SPACES = 47;
 const WIDE_HORIZONTAL_SPACES = 65;
 
-const stratifyFn = stratify().id(d => d.id).parentId(d => d.parent);
+const stratifyFn = stratify()
+    .id(d => d.id)
+    .parentId(d => d.parent);
 
 class Tree extends Component {
+    // state = {
+    // 	startingCoordinates: null,
+    // 	isDown: false
+    // }
 
-	// state = {
-	// 	startingCoordinates: null,
-	// 	isDown: false
-	// }
+    static propTypes = {
+        name: PropTypes.string,
+        width: PropTypes.number,
+        allowScaleWidth: PropTypes.bool,
+        nodes: PropTypes.arrayOf(
+            PropTypes.shape({
+                id: PropTypes.string,
+                name: PropTypes.string,
+                parent: PropTypes.string
+            })
+        ),
+        selectedNodeId: PropTypes.string,
+        onNodeClick: PropTypes.func,
+        onRenderedBeyondWidth: PropTypes.func
+    };
 
-	static propTypes = {
-		name: PropTypes.string,
-		width: PropTypes.number,
-		allowScaleWidth: PropTypes.bool,
-		nodes: PropTypes.arrayOf(PropTypes.shape({
-			id: PropTypes.string,
-			name: PropTypes.string,
-			parent: PropTypes.string
-		})),
-		selectedNodeId: PropTypes.string,
-		onNodeClick: PropTypes.func,
-		onRenderedBeyondWidth: PropTypes.func
-	};
+    static defaultProps = {
+        width: 500,
+        allowScaleWidth: true,
+        name: 'default-name'
+    };
 
-	static defaultProps = {
-		width: 500,
-		allowScaleWidth : true,
-		name: 'default-name'
-	};
+    render() {
+        let { width, name, scrollable = false } = this.props;
+        return (
+            <div
+                className={`tree-view ${name}-container ${
+                    scrollable ? 'scrollable' : ''
+                }`}>
+                <svg width={width} className={name} />
+            </div>
+        );
+    }
 
-	render() {
-		let {width, name, scrollable = false} = this.props;
-		return (
-			<div
-				className={`tree-view ${name}-container ${scrollable ? 'scrollable' : ''}`}>
-				<svg width={width} className={name}></svg>
-			</div>
-		);
-	}
+    componentDidMount() {
+        this.renderTree();
+    }
 
-	componentDidMount() {
-		this.renderTree();
-	}
+    // handleMouseMove(e) {
+    // 	if (!this.state.isDown) {
+    // 		return;
+    // 	}
+    // 	const container = select(`.tree-view.${this.props.name}-container`);
+    // 	let coordinates = this.getCoordinates(e);
+    // 	container.property('scrollLeft' , container.property('scrollLeft') + coordinates.x - this.state.startingCoordinates.x);
+    // 	container.property('scrollTop' , container.property('scrollTop') + coordinates.y - this.state.startingCoordinates.y);
+    // }
 
-	// handleMouseMove(e) {
-	// 	if (!this.state.isDown) {
-	// 		return;
-	// 	}
-	// 	const container = select(`.tree-view.${this.props.name}-container`);
-	// 	let coordinates = this.getCoordinates(e);
-	// 	container.property('scrollLeft' , container.property('scrollLeft') + coordinates.x - this.state.startingCoordinates.x);
-	// 	container.property('scrollTop' , container.property('scrollTop') + coordinates.y - this.state.startingCoordinates.y);
-	// }
+    // handleMouseDown(e) {
+    // 	let startingCoordinates = this.getCoordinates(e);
+    // 	this.setState({
+    // 		startingCoordinates,
+    // 		isDown: true
+    // 	});
+    // }
 
-	// handleMouseDown(e) {
-	// 	let startingCoordinates = this.getCoordinates(e);
-	// 	this.setState({
-	// 		startingCoordinates,
-	// 		isDown: true
-	// 	});
-	// }
+    // handleMouseUp() {
+    // 	this.setState({
+    // 		startingCorrdinates: null,
+    // 		isDown: false
+    // 	});
+    // }
 
-	// handleMouseUp() {
-	// 	this.setState({
-	// 		startingCorrdinates: null,
-	// 		isDown: false
-	// 	});
-	// }
+    // getCoordinates(e) {
+    // 	var bounds = e.target.getBoundingClientRect();
+    // 	var x = e.clientX - bounds.left;
+    // 	var y = e.clientY - bounds.top;
+    // 	return {x, y};
+    // }
 
-	// getCoordinates(e) {
-	// 	var bounds = e.target.getBoundingClientRect();
-	// 	var x = e.clientX - bounds.left;
-	// 	var y = e.clientY - bounds.top;
-	// 	return {x, y};
-	// }
+    componentDidUpdate(prevProps) {
+        if (
+            this.props.nodes.length !== prevProps.nodes.length ||
+            this.props.selectedNodeId !== prevProps.selectedNodeId
+        ) {
+            console.log('update');
+            this.renderTree();
+        }
+    }
 
-	componentDidUpdate(prevProps) {
-		if (this.props.nodes.length !== prevProps.nodes.length ||
-			this.props.selectedNodeId !== prevProps.selectedNodeId) {
-			console.log('update');
-			this.renderTree();
-		}
-	}
+    renderTree() {
+        let {
+            width,
+            nodes,
+            name,
+            allowScaleWidth,
+            selectedNodeId,
+            onRenderedBeyondWidth,
+            toWiden
+        } = this.props;
+        if (nodes.length > 0) {
+            let horizontalSpaceBetweenLeaves = toWiden
+                ? WIDE_HORIZONTAL_SPACES
+                : NARROW_HORIZONTAL_SPACES;
+            const treeFn = tree().nodeSize([
+                horizontalSpaceBetweenLeaves,
+                verticalSpaceBetweenNodes
+            ]); //.size([width - 50, height - 50])
+            let root = stratifyFn(nodes).sort((a, b) =>
+                a.data.name.localeCompare(b.data.name)
+            );
+            let svgHeight =
+                verticalSpaceBetweenNodes * root.height + nodeRadius * 6;
 
-	renderTree() {
-		let {width, nodes, name, allowScaleWidth, selectedNodeId, onRenderedBeyondWidth, toWiden} = this.props;
-		if (nodes.length > 0) {
+            treeFn(root);
 
-			let horizontalSpaceBetweenLeaves = toWiden ? WIDE_HORIZONTAL_SPACES : NARROW_HORIZONTAL_SPACES;
-			const treeFn = tree().nodeSize([horizontalSpaceBetweenLeaves, verticalSpaceBetweenNodes]);//.size([width - 50, height - 50])
-			let root = stratifyFn(nodes).sort((a, b) => a.data.name.localeCompare(b.data.name));
-			let svgHeight = verticalSpaceBetweenNodes * root.height + nodeRadius * 6;
+            let nodesXValue = root.descendants().map(node => node.x);
+            let maxX = Math.max(...nodesXValue);
+            let minX = Math.min(...nodesXValue);
 
-			treeFn(root);
+            let svgTempWidth =
+                (maxX - minX) / 30 * horizontalSpaceBetweenLeaves;
+            let svgWidth = svgTempWidth < width ? width - 5 : svgTempWidth;
+            const svgEL = select(`svg.${name}`);
+            const container = select(`.tree-view.${name}-container`);
+            svgEL.html('');
+            svgEL.attr('height', svgHeight);
+            let canvasWidth = width;
+            if (svgTempWidth > width) {
+                if (allowScaleWidth) {
+                    canvasWidth = svgTempWidth;
+                }
+                // we seems to have a margin of 25px that we can still see with text
+                if (
+                    svgTempWidth - 25 > width &&
+                    onRenderedBeyondWidth !== undefined
+                ) {
+                    onRenderedBeyondWidth();
+                }
+            }
+            svgEL.attr('width', canvasWidth);
+            let rootGroup = svgEL
+                .append('g')
+                .attr(
+                    'transform',
+                    `translate(${svgWidth / 2 + nodeRadius},${nodeRadius *
+                        4}) rotate(90)`
+                );
 
-			let nodesXValue = root.descendants().map(node => node.x);
-			let maxX = Math.max(...nodesXValue);
-			let minX = Math.min(...nodesXValue);
+            // handle link
+            rootGroup
+                .selectAll('.link')
+                .data(root.descendants().slice(1))
+                .enter()
+                .append('path')
+                .attr('class', 'link')
+                .attr('d', diagonal);
 
-			let svgTempWidth = (maxX - minX) / 30 * (horizontalSpaceBetweenLeaves);
-			let svgWidth = svgTempWidth < width ? (width - 5) : svgTempWidth;
-			const svgEL = select(`svg.${name}`);
-			const container = select(`.tree-view.${name}-container`);
-			svgEL.html('');
-			svgEL.attr('height', svgHeight);
-			let canvasWidth = width;
-			if (svgTempWidth > width) {
-				if (allowScaleWidth) {
-					canvasWidth = svgTempWidth;
-				}
-				// we seems to have a margin of 25px that we can still see with text
-				if (((svgTempWidth - 25) > width) && onRenderedBeyondWidth !== undefined) {
-					onRenderedBeyondWidth();
-				}
-			};
-			svgEL.attr('width', canvasWidth);
-			let rootGroup = svgEL.append('g').attr('transform', `translate(${svgWidth / 2 + nodeRadius},${nodeRadius * 4}) rotate(90)`);
+            let node = rootGroup
+                .selectAll('.node')
+                .data(root.descendants())
+                .enter()
+                .append('g')
+                .attr(
+                    'class',
+                    node =>
+                        `node ${node.children ? ' has-children' : ' leaf'} ${
+                            node.id === selectedNodeId ? 'selectedNode' : ''
+                        } ${this.props.onNodeClick ? 'clickable' : ''}`
+                )
+                .attr(
+                    'transform',
+                    node => 'translate(' + node.y + ',' + node.x + ')'
+                )
+                .on('click', node => this.onNodeClick(node));
 
-			// handle link
-			rootGroup.selectAll('.link')
-				.data(root.descendants().slice(1))
-				.enter().append('path')
-				.attr('class', 'link')
-				.attr('d', diagonal);
+            node
+                .append('circle')
+                .attr('r', nodeRadius)
+                .attr('class', 'outer-circle');
+            node
+                .append('circle')
+                .attr('r', nodeRadius - 3)
+                .attr('class', 'inner-circle');
 
-			let node = rootGroup.selectAll('.node')
-				.data(root.descendants())
-				.enter().append('g')
-				.attr('class', node => `node ${node.children ? ' has-children' : ' leaf'} ${node.id === selectedNodeId ? 'selectedNode' : ''} ${this.props.onNodeClick ? 'clickable' : ''}`)
-				.attr('transform', node => 'translate(' + node.y + ',' + node.x + ')')
-				.on('click', node => this.onNodeClick(node));
+            node
+                .append('text')
+                .attr('y', nodeRadius / 4 + 1)
+                .attr('x', -nodeRadius * 1.8)
+                .text(node => node.data.name)
+                .attr('transform', 'rotate(-90)');
 
-			node.append('circle').attr('r', nodeRadius).attr('class', 'outer-circle');
-			node.append('circle').attr('r', nodeRadius - 3).attr('class', 'inner-circle');
+            let selectedNode = selectedNodeId
+                ? root.descendants().find(node => node.id === selectedNodeId)
+                : null;
+            if (selectedNode) {
+                container.property(
+                    'scrollLeft',
+                    svgWidth / 4 +
+                        (svgWidth / 4 - 100) -
+                        selectedNode.x / 30 * horizontalSpaceBetweenLeaves
+                );
+                container.property(
+                    'scrollTop',
+                    selectedNode.y / 100 * verticalSpaceBetweenNodes
+                );
+            } else {
+                container.property(
+                    'scrollLeft',
+                    svgWidth / 4 + (svgWidth / 4 - 100)
+                );
+            }
+        }
+    }
 
-			node.append('text')
-				.attr('y', nodeRadius / 4 + 1)
-				.attr('x', - nodeRadius * 1.8)
-				.text(node => node.data.name)
-				.attr('transform', 'rotate(-90)');
-
-			let selectedNode = selectedNodeId ? root.descendants().find(node => node.id === selectedNodeId) : null;
-			if (selectedNode) {
-
-				container.property('scrollLeft', (svgWidth / 4) + (svgWidth / 4 - 100) - (selectedNode.x / 30 * horizontalSpaceBetweenLeaves));
-				container.property('scrollTop', (selectedNode.y / 100 * verticalSpaceBetweenNodes));
-
-			} else {
-				container.property('scrollLeft', (svgWidth / 4) + (svgWidth / 4 - 100));
-			}
-		}
-	}
-
-	onNodeClick(node) {
-		if (this.props.onNodeClick) {
-			this.props.onNodeClick(node.data);
-		}
-	}
-
+    onNodeClick(node) {
+        if (this.props.onNodeClick) {
+            this.props.onNodeClick(node.data);
+        }
+    }
 }
 
 export default Tree;
