QFLogTree.js 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359
  1. /****************************************************************************************************************************
  2. Licensed Materials - Property of IBM
  3. BI and PM: QFW
  4. © Copyright IBM Corp. 2005, 2010
  5. US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  6. *****************************************************************************************************************************/
  7. function LogTreeNode( id, parentNode, nestedParentNode, tree, content, width, height, boxColor, title )
  8. {
  9. this.id = id;
  10. this.parentNode = parentNode;
  11. this.tree = tree;
  12. this.content = content;
  13. this.visible = true;
  14. if( title )
  15. this.title = title;
  16. if( width != null )
  17. this.width = width;
  18. else
  19. this.width = (tree.config.nodeWidth)? tree.config.nodeWidth: 0;
  20. if( height != null )
  21. this.height = height;
  22. else
  23. this.height = (tree.config.nodeHeight)? tree.config.nodeHeight: 0;
  24. this.X = 0;
  25. this.Y = 0;
  26. this.groupHeight = 0;
  27. this.groupWidth = 0;
  28. this.groupX = 0;
  29. this.groupY = 0;
  30. this.boxColor = boxColor;
  31. this.connectorElems = [];
  32. this.childNodes = [];
  33. this.connectorNestedElems = [];
  34. this.nestedChildNodes = [];
  35. this.createContent();
  36. if( id >= 0 )
  37. {
  38. this.tree.config.tempTreeContainer.appendChild( this.contentNode );
  39. if( this.contentNode.offsetWidth > this.width - 10 )
  40. {
  41. this.width = this.contentNode.offsetWidth + 10;
  42. }
  43. this.contentHeight = this.contentNode.offsetHeight;
  44. this.tree.config.tempTreeContainer.removeChild( this.contentNode );
  45. this.tree.config.tempTreeContainer.innerHTML = "";
  46. }
  47. }
  48. LogTreeNode.prototype.updateLocation_nestedInside = function updateLocation_nestedInside()
  49. {
  50. if( this.nestedChildNodes.length == 0 )
  51. return;
  52. var nestedChildGroupY = this.Y + this.contentHeight;
  53. for( var i = 0; i < this.nestedChildNodes.length; ++i )
  54. {
  55. if( i == 0 )
  56. nestedChildGroupY += this.tree.config.nestedChildGroupYMarginTop;
  57. else
  58. nestedChildGroupY += this.tree.config.siblingMargin;
  59. var child = this.nestedChildNodes[i];
  60. child.updateLocation( this.X + this.tree.config.nestedChildGroupXMargin, nestedChildGroupY );
  61. nestedChildGroupY += child.groupHeight;
  62. if( this.width < 2 * this.tree.config.nestedChildGroupXMargin + child.groupWidth )
  63. this.width = 2 * this.tree.config.nestedChildGroupXMargin + child.groupWidth;
  64. }
  65. this.height = nestedChildGroupY + this.tree.config.nestedChildGroupYMarginBottom - this.Y;
  66. }
  67. LogTreeNode.prototype.updateLocation_children = function updateLocation_children( childGroupX, childGroupY )
  68. {
  69. var i = 0;
  70. this.groupWidth = this.width;
  71. for( ; i < this.childNodes.length; ++i )
  72. {
  73. if( i > 0 )
  74. childGroupY += this.tree.config.siblingMargin;
  75. var child = this.childNodes[i];
  76. child.updateLocation( childGroupX, childGroupY );
  77. childGroupY += child.groupHeight;
  78. if( this.groupWidth < this.width + this.tree.config.levelMargin + child.groupWidth )
  79. this.groupWidth = this.width + this.tree.config.levelMargin + child.groupWidth;
  80. }
  81. return childGroupY;
  82. }
  83. LogTreeNode.prototype.updateLocation = function updateLocation( groupX, groupY )
  84. {
  85. this.groupX = this.X = groupX;
  86. this.groupY = groupY;
  87. if( this.tree.config.bNestedInside )
  88. this.updateLocation_nestedInside();
  89. var childGroupX = this.X + this.width + this.tree.config.levelMargin;
  90. this.groupWidth = this.width;
  91. var childGroupYBottom = this.updateLocation_children( childGroupX, groupY );
  92. this.groupHeight = childGroupYBottom - groupY;
  93. if( this.groupHeight < this.height )
  94. {
  95. this.updateLocation_children( childGroupX, groupY + this.height/2 - this.groupHeight/2 );
  96. this.groupHeight = this.height;
  97. this.Y = groupY;
  98. }
  99. else
  100. if( this.childNodes.length == 1 && this.tree.config.bNestedUnder )
  101. this.Y = this.childNodes[0].Y;
  102. else
  103. this.Y = this.groupHeight / 2 - this.height / 2 + this.groupY;
  104. if( this.tree.config.bNestedUnder )
  105. this.updateLocaltion_nestedUnder();
  106. }
  107. LogTreeNode.prototype.updateLocation_nestedUnder = function updateLocation_nestedUnder()
  108. {
  109. var nestedChildGroupX = this.X;
  110. for( var i = 0; i < this.nestedChildNodes.length; ++i )
  111. {
  112. if( i == 0 )
  113. this.groupHeight += this.tree.config.nestedChildGroupYMarginTop;
  114. else
  115. this.groupHeight += this.tree.config.siblingMargin;
  116. var child = this.nestedChildNodes[i];
  117. child.updateLocation( nestedChildGroupX, this.groupHeight + this.groupY );
  118. this.groupHeight += child.groupHeight;
  119. if( this.groupWidth < nestedChildGroupX + child.groupWidth )
  120. this.groupWidth = nestedChildGroupX + child.groupWidth;
  121. }
  122. }
  123. LogTreeNode.prototype.createContent = function createContent()
  124. {
  125. this.contentNode = document.createElement( "div" );
  126. if( this.title )
  127. {
  128. var title = document.createElement( "b" );
  129. title.innerHTML = this.title;
  130. this.contentNode.appendChild( title );
  131. }
  132. var info = document.createElement( "div" );
  133. //info.style.marginLeft = 10;
  134. info.innerHTML = this.content;
  135. this.contentNode.appendChild( info );
  136. }
  137. LogTreeNode.prototype.createElement = function createElement()
  138. {
  139. if( this.id < 0 )
  140. return null;
  141. var v_dArcsize = 0.20;
  142. if( this.tree.config.bNestedInside && this.nestedChildNodes.length > 0 )
  143. v_dArcsize = 0.05;
  144. this.tree.tempDiv.innerHTML = "<v:roundrect arcsize=\"" + v_dArcsize + "\" />";
  145. this.elem = this.tree.tempDiv.firstChild;
  146. this.tree.container.appendChild( this.elem );
  147. this.elem.id = this.id;
  148. this.elem.style.position = "absolute";
  149. this.elem.style.top = this.Y;
  150. this.elem.style.left = this.X;
  151. this.elem.style.height = this.height;
  152. this.elem.style.width = this.width;
  153. this.elem.style.paddingTop = 3;
  154. this.elem.style.paddingBottom = 3;
  155. this.elem.style.paddingLeft = 3;
  156. this.elem.style.paddingRight = 3;
  157. if( this.boxColor )
  158. {
  159. //if( !(this.tree.config.bNestedInside && this.nestedChildNodes.length > 0) )
  160. this.elem.fillColor = this.boxColor;
  161. }
  162. this.elem.appendChild( this.contentNode );
  163. return this.elem;
  164. }
  165. var plID = 0;
  166. var arrAngle = 0.25;
  167. var arrLength = 7;
  168. LogTreeNode.prototype.createConnector = function createConnector( toChildOrdinal )
  169. {
  170. var childNode = this.childNodes[ toChildOrdinal ];
  171. var connectorElem = document.createElement( "v:polyline" );
  172. this.tree.container.appendChild( connectorElem );
  173. //defines points and draws line and arrowhead
  174. var A = (this.X + this.width) + "," + (this.Y + this.height/2);
  175. var B = (3*this.X + 3*this.width + childNode.X)/4 + "," + (this.Y + .45*this.height );
  176. var C = (3*this.X + 3*this.width + childNode.X)/4 + "," + (this.Y + .55*this.height );
  177. var D = childNode.X + "," + (childNode.Y + childNode.height/2);
  178. var angle = Math.atan( ( (childNode.Y + childNode.height/2) -
  179. (this.Y + this.height/2) ) /
  180. ( childNode.X - (this.X + this.width) ) );
  181. var B1 = (this.X + this.width + arrLength * Math.cos(angle+arrAngle)) + "," +
  182. (this.Y + this.height/2 + arrLength * Math.sin(angle+arrAngle));
  183. var C1 = (this.X + this.width + arrLength * Math.cos(angle-arrAngle)) + "," +
  184. (this.Y + this.height/2 + arrLength * Math.sin(angle-arrAngle));
  185. connectorElem.points.value = A +" "+ B1 +" "+ A +" "+ C1 +" "+ A +" "+ D;
  186. this.connectorElems[toChildOrdinal] = connectorElem;
  187. }
  188. LogTreeNode.prototype.createNestingConnector = function createConnector( toChildOrdinal )
  189. {
  190. if( !this.tree.config.bNestedUnder )
  191. return;
  192. var childNode = this.nestedChildNodes[ toChildOrdinal ];
  193. var connectorElem = document.createElement( "v:polyline" );
  194. this.tree.container.appendChild( connectorElem );
  195. //defines points and draws line and arrowhead
  196. var A = (this.X + 10) + "," + (this.Y + this.height);
  197. var B = (childNode.X + 10) + "," + (childNode.Y);
  198. var C = (this.X + 14) + "," + (this.Y + this.height);
  199. var D = (childNode.X + 14) + "," + (childNode.Y);
  200. connectorElem.points.value = A +" "+ B +" "+ D +" "+ C;
  201. this.connectorNestedElems[toChildOrdinal] = connectorElem;
  202. }
  203. LogTreeNode.prototype.createSubtree = function createSubtree()
  204. {
  205. this.createElement();
  206. var i = 0;
  207. for( ; i < this.childNodes.length; ++i )
  208. {
  209. this.childNodes[i].createSubtree();
  210. if( this != this.tree.rootNode )
  211. this.createConnector( i );
  212. }
  213. for( i = 0; i < this.nestedChildNodes.length; ++i )
  214. {
  215. this.nestedChildNodes[i].createSubtree();
  216. if( this != this.tree.rootNode )
  217. this.createNestingConnector( i );
  218. }
  219. }
  220. function LogTree( objectRef, container )
  221. {
  222. this.objectRef = objectRef;
  223. this.container = document.createElement( "v:group" );
  224. container.appendChild( this.container );
  225. this.container.style.position = "absolute";
  226. this.config = new Object();
  227. this.width = 0;
  228. this.height = 0;
  229. this.nodes = new Array();
  230. this.tempDiv = document.createElement( "DIV" );
  231. this.rootNode = new LogTreeNode( -1, null, null, this, null );
  232. return this;
  233. }
  234. LogTree.prototype.UpdateTree = function UpdateTree()
  235. {
  236. this.rootNode.updateLocation( 0, 0 );
  237. this.rootNode.createSubtree();
  238. this.container.style.width = this.rootNode.groupWidth;
  239. this.container.style.height = this.rootNode.groupHeight;
  240. this.container.coordsize = "" + this.rootNode.groupWidth + "," + this.rootNode.groupHeight;
  241. }
  242. LogTree.prototype.add = function add( id, parentId, content, width, height, boxColor, title )
  243. {
  244. var v_oParentNode;
  245. if( parentId < 0 )
  246. v_oParentNode = this.rootNode;
  247. else
  248. v_oParentNode = this.nodes[parentId];
  249. var v_oNewNode = new LogTreeNode( id, v_oParentNode, null, this, content, width, height, boxColor, title );
  250. this.nodes[id] = v_oNewNode;
  251. v_oParentNode.childNodes.push( v_oNewNode );
  252. return v_oNewNode;
  253. }
  254. LogTree.prototype.addNested = function addNested( id, nestedParentId, content, width, height, boxColor, title )
  255. {
  256. if( !nestedParentId || nestedParentId < 0 )
  257. return this.add( id, -1, content, width, height, boxColor, title );
  258. var v_oParentNode = this.nodes[nestedParentId];
  259. var v_oNewNode = new LogTreeNode( id, null, v_oParentNode, this, content, width, height, boxColor, title );
  260. this.nodes[id] = v_oNewNode;
  261. v_oParentNode.nestedChildNodes.push( v_oNewNode );
  262. return v_oNewNode;
  263. }