Graph.js 54 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207
  1. /****************************************************************
  2. ** Licensed Materials - Property of IBM
  3. **
  4. ** IBM Cognos Products: mdsrv
  5. **
  6. ** (C) Copyright IBM Corp. 2008, 2014
  7. **
  8. ** US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  9. *****************************************************************/
  10. //***********************************************************************************************
  11. // Copyright (C) 2008 Cognos ULC, an IBM Company. All rights reserved.
  12. // Cognos (R) is a trademark of Cognos ULC, (formerly Cognos Incorporated).
  13. //
  14. // Component: Graph control
  15. //***********************************************************************************************
  16. //var DG = {}; // The diagram namespace
  17. var DG = new CNamespace(); // The diagram namespace
  18. //===============================================================================================
  19. // Global Variables & Consts
  20. //===============================================================================================
  21. DG.DebugOutputOn = false;
  22. DG.nObjectCounter = 0; // Required to generate the objects' unique Id
  23. DG.nLineCounter = 0; // Required to generate the lines' sequential Id
  24. //-----------------------------------------------------------------------------------------------
  25. DG.sSelectedObjectName = ''; // Persists the Selected Object between graph refreshes
  26. DG.sSelectedObjectType = '';
  27. DG.CookieMgr = new CCookieMgr ();
  28. DG.sCookieSelObjectName = "graphSelectedObjectName";
  29. DG.sCookieSelObjectType = "graphSelectedObjectType";
  30. //-----------------------------------------------------------------------------------------------
  31. DG.DragDrop = new CDragDrop();
  32. //-----------------------------------------------------------------------------------------------
  33. DG.typeGObject =
  34. {
  35. eNone: 0,
  36. eNode: 1,
  37. eItem: 2,
  38. eConnection: 3,
  39. getTypeString: function( type ) { return getPropertyName( this, type ); }
  40. };
  41. //-----------------------------------------------------------------------------------------------
  42. DG.mapCssClasses = [];
  43. DG.mapCssClasses[ DG.typeGObject.eItem ] = 'classGraphItem';
  44. DG.mapCssClasses[ DG.typeGObject.eNode ] = 'classGraphNode';
  45. DG.mapCssClasses[ DG.typeGObject.eConnection ] = 'classGraphConnection';
  46. //-----------------------------------------------------------------------------------------------
  47. // Colors' Default values
  48. DG.colorDefaults =
  49. {
  50. colorTextStandard: "Black",
  51. colorTextSelected: "White",
  52. colorBkSelTarget: "RGB(219,226,234)",
  53. colorSelectedScope: "Yellow",
  54. colorScope: "Blue",
  55. colorBkScope: "LightYellow",
  56. colorShortcut: "Red",
  57. colorBkShortcut: "White",
  58. colorLineStandard: "#999999",
  59. colorLineSelected: "#3085a5", /*Blue*/
  60. colorBkStandard: "#f6f6f6",
  61. colorBkSelected: "#325C88",
  62. colorBorderStandard: "DarkGray",
  63. // colorBorderExternal: "DarkGray",
  64. colorBorderExternal: "Blue",
  65. colorBorderInternal: "LightGrey",
  66. colorShadow: "DarkGray"
  67. };
  68. // Graph Default values
  69. DG.nRefResolution = { width: 1600 , height: 1200 };
  70. DG.graphDefaults =
  71. {
  72. nNodeWidth: 130,
  73. nItemHeight: 18,
  74. nItemWidth: 170,
  75. nNodeOffsetX: 50,
  76. nNodeOffsetY: 40,
  77. nLineInOffsetY: 2,
  78. nLineOutOffsetY: -2,
  79. nIconSize: 16,
  80. nShadowWidth: 3,
  81. nPenWidth: 1,
  82. nLineWidthStandard: 1,
  83. nLineWidthSelected: 2,
  84. nArrowSize: 8,
  85. styleLine: 'solid',
  86. styleBorder: 'solid',
  87. styleShortcut: 'dotted',
  88. opacityCaption: 0.8,
  89. opacityBody: 0.8,
  90. opacityShadow: 0.5,
  91. nItemFontSize: 10,
  92. nNodeFontSize: 10,
  93. sBkImageSelected: 'Gradient2.png',
  94. sBkImageUnSelected: 'Gradient1.png',
  95. sActionIcon: 'action_custom.gif',
  96. sActionIconTooltip: '',
  97. sCurrentDir: '.',
  98. sImageSubdir: '/images/',
  99. getImagePath: function () { return this.sCurrentDir + this.sImageSubdir; },
  100. bUseShadows: true,
  101. bInclParentProperties: false,
  102. bShowActionLinks: false
  103. };
  104. //-----------------------------------------------------------------------
  105. DG.nScreenResolution = GetScreenResolution();
  106. if ( DG.nScreenResolution.width > 0 )
  107. {
  108. DG.graphDefaults.nScreenRatioWidth = DG.nScreenResolution.width / DG.nRefResolution.width;
  109. DG.graphDefaults.nNodeWidth *= DG.graphDefaults.nScreenRatioWidth;
  110. DG.graphDefaults.nNodeOffsetX *= DG.graphDefaults.nScreenRatioWidth;
  111. }
  112. if ( DG.nScreenResolution.height > 0 )
  113. {
  114. DG.graphDefaults.nScreenRatioHeight = DG.nScreenResolution.height / DG.nRefResolution.height;
  115. DG.graphDefaults.nNodeOffsetY *= DG.graphDefaults.nScreenRatioHeight;
  116. }
  117. // alert( "nNodeWidth = " + DG.graphDefaults.nNodeWidth + ", nNodeOffsetX = " + DG.graphDefaults.nNodeOffsetX );
  118. //---------------------------------------------------------------------
  119. // Optimisation hack - Preload images
  120. var bkImageReg = new Image(30,400);
  121. bkImageReg.src = DG.graphDefaults.getImagePath() + DG.graphDefaults.sBkImageUnSelected;
  122. var bkImageSel = new Image(30,400);
  123. bkImageSel.src = DG.graphDefaults.getImagePath() + DG.graphDefaults.sBkImageSelected;
  124. //***********************************************************************************************
  125. // Class CGraphControl
  126. //***********************************************************************************************
  127. DG.CGraphControl = function ( controller, id_canvas, propertyManager )
  128. {
  129. // Parameters Verification
  130. ASSERT( controller, "CGraphControl: controller is NOT valid !" );
  131. ASSERT( id_canvas, "CGraphControl: id_canvas is NOT valid !" );
  132. ASSERT( propertyManager, "CGraphControl: propertyManager is NOT valid !" );
  133. // Members
  134. this.controller = controller;
  135. this.m_gdi = new gdi ( id_canvas, 100 );
  136. this.m_name = "";
  137. this.m_nodeList = [];
  138. this.m_connectionList = [];
  139. this.m_iconList = [];
  140. this.m_selTargetList = [];
  141. this.m_selObject = null; // implies single selection
  142. this.m_selNode = null; // if an item is selected -> this is its parent node
  143. this.m_mapGObjectIds = []; // the map of all graph's objects by their graph unique Ids (contains all graph objects)
  144. this.m_mapMObjectIds = []; // the map of graph's objects by their model unique Ids (contains only graph objects with valid model object)
  145. this.m_bCreated = false;
  146. this.m_isDragAllowed = true;
  147. this.m_isDragHorzAllowed = true;
  148. this.m_isDragVertAllowed = true;
  149. this.m_propertyManager = propertyManager;
  150. // Hookup event handlers
  151. this.m_gdi.canvas.graph = this;
  152. addEvent( this.m_gdi.canvas, 'click', processOnClick, false );
  153. addEvent( this.m_gdi.canvas, 'dblclick', processOnDblClick, false );
  154. addEvent( this.m_gdi.canvas, 'mousedown', processOnMouseDown, false );
  155. addEvent( this.m_gdi.canvas, 'selectstart', processOnSelectStart, false );
  156. // API
  157. this.getId = function () { return this.m_gdi.id; }
  158. this.setZoom = function ( zoom ) { this.m_gdi.setZoom (zoom); }
  159. this.getZoom = function () { return this.m_gdi.getZoom (); }
  160. this.setName = function ( sName ) { this.m_name = sName; }
  161. this.getIcon = function ( nIndex )
  162. {
  163. return DG.graphDefaults.getImagePath() + this.m_iconList[ nIndex ];
  164. }
  165. this.getActionIcon = function ()
  166. {
  167. return DG.graphDefaults.getImagePath() + DG.graphDefaults.sActionIcon;
  168. }
  169. this.getIconIndex = function (icon)
  170. {
  171. var index = -1;
  172. var size = this.m_iconList.length;
  173. for ( var i = 0; i < size; i++ )
  174. {
  175. if ( this.m_iconList[i] === icon )
  176. {
  177. index = i;
  178. break;
  179. }
  180. }
  181. if ( index >= 0 )
  182. return index;
  183. this.m_iconList.push (icon);
  184. return this.m_iconList.length - 1;
  185. }
  186. //----------------------------------------------------------------------------
  187. // @VIRTUAL METHODS - should be overridden by the controller
  188. //----------------------------------------------------------------------------
  189. this.getObjectIcon = function ( modelObject )
  190. {
  191. if ( this.controller.getObjectIcon )
  192. {
  193. return this.controller.getObjectIcon( modelObject );
  194. }
  195. else
  196. {
  197. ASSERT( false, "getObjectIcon is VIRTUAL METHOD - OVERRIDE it !!!!" );
  198. return "";
  199. }
  200. }
  201. this.isShowItemIcon = function ( modelObject )
  202. {
  203. if ( this.controller.isShowItemIcon )
  204. {
  205. return this.controller.isShowItemIcon( modelObject );
  206. }
  207. else
  208. {
  209. ASSERT( false, "isShowItemIcon is VIRTUAL METHOD - OVERRIDE it !!!!" );
  210. return false;
  211. }
  212. }
  213. this.OnActionClick = function( modelObject )
  214. {
  215. if ( this.controller.OnActionClick )
  216. {
  217. return this.controller.OnActionClick( modelObject );
  218. }
  219. else
  220. {
  221. ASSERT( false, "OnActionClick is VIRTUAL METHOD - OVERRIDE it !!!!" );
  222. return false;
  223. }
  224. }
  225. //----------------------------------------------------------------------------
  226. this.getNode = function ( nIndex )
  227. {
  228. ASSERT( nIndex < this.m_nodeList.length, "getNode: node index is NOT valid !" );
  229. var gNode = this.m_nodeList[ nIndex ];
  230. return gNode;
  231. }
  232. this.getNodeByName = function ( sName )
  233. {
  234. ASSERT( sName, "getNodeByName: sName is NOT valid !" );
  235. var cNodes = this.m_nodeList.length;
  236. for ( var i = 0; i < cNodes; i++ )
  237. {
  238. if ( this.m_nodeList[i].modelObject.getName() === sName )
  239. return this.m_nodeList[i];
  240. }
  241. return null;
  242. }
  243. this.addNode = function ( gNode )
  244. {
  245. ASSERT( gNode, "addNode: node is NOT valid !" );
  246. this.m_nodeList.push ( gNode );
  247. gNode.calculateSize ();
  248. }
  249. this.addConnection = function (connection)
  250. {
  251. ASSERT( connection, "addConnection: connection is NOT valid !" );
  252. this.m_connectionList.push (connection);
  253. }
  254. this.init = function ()
  255. {
  256. var cNodes = this.m_nodeList.length;
  257. for ( var i = 0; i < cNodes; i++ )
  258. {
  259. var gNode = this.m_nodeList[i];
  260. gNode.restoreDefaults ();
  261. gNode.setZIndex ( false );
  262. var cItems = gNode.itemList.length;
  263. for ( var j = 0; j < cItems; j++ )
  264. {
  265. var gItem = gNode.itemList[j];
  266. if ( gItem.isInScope || gItem.isShortcut )
  267. {
  268. var cssHelper = UTIL.ElementHelper.setElem ( gItem.getObjectElem() );
  269. cssHelper.setFontStyle ( 'italic' );
  270. }
  271. }
  272. }
  273. var cConnections = this.m_connectionList.length;
  274. for ( var j2 = 0; j2 < cConnections; j2++ )
  275. {
  276. this.m_connectionList[j2].setZIndex ( false );
  277. }
  278. }
  279. this.onPostPaint = function ()
  280. {
  281. var timeStart = new Date().getTime();
  282. this.init ();
  283. DG.sSelectedObjectName = DG.CookieMgr.getCookie( DG.sCookieSelObjectName );
  284. DG.sSelectedObjectType = DG.CookieMgr.getCookie( DG.sCookieSelObjectType );
  285. if ( DG.sSelectedObjectName )
  286. {
  287. var selObject = null;
  288. if ( DG.sSelectedObjectType === DG.typeGObject.getTypeString ( DG.typeGObject.eNode ) )
  289. selObject = this.getNodeByName ( DG.sSelectedObjectName );
  290. else
  291. selObject = this.findGItemByName ( DG.sSelectedObjectName );
  292. if ( selObject )
  293. {
  294. this.m_selObject = selObject;
  295. }
  296. }
  297. this.SelectObject ( this.m_selObject );
  298. // alertTimeDiff ( timeStart, "CGraphControl.onPostPaint" );
  299. }
  300. this.getClientSize = function ()
  301. {
  302. var cssHelper = UTIL.ElementHelper.setElem ( this.m_gdi.canvas );
  303. var sizeGraph = cssHelper.getClientSize ();
  304. return sizeGraph;
  305. }
  306. this.paint = function ()
  307. {
  308. var timeStart = new Date().getTime();
  309. this.m_gdi.init ();
  310. if ( this.m_name )
  311. this.m_gdi.drawString ( this.m_name, "Lavender", 20, 80, 1200, 200, "", 80, "bold, italic" );
  312. // alert( "CGraphControl.paint: Nodes = " + this.m_nodeList.length + ", Connections = " + this.m_connectionList.length );
  313. // Paint connections
  314. var cConnections = this.m_connectionList.length;
  315. for ( var i = 0; i < cConnections; i++ )
  316. {
  317. this.m_connectionList[i].paint ( this.m_gdi );
  318. }
  319. // Paint nodes
  320. var cNodes = this.m_nodeList.length;
  321. for ( var j = 0; j < cNodes; j++ )
  322. {
  323. this.m_nodeList[j].paint ( this.m_gdi );
  324. }
  325. //----------------------------------------------------------------
  326. // Refresh is inserting the accumulated HTML into the GRAPH area
  327. //----------------------------------------------------------------
  328. this.m_gdi.refresh ();
  329. // alertTimeDiff ( timeStart, "DG.CGraphControl.paint" );
  330. this.m_bCreated = true;
  331. //----------------------------------------------------------------
  332. // At this point all GRAPH elements are ready for post-processing
  333. //----------------------------------------------------------------
  334. this.onPostPaint();
  335. }
  336. this.refreshConnections = function ()
  337. {
  338. var cConnections = this.m_connectionList.length;
  339. for ( var i = 0; i < cConnections; i++)
  340. {
  341. var conn = this.m_connectionList[i];
  342. conn.refresh ( this.m_gdi );
  343. }
  344. }
  345. this.refreshConnectionsForNode = function ( gNode )
  346. {
  347. var cConnections = this.m_connectionList.length;
  348. for ( var i = 0; i < cConnections; i++ )
  349. {
  350. var conn = this.m_connectionList[i];
  351. if ( conn.m_left === gNode || conn.m_right === gNode )
  352. {
  353. conn.refresh ( this.m_gdi );
  354. }
  355. }
  356. }
  357. this.findConnectionElbowOffsetX = function ( oConnection )
  358. {
  359. var nElbowOffset = -1;
  360. var cConnections = this.m_connectionList.length;
  361. for ( var i = 0; i < cConnections; i++ )
  362. {
  363. var oConn = this.m_connectionList[i];
  364. if ( oConn !== oConnection )
  365. {
  366. if ( ( oConn.gItemLeft && ( oConn.gItemLeft === oConnection.gItemLeft ) ) ||
  367. ( oConn.gItemRight && ( oConn.gItemRight === oConnection.gItemRight ) ) )
  368. {
  369. if ( oConn.m_left !== oConn.m_right && oConnection.m_left !== oConnection.m_right )
  370. {
  371. nElbowOffset = 0;
  372. break;
  373. }
  374. }
  375. else
  376. if ( ( ! oConn.gItemLeft && ! oConnection.gItemLeft && oConn.m_left === oConnection.m_left ) ||
  377. ( ! oConn.gItemRight && ! oConnection.gItemRight && oConn.m_right === oConnection.m_right ) )
  378. {
  379. nElbowOffset = 0;
  380. break;
  381. }
  382. }
  383. }
  384. return nElbowOffset;
  385. }
  386. this.findGItem = function ( id )
  387. {
  388. var gObject = this.m_mapGObjectIds[ id ];
  389. if ( gObject && gObject.type !== DG.typeGObject.eItem )
  390. {
  391. gObject = null;
  392. }
  393. return gObject;
  394. }
  395. this.findGNode = function ( id )
  396. {
  397. var gObject = this.m_mapGObjectIds[ id ];
  398. if ( gObject && gObject.type !== DG.typeGObject.eNode )
  399. {
  400. gObject = null;
  401. }
  402. return gObject;
  403. }
  404. this.findGObject = function ( id )
  405. {
  406. return this.m_mapGObjectIds[ id ];
  407. }
  408. this.findGObjectByModelObjectId = function ( modelObjectId )
  409. {
  410. var gObject = this.m_mapMObjectIds[ modelObjectId ];
  411. return gObject;
  412. }
  413. this.findGItemByName = function ( sName )
  414. {
  415. var gItem = null;
  416. for ( var i = 0; i < this.m_nodeList.length; i++ )
  417. {
  418. gItem = this.m_nodeList[i].findItemByName ( sName );
  419. if ( gItem )
  420. break;
  421. }
  422. return gItem;
  423. }
  424. this.findGObjectByName = function ( sName )
  425. {
  426. // First check if it's a node
  427. for ( var i = 0; i < this.m_nodeList.length; i++ )
  428. {
  429. if ( this.m_nodeList[i].getName() === sName )
  430. return this.m_nodeList[i];
  431. }
  432. // Second check if it's an item
  433. var gItem = this.findGItemByName ( sName );
  434. return gItem;
  435. }
  436. this.SelectConnections = function( gObject_clicked )
  437. {
  438. var cConnections = this.m_connectionList.length;
  439. for ( var i = 0; i < cConnections; i++ )
  440. {
  441. with ( this.m_connectionList[i] )
  442. {
  443. select ( false );
  444. }
  445. }
  446. if ( ! gObject_clicked )
  447. return;
  448. // The selection logic depends on the type of Object clicked
  449. var bSelected = false;
  450. for ( var i = 0; i < cConnections; i++ )
  451. {
  452. bSelected = false;
  453. var conn = this.m_connectionList[i];
  454. if ( gObject_clicked.type === DG.typeGObject.eNode )
  455. {
  456. if ( conn.m_left === gObject_clicked )
  457. {
  458. bSelected = true;
  459. }
  460. }
  461. else
  462. if ( gObject_clicked.type === DG.typeGObject.eItem )
  463. {
  464. if ( conn.gItemLeft === gObject_clicked )
  465. {
  466. bSelected = true;
  467. }
  468. }
  469. if ( bSelected )
  470. {
  471. conn.select ( true );
  472. }
  473. }
  474. }
  475. this.SelectObject = function ( gObject_clicked )
  476. {
  477. // alert ( gObject_clicked ? ( "Clicked Object Type " + gObject_clicked.type ) : "Empty space" );
  478. var timeStart = new Date().getTime();
  479. for ( var i = 0; i < this.m_selTargetList.length; i++ )
  480. {
  481. this.m_selTargetList[i].update();
  482. }
  483. this.m_selTargetList.length = 0;
  484. for ( var i = 0; i < this.m_nodeList.length; i++ )
  485. {
  486. this.m_nodeList[i].select( false );
  487. }
  488. for ( var i = 0; i < this.m_nodeList.length; i++ )
  489. {
  490. var gNode = this.m_nodeList[i];
  491. if ( gNode === gObject_clicked )
  492. {
  493. gNode.select( true );
  494. if ( DG.DebugOutputOn )
  495. {
  496. var elem = gNode.getObjectElem();
  497. alert( elem.innerHTML );
  498. alert( elem.outerHTML );
  499. }
  500. }
  501. else
  502. {
  503. for ( var j = 0; j < gNode.itemList.length; j++ )
  504. {
  505. var gItem = gNode.itemList[j];
  506. if ( gItem === gObject_clicked )
  507. {
  508. gItem.select( true );
  509. if ( DG.DebugOutputOn )
  510. {
  511. var domItemNode = document.getElementById( gItem.id );
  512. // domItemNode.style.overflow = 'visible';
  513. alert( domItemNode.innerHTML );
  514. alert( domItemNode.outerHTML );
  515. }
  516. }
  517. else
  518. gItem.select( false );
  519. }
  520. }
  521. }
  522. if ( gObject_clicked )
  523. {
  524. this.m_selObject = gObject_clicked;
  525. this.m_selNode = this.m_selObject.isTypeOf ( DG.typeGObject.eItem ) ? this.m_selObject.getParentObj() : this.m_selObject;
  526. }
  527. else
  528. {
  529. this.m_selObject = null;
  530. this.m_selNode = null;
  531. }
  532. this.SelectConnections( gObject_clicked );
  533. // Set Properties
  534. if ( gObject_clicked )
  535. {
  536. DG.sSelectedObjectName = gObject_clicked.getName ();
  537. DG.sSelectedObjectType = DG.typeGObject.getTypeString ( gObject_clicked.type );
  538. DG.CookieMgr.setCookie( DG.sCookieSelObjectName, DG.sSelectedObjectName );
  539. DG.CookieMgr.setCookie( DG.sCookieSelObjectType, DG.sSelectedObjectType );
  540. var Query = null;
  541. var Item = null;
  542. if ( gObject_clicked.type === DG.typeGObject.eNode )
  543. {
  544. Query = gObject_clicked;
  545. Item = null;
  546. }
  547. else
  548. if ( gObject_clicked.type === DG.typeGObject.eItem )
  549. {
  550. Query = DG.graphDefaults.bInclParentProperties ? gObject_clicked.parentGObj : null;
  551. Item = gObject_clicked;
  552. }
  553. this.m_propertyManager.updateObjects ( Query ? Query.modelObject : null, Item ? Item.modelObject : null );
  554. }
  555. else
  556. {
  557. DG.CookieMgr.deleteCookie ( DG.sCookieSelObjectName );
  558. DG.CookieMgr.deleteCookie ( DG.sCookieSelObjectType );
  559. this.m_propertyManager.updateObjects ( null, null );
  560. }
  561. // alertTimeDiff ( timeStart, "CGraphControl.SelectObject" );
  562. }
  563. this.processKeyEvent = function ( keyEvent )
  564. {
  565. ASSERT( this.m_selNode, "processKeyEvent: NO selected nodes !" );
  566. if ( ! this.m_selNode )
  567. return true;
  568. //---------------------------------------------------------------
  569. var bProcessed = false;
  570. var evt = new CKeyboardEvent ( keyEvent );
  571. // if ( keyEvent.shiftKey || keyEvent.ctrlKey || keyEvent.altKey )
  572. // alert( "ALT !" );
  573. var cNodes = this.m_nodeList.length;
  574. var selSize = this.m_selNode.getScreenSize();
  575. var nextObject = null;
  576. if ( evt.key === UTIL.KEYCODE_ARROW_LEFT )
  577. {
  578. // alert( 'Left Arrow pressed !' );
  579. if ( keyEvent.ctrlKey )
  580. {
  581. bProcessed = true;
  582. var nextSize = null;
  583. for ( var i = 0; i < cNodes; i++ )
  584. {
  585. var size = this.m_nodeList[i].getScreenSize();
  586. if ( size.x < selSize.x )
  587. {
  588. if ( ! nextSize )
  589. {
  590. nextSize = new CSize();
  591. nextSize.clone( size );
  592. nextObject = this.m_nodeList[i];
  593. }
  594. else
  595. if ( size.x > nextSize.x )
  596. {
  597. nextSize.clone( size );
  598. nextObject = this.m_nodeList[i];
  599. }
  600. }
  601. }
  602. }
  603. }
  604. else
  605. if ( evt.key === UTIL.KEYCODE_ARROW_RIGHT )
  606. {
  607. // alert( 'Right Arrow pressed !' );
  608. if ( keyEvent.ctrlKey )
  609. {
  610. bProcessed = true;
  611. var nextSize = null;
  612. for ( var i = 0; i < cNodes; i++ )
  613. {
  614. var size = this.m_nodeList[i].getScreenSize();
  615. if ( size.x > selSize.x )
  616. {
  617. if ( ! nextSize )
  618. {
  619. nextSize = new CSize();
  620. nextSize.clone( size );
  621. nextObject = this.m_nodeList[i];
  622. }
  623. else
  624. if ( size.x < nextSize.x )
  625. {
  626. nextSize.clone( size );
  627. nextObject = this.m_nodeList[i];
  628. }
  629. }
  630. }
  631. }
  632. }
  633. else
  634. if ( evt.key === UTIL.KEYCODE_ARROW_UP )
  635. {
  636. // alert( 'Up Arrow pressed !' );
  637. if ( keyEvent.altKey || keyEvent.ctrlKey )
  638. bProcessed = true;
  639. if ( keyEvent.altKey )
  640. {
  641. var nextItem = this.m_selNode.getPrevItem ( this.m_selObject );
  642. if ( nextItem )
  643. {
  644. nextObject = nextItem;
  645. }
  646. else
  647. {
  648. nextObject = this.m_selNode;
  649. }
  650. }
  651. else
  652. if ( keyEvent.ctrlKey )
  653. {
  654. var size_closest = null;
  655. for ( var i = 0; i < cNodes; i++ )
  656. {
  657. var size = this.m_nodeList[i].getScreenSize();
  658. if ( size.x == selSize.x )
  659. {
  660. if ( size.y < selSize.y )
  661. {
  662. if ( ! size_closest || size.y > size_closest.y )
  663. {
  664. size_closest = size;
  665. nextObject = this.m_nodeList[i];
  666. }
  667. }
  668. }
  669. }
  670. if ( ! nextObject ) // a case when an item was selected -> select the node
  671. nextObject = this.m_selNode;
  672. }
  673. }
  674. else
  675. if ( evt.key === UTIL.KEYCODE_ARROW_DOWN )
  676. {
  677. // alert( 'Down Arrow pressed !' );
  678. if ( keyEvent.altKey || keyEvent.ctrlKey )
  679. bProcessed = true;
  680. if ( keyEvent.altKey )
  681. {
  682. var nextItem = this.m_selNode.getNextItem ( this.m_selObject );
  683. if ( nextItem )
  684. {
  685. nextObject = nextItem;
  686. }
  687. }
  688. else
  689. if ( keyEvent.ctrlKey )
  690. {
  691. var size_closest = null;
  692. for ( var i = 0; i < cNodes; i++ )
  693. {
  694. var size = this.m_nodeList[i].getScreenSize();
  695. if ( size.x == selSize.x )
  696. {
  697. if ( size.y > selSize.y )
  698. {
  699. if ( ! size_closest || size.y < size_closest.y )
  700. {
  701. size_closest = size;
  702. nextObject = this.m_nodeList[i];
  703. }
  704. }
  705. }
  706. }
  707. }
  708. }
  709. if ( nextObject )
  710. {
  711. this.SelectObject ( nextObject );
  712. }
  713. return bProcessed;
  714. }
  715. //*************************************************************************
  716. // Diagram Event handlers
  717. //*************************************************************************
  718. function processOnClick ( ev )
  719. {
  720. // alert ( ' processOnClick !!!' );
  721. var evtObj = new CMouseEvent ( ev );
  722. var gNode = getGNode ( evtObj );
  723. if ( gNode )
  724. stopEvent( evtObj.evt );
  725. cancelEvent ( evtObj.evt );
  726. stopEvent ( evtObj.evt );
  727. return false;
  728. }
  729. function processOnDblClick ( ev )
  730. {
  731. // alert ( ' processOnDblClick !!!' );
  732. var evtObj = new CMouseEvent ( ev );
  733. cancelEvent ( evtObj.evt );
  734. stopEvent ( evtObj.evt );
  735. return false;
  736. }
  737. function processOnSelectStart ( ev )
  738. {
  739. // alert ( ' SELECT_START !!!' );
  740. var evtObj = new CMouseEvent ( ev );
  741. cancelEvent ( evtObj.evt );
  742. stopEvent ( evtObj.evt );
  743. return false;
  744. }
  745. function processOnMouseDown ( ev )
  746. {
  747. var evtObj = new CMouseEvent ( ev );
  748. // alert ( ' processOnMouseDown: ObjId = ' + evtObj.target.id );
  749. var gObject = getGObject( evtObj );
  750. // alert ( ' MOUSE_DOWN - ctrlKey: ' + evtObj.evt.ctrlKey );
  751. if ( gObject )
  752. {
  753. gObject.graph.SelectObject( gObject );
  754. if ( evtObj.target.id === '_action' )
  755. {
  756. gObject.graph.OnActionClick( gObject.modelObject );
  757. cancelEvent ( evtObj.evt );
  758. stopEvent ( evtObj.evt );
  759. return false;
  760. }
  761. }
  762. //--------------------------------------------------------
  763. var obj = getObjectElem ( evtObj );
  764. if ( obj )
  765. {
  766. var graph = obj.parentNode.graph;
  767. if ( graph && graph.m_isDragAllowed )
  768. {
  769. DG.DragDrop.dragObject = obj;
  770. DG.DragDrop.originalPosition = new CPosition( parseInt( obj.offsetLeft ), parseInt( obj.offsetTop ) );
  771. DG.DragDrop.originalMousePosition = new CPosition( evtObj.x, evtObj.y );
  772. addEvent( graph.m_gdi.canvas, 'mousemove', processOnMouseMove, true );
  773. addEvent( graph.m_gdi.canvas, 'mouseup', processOnMouseUp, true );
  774. // graph.m_gdi.canvas.onmousemove = processOnMouseMove;
  775. // graph.m_gdi.canvas.onmouseup = processOnMouseUp;
  776. }
  777. stopEvent( evtObj.evt );
  778. }
  779. else
  780. {
  781. cancelEvent ( evtObj.evt );
  782. stopEvent ( evtObj.evt );
  783. }
  784. return false;
  785. }
  786. function processOnMouseMove ( ev )
  787. {
  788. var evtObj = new CMouseEvent ( ev );
  789. if ( DG.DragDrop.dragObject )
  790. {
  791. var graph = DG.DragDrop.dragObject.parentNode.graph;
  792. if ( graph )
  793. {
  794. if ( graph.m_isDragAllowed )
  795. {
  796. var gNode = graph.findGNode ( DG.DragDrop.dragObject.id );
  797. if ( gNode )
  798. {
  799. if ( ! graph.m_isDragHorzAllowed )
  800. evtObj.x = DG.DragDrop.originalMousePosition.x;
  801. if ( ! graph.m_isDragVertAllowed )
  802. evtObj.y = DG.DragDrop.originalMousePosition.y;
  803. var deltax = evtObj.x - DG.DragDrop.originalMousePosition.x;
  804. var deltay = evtObj.y - DG.DragDrop.originalMousePosition.y;
  805. if ( Math.abs( deltax ) > 5 || Math.abs( deltay ) > 5 )
  806. {
  807. gNode.move ( ( DG.DragDrop.originalPosition.x + deltax) * 100 / graph.getZoom (),
  808. ( DG.DragDrop.originalPosition.y + deltay) * 100 / graph.getZoom (), true );
  809. //gNode.paint(this.graph.m_gdi);
  810. //this.graph.m_gdi.refreshObject (DG.DragDrop.dragObject.id);
  811. // Hack to repaint the element
  812. //var el = document.getElementById ( DG.DragDrop.dragObject.id );
  813. //if ( el )
  814. //{
  815. // var t = el.ownerDocument.createTextNode(' ');
  816. // el.appendChild(t);
  817. // setTimeout(function() { el.removeChild(t); }, 0);
  818. //}
  819. }
  820. cancelEvent ( evtObj.evt );
  821. stopEvent ( evtObj.evt );
  822. }
  823. }
  824. }
  825. }
  826. else
  827. cancelEvent( evtObj.evt );
  828. return false;
  829. }
  830. function processOnMouseUp ( ev )
  831. {
  832. var evtObj = new CMouseEvent ( ev );
  833. var graph = DG.DragDrop.dragObject ? DG.DragDrop.dragObject.parentNode.graph : null;
  834. if ( graph )
  835. {
  836. var gNode = graph.findGNode ( DG.DragDrop.dragObject.id );
  837. if ( gNode )
  838. {
  839. if ( graph.m_isDragAllowed )
  840. {
  841. var deltax = evtObj.x - DG.DragDrop.originalMousePosition.x;
  842. var deltay = evtObj.y - DG.DragDrop.originalMousePosition.y;
  843. }
  844. gNode.restoreDefaults();
  845. }
  846. removeEvent ( graph.m_gdi.canvas, 'mousemove', processOnMouseMove, true );
  847. removeEvent ( graph.m_gdi.canvas, 'mouseup', processOnMouseUp, true );
  848. // addEvent( graph.m_gdi.canvas, 'mousemove', null, false );
  849. // addEvent( graph.m_gdi.canvas, 'mouseup', null, false );
  850. // graph.m_gdi.canvas.onmousemove = null;
  851. // graph.m_gdi.canvas.onmouseup = null;
  852. }
  853. DG.DragDrop.dragObject = null;
  854. cancelEvent( evtObj.evt );
  855. return false;
  856. }
  857. function getGNode ( evtObj )
  858. {
  859. var elem = evtObj.target;
  860. if ( elem )
  861. {
  862. while ( elem.id === "" || elem.id.charAt (0) === '_' )
  863. {
  864. elem = elem.parentNode;
  865. }
  866. if ( elem )
  867. {
  868. graph = elem.parentNode.graph;
  869. if ( graph )
  870. return graph.findGNode ( elem.id );
  871. }
  872. }
  873. return null;
  874. }
  875. function getGObject ( evtObj )
  876. {
  877. var gObject = null;
  878. if ( evtObj.evt )
  879. {
  880. var elem = evtObj.target;
  881. if ( elem && typeof elem.id === "string" )
  882. {
  883. while ( elem.id === "" || elem.id.charAt (0) === '_' )
  884. {
  885. elem = elem.parentNode;
  886. }
  887. if ( elem )
  888. {
  889. var parent_elem = elem;
  890. while ( typeof parent_elem.graph === "undefined" )
  891. {
  892. parent_elem = parent_elem.parentNode;
  893. }
  894. var graph = parent_elem.graph;
  895. if ( typeof graph !== "undefined" )
  896. {
  897. gObject = graph.findGObject( elem.id );
  898. }
  899. }
  900. }
  901. }
  902. return gObject;
  903. }
  904. function getObjectElem ( evtObj )
  905. {
  906. var elem = evtObj.target;
  907. if ( elem )
  908. {
  909. while ( elem && ( elem.id === "" || elem.id.charAt (0) === '_') )
  910. {
  911. elem = elem.parentNode;
  912. }
  913. return elem;
  914. }
  915. return null;
  916. }
  917. this.layout = function()
  918. {
  919. var layout = new Autolayout ( this.m_nodeList, this.m_connectionList );
  920. layout.doIt ();
  921. }
  922. }
  923. //***********************************************************************************************
  924. // Class CGraphObject - the base object for all diagram objects
  925. //***********************************************************************************************
  926. DG.CGraphObject = function ( type, graph, modelObject )
  927. {
  928. // ASSERT( type, "CGraphObject: type is NOT valid !" );
  929. // ASSERT( graph, "CGraphObject: graph is NOT valid !" );
  930. if ( ! type || ! graph )
  931. return;
  932. CSize.call (); // constructor chaining
  933. // Assemble the object's unique Id
  934. this.nUniqueId = ++DG.nObjectCounter;
  935. this.id = 'id' + this.nUniqueId;
  936. this.type = type;
  937. this.id += '_' + DG.typeGObject.getTypeString( this.type );
  938. // Register in the Graph Hash table
  939. graph.m_mapGObjectIds[ this.id ] = this;
  940. this.container = false;
  941. this.parentGObj = null;
  942. this.graph = graph;
  943. this.modelObject = modelObject;
  944. this.icon = 0;
  945. this.bShowIcon = true;
  946. this.elemObject = null;
  947. this.sCssClass = DG.mapCssClasses[this.type];
  948. this.isSelected = false;
  949. this.isInScope = false;
  950. this.colorText = DG.colorDefaults.colorTextStandard;
  951. this.colorBk = DG.colorDefaults.colorBkStandard;
  952. this.colorBorderExternal = DG.colorDefaults.colorBorderExternal;
  953. this.colorBorderInternal = DG.colorDefaults.colorBorderInternal;
  954. this.thickness = DG.graphDefaults.nPenWidth;
  955. this.zOrderRegular = 0;
  956. this.zOrderSelected = 0;
  957. // Icon selection
  958. if ( this.modelObject )
  959. {
  960. this.icon = this.graph.getObjectIcon ( this.modelObject );
  961. graph.m_mapMObjectIds[ this.modelObject.getId() ] = this;
  962. }
  963. }
  964. DG.CGraphObject.inherits( CSize );
  965. //--------------------------------------------------------------------
  966. // CGraphObject API
  967. //--------------------------------------------------------------------
  968. DG.CGraphObject.prototype.isTypeOf = function ( type ) { return ( type === this.type ); }
  969. DG.CGraphObject.prototype.getId = function () { return ( this.id ); }
  970. DG.CGraphObject.prototype.getTextId = function () { return ( '_' + this.id + '_text' ); }
  971. DG.CGraphObject.prototype.getRectId = function () { return ( '_' + this.id + '_rect' ); }
  972. DG.CGraphObject.prototype.getActionId = function () { return ( '_action' ); }
  973. DG.CGraphObject.prototype.getParentObj = function () { return this.parentGObj; }
  974. DG.CGraphObject.prototype.getObjectElem = function ()
  975. {
  976. var elem = this.id;
  977. if ( ! this.elemObject )
  978. {
  979. if ( this.graph.m_bCreated )
  980. this.elemObject = document.getElementById( this.id );
  981. }
  982. if ( this.elemObject )
  983. {
  984. elem = this.elemObject;
  985. }
  986. return elem;
  987. }
  988. DG.CGraphObject.prototype.equals = function ( gObject )
  989. {
  990. if ( ! gObject )
  991. return false;
  992. return ( this.type === gObject.type ) && ( this.getId() === gObject.getId() );
  993. }
  994. DG.CGraphObject.prototype.show = function ( bShow )
  995. {
  996. var cssHelper = UTIL.ElementHelper.setElem ( this.getObjectElem() );
  997. cssHelper.show ( bShow );
  998. }
  999. DG.CGraphObject.prototype.isShown = function ()
  1000. {
  1001. var cssHelper = UTIL.ElementHelper.setElem ( this.getObjectElem() );
  1002. var bShown = cssHelper.isShown ();
  1003. return bShown;
  1004. }
  1005. DG.CGraphObject.prototype.setZIndex = function ( bSelect )
  1006. {
  1007. var cssHelper = UTIL.ElementHelper.setElem ( this.getObjectElem() );
  1008. cssHelper.setZIndex ( bSelect ? this.zOrderSelected : this.zOrderRegular );
  1009. }
  1010. DG.CGraphObject.prototype.setZIndexFn = function ( zOrder )
  1011. {
  1012. var cssHelper = UTIL.ElementHelper.setElem ( this.getObjectElem() );
  1013. cssHelper.setZIndex ( zOrder );
  1014. }
  1015. DG.CGraphObject.prototype.getName = function ()
  1016. {
  1017. var name = "";
  1018. if ( this.modelObject )
  1019. name = this.modelObject.getName();
  1020. return name;
  1021. }
  1022. DG.CGraphObject.prototype.setText = function ( sText )
  1023. {
  1024. var cssHelper = UTIL.ElementHelper.setElem ( this.getTextId() );
  1025. cssHelper.setText ( sText );
  1026. }
  1027. DG.CGraphObject.prototype.setTextColors = function ()
  1028. {
  1029. var cssHelper = UTIL.ElementHelper.setElem ( this.getTextId() );
  1030. cssHelper.setColors ( this.colorText, this.colorBk );
  1031. }
  1032. DG.CGraphObject.prototype.setTextBold = function ()
  1033. {
  1034. var cssHelper = UTIL.ElementHelper.setElem ( this.getTextId() );
  1035. cssHelper.setTextBold ();
  1036. }
  1037. DG.CGraphObject.prototype.setBorderStyle = function ( sStyle )
  1038. {
  1039. var cssHelper = UTIL.ElementHelper.setElem ( this.getRectId() );
  1040. cssHelper.setBorderStyle ( sStyle );
  1041. }
  1042. DG.CGraphObject.prototype.select = function ( bSelect ) { this.isSelected = bSelect; }
  1043. DG.CGraphObject.prototype.getScreenSize = function ()
  1044. {
  1045. var cssHelper = UTIL.ElementHelper.setElem ( this.getObjectElem() );
  1046. var size = cssHelper.getScreenSize();
  1047. return size;
  1048. }
  1049. //***********************************************************************************************
  1050. // Class CGraphItem
  1051. //***********************************************************************************************
  1052. DG.CGraphItem = function ( parentGObj, modelObject, graph )
  1053. {
  1054. ASSERT( graph, "CGraphItem: graph is NOT valid !" );
  1055. ASSERT( modelObject,"CGraphItem: modelObject is NOT valid !" );
  1056. // First, invoke the superclass constructor on the new object so that it can initialize its members.
  1057. // We use the call method so that we invoke the constructor as a method of the object to be initialized.
  1058. // This is called constructor chaining
  1059. DG.CGraphObject.call( this, DG.typeGObject.eItem, graph, modelObject ); // constructor chaining
  1060. // Members
  1061. this.parentGObj = parentGObj;
  1062. this.zOrderRegular = 5;
  1063. this.zOrderSelected = 6;
  1064. this.cInConnections = 0;
  1065. this.cOutConnections = 0;
  1066. }
  1067. DG.CGraphItem.inherits( DG.CGraphObject );
  1068. //--------------------------------------------------------------------
  1069. // CGraphItem API
  1070. //--------------------------------------------------------------------
  1071. DG.CGraphItem.prototype.getTextId = function () { return ( this.id ); }
  1072. DG.CGraphItem.prototype.getRectId = function () { return ( this.id ); }
  1073. DG.CGraphItem.prototype.setCurrColors = function ()
  1074. {
  1075. this.colorText = DG.colorDefaults.colorTextStandard;
  1076. this.colorBk = DG.colorDefaults.colorBkStandard;
  1077. if ( this.isShortcut )
  1078. {
  1079. this.colorText = DG.colorDefaults.colorShortcut;
  1080. this.colorBk = DG.colorDefaults.colorBkShortcut;
  1081. }
  1082. else
  1083. if ( this.isInScope )
  1084. {
  1085. this.colorText = DG.colorDefaults.colorScope;
  1086. this.colorBk = DG.colorDefaults.colorBkScope;
  1087. }
  1088. if ( this.isSelected )
  1089. {
  1090. this.colorText = this.isInScope ? DG.colorDefaults.colorSelectedScope : DG.colorDefaults.colorTextSelected;
  1091. this.colorBk = DG.colorDefaults.colorBkSelected;
  1092. }
  1093. }
  1094. DG.CGraphItem.prototype.paint = function ( gdi )
  1095. {
  1096. var x = this.x + 1;
  1097. var width = gdi.ie ? this.parentGObj.width - 3 : this.parentGObj.width - 5;
  1098. if ( this.graph.isShowItemIcon( this.modelObject ) )
  1099. {
  1100. gdi.drawIcon ( this.graph.getIcon ( this.icon ), x, this.y + 1, DG.graphDefaults.nIconSize, DG.graphDefaults.nIconSize );
  1101. x += DG.graphDefaults.nIconSize;
  1102. width -= DG.graphDefaults.nIconSize;
  1103. }
  1104. gdi.startContainer ( this.sCssClass, x, this.y + 1, width, this.height - 1, this.getId(), "hidden", this.modelObject.getName() );
  1105. gdi.addText ( this.modelObject.getName() );
  1106. if ( DG.graphDefaults.bShowActionLinks )
  1107. if ( this.modelObject.bPackageDataSourceObject )
  1108. gdi.drawActionIcon( this.graph.getActionIcon (), width - DG.graphDefaults.nIconSize, 1, DG.graphDefaults.nIconSize, DG.graphDefaults.nIconSize, this.getActionId(), DG.graphDefaults.sActionIconTooltip );
  1109. gdi.endContainer ();
  1110. }
  1111. DG.CGraphItem.prototype.update = function ()
  1112. {
  1113. var oRect = document.getElementById ( this.getRectId() );
  1114. var oText = document.getElementById ( this.getTextId() );
  1115. this.setCurrColors ();
  1116. oText.style.color = this.colorText;
  1117. oRect.style.backgroundColor = this.colorBk;
  1118. }
  1119. DG.CGraphItem.prototype.select = function ( bSelect )
  1120. {
  1121. if ( this.isSelected === bSelect )
  1122. return;
  1123. this.isSelected = bSelect;
  1124. this.update();
  1125. if ( this.isSelected )
  1126. this.parentGObj.setZIndex ( true ); // Restore parent Z-order
  1127. }
  1128. DG.CGraphItem.prototype.PaintTarget = function ()
  1129. {
  1130. if ( this.isSelected )
  1131. return;
  1132. var oRect = document.getElementById ( this.getRectId() );
  1133. if ( oRect )
  1134. {
  1135. oRect.style.backgroundColor = DG.colorDefaults.colorBkSelTarget;
  1136. }
  1137. }
  1138. //***********************************************************************************************
  1139. // Class CGraphNode
  1140. //***********************************************************************************************
  1141. DG.CGraphNode = function ( modelObject, graph )
  1142. {
  1143. ASSERT( graph, "CGraphNode: graph is NOT valid !" );
  1144. ASSERT( modelObject,"CGraphNode: modelObject is NOT valid !" );
  1145. // First, invoke the superclass constructor on the new object so that it can initialize its members.
  1146. // We use the call method so that we invoke the constructor as a method of the object to be initialized.
  1147. // This is called constructor chaining
  1148. DG.CGraphObject.call( this, DG.typeGObject.eNode, graph, modelObject ); // constructor chaining
  1149. // Members
  1150. this.itemList = [];
  1151. this.titleHeight = 22;
  1152. this.width = DG.graphDefaults.nNodeWidth;
  1153. this.zOrderRegular = 10;
  1154. this.zOrderSelected = 100;
  1155. this.colorBk = 'transparent';
  1156. this.elemCaption = null;
  1157. this.bUpdateConnections = true;
  1158. this.mapGItemsByName = []; // the map of all node's items by their graph name
  1159. // Populating Children
  1160. var y_item = this.titleHeight;
  1161. var cItems = this.modelObject.getItemCount();
  1162. for ( var i = 0; i < cItems; i++ )
  1163. {
  1164. var gItem = new DG.CGraphItem ( this, this.modelObject.getItem(i), graph );
  1165. this.mapGItemsByName [ gItem.getName()] = gItem;
  1166. gItem.SetPosition( 1, y_item, this.width, DG.graphDefaults.nItemHeight );
  1167. this.itemList.push( gItem );
  1168. y_item += DG.graphDefaults.nItemHeight;
  1169. }
  1170. }
  1171. DG.CGraphNode.inherits( DG.CGraphObject );
  1172. //--------------------------------------------------------------------
  1173. // CGraphNode API
  1174. //--------------------------------------------------------------------
  1175. DG.CGraphNode.prototype.getCaptionId = function () { return ( '_' + this.id + '_caption' ); }
  1176. // DG.CGraphNode.prototype.getTextId = function () { return this.getCaptionId(); }
  1177. DG.CGraphNode.prototype.findItemByName = function ( sName )
  1178. {
  1179. return this.mapGItemsByName [ sName ];
  1180. }
  1181. DG.CGraphNode.prototype.getItemOffset = function ( gItem )
  1182. {
  1183. if ( ! gItem )
  1184. return 0;
  1185. var nOffset = 0;
  1186. for ( var i = 0; i < this.itemList.length; i++ )
  1187. {
  1188. if ( this.itemList[i] === gItem )
  1189. {
  1190. nOffset = this.titleHeight + DG.graphDefaults.nItemHeight * i + DG.graphDefaults.nItemHeight / 2;
  1191. break;
  1192. }
  1193. }
  1194. return nOffset;
  1195. }
  1196. DG.CGraphNode.prototype.getItemPosition = function ( gItem )
  1197. {
  1198. if ( ! gItem )
  1199. return null;
  1200. var pos = null;
  1201. for ( var i = 0; i < this.itemList.length; i++ )
  1202. {
  1203. if ( this.itemList[i] === gItem )
  1204. {
  1205. var nItemOffset = this.getItemOffset ( gItem );
  1206. pos = new CPosition ( this.x, this.y + nItemOffset );
  1207. break;
  1208. }
  1209. }
  1210. return pos;
  1211. }
  1212. DG.CGraphNode.prototype.getConnectPoint = function ( pointFrom )
  1213. {
  1214. var x = this.getCenterX ();
  1215. var y = this.getCenterY ();
  1216. var pointNew = new CPoint( x, y );
  1217. if ( pointFrom )
  1218. {
  1219. if ( pointFrom.x > pointNew.x )
  1220. pointNew.x = this.x + this.width;
  1221. else
  1222. if ( pointFrom.x < pointNew.x )
  1223. pointNew.x = this.x;
  1224. else
  1225. if ( pointFrom.y > pointNew.y )
  1226. pointNew.y = this.y + this.height;
  1227. else
  1228. if ( pointFrom.y < pointNew.y )
  1229. pointNew.y = this.y;
  1230. }
  1231. return pointNew;
  1232. }
  1233. DG.CGraphNode.prototype.setCurrColors = function ()
  1234. {
  1235. this.colorText = DG.colorDefaults.colorTextStandard;
  1236. if ( this.isSelected )
  1237. {
  1238. this.colorText = DG.colorDefaults.colorTextSelected;
  1239. }
  1240. }
  1241. DG.CGraphNode.prototype.paint = function ( gdi )
  1242. {
  1243. var nTextWidth = this.width - 28;
  1244. if ( DG.graphDefaults.bShowActionLinks )
  1245. if ( this.modelObject.bPackageDataSourceObject )
  1246. this.width += DG.graphDefaults.nIconSize + 12 / DG.graphDefaults.nScreenRatioWidth; // increase width to make space for an action icon
  1247. gdi.startContainer ( this.sCssClass, this.x, this.y, this.width + DG.graphDefaults.nShadowWidth, this.height + DG.graphDefaults.nShadowWidth, this.getId(), "visible" );
  1248. this.setCurrColors ();
  1249. var width = gdi.ie ? this.width - 3 : this.width - 7;
  1250. width -= DG.graphDefaults.nIconSize;
  1251. var height = this.titleHeight - 3;
  1252. gdi.drawBackgroundImage ( DG.graphDefaults.getImagePath() + ( this.isSelected ? DG.graphDefaults.sBkImageSelected : DG.graphDefaults.sBkImageUnSelected ), 1, 1, this.width - 1, this.titleHeight - 2, this.getCaptionId() );
  1253. // gdi.drawCaptionRect ( this.getCaptionId(), 'classGraphCaption', this.modelObject.getName(), 1, 1, width, height, DG.graphDefaults.nPenWidth, DG.graphDefaults.sBkImageUnSelected );
  1254. // Full Rect Background
  1255. // gdi.fillRectangle ( this.colorBk, 1, this.titleHeight, this.width - 2, this.height - this.titleHeight - 1, DG.graphDefaults.opacityBody );
  1256. // Line under title
  1257. gdi.drawHorzLine ( this.colorBorderInternal, 1, DG.graphDefaults.styleBorder, 1, this.titleHeight - 1, this.width - 2 );
  1258. // Full Rect
  1259. gdi.drawRectangle ( this.colorBorderExternal, 0, 0, this.width, this.height - 1, DG.graphDefaults.styleBorder, DG.graphDefaults.nPenWidth, this.getRectId() );
  1260. // Title
  1261. gdi.drawString ( this.modelObject.getName(), this.colorText, 20, 3, nTextWidth, 14, "", DG.graphDefaults.nNodeFontSize, "normal", this.getTextId(), this.modelObject.getName() );
  1262. // Icon
  1263. var nIconOffset = ( this.titleHeight - DG.graphDefaults.nIconSize ) / 2;
  1264. gdi.drawIcon ( this.graph.getIcon ( this.icon ), nIconOffset, nIconOffset, DG.graphDefaults.nIconSize, DG.graphDefaults.nIconSize );
  1265. if ( DG.graphDefaults.bShowActionLinks )
  1266. if ( this.modelObject.bPackageDataSourceObject )
  1267. gdi.drawActionIcon( this.graph.getActionIcon (), width + 1, 3, DG.graphDefaults.nIconSize, DG.graphDefaults.nIconSize, this.getActionId(), DG.graphDefaults.sActionIconTooltip );
  1268. // Paint children
  1269. for ( var i = 0; i < this.itemList.length; i++ )
  1270. {
  1271. this.itemList[i].paint( gdi );
  1272. }
  1273. if ( DG.graphDefaults.bUseShadows )
  1274. {
  1275. gdi.fillRectangle ( DG.colorDefaults.colorShadow, this.width+1, DG.graphDefaults.nShadowWidth + 2, DG.graphDefaults.nShadowWidth, this.height - 2, DG.graphDefaults.opacityShadow );
  1276. gdi.fillRectangle ( DG.colorDefaults.colorShadow, DG.graphDefaults.nShadowWidth + 2, this.height, this.width - DG.graphDefaults.nShadowWidth - 1, DG.graphDefaults.nShadowWidth, DG.graphDefaults.opacityShadow );
  1277. }
  1278. gdi.endContainer ();
  1279. }
  1280. DG.CGraphNode.prototype.select = function ( bSelect )
  1281. {
  1282. if ( this.isSelected === bSelect )
  1283. return;
  1284. for ( var i = 0; i < this.itemList.length; i++ )
  1285. {
  1286. this.itemList[ i ].select( false );
  1287. }
  1288. var elem = document.getElementById ( this.getCaptionId() );
  1289. this.isSelected = bSelect;
  1290. elem.src = DG.graphDefaults.getImagePath();
  1291. if ( this.isSelected )
  1292. elem.src += DG.graphDefaults.sBkImageSelected;
  1293. else
  1294. elem.src += DG.graphDefaults.sBkImageUnSelected;
  1295. this.setZIndex ( this.isSelected );
  1296. this.setCurrColors ();
  1297. this.setTextColors ();
  1298. }
  1299. DG.CGraphNode.prototype.calculateSize = function ()
  1300. {
  1301. if ( this.width === 0 )
  1302. this.width = 120;
  1303. if ( this.height === 0 )
  1304. {
  1305. var cItems = this.itemList.length;
  1306. this.height = this.titleHeight + cItems * DG.graphDefaults.nItemHeight + ( cItems > 0 ? 3 : 0 );
  1307. }
  1308. }
  1309. DG.CGraphNode.prototype.move = function ( newx, newy, bByDrag )
  1310. {
  1311. if ( newx < 0 || newy < 0 )
  1312. return;
  1313. if ( ! this.elemObject )
  1314. this.elemObject = document.getElementById ( this.getId() );
  1315. if ( ! this.elemCaption )
  1316. this.elemCaption = document.getElementById ( this.getCaptionId() );
  1317. if ( this.elemObject )
  1318. {
  1319. if ( bByDrag )
  1320. {
  1321. this.elemObject.style.cursor = 'move';
  1322. this.elemCaption.style.cursor = 'move';
  1323. }
  1324. this.SetPosition( newx, newy );
  1325. this.graph.m_gdi.moveObject ( this.elemObject, newx, newy );
  1326. if ( ! bByDrag || this.bUpdateConnections )
  1327. this.graph.refreshConnectionsForNode ( this );
  1328. this.bUpdateConnections = ! this.bUpdateConnections; // Hack to make the node more responsive during move
  1329. }
  1330. }
  1331. DG.CGraphNode.prototype.refresh = function ()
  1332. {
  1333. this.move ( this.x, this.y );
  1334. }
  1335. DG.CGraphNode.prototype.restoreDefaults = function ()
  1336. {
  1337. if ( ! this.elemObject )
  1338. this.elemObject = document.getElementById ( this.getId() );
  1339. if ( ! this.elemCaption )
  1340. this.elemCaption = document.getElementById ( this.getCaptionId() );
  1341. if ( this.elemObject )
  1342. {
  1343. this.elemObject.style.cursor = 'default';
  1344. this.elemCaption.style.cursor = 'move';
  1345. this.graph.refreshConnectionsForNode ( this );
  1346. }
  1347. }
  1348. DG.CGraphNode.prototype.getItemIndex = function ( gItem )
  1349. {
  1350. var nItem = -1;
  1351. for ( var index = 0; index < this.itemList.length; index++ )
  1352. {
  1353. if ( this.itemList[index] === gItem )
  1354. {
  1355. nItem = index;
  1356. break;
  1357. }
  1358. }
  1359. return nItem;
  1360. }
  1361. DG.CGraphNode.prototype.getNextItem = function ( gItem )
  1362. {
  1363. var gNextItem = null;
  1364. var nNextItem = -1;
  1365. var nItem = this.getItemIndex( gItem );
  1366. if ( nItem === -1 )
  1367. nNextItem = this.itemList.length > 0 ? 0 : -1;
  1368. else
  1369. nNextItem = nItem < ( this.itemList.length - 1 ) ? ( nItem + 1 ) : -1;
  1370. if ( nNextItem !== -1 )
  1371. gNextItem = this.itemList[ nNextItem ];
  1372. return gNextItem;
  1373. }
  1374. DG.CGraphNode.prototype.getPrevItem = function ( gItem )
  1375. {
  1376. var gPrevItem = null;
  1377. var nPrevItem = -1;
  1378. var nItem = this.getItemIndex( gItem );
  1379. if ( nItem === -1 )
  1380. nPrevItem = this.itemList.length > 0 ? 0 : -1;
  1381. else
  1382. nPrevItem = nItem > 0 ? ( nItem - 1 ) : -1;
  1383. if ( nPrevItem !== -1 )
  1384. gPrevItem = this.itemList[ nPrevItem ];
  1385. return gPrevItem;
  1386. }
  1387. //***********************************************************************************************
  1388. // Class CGraphConnection
  1389. //***********************************************************************************************
  1390. DG.CGraphConnection = function ( left, right, graph )
  1391. {
  1392. ASSERT( left, "CGraphConnection: left end is NOT valid !" );
  1393. ASSERT( right, "CGraphConnection: right end is NOT valid !" );
  1394. DG.CGraphObject.call( this, DG.typeGObject.eConnection, graph, null ); // constructor chaining
  1395. //-----------------------------------------------------------
  1396. // Members
  1397. //-----------------------------------------------------------
  1398. this.isValid = true;
  1399. this.nIndex = ++DG.nLineCounter;
  1400. this.thickness = DG.graphDefaults.nLineWidthStandard;
  1401. this.nElbowOffset = 0;
  1402. if ( ! left || ! right )
  1403. {
  1404. this.isValid = false;
  1405. return;
  1406. }
  1407. left.isInScope = false;
  1408. right.isInScope = false;
  1409. //------------------------------------------------------------------------------------
  1410. // Determine the real Left and Right nodes
  1411. //------------------------------------------------------------------------------------
  1412. var bIsLeftGraphObject = left instanceof DG.CGraphObject;
  1413. // An alternative way to check for object inheritence
  1414. // var bIsLeftGraphObject = DG.CGraphObject.prototype.isPrototypeOf ( left );
  1415. if ( ! bIsLeftGraphObject )
  1416. {
  1417. // It means the LEFT object is a model object and we need to find its GObject container
  1418. var gObject = graph.findGObjectByModelObjectId ( left );
  1419. if ( gObject )
  1420. {
  1421. left = gObject;
  1422. }
  1423. else
  1424. {
  1425. this.isValid = false;
  1426. ASSERT( false, "CGraphConnection: left node " + left + "is NOT found !" );
  1427. }
  1428. }
  1429. var bIsRightGraphObject = right instanceof DG.CGraphObject;
  1430. if ( ! bIsRightGraphObject )
  1431. {
  1432. // It means the RIGHT object is a model object and we need to find its GObject container
  1433. var gObject = graph.findGObjectByModelObjectId ( right );
  1434. if ( gObject )
  1435. {
  1436. right = gObject;
  1437. }
  1438. else
  1439. {
  1440. this.isValid = false;
  1441. ASSERT( false, "CGraphConnection: right node " + right + "is NOT found !" );
  1442. }
  1443. }
  1444. if ( ! this.isValid )
  1445. {
  1446. this.isValid = false;
  1447. return;
  1448. }
  1449. // By now, the LEFT & RIGHT object must be graph objects
  1450. ASSERT( left && left.type, "CGraphConnection: left node is NOT valid !" );
  1451. ASSERT( right && right.type, "CGraphConnection: right node is NOT valid !" );
  1452. // A special case for object shortcuts
  1453. if ( left.modelObject.getShortcutTo() === right.modelObject )
  1454. {
  1455. this.isShortcut = true;
  1456. left.isShortcut = true;
  1457. }
  1458. if ( right.modelObject.getShortcutTo() === left.modelObject )
  1459. {
  1460. this.isShortcut = true;
  1461. right.isShortcut= true;
  1462. }
  1463. //-------------------------------------------------------------------------------
  1464. if ( left.isTypeOf ( DG.typeGObject.eNode ) )
  1465. {
  1466. this.gItemLeft = null;
  1467. this.m_left = left;
  1468. }
  1469. else
  1470. if ( left.isTypeOf ( DG.typeGObject.eItem ) )
  1471. {
  1472. this.gItemLeft = left;
  1473. this.m_left = left.parentGObj;
  1474. this.gItemLeft.cInConnections++;
  1475. }
  1476. else
  1477. ASSERT( null, "CGraphConnection: left object type is unknown !" );
  1478. if ( right.isTypeOf ( DG.typeGObject.eNode ) )
  1479. {
  1480. this.gItemRight = null;
  1481. this.m_right = right;
  1482. }
  1483. else
  1484. if ( right.isTypeOf ( DG.typeGObject.eItem ) )
  1485. {
  1486. this.gItemRight = right;
  1487. this.m_right = right.parentGObj;
  1488. this.gItemRight.cOutConnections++;
  1489. }
  1490. else
  1491. ASSERT( null, "CGraphConnection: right object type is unknown !" );
  1492. this.color = DG.colorDefaults.colorLineStandard;
  1493. this.colorBk = DG.colorDefaults.colorBkStandard;
  1494. this.zOrderRegular = 2;
  1495. this.zOrderSelected = 200;
  1496. }
  1497. DG.CGraphConnection.inherits( DG.CGraphObject );
  1498. //-----------------------------------------------------------
  1499. // CGraphConnection API
  1500. //-----------------------------------------------------------
  1501. DG.CGraphConnection.prototype.setZIndexLine = function ( bSelect )
  1502. {
  1503. // Set the line's DIV z-index
  1504. this.setZIndex ( this.isSelected );
  1505. // Set z-index for all segments
  1506. var elem = this.getObjectElem();
  1507. var nodeList = elem.childNodes;
  1508. if ( nodeList === null )
  1509. {
  1510. return;
  1511. }
  1512. for ( var current = 0; current < nodeList.length; current++ )
  1513. {
  1514. var node = nodeList.item ( current );
  1515. node.style.zIndex = bSelect ? this.zOrderSelected : this.zOrderRegular;
  1516. }
  1517. }
  1518. DG.CGraphConnection.prototype.setColor = function ( color )
  1519. {
  1520. this.color = color;
  1521. var elem = this.getObjectElem();
  1522. // NodeList nodeList = elem.getChildNodes();
  1523. var nodeList = elem.childNodes;
  1524. if ( nodeList === null )
  1525. {
  1526. return;
  1527. }
  1528. for ( var current = 0; current < nodeList.length; current++ )
  1529. {
  1530. var node = nodeList.item ( current );
  1531. node.style.backgroundColor = 'transparent';
  1532. node.style.borderTopColor = color;
  1533. node.style.borderLeftColor = color;
  1534. }
  1535. }
  1536. DG.CGraphConnection.prototype.paint = function ( gdi )
  1537. {
  1538. var sizeClient = this.graph.getClientSize();
  1539. // gdi.startContainer ( this.sCssClass, 0, 0, sizeClient.width, sizeClient.height, this.getId(), 'visible' );
  1540. gdi.startContainer ( this.sCssClass, 0, 0, 1, 1, this.getId(), 'visible' );
  1541. this.paintContent ( gdi, this.m_left, this.m_right );
  1542. gdi.endContainer ();
  1543. }
  1544. DG.CGraphConnection.prototype.paintContent = function ( gdi, nodeL, nodeR )
  1545. {
  1546. var sLineStyle = this.isShortcut ? DG.graphDefaults.styleShortcut : DG.graphDefaults.styleLine;
  1547. if ( nodeL === nodeR )
  1548. {
  1549. ASSERT ( this.gItemLeft && this.gItemRight, "Connection: items for the same nod NOT valid !" );
  1550. // A Special case for self-referencing nodes
  1551. var posL = this.m_left.getItemPosition ( this.gItemLeft );
  1552. var posR = this.m_right.getItemPosition ( this.gItemRight );
  1553. posL.y += DG.graphDefaults.nLineOutOffsetY;
  1554. posR.y += DG.graphDefaults.nLineInOffsetY;
  1555. this.nElbowOffset = - ( this.nIndex % 3 ) * 3;
  1556. gdi.drawVertAngledLineToPoint ( this.color, this.thickness, sLineStyle, posL, posR, this.nElbowOffset );
  1557. return;
  1558. }
  1559. if ( nodeL.HasIntersection( nodeR ) )
  1560. {
  1561. // alert ( "Connection: Intersection !!" );
  1562. return; // no space to paint the connection
  1563. }
  1564. // Ensure that the left node is really left on the X axis
  1565. var itemLeft = this.gItemLeft;
  1566. var itemRight = this.gItemRight;
  1567. if ( nodeL.x > nodeR.x )
  1568. {
  1569. var nodeTemp = nodeL;
  1570. nodeL = nodeR;
  1571. nodeR = nodeTemp;
  1572. itemLeft = this.gItemRight;
  1573. itemRight = this.gItemLeft;
  1574. }
  1575. if ( nodeL.x + nodeL.width >= nodeR.x )
  1576. {
  1577. // alert ( "Connection: Straight Line !!" );
  1578. // A Special case for nodes overlapping on the X axis
  1579. var xIntersect = nodeL.x + nodeL.width - nodeR.x;
  1580. var xLine = nodeR.x + xIntersect / 2;
  1581. var nodeTop = nodeL.y < nodeR.y ? nodeL : nodeR;
  1582. var bLeftEndIsOnTop = nodeTop === this.m_left;
  1583. var yTopEnd = nodeL.y + nodeL.height < nodeR.y ? nodeL.y + nodeL.height : nodeR.y + nodeR.height;
  1584. var yBottomEnd = nodeL.y + nodeL.height > nodeR.y ? nodeL.y : nodeR.y;
  1585. var ptTop = new CPoint ( xLine, yTopEnd );
  1586. var ptBottom = new CPoint ( xLine, yBottomEnd );
  1587. if ( ! bLeftEndIsOnTop )
  1588. {
  1589. gdi.drawArrowUp ( this.color, xLine, yTopEnd, sLineStyle, DG.graphDefaults.nArrowSize );
  1590. }
  1591. gdi.drawVertLineToPoint ( this.color, this.thickness, sLineStyle, ptTop, ptBottom );
  1592. if ( bLeftEndIsOnTop )
  1593. {
  1594. gdi.drawArrowDown ( this.color, xLine, yBottomEnd, sLineStyle, DG.graphDefaults.nArrowSize );
  1595. }
  1596. return;
  1597. }
  1598. // The rest is a case for nodes NOT overlapping on the X axis, i.e. one on the left & another on the right
  1599. var nodeLeft = nodeL.x < nodeR.x ? nodeL : nodeR;
  1600. var bSourceIsOnLeft = nodeLeft === this.m_left;
  1601. var xLeft = nodeL.x + nodeL.width;
  1602. var yLeft = nodeL.y + nodeL.height / 2;
  1603. var xRight = nodeR.x;
  1604. var yRight = nodeR.y + nodeR.height / 2;
  1605. var lItemOffset = nodeL.getItemOffset ( itemLeft );
  1606. if ( lItemOffset !== 0 )
  1607. yLeft = nodeL.y + lItemOffset;
  1608. var rItemOffset = nodeR.getItemOffset ( itemRight );
  1609. if ( rItemOffset !== 0 )
  1610. yRight = nodeR.y + rItemOffset;
  1611. var ptLeft = new CPoint ( xLeft, yLeft );
  1612. var ptRight = new CPoint ( xRight, yRight );
  1613. if ( bSourceIsOnLeft )
  1614. {
  1615. if ( ! itemLeft || ( itemLeft.cOutConnections > 1 || itemLeft.cInConnections > 1 ) )
  1616. ptLeft.y += DG.graphDefaults.nLineOutOffsetY;
  1617. if ( ! itemRight || ( itemRight.cOutConnections > 1 || itemRight.cInConnections > 1 ) )
  1618. ptRight.y += DG.graphDefaults.nLineInOffsetY;
  1619. }
  1620. else
  1621. {
  1622. if ( ! itemLeft || ( itemLeft.cOutConnections > 1 || itemLeft.cInConnections > 1 ) )
  1623. ptLeft.y += DG.graphDefaults.nLineInOffsetY;
  1624. if ( ! itemRight || ( itemRight.cOutConnections > 1 || itemRight.cInConnections > 1 ) )
  1625. ptRight.y += DG.graphDefaults.nLineOutOffsetY;
  1626. }
  1627. this.nElbowOffset = this.graph.findConnectionElbowOffsetX ( this );
  1628. if ( this.nElbowOffset === -1 )
  1629. this.nElbowOffset = 10 - ( this.nIndex % 7 ) * 3;
  1630. gdi.drawLinePointToPoint ( this.color, this.thickness, sLineStyle, ptLeft, ptRight, this.nElbowOffset );
  1631. if ( bSourceIsOnLeft )
  1632. gdi.drawArrowRight ( this.color, ptRight.x, ptRight.y, sLineStyle, DG.graphDefaults.nArrowSize );
  1633. else
  1634. {
  1635. // if ( DG.graphDefaults.bUseShadows )
  1636. // ptLeft.x += DG.graphDefaults.nShadowWidth - 3;
  1637. gdi.drawArrowLeft ( this.color, ptLeft.x, ptLeft.y, sLineStyle, DG.graphDefaults.nArrowSize );
  1638. }
  1639. }
  1640. DG.CGraphConnection.prototype.select = function ( bSelect )
  1641. {
  1642. if ( this.isSelected === bSelect )
  1643. return;
  1644. this.isSelected = bSelect;
  1645. this.color = bSelect ? DG.colorDefaults.colorLineSelected : DG.colorDefaults.colorLineStandard;
  1646. this.thickness = bSelect ? DG.graphDefaults.nLineWidthSelected : DG.graphDefaults.nLineWidthStandard;
  1647. this.refresh ( this.graph.m_gdi );
  1648. this.setZIndex ( bSelect );
  1649. if ( bSelect && this.gItemRight )
  1650. {
  1651. this.gItemRight.PaintTarget();
  1652. this.graph.m_selTargetList.push( this.gItemRight );
  1653. }
  1654. }
  1655. DG.CGraphConnection.prototype.refresh = function ( gdi )
  1656. {
  1657. if ( ! this.m_left.isShown() || ! this.m_right.isShown() )
  1658. {
  1659. this.show ( false );
  1660. }
  1661. else
  1662. {
  1663. if ( ! this.m_left.bShowConnections || ! this.m_right.bShowConnections )
  1664. {
  1665. this.show ( false );
  1666. }
  1667. else
  1668. {
  1669. this.show ( true );
  1670. this.paintContent ( gdi, this.m_left, this.m_right );
  1671. gdi.refreshObject ( this.getId() );
  1672. }
  1673. }
  1674. }
  1675. //----------------------------------------------------------------------------------------------