<%@ page import = "net.sf.json.*"%>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>


<!doctype html>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta charset="utf-8">
<script  src="/final/jquery/jquery.js"></script>
<script  src="/final/scripts/d3.min.js"></script>
<script  src="/final/scripts/dagre-d3.js"></script>
<script>
<%
JSONObject jsonResult = (JSONObject)session.getAttribute("jsonResult");
JSONObject jsonResultTop = new JSONObject();
if(jsonResult!=null)
{
	jsonResultTop.putAll(jsonResult);
	jsonResultTop.remove("headerDetails");
	jsonResultTop.remove("userTooltip");
}
String strInstallDir = com.eg.EgInstallInfo.getInstallDir();
strInstallDir = strInstallDir.replaceAll("\\\\","/");

%>
var jsondata = '<%=jsonResultTop%>'
jsondata = jsondata.replace(/\\/g, "\\\\") ;
var imgpath='<%=strInstallDir+"/manager/tomcat/webapps/final/images"%>';
</script>
<style id="css">
*{margin:0;padding:0px}
body,svg{overflow:hidden}
rect {
  fill: none;
}
rect.labelpatch,
rect.linestateiconpatch{
fill: #fff;
}
.edgePath path {
  stroke: #918f8f;
  fill: #918f8f;
  stroke-width: 2px;
  shape-rendering:auto
}
</style>
<body background-color="#ffffff">
<div id="render"></div>
</body>
<script>
var data = JSON.parse(jsondata);
var lindwidth=1;
var tempmarginy=50;
/*
if(data.nodes.length<=3)
{
	lindwidth=55;
	if(data.links.length>4)
		lindwidth=1;
}*/
var viewBoxX=0;
var viewBoxY=0;
/*
if(data.nodes.length<=3)
{
	viewBoxX=-20;
	if(data.links.length>4)
		viewBoxX=0;
}
if(data.nodes.length<=3)
{
	viewBoxX=-150;
	if(data.links.length>4)
	viewBoxX=0;
}
if(data.nodes.length<=3)
{
	tempmarginy=155;
}
*/

(function(selector, graphData) {
  var graphDataBTM = graphData;
  var drawGraph = function() {
        var graphObjTools = {
            graphRender: new dagreD3.render(),
            zoom: d3.behavior.zoom(),
            minZoom: 0.2,
            maxZoom: 2,
            initialScale: 1.7,
            d3Translate: d3.behavior.zoom().translate(),
            d3Scale: d3.behavior.zoom().scale(),
            assets: {},
            fontSize: 10,
            graphWidth: 842,
            graphHeight: 595,
            getWidth: function() {
                return this.graphWidth;
            },
            getHeight: function() {
                return this.graphHeight;
            },
			
            lineInterpolate: "monotone",
            graphAlign: "LR",
            nodeData: [],
            linkData: []
        }
		// Removing All child nodes
		d3.select(selector[0]).selectAll("*").remove();
        var rootSVG = d3.select(selector[0]).append("svg").attr("width", graphObjTools.graphWidth).attr("height", graphObjTools.graphHeight).attr("class", "graph-attach");
        //rootSVG.attr('viewBox', "-20 -180 " + graphObjTools.graphWidth + " " + graphObjTools.graphHeight + "").attr('preserveAspectRatio', 'xMinYMin meet');
        rootSVG.attr('viewBox', viewBoxX+" "+viewBoxY +" "+ graphObjTools.graphWidth + " " + graphObjTools.graphHeight + "").attr('preserveAspectRatio', 'xMinYMin meet');
        rootSVG.attr('xmlns', "http://www.w3.org/2000/svg");
        var innerGroupNode = rootSVG.append('g').attr("class", "graphinnergrp");
        graphObjTools.baseSvg = d3.select("svg.graph-attach");
        graphObjTools.innerGrp = d3.select("g.graphinnergrp");
		// Adding cursor
		$('.graph-attach').mousedown(function() {
            $(this).css("cursor", "url('/final/images/closedhand.cur'),default");
        }).mouseover(function() {
            $(this).css("cursor", "url('/final/images/openhand.cur'),default");
        }).mouseup(function() {
            $(this).css("cursor", "url('/final/images/openhand.cur'),default");
        });
        // Adding zoom slider width jquery UI
		// info
		if(graphDataBTM.incompleteDataText == "None"){
			$('#info').hide();
		}else if(graphDataBTM.incompleteDataText == "Note"){
			$('#info').html('<span class="btminfoholder"><span ></span><span class="btmhelptext">*Topology above represents the complete request flow</span>&nbsp;<span class="iconTooltipHelp" id="btminfo"  style="cursor:pointer;padding:4px 7px"></span></span>').show();
		}
		else{
			$('#info').html('<span class="btminfoholder"><span >Incomplete Data</span><span class="btmhelptext">*Topology above represents the complete request flow</span><span id="btminfo" class="iconTooltipHelp" style="cursor:pointer;padding:4px 7px">&nbsp;</span></span>').show();
		}
        // Finding the total number of nodes and links
        Object.size = function(obj) {
            var size = 0;
            for (var key in obj) {
                if (obj.hasOwnProperty(key)) {
                    size++;
                }
            }
            return size;
        }
        var graphObj = new dagreD3.graphlib.Graph().setGraph({
            //ranksep: (graphObjTools.graphWidth /Object.size(graphData.nodes[0])) /Object.size(graphData.nodes[0]) * Object.size(graphData.nodes[0]),
            ranksep: 165,
            //edgesep: graphObjTools.graphHeight /Object.size(graphData.links[0]),
            edgesep: 10,
            nodesep: 60,
            width: graphObjTools.graphWidth,
            height: graphObjTools.graphHeight,
            rankdir: graphObjTools.graphAlign,
            marginx: 10,
			//marginy: 50 // Mid and Large Topology
			marginy: tempmarginy // SMALL Topology
        });
        var creatingNodeAndLinks = function() {
                for (var n = 0; n < graphDataBTM.nodes.length; n++) {
                    graphObjTools.assets.nodeObject = graphDataBTM.nodes[n];
                    graphObjTools.nodeData.push(graphObjTools.assets.nodeObject);
                }
                for (var l = 0; l < graphDataBTM.links.length; l++) {
                    graphObjTools.assets.linkObject = graphDataBTM.links[l];
                    graphObjTools.linkData.push(graphObjTools.assets.linkObject);
                }
            }
        //  Rendering the edgeData
		var labelRect = ""; //.attr('height','20px').attr('width','100px');
        function creatingEdgesLabels(data) {
            this.group = d3.select(document.createElementNS(d3.ns.prefix.svg, 'g'));
            if (data) {
                group.classed("labelgrp", true);
                group.style('cursor', 'pointer');
				labelRect = group.append('rect').style('fill','#ffffff').classed("labelpatch", true);
				
                if (data.lineCall !='None') {
					 // duplicate
					var lineCall =  group.append('text')
					.attr('class', 'commonsize_stroke lineCall')
                    .attr('text-anchor', 'start')
                       .attr('dy', function(){
						 if (data.linePercent == "None" || data.lineTime == "None"){
							return '0.55em';
						 }else{
							return '1em';
						 }
					 })
                    .text(function(d) {
                            return data.lineCall
                        }).style({'stroke': '#fff','stroke-width':'5px'});
                     group.append('text')
					.attr('class', 'commonsize lineCall')
                    .attr('text-anchor', 'start')
                    .attr('dy', function(){
						 if (data.linePercent == "None" || data.lineTime == "None"){
							return '0.55em';
						 }else{
							return '1em';
						 }
					 })
                    .text(function(d) {
                            return data.lineCall
                        });
                }
                if (data.linePercent !== "None" || data.lineTime !== "None") {
					// duplicate
					var timeStroke = group.append('text').attr('text-anchor', 'start').attr('class', 'commonsize_stroke linedata').attr('dy', '2.3em');
					if(data.lineTime !== "None"){
						timeStroke.append('tspan').attr('class', 'nodeTime').text(function(d) {
							return " "+data.lineTime
						});
					}
                    timeStroke.append('tspan').attr('class', 'nodePercent').text(function(d) {
                       if(data.linePercent !== "None"){
							return " "+data.linePercent;
						}else{
							return " ";
						}
                    }).style('opacity', "1").style('display', "none");
						
                    var time = group.append('text').attr('text-anchor', 'start').attr('class', 'commonsize linedata').attr('dy', '2.3em');
						if(data.lineTime !== "None"){
								time.append('tspan').attr('class', 'nodeTime').text(function(d) {
									return " "+data.lineTime
								});
							}
                    time.append('tspan').attr('class', 'nodePercent').text(function(d) {
						if(data.linePercent !== "None"){
							return " "+data.linePercent;
						}else{
							return " ";
						}
                    }).style('opacity',"1").style('display',"none");
		
                }
            }
			//Duplicate
			if(data.asynclineTime !== "None"){
				var asynclineTime = group.append('text').attr('text-anchor', 'start').attr('class', 'commonsize asynclineTime').attr('dy', '3.7em');
				asynclineTime.append('tspan').attr('class', 'asynclineTime').text(function(d) {
                        return "  "+data.asynclineTime;
                });
			}
			
            if ( data.lineExperience != "None" && data.lineExperience != undefined && data.lineExperience != 'undefined') {
				
				group.append('rect').attr('width',18).attr('height', 18)
				.attr('class','linestateiconpatch')
				.style('fill','#ffffff')
				.attr('y', -2)
                .attr('x', -21);
                group.append('image')
                    .attr('xlink:href', function() {
                        if (data.lineExperience == 'HEALTHY') { 
                            return 'file:////'+imgpath+'/component_icons/svg/stateicon/'+graphDataBTM.paper.skin+'/state_GOOD.svg'
                        } else if (data.lineExperience == 'ERROR') {
                            return 'file:////'+imgpath+'/component_icons/svg/stateicon/'+graphDataBTM.paper.skin+'/state_HIGH.svg'
                        } else if (data.lineExperience == 'SLOW') {
                            return 'file:////'+imgpath+'/component_icons/svg/stateicon/'+graphDataBTM.paper.skin+'/state_LOW.svg'
                        } else if (data.lineExperience == 'STALLED') {
                            return 'file:////'+imgpath+'/component_icons/svg/stateicon/'+graphDataBTM.paper.skin+'/state_INTERMEDIATE.svg'
                        }
                    })
                    .attr('class', 'lineState lineState' + data.lineExperience)
                    .attr('height', 15)
                    .attr('width', 15)
                    .attr('y',0)
                    .attr('x', -18);
            }
			
				
					
			this.group.attr('transform', 'translate(0,10)');
            return this.group.node();
        }
        // Setting the marker, Yet to optimize :(
        var marker = function() {
            var marker = d3.select('g.graphinnergrp')
                .selectAll("marker")
                .data([{
                    "name": "default",
                    "color": "#909090"
                }, {
                    "name": "undefined",
                    "color": "#909090"
                }, {
                    "name": "HEALTHY",
                    "color": "#588c73"
                }, {
                    "name": "SLOW",
                    "color": "#d74141"
                }, {
                    "name": "ERROR",
                    "color": "#d74141"
                }, {
                    "name": "STALLED",
                    "color": "#d74141"
                }]).enter();
            marker.append("svg:marker")
                .attr("id", function(d) {
                    return d.name
                })
                .attr("fill", function(d) {
                    return d.color;
                })
                .attr("viewBox", "0 0 13 13")
                .attr("markerWidth", 10)
				.attr("markerUnits", "strokeWidth")
				.attr("stroke-width", 1)
				.attr("stroke-dasharray", function(l) {
						return 0 + " " + 0
                 })
                 .attr("stroke-dashoffset", function(l) {
						return 0
                 })
                .attr("markerHeight", 16)
                .attr("refX", function(d) {
                    return 5
                })
                .attr("refY", 7)
                .attr("orient", "auto")
                .append("svg:path").attr('d', function(d) {
                    return d.path
                })
                .attr("d", "M2,2 L2,13 L8,7 L2,2");
        }
        marker();
        var renderingNodeLinks = function() {
            creatingNodeAndLinks();
			for (var keys in graphObjTools.nodeData[0])
			{
				 graphObj.setNode(keys, {
                        label: "",
                        width: 30,
                        height: 30
                    });
			}
            graphObjTools.linkData.forEach(function(d, i) {
				
					graphObj.setEdge(0, 1, {
                        label:'  ',
						width:-80,
                        labelpos: "c",
                        lineInterpolate: graphObjTools.lineInterpolate
						
                    });
					// Rest of others
					if(d.source === d.target){
						graphObjTools.lineInterpolate =  "basis";
					}
                    graphObj.setEdge(d.source, d.target, {
                        labelType: 'svg',
                        label: creatingEdgesLabels(d),
                        labelpos: "c",
                        lineInterpolate: graphObjTools.lineInterpolate,
						width:lindwidth
                    });
               // });
            });
            graphObjTools.graphRender(graphObjTools.innerGrp, graphObj);
        }
        renderingNodeLinks();
        // Setting the  Zoom object thanks to d3
        var zoom = graphObjTools.zoom.scaleExtent([graphObjTools.minZoom, graphObjTools.maxZoom])
            .size([graphObjTools.graphWidth / 2, graphObjTools.graphHeight / 2]);
        // Indexing the link source & target coz for line animation
        var connectedIndex = [];
        var count = 0;
        for (var i in graphObj._edgeObjs) {
            count = count + 1;
            if (graphObj._edgeObjs.hasOwnProperty(i)) {
                connectedIndex.push({
                    'index': count,
                    'target': graphObj._edgeObjs[i].w,
                    'source': graphObj._edgeObjs[i].v
                })
            }
        };
        var pathLine = graphObjTools.innerGrp.selectAll('.path').data(connectedIndex);
		var edgePath = graphObjTools.innerGrp.selectAll('.edgePath').data(graphObjTools.linkData);
        var pathlineExperience = edgePath.filter(function(d) {
            return d.lineExperience == 'undefined';
        });
		
		// @ adding pointer to the line path to click
	var incalltextArr = [], linedatatextArr =[];
		d3.selectAll('text.lineCall').each(function(d){
				incalltextArr.push(d3.select(this).node().getBBox().width);
				
		});
	d3.selectAll('.linedata').each(function(d,i){
			linedatatextArr.push(d3.select(this).node().getBBox().width);
	});
		d3.selectAll('rect.labelpatch').each(function(d,g){
				if(linedatatextArr[g] =='' || linedatatextArr[g] ==undefined || linedatatextArr[g] =='undefined')
					linedatatextArr[g]=80;
				if(linedatatextArr[g] >  incalltextArr[g]){
					d3.select(this).attr({
                                'width': incalltextArr[g],
                                'height': 30,
                                'x': 0,
                                'y': 0
                            });
				}else{
				d3.select(this).attr({
								'width': linedatatextArr[g] ,
								//'width': linedatatextArr[g]-50 ,// For Mid Topology only
                                'height': 30,
                                'x': 0,
                                'y': 0
                            });
				}
		});
		// setting up the line style
        pathLine.attr("stroke-linecap","round")
		.style({"stroke": "#918f8f"})
		.attr("stroke-dasharray", function(l,i) {
								//console.log(graphObjTools.linkData[i])
                                if (graphObjTools.linkData[i].asynclineTime == "None") {
                                    return 0 + " " + 0;
                                }else{
									return 5 + " " + 5;
								}
                            })	.attr('marker-end', '').attr('marker-end', 'url(#default)');
        var cal = {
            fontSize: graphObjTools.fontSize,
            getScale: function(scale) {
                return scale;
            },
            getFontSize: function(scale) {
                return this.fontSize / scale;
            },
            interpolateZoom: function(translate, scale, duration) {
                var self = this;
                return d3.transition().duration(duration).tween("zoom", function() {
                    var iTranslate = d3.interpolate(zoom.translate(), translate),
                        iScale = d3.interpolate(zoom.scale(), scale);
                    return function(t) {
						zoom.scale(iScale(t)).translate(iTranslate(t)).event(rootSVG);
                    };
                });
            },
            hideText: function(scale, val) {
                if (val > scale) {
                    graphObjTools.innerGrp.selectAll('text').style("visibility", "visible");
                    graphObjTools.innerGrp.selectAll('.componentState, .userExpLine, .labelpatch').style("visibility", "visible");
                    graphObjTools.innerGrp.selectAll('.lineState').style("visibility", "visible");
                    graphObjTools.innerGrp.selectAll('.greyCompIcon').style("display", "none");
                    graphObjTools.innerGrp.selectAll('.linestateiconpatch').style("display", "none");
                    graphObjTools.innerGrp.selectAll('.colorCompIcon').style("visibility", "visible").style("display", "block");
                    pathLine.attr('class', function() {
						if(d3.select(this.parentNode).datum().lineExperience){
							return 'link ' + d3.select(this.parentNode).datum().lineExperience;
						}
                    });
                    pathLine.attr('marker-end', '').style('stroke-width', 2)
                        .attr('marker-end', function() {
							if(d3.select(this.parentNode).datum().lineExperience){
								return 'url(#' + d3.select(this.parentNode).datum().lineExperience + 'over)';
							}
                        });
                } else {
                    graphObjTools.innerGrp.selectAll('text').style("visibility", "visible");
                    graphObjTools.innerGrp.selectAll('.componentState, .userExpLine, .labelpatch').style("visibility", "visible");
                    graphObjTools.innerGrp.selectAll('.lineState').style("visibility", "visible");
					graphObjTools.innerGrp.selectAll('.linestateiconpatch').style("display", "block");
                    pathLine.attr('class', function() {
						if(d3.select(this.parentNode).datum().lineExperience){
							return 'path ' + d3.select(this.parentNode).datum().lineExperience;
						}
                    });
                    pathLine.attr('marker-end', '').style('stroke-width', 1)
                        .attr('marker-end', function() {
                            return 'url(#default)';
                        });
                    graphObjTools.innerGrp.selectAll('.greyCompIcon').style("display", "block");
                    graphObjTools.innerGrp.selectAll('.colorCompIcon').style("visibility", "hidden").style("display", "none");
                }
            }
        }
		/*if (navigator.appVersion.indexOf("MSIE 10") != -1) {
			pathLine.each(function() {this.parentNode.insertBefore(this, this); });
		}*/
        var serverType, serverTypeHoverImages, displayName, displayName_stroke, compName, userExpLine, isJavaComp, componentState, componentTranValue, startImg, displayName_compName, displayName_compName_stroke, compNametrick, compNametrick_stroke, serverTypeState;
        var renderNode = function(scale) {
            graphObj.nodes().forEach(function(i) {
                // Yet to optimize
                d3.selectAll('.linedata,.lineCall, .linedataStroke, .lineCallStroke')
				.style("font-size", cal.getFontSize(scale) + "px");
                d3.selectAll('.linedata')
                    .attr('x', function() {
                        return d3.select(this).attr('x') / cal.getScale(scale)
                    })
                    .attr('y', function() {
                        return d3.select(this).attr('y') / cal.getScale(scale)
                    });
                d3.selectAll('.lineCall')
                    .attr('x', function() {
                        return d3.select(this).attr('x') / cal.getScale(scale)
                    })
                    .attr('y', function() {
                        return d3.select(this).attr('y') / cal.getScale(scale)
                    });
                d3.selectAll('.lineState')
                    .attr('x', function() {
                        return -18 / cal.getScale(scale);
                    })
                    .attr('y', function() {
                        return 0 / cal.getScale(scale);
                    })
                    .attr('width', function() {
                        return 15 / cal.getScale(scale);
                    })
                    .attr('height', function() {
                        return 15 / cal.getScale(scale);
                    });
					
				
                var node = graphObj.node(i);
		
                var parentNode = d3.select(node.elem).data(graphObjTools.nodeData);
                parentNode.attr('id', function(d) {
                    return d[i].componentName;
                }).style('opacity', function(d) {
					if(!d[i].activeNode) return '0.6';
                 }).attr('class',function(d){
				if (d[i].drillDownUrl != 'None') {
							return 'pointer';
						}
				});
                //parentNode.classed('node',false);
                parentNode.classed('parentNode', true);
                parentNode.selectAll("*").remove();
                
				isHighlight =  parentNode.filter(function(d){  return d[i].highlight == true  }).append('rect').attr('class', 'isHighlight');
                          
                serverTypeState = parentNode.append('image').attr('xlink:href', function(d) {
                        if (d[i].nodeExperience != 'None') {
                            return "file:////"+imgpath+"/component_icons/svg/"+graphDataBTM.paper.skin+"/"+d[i].serverType+"_"+d[i].nodeExperience+".svg";
                        }else{
							return "file:////"+imgpath+"/Light/clear.png";
						}
                    }).attr({
                        'width': function(d) {
                            if (d[i].componentName === "User") {
                                if (0.4 >= scale >= 0.2) {
                                    return 75;
                                }
                                return 75 / cal.getScale(scale);
                            } else {
                                if (0.4 >= scale >= 0.2) {
                                    return 44;
                                }
                                return 44 / cal.getScale(scale);
                            }
                        },
                        'height': function(d) {
                            if (d[i].componentName === "User") {
                                if (0.4 >= scale >= 0.2) {
                                    return 75;
                                }
                                return 75 / cal.getScale(scale);
                            } else {
                                if (0.4 >= scale >= 0.2) {
                                    return 55;
                                }
                                return 55 / cal.getScale(scale);
                            }
                        }
                    })
                    .attr('x', function(d) {
                        if (d[i].componentName === "User") {
                            if (0.4 >= scale >= 0.2) {
                                return Math.round(-19 * cal.getScale(scale));
                            } else {
                                return Math.round(-35 / cal.getScale(scale));
                            }
                        } else {
                            if (0.4 >= scale >= 0.2) {
                                return Math.round(-100 * cal.getScale(scale));
                            }
                            return Math.round(-24 / cal.getScale(scale));
                        }
                    })
                    .attr('y', function(d) {
                        if (d[i].componentName === "User") {
                            if (0.4 >= scale >= 0.2) {
                                return Math.round(-135 * cal.getScale(scale));
                            }
                            return Math.round(-38 / cal.getScale(scale));
                        } else {
                            if (0.4 >= scale >= 0.2) {
                                return Math.round(-95 * cal.getScale(scale));
                            }
                            return Math.round(-24 / cal.getScale(scale));
                        }
                    }).attr('class', 'colorCompIcon').style('display', 'none');
                serverType = parentNode.append('image').attr('xlink:href', function(d) {
                        if (d[i].nodeExperience != 'None') {
                            if (scale > 0.600) {
                                return "file:////"+imgpath+"/component_icons/svg/"+graphDataBTM.paper.skin+"/"+d[i].serverType+".svg";
                            } else {
                                return "file:////"+imgpath+"/component_icons/svg/"+graphDataBTM.paper.skin+"/"+d[i].serverType+"_"+d[i].nodeExperience+".svg";
                            }
                        } else {
                            return "file:////"+imgpath+"/component_icons/svg/"+graphDataBTM.paper.skin+"/"+d[i].serverType+".svg";
                        }
                    }).attr({
                        'width': function(d) {
							if(d[i].serverType === "CUSTOM"){
								if (0.4 >= scale >= 0.2) {
                                    return 75;
                                }
                                return 75 / cal.getScale(scale);
							}
                            if (d[i].componentName === "User") {
                                if (0.4 >= scale >= 0.2) {
                                    return 75;
                                }
                                return 75 / cal.getScale(scale);
                            } else {
                                if (0.4 >= scale >= 0.2) {
                                    return 44;
                                }
                                return 44 / cal.getScale(scale);
                            }
                        },
                        'height': function(d) {
							if(d[i].serverType === "CUSTOM"){
								if (0.4 >= scale >= 0.2) {
                                    return 75;
                                }
                                return 75 / cal.getScale(scale);
							}
                            if (d[i].componentName === "User") {
                                if (0.4 >= scale >= 0.2) {
                                    return 75;
                                }
                                return 75 / cal.getScale(scale);
                            } else {
                                if (0.4 >= scale >= 0.2) {
                                    return 55;
                                }
                                return 55 / cal.getScale(scale);
                            }
                        }
                    })
                    .attr('x', function(d) {
                        if (d[i].componentName === "User" || d[i].serverType === "CUSTOM") {
                            if (0.4 >= scale >= 0.2) {
                                return Math.round(-19 * cal.getScale(scale));
                            } else {
                                return Math.round(-35 / cal.getScale(scale));
                            }
                        } else {
                            if (0.4 >= scale >= 0.2) {
                                return Math.round(-100 * cal.getScale(scale));
                            }
                            return Math.round(-24 / cal.getScale(scale));
                        }
                    })
                    .attr('y', function(d) {
                        if (d[i].componentName === "User" || d[i].serverType === "CUSTOM") {
                            if (0.4 >= scale >= 0.2) {
                                return Math.round(-135 * cal.getScale(scale));
                            }
                            return Math.round(-38 / cal.getScale(scale));
                        } else {
                            if (0.4 >= scale >= 0.2) {
                                return Math.round(-95 * cal.getScale(scale));
                            }
                            return Math.round(-24 / cal.getScale(scale));
                        }
                    }).attr('class', function(d) {
                        if (d[i].nodeExperience != 'None') {
                            return 'greyCompIcon';
                        }
                    });
				// duplicate
                displayName_compName = parentNode.append('text').attr('text-anchor', 'middle')
					.attr('x', function(d){
						if (d[i].componentName == "User" || d[i].serverType === "CUSTOM") {
								return 5;
							}else{
								return  0 / cal.getScale(scale);
							}
					})
                    .attr('y', function(d) {
                        return 35 / cal.getScale(scale);
                    })
                    .attr('class', 'displayName_compName commonsize')
					.style("fill", function(d){
						if(d[i].highlight ){
							return  "#ffffff"
					}})
                    .style("font-size", cal.getFontSize(scale) + "px")
                    .style('opacity', '0').style('display', 'none');
				 //compNametrick_stroke = displayName_compName_stroke.append('tspan').text(function(d) {
                  //  return d[i].componentName;
                //}).attr('class', 'displayName_compName').attr('text-anchor', 'middle');
                compNametrick = displayName_compName.append('tspan').text(function(d) {
                    return d[i].componentName;
                }).attr('class', 'displayName_compName').attr('text-anchor', 'middle');
				//duplicate
				displayName_stroke = parentNode.filter(function(d) {
                        return d[i].displayName != "None" && !d[i].highlight ;
                    })
					.append('text').text(function(d) {
                        return d[i].displayName;
                    })
					.attr('text-anchor', 'middle')
					.attr('class', 'displayName')
                    .attr('x', function(d){
							if (d[i].componentName == "User" || d[i].serverType === "CUSTOM") {
								return 5;
							}else{
								return  0 / cal.getScale(scale);
							}
					})
                    .attr('y', function(d) {
                       if (d[i].componentName == "User" || d[i].serverType === "CUSTOM") {
								  return 35 / cal.getScale(scale);
							}else{
								return 36 / cal.getScale(scale);	
							}
                    })
					.style("font-size", cal.getFontSize(scale) + "px")
					.classed('commonsize_stroke', true);
                displayName = parentNode.filter(function(d) {
                        return d[i].displayName != "None";
                    })
					.append('text').text(function(d) {
                        return d[i].displayName;
                    })
					.attr('text-anchor', 'middle')
					.attr('class', function(d){
						if(d[i].highlight ){
							return 'displayName highlight';
						}else{
							return 'displayName';
						}
						})
                    .attr('x',function(d){
							if (d[i].componentName == "User" || d[i].serverType === "CUSTOM") {
								return 5;
							}else{
								return  0 / cal.getScale(scale);
							}
					})
                    .attr('y', function(d) {
							if (d[i].componentName == "User" || d[i].serverType === "CUSTOM") {
								  return 35 / cal.getScale(scale);
							}else{
								return 36 / cal.getScale(scale);	
							}
                        
                    })
					.style("font-size", cal.getFontSize(scale) + "px")
					.style("fill", function(d){
						if(d[i].highlight ){
							return  "#ffffff"
						}
					})
					.classed('commonsize', true);
				// duplicate
				/*
				compName_stroke = parentNode.append('text').text(function(d) {
					if(d[i].componentName != 'None' ){
						return d[i].componentName
					}else{
						return "";	
					}
                })
				.style('visibility','hidden')
				.attr('text-anchor', 'middle')
				.attr('class', function(d){
					if(!d[i].highlight){
						return 'commonsize_stroke compName '
					}else{
						return 'commonsize_stroke_highlight compName '
					}
				})
				.attr('visibility','hidden')
				.attr('x', function(d){
							if (d[i].componentName == "User" || d[i].serverType === "CUSTOM") {
									return 5;
							} else {
									return 0;
						}	
					}).attr('y', function(d) {
                    if (d[i].componentName == "User" || d[i].serverType === "CUSTOM") {
                        return 35 / cal.getScale(scale);
                    } else {
                        return 50 / cal.getScale(scale);
                    }
                }).style("font-size", cal.getFontSize(scale) + "px");
				*/
                compName = parentNode.append('text').text(function(d) {
                  if(d[i].componentName != 'None'){
						if(d[i].componentName == "User")
							return "";
						else
							return d[i].componentName
					}else{
						return "";	
					}
                }).attr('text-anchor', 'middle')
				.attr('class', 'commonsize compName').attr('x', function(d){
							if (d[i].componentName == "User" || d[i].serverType === "CUSTOM") {
									return 5;
							} else {
									return 0;
						}	
					})
					.attr('y', function(d) {
                    if (d[i].componentName == "User" || d[i].serverType === "CUSTOM") {
                        return 35 / cal.getScale(scale);
                    } else {
                        return 50 / cal.getScale(scale);
                    }
                }).style("fill", function(d){
						if(d[i].highlight ){
							return  "#ffffff"
				}}).style("font-size", cal.getFontSize(scale) + "px");
                userExpLine = parentNode.filter(function(d) {
                    if (d[i].componentName == "User") {
                        var src = "file:////"+imgpath+"/Light/clear.png";
                        if (d[i].nodeExperience == 'HEALTHY') {
                            src = "file:////"+imgpath+"/component_icons/svg/stateicon/"+graphDataBTM.paper.skin+"/state_GOOD.svg";
                        } else if (d[i].nodeExperience == 'ERROR') {
                            src = "file:////"+imgpath+"/component_icons/svg/stateicon/"+graphDataBTM.paper.skin+"/state_HIGH.svg";
                        } else if (d[i].nodeExperience == 'SLOW') {
                            src = "file:////"+imgpath+"/component_icons/svg/stateicon/"+graphDataBTM.paper.skin+"/state_LOW.svg";
                        } else if (d[i].nodeExperience == 'STALLED') {
                            src = "file:////"+imgpath+"/component_icons/svg/stateicon/"+graphDataBTM.paper.skin+"/state_INTERMEDIATE.svg";
                        }
                        d3.select(this)
                            .append('image').attr('class', 'userExpLine')
                            .attr({
                                'width':16,
                                'height': 16,
                                'x': compName.node().getBBox().x - 20,
                                'y': compName.node().getBBox().y
                            }) .attr('xlink:href', function(d) { return src });
                            
                    } else {
                        return true;
                    }
                });
				
				/*
				*@ setting the highlight rectangle node
				*/
				if(displayName.node() != null){
					if(displayName.node().getBBox().width >= compName.node().getBBox().width){
							isHighlight.attr('class', 'highlight userExpLine')
                            .attr({
                                'width': (displayName.node().getBBox().width /2) - (displayName.node().getBBox().x * 1.6),
                                'height': 35,
                                'x': ((-displayName.node().getBBox().width/2)/2)+ ((displayName.node().getBBox().x* 1.6) /2),
                                'y': 23
                            }) .style({
                                'fill': '#40b5c5'
                            });
					}else{
							isHighlight.attr('class', 'highlight userExpLine')
                            .attr({
                                'width': (compName.node().getBBox().width /2) - (compName.node().getBBox().x * 1.8),
                                'height': 35,
                                'x': ((-compName.node().getBBox().width/2)/2)+ ((compName.node().getBBox().x* 1.8) /2),
                                'y': 23
                            }) .style({
                                'fill': '#40b5c5'
                            });	
					
					}
				}
			
			
				// duplicate
				 isJavaComp_stroke = parentNode.filter(function(d) {
                        return d[i].nodeText !== "None";
                    })
                isJavaComp = parentNode.filter(function(d) {
                        return d[i].nodeText !== "None";
                    }).append('text').attr('class', 'commonsize isJavaComp')
					.attr('text-anchor', 'start')
                    .attr('x', -5 / cal.getScale(scale))
                    .attr('y', function(d) {
                        return -38 / cal.getScale(scale)
                    }).style("font-size", cal.getFontSize(scale) + "px");
					
					// duplicate
                    isJavaComp.append('tspan').text(function(d) {
                        return d[i].nodeText +' ';
                    }).attr('class', 'commonsize isJavaComp');
					
					// duplicate
					 isJavaComp_stroke.filter(function(d) {
                        return d[i].isAsync;
                    }).append('tspan').attr('class', 'nodeTime').text(function(d) {
                        return d[i].nodeTime +' ';
                    });
					isJavaComp_stroke.filter(function(d) {
                        return d[i].isAsync;
                    }).append('tspan').attr('class', 'nodePercent').text(function(d) {
                        return d[i].nodePercent +' ';
                    }).style('opacity', '0').style('display', 'none');
                    isJavaComp.filter(function(d) {
                        return d[i].isAsync;
                    }).append('tspan').attr('class', 'nodeTime').text(function(d) {
                        return d[i].nodeTime +' ';
                    });
					isJavaComp.filter(function(d) {
                        return d[i].isAsync;
                    }).append('tspan').attr('class', 'nodePercent').text(function(d) {
                        return d[i].nodePercent +' ';
                    }).style('opacity', '0').style('display', 'none');
				// duplicate
				isAsyncComp_stroke = parentNode.filter(function(d) {
                        return d[i].isAsync ;
                    })
                    .append('text').text(function(d) {
                        return d[i].asyncTime + ' (async)';
                    })
                    .attr('text-anchor', 'start')
                    .attr('class', 'commonsize_stroke isAsyncComp')
                    .attr('x', -5 / cal.getScale(scale))
                    .attr('y', function(d) {
                        return -25 / cal.getScale(scale);
                    }).style("font-size", cal.getFontSize(scale) + "px");
				isAsyncComp = parentNode.filter(function(d) {
                        return d[i].isAsync ;
                    })
                    .append('text').text(function(d) {
                        return d[i].asyncTime + ' (async)';
                    })
                    .attr('text-anchor', 'start')
                    .attr('class', 'commonsize isAsyncComp')
                    .attr('x', -5 / cal.getScale(scale))
                    .attr('y', function(d) {
                        return -25 / cal.getScale(scale);
                    }).style("font-size", cal.getFontSize(scale) + "px");
                componentState = parentNode.filter(function(d) {
                        return d[i].nodeExperience != 'None' && d[i].componentName != "User";
                    }).append('image')
                    .attr('xlink:href', function(d) {
                        if (d[i].nodeExperience == 'HEALTHY') {
                            return 'file:////'+imgpath+'/component_icons/svg/stateicon/'+graphDataBTM.paper.skin+'/state_GOOD.svg'
                        } else if (d[i].nodeExperience == 'ERROR') {
                            return 'file:////'+imgpath+'/component_icons/svg/stateicon/'+graphDataBTM.paper.skin+'/state_HIGH.svg'
                        } else if (d[i].nodeExperience == 'SLOW') {
                            return 'file:////'+imgpath+'/component_icons/svg/stateicon/'+graphDataBTM.paper.skin+'/state_LOW.svg'
                        } else if (d[i].nodeExperience == 'STALLED') {
                            return 'file:////'+imgpath+'/component_icons/svg/stateicon/'+graphDataBTM.paper.skin+'/state_INTERMEDIATE.svg'
                        }
                    })
                    .attr('class', function(d) {
                        return 'componentState componentState' + d[i].nodeExperience
                    })
                    .attr('height', 16 / cal.getScale(scale))
                    .attr('width', 16 / cal.getScale(scale))
                    .attr('x', function() {
                        return 16 / cal.getScale(scale);
                    }).attr('y', function() {
                        if (isJavaComp.node() != null) {
                            isJavaCompbox = isJavaComp.node().getBBox();
                            return isJavaCompbox.y;
                        }
                    }).attr('x', function() {
                        if (isJavaComp.node() != null) {
                            isJavaCompbox = isJavaComp.node().getBBox();
                            return isJavaCompbox.x - 20 / cal.getScale(scale);
                        }
                    });
				// duplicate
				 componentTranValue_stroke = parentNode.filter(function(d) {
                        return (d[i].nodeTime !== "None") && !d[i].isAsync;
                    })
                    .append('text')
                    .attr('text-anchor', 'start')
                    .attr('class', 'commonsize_stroke componentTranValue')
                    .attr('x', -6 / cal.getScale(scale))
                    .attr('y', function(d) {
                        return -24 / cal.getScale(scale);
                    })
                    .style("font-size", cal.getFontSize(scale) + "px");
                componentTranValue_stroke.append('tspan').attr('class', 'nodeTime').text(function(d) {
                    return d[i].nodeTime + " ";
                });
                componentTranValue_stroke.append('tspan').attr('class', 'nodePercent').text(function(d) {
                    return d[i].nodePercent + "  ";
                }).style('opacity', '0').style('display', 'none');
                componentTranValue = parentNode.filter(function(d) {
                        return (d[i].nodeTime != "None") && !d[i].isAsync;
                    })
                    .append('text')
                    .attr('text-anchor', 'start')
                    .attr('class', 'commonsize componentTranValue')
                    .attr('x', -6 / cal.getScale(scale))
                    .attr('y', function(d) {
                        return -24 / cal.getScale(scale);
                    })
                    .style("font-size", cal.getFontSize(scale) + "px");
                componentTranValue.append('tspan').attr('class', 'nodeTime').text(function(d) {
                    return d[i].nodeTime + " ";
                });
                componentTranValue.append('tspan').attr('class', 'nodePercent').text(function(d) {
                    return d[i].nodePercent + "  ";
                }).style('opacity', '0').style('display', 'none');
            });
		// For performance TODO
        serverType = null;
		serverTypeHoverImages = null;
		displayName = null;
		displayName_stroke = null;
		compName = null;
		userExpLine = null;
		isJavaComp = null;
		componentState = null;
		componentTranValue = null;
		startImg = null;
		displayName_compName = null;
		displayName_compName_stroke = null;
		compNametrick = null;
		compNametrick_stroke = null;
		serverTypeState = null;
		delete serverType;
		delete serverTypeHoverImages;
		delete displayName;
		delete displayName_stroke;
		delete compName;
		delete userExpLine;
		delete isJavaComp;
		delete componentState;
		delete componentTranValue;
		delete startImg;
		delete displayName_compName;
		delete displayName_compName_stroke;
		delete compNametrick;
		delete compNametrick_stroke;
		delete serverTypeState;
        }
        renderNode(graphObjTools.d3Scale);
        // Taking the bound of the graph
        var allparentnodes = graphObjTools.innerGrp.selectAll('.parentNode');
        var graphBounds = function() {
            var x = Number.POSITIVE_INFINITY,
                X = Number.NEGATIVE_INFINITY,
                y = Number.POSITIVE_INFINITY,
                Y = Number.NEGATIVE_INFINITY;
            allparentnodes.each(function(v, i) {
				for (keys in v)
				{
					if (v.hasOwnProperty(keys)){
						x = Math.min(x, graphObj.node(keys).x - this.getBBox().width * zoom.scale());
						X = Math.max(X, graphObj.node(keys).x + this.getBBox().width * zoom.scale());
						y = Math.min(y, graphObj.node(keys).y - this.getBBox().height * zoom.scale());
						Y = Math.max(Y, graphObj.node(keys).y + this.getBBox().height * zoom.scale());
					}
				}
            });
            return {
                x: x,
                X: X,
                y: y,
                Y: Y
            };
        }
        var graph_bound = graphBounds();
        var zoomToFit = function() {
            var graph_width = graph_bound.X - graph_bound.x,
                graph_height = graph_bound.Y - graph_bound.y,
                total_width = graphObjTools.graphWidth - graphObj.graph().marginx,
                total_height = graphObjTools.graphHeight - graphObj.graph().marginy,
                fit_scale = Math.min(total_width / graph_width, total_height / graph_height);
            graphObjTools.d3Translate[0] = (-graph_bound.x * fit_scale + (total_width / fit_scale - graph_width) * fit_scale / 2),
            graphObjTools.d3Translate[1] = (-graph_bound.y * fit_scale + (total_height / fit_scale - graph_height) * fit_scale / 2);
			 cal.interpolateZoom(graphObjTools.d3Translate, fit_scale, 200);
            //innerGroupNode.attr("transform", "translate(" + xPrime + ", " + yPrime + ") scale(" + scale + ")");
            delete fit_scale, total_width, total_height;
        }
		// setting the graph position on load
        var xCenterOffset = (rootSVG.attr("width") - graphObj.graph().width);
        var bbox = d3.select('g.graphinnergrp')[0][0].getBBox(),
			graphWidth = graphObj.graph().width,
			graphHeight = graphObj.graph().height
            graph_width = graph_bound.X - graph_bound.x,
            graph_height = graph_bound.Y - graph_bound.y,
            total_width = graphObjTools.graphWidth - graphObj.graph().marginx - 15,
            total_height = graphObjTools.graphHeight - graphObj.graph().marginy - 15,
			// fit_scale = Math.min(graphWidth - graphObj.graph().marginx, graphHeight - graphObj.graph().marginy);
            //fit_scale = 0.495;//Math.min(total_width / graph_width, (total_height+100) / graph_height);
			fit_scale = Math.min(total_width / graph_width, (total_height+100) / graph_height);
			graphObjTools.d3Translate[0] = (-graph_bound.x * fit_scale + (total_width / fit_scale - graph_width) * fit_scale / 2),
            graphObjTools.d3Translate[1] = (-graph_bound.y * fit_scale + (total_height / fit_scale - graph_height) * fit_scale / 2);
			// condition for signal line components
			if((total_height/2) > graph_height){
				//fit_scale= Math.min(total_width / graph_width, total_height / graph_height);
				fit_scale= graphObjTools.initialScale;
				graphObjTools.d3Translate[0] = (-graph_bound.x * fit_scale + (total_width / fit_scale - graph_width) * fit_scale / 2),
				graphObjTools.d3Translate[1] = (-graph_bound.y * fit_scale + (total_height / fit_scale - graph_height) * fit_scale / 2);
			}
			cal.interpolateZoom(graphObjTools.d3Translate, fit_scale, 10);
        var zoomFunction = function() {
            translation = d3.event.translate,
			scale = fit_scale;//d3.event.scale ;
            innerGroupNode.attr("transform", "translate("+ translation +") scale(" + scale + ")");
            cal.hideText(scale, 0.300);
        }
        zoom.on("zoom", zoomFunction);
	}
    drawGraph();
})($('#render'), data);
</script>