Shapes.js 119 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857
  1. /**
  2. * Copyright (c) 2006-2015, JGraph Ltd
  3. */
  4. /**
  5. * Registers shapes.
  6. */
  7. (function()
  8. {
  9. // Cube Shape, supports size style
  10. function CubeShape()
  11. {
  12. mxCylinder.call(this);
  13. };
  14. mxUtils.extend(CubeShape, mxCylinder);
  15. CubeShape.prototype.size = 20;
  16. CubeShape.prototype.redrawPath = function(path, x, y, w, h, isForeground)
  17. {
  18. var s = Math.max(0, Math.min(w, Math.min(h, parseFloat(mxUtils.getValue(this.style, 'size', this.size)))));
  19. if (isForeground)
  20. {
  21. path.moveTo(s, h);
  22. path.lineTo(s, s);
  23. path.lineTo(0, 0);
  24. path.moveTo(s, s);
  25. path.lineTo(w, s);
  26. path.end();
  27. }
  28. else
  29. {
  30. path.moveTo(0, 0);
  31. path.lineTo(w - s, 0);
  32. path.lineTo(w, s);
  33. path.lineTo(w, h);
  34. path.lineTo(s, h);
  35. path.lineTo(0, h - s);
  36. path.lineTo(0, 0);
  37. path.close();
  38. path.end();
  39. }
  40. };
  41. CubeShape.prototype.getLabelMargins = function(rect)
  42. {
  43. if (mxUtils.getValue(this.style, 'boundedLbl', false))
  44. {
  45. var s = parseFloat(mxUtils.getValue(this.style, 'size', this.size)) * this.scale;
  46. return new mxRectangle(s, s, 0, 0);
  47. }
  48. return null;
  49. };
  50. mxCellRenderer.registerShape('cube', CubeShape);
  51. var tan30 = Math.tan(mxUtils.toRadians(30));
  52. var tan30Dx = (0.5 - tan30) / 2;
  53. // Cube Shape, supports size style
  54. function IsoRectangleShape()
  55. {
  56. mxActor.call(this);
  57. };
  58. mxUtils.extend(IsoRectangleShape, mxActor);
  59. IsoRectangleShape.prototype.size = 20;
  60. IsoRectangleShape.prototype.redrawPath = function(path, x, y, w, h)
  61. {
  62. var m = Math.min(w, h / tan30);
  63. path.translate((w - m) / 2, (h - m) / 2 + m / 4);
  64. path.moveTo(0, 0.25 * m);
  65. path.lineTo(0.5 * m, m * tan30Dx);
  66. path.lineTo(m, 0.25 * m);
  67. path.lineTo(0.5 * m, (0.5 - tan30Dx) * m);
  68. path.lineTo(0, 0.25 * m);
  69. path.close();
  70. path.end();
  71. };
  72. mxCellRenderer.registerShape('isoRectangle', IsoRectangleShape);
  73. // Cube Shape, supports size style
  74. function IsoCubeShape()
  75. {
  76. mxCylinder.call(this);
  77. };
  78. mxUtils.extend(IsoCubeShape, mxCylinder);
  79. IsoCubeShape.prototype.size = 20;
  80. IsoCubeShape.prototype.redrawPath = function(path, x, y, w, h, isForeground)
  81. {
  82. var m = Math.min(w, h / (0.5 + tan30));
  83. if (isForeground)
  84. {
  85. path.moveTo(0, 0.25 * m);
  86. path.lineTo(0.5 * m, (0.5 - tan30Dx) * m);
  87. path.lineTo(m, 0.25 * m);
  88. path.moveTo(0.5 * m, (0.5 - tan30Dx) * m);
  89. path.lineTo(0.5 * m, (1 - tan30Dx) * m);
  90. path.end();
  91. }
  92. else
  93. {
  94. path.translate((w - m) / 2, (h - m) / 2);
  95. path.moveTo(0, 0.25 * m);
  96. path.lineTo(0.5 * m, m * tan30Dx);
  97. path.lineTo(m, 0.25 * m);
  98. path.lineTo(m, 0.75 * m);
  99. path.lineTo(0.5 * m, (1 - tan30Dx) * m);
  100. path.lineTo(0, 0.75 * m);
  101. path.close();
  102. path.end();
  103. }
  104. };
  105. mxCellRenderer.registerShape('isoCube', IsoCubeShape);
  106. // DataStore Shape, supports size style
  107. function DataStoreShape()
  108. {
  109. mxCylinder.call(this);
  110. };
  111. mxUtils.extend(DataStoreShape, mxCylinder);
  112. DataStoreShape.prototype.redrawPath = function(c, x, y, w, h, isForeground)
  113. {
  114. var dy = Math.min(h / 2, Math.round(h / 8) + this.strokewidth - 1);
  115. if ((isForeground && this.fill != null) || (!isForeground && this.fill == null))
  116. {
  117. c.moveTo(0, dy);
  118. c.curveTo(0, 2 * dy, w, 2 * dy, w, dy);
  119. // Needs separate shapes for correct hit-detection
  120. if (!isForeground)
  121. {
  122. c.stroke();
  123. c.begin();
  124. }
  125. c.translate(0, dy / 2);
  126. c.moveTo(0, dy);
  127. c.curveTo(0, 2 * dy, w, 2 * dy, w, dy);
  128. // Needs separate shapes for correct hit-detection
  129. if (!isForeground)
  130. {
  131. c.stroke();
  132. c.begin();
  133. }
  134. c.translate(0, dy / 2);
  135. c.moveTo(0, dy);
  136. c.curveTo(0, 2 * dy, w, 2 * dy, w, dy);
  137. // Needs separate shapes for correct hit-detection
  138. if (!isForeground)
  139. {
  140. c.stroke();
  141. c.begin();
  142. }
  143. c.translate(0, -dy);
  144. }
  145. if (!isForeground)
  146. {
  147. c.moveTo(0, dy);
  148. c.curveTo(0, -dy / 3, w, -dy / 3, w, dy);
  149. c.lineTo(w, h - dy);
  150. c.curveTo(w, h + dy / 3, 0, h + dy / 3, 0, h - dy);
  151. c.close();
  152. }
  153. };
  154. DataStoreShape.prototype.getLabelMargins = function(rect)
  155. {
  156. return new mxRectangle(0, 2.5 * Math.min(rect.height / 2, Math.round(rect.height / 8) +
  157. this.strokewidth - 1) * this.scale, 0, 0);
  158. }
  159. mxCellRenderer.registerShape('datastore', DataStoreShape);
  160. // Note Shape, supports size style
  161. function NoteShape()
  162. {
  163. mxCylinder.call(this);
  164. };
  165. mxUtils.extend(NoteShape, mxCylinder);
  166. NoteShape.prototype.size = 30;
  167. NoteShape.prototype.redrawPath = function(path, x, y, w, h, isForeground)
  168. {
  169. var s = Math.max(0, Math.min(w, Math.min(h, parseFloat(mxUtils.getValue(this.style, 'size', this.size)))));
  170. if (isForeground)
  171. {
  172. path.moveTo(w - s, 0);
  173. path.lineTo(w - s, s);
  174. path.lineTo(w, s);
  175. path.end();
  176. }
  177. else
  178. {
  179. path.moveTo(0, 0);
  180. path.lineTo(w - s, 0);
  181. path.lineTo(w, s);
  182. path.lineTo(w, h);
  183. path.lineTo(0, h);
  184. path.lineTo(0, 0);
  185. path.close();
  186. path.end();
  187. }
  188. };
  189. mxCellRenderer.registerShape('note', NoteShape);
  190. // Note Shape, supports size style
  191. function SwitchShape()
  192. {
  193. mxActor.call(this);
  194. };
  195. mxUtils.extend(SwitchShape, mxActor);
  196. SwitchShape.prototype.redrawPath = function(c, x, y, w, h)
  197. {
  198. var curve = 0.5;
  199. c.moveTo(0, 0);
  200. c.quadTo(w / 2, h * curve, w, 0);
  201. c.quadTo(w * (1 - curve), h / 2, w, h);
  202. c.quadTo(w / 2, h * (1 - curve), 0, h);
  203. c.quadTo(w * curve, h / 2, 0, 0);
  204. c.end();
  205. };
  206. mxCellRenderer.registerShape('switch', SwitchShape);
  207. // Folder Shape, supports tabWidth, tabHeight styles
  208. function FolderShape()
  209. {
  210. mxCylinder.call(this);
  211. };
  212. mxUtils.extend(FolderShape, mxCylinder);
  213. FolderShape.prototype.tabWidth = 60;
  214. FolderShape.prototype.tabHeight = 20;
  215. FolderShape.prototype.tabPosition = 'right';
  216. FolderShape.prototype.redrawPath = function(path, x, y, w, h, isForeground)
  217. {
  218. var dx = Math.max(0, Math.min(w, parseFloat(mxUtils.getValue(this.style, 'tabWidth', this.tabWidth))));
  219. var dy = Math.max(0, Math.min(h, parseFloat(mxUtils.getValue(this.style, 'tabHeight', this.tabHeight))));
  220. var tp = mxUtils.getValue(this.style, 'tabPosition', this.tabPosition);
  221. if (isForeground)
  222. {
  223. if (tp == 'left')
  224. {
  225. path.moveTo(0, dy);
  226. path.lineTo(dx, dy);
  227. }
  228. // Right is default
  229. else
  230. {
  231. path.moveTo(w - dx, dy);
  232. path.lineTo(w, dy);
  233. }
  234. path.end();
  235. }
  236. else
  237. {
  238. if (tp == 'left')
  239. {
  240. path.moveTo(0, 0);
  241. path.lineTo(dx, 0);
  242. path.lineTo(dx, dy);
  243. path.lineTo(w, dy);
  244. }
  245. // Right is default
  246. else
  247. {
  248. path.moveTo(0, dy);
  249. path.lineTo(w - dx, dy);
  250. path.lineTo(w - dx, 0);
  251. path.lineTo(w, 0);
  252. }
  253. path.lineTo(w, h);
  254. path.lineTo(0, h);
  255. path.lineTo(0, dy);
  256. path.close();
  257. path.end();
  258. }
  259. };
  260. mxCellRenderer.registerShape('folder', FolderShape);
  261. // Card shape
  262. function CardShape()
  263. {
  264. mxActor.call(this);
  265. };
  266. mxUtils.extend(CardShape, mxActor);
  267. CardShape.prototype.size = 30;
  268. CardShape.prototype.redrawPath = function(c, x, y, w, h)
  269. {
  270. var s = Math.max(0, Math.min(w, Math.min(h, parseFloat(mxUtils.getValue(this.style, 'size', this.size)))));
  271. var arcSize = mxUtils.getValue(this.style, mxConstants.STYLE_ARCSIZE, mxConstants.LINE_ARCSIZE) / 2;
  272. this.addPoints(c, [new mxPoint(s, 0), new mxPoint(w, 0), new mxPoint(w, h), new mxPoint(0, h), new mxPoint(0, s)],
  273. this.isRounded, arcSize, true);
  274. c.end();
  275. };
  276. mxCellRenderer.registerShape('card', CardShape);
  277. // Tape shape
  278. function TapeShape()
  279. {
  280. mxActor.call(this);
  281. };
  282. mxUtils.extend(TapeShape, mxActor);
  283. TapeShape.prototype.size = 0.4;
  284. TapeShape.prototype.redrawPath = function(c, x, y, w, h)
  285. {
  286. var dy = h * Math.max(0, Math.min(1, parseFloat(mxUtils.getValue(this.style, 'size', this.size))));
  287. var fy = 1.4;
  288. c.moveTo(0, dy / 2);
  289. c.quadTo(w / 4, dy * fy, w / 2, dy / 2);
  290. c.quadTo(w * 3 / 4, dy * (1 - fy), w, dy / 2);
  291. c.lineTo(w, h - dy / 2);
  292. c.quadTo(w * 3 / 4, h - dy * fy, w / 2, h - dy / 2);
  293. c.quadTo(w / 4, h - dy * (1 - fy), 0, h - dy / 2);
  294. c.lineTo(0, dy / 2);
  295. c.close();
  296. c.end();
  297. };
  298. TapeShape.prototype.getLabelBounds = function(rect)
  299. {
  300. if (mxUtils.getValue(this.style, 'boundedLbl', false))
  301. {
  302. var size = mxUtils.getValue(this.style, 'size', this.size);
  303. var w = rect.width;
  304. var h = rect.height;
  305. if (this.direction == null ||
  306. this.direction == mxConstants.DIRECTION_EAST ||
  307. this.direction == mxConstants.DIRECTION_WEST)
  308. {
  309. var dy = h * size;
  310. return new mxRectangle(rect.x, rect.y + dy, w, h - 2 * dy);
  311. }
  312. else
  313. {
  314. var dx = w * size;
  315. return new mxRectangle(rect.x + dx, rect.y, w - 2 * dx, h);
  316. }
  317. }
  318. return rect;
  319. };
  320. mxCellRenderer.registerShape('tape', TapeShape);
  321. // Document shape
  322. function DocumentShape()
  323. {
  324. mxActor.call(this);
  325. };
  326. mxUtils.extend(DocumentShape, mxActor);
  327. DocumentShape.prototype.size = 0.3;
  328. DocumentShape.prototype.getLabelMargins = function(rect)
  329. {
  330. if (mxUtils.getValue(this.style, 'boundedLbl', false))
  331. {
  332. return new mxRectangle(0, 0, 0, parseFloat(mxUtils.getValue(
  333. this.style, 'size', this.size)) * rect.height);
  334. }
  335. return null;
  336. };
  337. DocumentShape.prototype.redrawPath = function(c, x, y, w, h)
  338. {
  339. var dy = h * Math.max(0, Math.min(1, parseFloat(mxUtils.getValue(this.style, 'size', this.size))));
  340. var fy = 1.4;
  341. c.moveTo(0, 0);
  342. c.lineTo(w, 0);
  343. c.lineTo(w, h - dy / 2);
  344. c.quadTo(w * 3 / 4, h - dy * fy, w / 2, h - dy / 2);
  345. c.quadTo(w / 4, h - dy * (1 - fy), 0, h - dy / 2);
  346. c.lineTo(0, dy / 2);
  347. c.close();
  348. c.end();
  349. };
  350. mxCellRenderer.registerShape('document', DocumentShape);
  351. mxCylinder.prototype.getLabelMargins = function(rect)
  352. {
  353. if (mxUtils.getValue(this.style, 'boundedLbl', false))
  354. {
  355. return new mxRectangle(0, Math.min(this.maxHeight * this.scale, rect.height * 0.3), 0, 0);
  356. }
  357. return null;
  358. };
  359. // Parallelogram shape
  360. function ParallelogramShape()
  361. {
  362. mxActor.call(this);
  363. };
  364. mxUtils.extend(ParallelogramShape, mxActor);
  365. ParallelogramShape.prototype.size = 0.2;
  366. ParallelogramShape.prototype.redrawPath = function(c, x, y, w, h)
  367. {
  368. var dx = w * Math.max(0, Math.min(1, parseFloat(mxUtils.getValue(this.style, 'size', this.size))));
  369. var arcSize = mxUtils.getValue(this.style, mxConstants.STYLE_ARCSIZE, mxConstants.LINE_ARCSIZE) / 2;
  370. this.addPoints(c, [new mxPoint(0, h), new mxPoint(dx, 0), new mxPoint(w, 0), new mxPoint(w - dx, h)],
  371. this.isRounded, arcSize, true);
  372. c.end();
  373. };
  374. mxCellRenderer.registerShape('parallelogram', ParallelogramShape);
  375. // Trapezoid shape
  376. function TrapezoidShape()
  377. {
  378. mxActor.call(this);
  379. };
  380. mxUtils.extend(TrapezoidShape, mxActor);
  381. TrapezoidShape.prototype.size = 0.2;
  382. TrapezoidShape.prototype.redrawPath = function(c, x, y, w, h)
  383. {
  384. var dx = w * Math.max(0, Math.min(0.5, parseFloat(mxUtils.getValue(this.style, 'size', this.size))));
  385. var arcSize = mxUtils.getValue(this.style, mxConstants.STYLE_ARCSIZE, mxConstants.LINE_ARCSIZE) / 2;
  386. this.addPoints(c, [new mxPoint(0, h), new mxPoint(dx, 0), new mxPoint(w - dx, 0), new mxPoint(w, h)],
  387. this.isRounded, arcSize, true);
  388. };
  389. mxCellRenderer.registerShape('trapezoid', TrapezoidShape);
  390. // Curly Bracket shape
  391. function CurlyBracketShape()
  392. {
  393. mxActor.call(this);
  394. };
  395. mxUtils.extend(CurlyBracketShape, mxActor);
  396. CurlyBracketShape.prototype.size = 0.5;
  397. CurlyBracketShape.prototype.redrawPath = function(c, x, y, w, h)
  398. {
  399. c.setFillColor(null);
  400. var s = w * Math.max(0, Math.min(1, parseFloat(mxUtils.getValue(this.style, 'size', this.size))));
  401. var arcSize = mxUtils.getValue(this.style, mxConstants.STYLE_ARCSIZE, mxConstants.LINE_ARCSIZE) / 2;
  402. this.addPoints(c, [new mxPoint(w, 0), new mxPoint(s, 0), new mxPoint(s, h / 2),
  403. new mxPoint(0, h / 2), new mxPoint(s, h / 2), new mxPoint(s, h),
  404. new mxPoint(w, h)], this.isRounded, arcSize, false);
  405. c.end();
  406. };
  407. mxCellRenderer.registerShape('curlyBracket', CurlyBracketShape);
  408. // Parallel marker shape
  409. function ParallelMarkerShape()
  410. {
  411. mxActor.call(this);
  412. };
  413. mxUtils.extend(ParallelMarkerShape, mxActor);
  414. ParallelMarkerShape.prototype.redrawPath = function(c, x, y, w, h)
  415. {
  416. c.setStrokeWidth(1);
  417. c.setFillColor(this.stroke);
  418. var w2 = w / 5;
  419. c.rect(0, 0, w2, h);
  420. c.fillAndStroke();
  421. c.rect(2 * w2, 0, w2, h);
  422. c.fillAndStroke();
  423. c.rect(4 * w2, 0, w2, h);
  424. c.fillAndStroke();
  425. };
  426. mxCellRenderer.registerShape('parallelMarker', ParallelMarkerShape);
  427. /**
  428. * Adds handJiggle style (jiggle=n sets jiggle)
  429. */
  430. function HandJiggle(canvas, defaultVariation)
  431. {
  432. this.canvas = canvas;
  433. // Avoids "spikes" in the output
  434. this.canvas.setLineJoin('round');
  435. this.canvas.setLineCap('round');
  436. this.defaultVariation = defaultVariation;
  437. this.originalLineTo = this.canvas.lineTo;
  438. this.canvas.lineTo = mxUtils.bind(this, HandJiggle.prototype.lineTo);
  439. this.originalMoveTo = this.canvas.moveTo;
  440. this.canvas.moveTo = mxUtils.bind(this, HandJiggle.prototype.moveTo);
  441. this.originalClose = this.canvas.close;
  442. this.canvas.close = mxUtils.bind(this, HandJiggle.prototype.close);
  443. this.originalQuadTo = this.canvas.quadTo;
  444. this.canvas.quadTo = mxUtils.bind(this, HandJiggle.prototype.quadTo);
  445. this.originalCurveTo = this.canvas.curveTo;
  446. this.canvas.curveTo = mxUtils.bind(this, HandJiggle.prototype.curveTo);
  447. this.originalArcTo = this.canvas.arcTo;
  448. this.canvas.arcTo = mxUtils.bind(this, HandJiggle.prototype.arcTo);
  449. };
  450. HandJiggle.prototype.moveTo = function(endX, endY)
  451. {
  452. this.originalMoveTo.apply(this.canvas, arguments);
  453. this.lastX = endX;
  454. this.lastY = endY;
  455. this.firstX = endX;
  456. this.firstY = endY;
  457. };
  458. HandJiggle.prototype.close = function()
  459. {
  460. if (this.firstX != null && this.firstY != null)
  461. {
  462. this.lineTo(this.firstX, this.firstY);
  463. this.originalClose.apply(this.canvas, arguments);
  464. }
  465. this.originalClose.apply(this.canvas, arguments);
  466. };
  467. HandJiggle.prototype.quadTo = function(x1, y1, x2, y2)
  468. {
  469. this.originalQuadTo.apply(this.canvas, arguments);
  470. this.lastX = x2;
  471. this.lastY = y2;
  472. };
  473. HandJiggle.prototype.curveTo = function(x1, y1, x2, y2, x3, y3)
  474. {
  475. this.originalCurveTo.apply(this.canvas, arguments);
  476. this.lastX = x3;
  477. this.lastY = y3;
  478. };
  479. HandJiggle.prototype.arcTo = function(rx, ry, angle, largeArcFlag, sweepFlag, x, y)
  480. {
  481. this.originalArcTo.apply(this.canvas, arguments);
  482. this.lastX = x;
  483. this.lastY = y;
  484. };
  485. HandJiggle.prototype.lineTo = function(endX, endY)
  486. {
  487. // LATER: Check why this.canvas.lastX cannot be used
  488. if (this.lastX != null && this.lastY != null)
  489. {
  490. var dx = Math.abs(endX - this.lastX);
  491. var dy = Math.abs(endY - this.lastY);
  492. var dist = Math.sqrt(dx * dx + dy * dy);
  493. if (dist < 2)
  494. {
  495. this.originalLineTo.apply(this.canvas, arguments);
  496. this.lastX = endX;
  497. this.lastY = endY;
  498. return;
  499. }
  500. var segs = Math.round(dist / 10);
  501. var variation = this.defaultVariation;
  502. if (segs < 5)
  503. {
  504. segs = 5;
  505. variation /= 3;
  506. }
  507. function sign(x)
  508. {
  509. return typeof x === 'number' ? x ? x < 0 ? -1 : 1 : x === x ? 0 : NaN : NaN;
  510. }
  511. var stepX = sign(endX - this.lastX) * dx / segs;
  512. var stepY = sign(endY - this.lastY) * dy / segs;
  513. var fx = dx / dist;
  514. var fy = dy / dist;
  515. for (var s = 0; s < segs; s++)
  516. {
  517. var x = stepX * s + this.lastX;
  518. var y = stepY * s + this.lastY;
  519. var offset = (Math.random() - 0.5) * variation;
  520. this.originalLineTo.call(this.canvas, x - offset * fy, y - offset * fx);
  521. }
  522. this.originalLineTo.call(this.canvas, endX, endY);
  523. this.lastX = endX;
  524. this.lastY = endY;
  525. }
  526. else
  527. {
  528. this.originalLineTo.apply(this.canvas, arguments);
  529. this.lastX = endX;
  530. this.lastY = endY;
  531. }
  532. };
  533. HandJiggle.prototype.destroy = function()
  534. {
  535. this.canvas.lineTo = this.originalLineTo;
  536. this.canvas.moveTo = this.originalMoveTo;
  537. this.canvas.close = this.originalClose;
  538. this.canvas.quadTo = this.originalQuadTo;
  539. this.canvas.curveTo = this.originalCurveTo;
  540. this.canvas.arcTo = this.originalArcTo;
  541. };
  542. // Installs hand jiggle in all shapes
  543. var mxShapePaint0 = mxShape.prototype.paint;
  544. mxShape.prototype.defaultJiggle = 1.5;
  545. mxShape.prototype.paint = function(c)
  546. {
  547. // NOTE: getValue does not return a boolean value so !('0') would return true here and below
  548. if (this.style != null && mxUtils.getValue(this.style, 'comic', '0') != '0' && c.handHiggle == null)
  549. {
  550. c.handJiggle = new HandJiggle(c, mxUtils.getValue(this.style, 'jiggle', this.defaultJiggle));
  551. }
  552. mxShapePaint0.apply(this, arguments);
  553. if (c.handJiggle != null)
  554. {
  555. c.handJiggle.destroy();
  556. delete c.handJiggle;
  557. }
  558. };
  559. // Sets default jiggle for diamond
  560. mxRhombus.prototype.defaultJiggle = 2;
  561. /**
  562. * Overrides to avoid call to rect
  563. */
  564. var mxRectangleShapeIsHtmlAllowed0 = mxRectangleShape.prototype.isHtmlAllowed;
  565. mxRectangleShape.prototype.isHtmlAllowed = function()
  566. {
  567. return (this.style == null || mxUtils.getValue(this.style, 'comic', '0') == '0') &&
  568. mxRectangleShapeIsHtmlAllowed0.apply(this, arguments);
  569. };
  570. var mxRectangleShapePaintBackground0 = mxRectangleShape.prototype.paintBackground;
  571. mxRectangleShape.prototype.paintBackground = function(c, x, y, w, h)
  572. {
  573. if (c.handJiggle == null)
  574. {
  575. mxRectangleShapePaintBackground0.apply(this, arguments);
  576. }
  577. else
  578. {
  579. var events = true;
  580. if (this.style != null)
  581. {
  582. events = mxUtils.getValue(this.style, mxConstants.STYLE_POINTER_EVENTS, '1') == '1';
  583. }
  584. if (events || (this.fill != null && this.fill != mxConstants.NONE) ||
  585. (this.stroke != null && this.stroke != mxConstants.NONE))
  586. {
  587. if (!events && (this.fill == null || this.fill == mxConstants.NONE))
  588. {
  589. c.pointerEvents = false;
  590. }
  591. c.begin();
  592. if (this.isRounded)
  593. {
  594. var r = 0;
  595. if (mxUtils.getValue(this.style, mxConstants.STYLE_ABSOLUTE_ARCSIZE, 0) == '1')
  596. {
  597. r = Math.min(w / 2, Math.min(h / 2, mxUtils.getValue(this.style,
  598. mxConstants.STYLE_ARCSIZE, mxConstants.LINE_ARCSIZE) / 2));
  599. }
  600. else
  601. {
  602. var f = mxUtils.getValue(this.style, mxConstants.STYLE_ARCSIZE,
  603. mxConstants.RECTANGLE_ROUNDING_FACTOR * 100) / 100;
  604. r = Math.min(w * f, h * f);
  605. }
  606. c.moveTo(x + r, y);
  607. c.lineTo(x + w - r, y);
  608. c.quadTo(x + w, y, x + w, y + r);
  609. c.lineTo(x + w, y + h - r);
  610. c.quadTo(x + w, y + h, x + w - r, y + h);
  611. c.lineTo(x + r, y + h);
  612. c.quadTo(x, y + h, x, y + h - r);
  613. c.lineTo(x, y + r);
  614. c.quadTo(x, y, x + r, y);
  615. }
  616. else
  617. {
  618. c.moveTo(x, y);
  619. c.lineTo(x + w, y);
  620. c.lineTo(x + w, y + h);
  621. c.lineTo(x, y + h);
  622. c.lineTo(x, y);
  623. }
  624. // LATER: Check if close is needed here
  625. c.close();
  626. c.end();
  627. c.fillAndStroke();
  628. }
  629. }
  630. };
  631. /**
  632. * Disables glass effect with hand jiggle.
  633. */
  634. var mxRectangleShapePaintForeground0 = mxRectangleShape.prototype.paintForeground;
  635. mxRectangleShape.prototype.paintForeground = function(c, x, y, w, h)
  636. {
  637. if (c.handJiggle == null)
  638. {
  639. mxRectangleShapePaintForeground0.apply(this, arguments);
  640. }
  641. };
  642. // End of hand jiggle integration
  643. // Process Shape
  644. function ProcessShape()
  645. {
  646. mxRectangleShape.call(this);
  647. };
  648. mxUtils.extend(ProcessShape, mxRectangleShape);
  649. ProcessShape.prototype.size = 0.1;
  650. ProcessShape.prototype.isHtmlAllowed = function()
  651. {
  652. return false;
  653. };
  654. ProcessShape.prototype.getLabelBounds = function(rect)
  655. {
  656. if (mxUtils.getValue(this.state.style, mxConstants.STYLE_HORIZONTAL, true) ==
  657. (this.direction == null ||
  658. this.direction == mxConstants.DIRECTION_EAST ||
  659. this.direction == mxConstants.DIRECTION_WEST))
  660. {
  661. var w = rect.width;
  662. var h = rect.height;
  663. var r = new mxRectangle(rect.x, rect.y, w, h);
  664. var inset = w * Math.max(0, Math.min(1, parseFloat(mxUtils.getValue(this.style, 'size', this.size))));
  665. if (this.isRounded)
  666. {
  667. var f = mxUtils.getValue(this.style, mxConstants.STYLE_ARCSIZE,
  668. mxConstants.RECTANGLE_ROUNDING_FACTOR * 100) / 100;
  669. inset = Math.max(inset, Math.min(w * f, h * f));
  670. }
  671. r.x += Math.round(inset);
  672. r.width -= Math.round(2 * inset);
  673. return r;
  674. }
  675. return rect;
  676. };
  677. ProcessShape.prototype.paintForeground = function(c, x, y, w, h)
  678. {
  679. var inset = w * Math.max(0, Math.min(1, parseFloat(mxUtils.getValue(this.style, 'size', this.size))));
  680. if (this.isRounded)
  681. {
  682. var f = mxUtils.getValue(this.style, mxConstants.STYLE_ARCSIZE,
  683. mxConstants.RECTANGLE_ROUNDING_FACTOR * 100) / 100;
  684. inset = Math.max(inset, Math.min(w * f, h * f));
  685. }
  686. // Crisp rendering of inner lines
  687. inset = Math.round(inset);
  688. c.begin();
  689. c.moveTo(x + inset, y);
  690. c.lineTo(x + inset, y + h);
  691. c.moveTo(x + w - inset, y);
  692. c.lineTo(x + w - inset, y + h);
  693. c.end();
  694. c.stroke();
  695. mxRectangleShape.prototype.paintForeground.apply(this, arguments);
  696. };
  697. mxCellRenderer.registerShape('process', ProcessShape);
  698. // Transparent Shape
  699. function TransparentShape()
  700. {
  701. mxRectangleShape.call(this);
  702. };
  703. mxUtils.extend(TransparentShape, mxRectangleShape);
  704. TransparentShape.prototype.paintBackground = function(c, x, y, w, h)
  705. {
  706. c.setFillColor(mxConstants.NONE);
  707. c.rect(x, y, w, h);
  708. c.fill();
  709. };
  710. TransparentShape.prototype.paintForeground = function(c, x, y, w, h) { };
  711. mxCellRenderer.registerShape('transparent', TransparentShape);
  712. // Callout shape
  713. function CalloutShape()
  714. {
  715. mxActor.call(this);
  716. };
  717. mxUtils.extend(CalloutShape, mxHexagon);
  718. CalloutShape.prototype.size = 30;
  719. CalloutShape.prototype.position = 0.5;
  720. CalloutShape.prototype.position2 = 0.5;
  721. CalloutShape.prototype.base = 20;
  722. CalloutShape.prototype.getLabelMargins = function()
  723. {
  724. return new mxRectangle(0, 0, 0, parseFloat(mxUtils.getValue(
  725. this.style, 'size', this.size)) * this.scale);
  726. };
  727. CalloutShape.prototype.redrawPath = function(c, x, y, w, h)
  728. {
  729. var arcSize = mxUtils.getValue(this.style, mxConstants.STYLE_ARCSIZE, mxConstants.LINE_ARCSIZE) / 2;
  730. var s = Math.max(0, Math.min(h, parseFloat(mxUtils.getValue(this.style, 'size', this.size))));
  731. var dx = w * Math.max(0, Math.min(1, parseFloat(mxUtils.getValue(this.style, 'position', this.position))));
  732. var dx2 = w * Math.max(0, Math.min(1, parseFloat(mxUtils.getValue(this.style, 'position2', this.position2))));
  733. var base = Math.max(0, Math.min(w, parseFloat(mxUtils.getValue(this.style, 'base', this.base))));
  734. this.addPoints(c, [new mxPoint(0, 0), new mxPoint(w, 0), new mxPoint(w, h - s),
  735. new mxPoint(Math.min(w, dx + base), h - s), new mxPoint(dx2, h),
  736. new mxPoint(Math.max(0, dx), h - s), new mxPoint(0, h - s)],
  737. this.isRounded, arcSize, true, [4]);
  738. };
  739. mxCellRenderer.registerShape('callout', CalloutShape);
  740. // Step shape
  741. function StepShape()
  742. {
  743. mxActor.call(this);
  744. };
  745. mxUtils.extend(StepShape, mxActor);
  746. StepShape.prototype.size = 0.2;
  747. StepShape.prototype.fixedSize = 20;
  748. StepShape.prototype.redrawPath = function(c, x, y, w, h)
  749. {
  750. var fixed = mxUtils.getValue(this.style, 'fixedSize', '0') != '0';
  751. var s = (fixed) ? Math.max(0, Math.min(w, parseFloat(mxUtils.getValue(this.style, 'size', this.fixedSize)))) :
  752. w * Math.max(0, Math.min(1, parseFloat(mxUtils.getValue(this.style, 'size', this.size))));
  753. var arcSize = mxUtils.getValue(this.style, mxConstants.STYLE_ARCSIZE, mxConstants.LINE_ARCSIZE) / 2;
  754. this.addPoints(c, [new mxPoint(0, 0), new mxPoint(w - s, 0), new mxPoint(w, h / 2), new mxPoint(w - s, h),
  755. new mxPoint(0, h), new mxPoint(s, h / 2)], this.isRounded, arcSize, true);
  756. c.end();
  757. };
  758. mxCellRenderer.registerShape('step', StepShape);
  759. // Hexagon shape
  760. function HexagonShape()
  761. {
  762. mxActor.call(this);
  763. };
  764. mxUtils.extend(HexagonShape, mxHexagon);
  765. HexagonShape.prototype.size = 0.25;
  766. HexagonShape.prototype.redrawPath = function(c, x, y, w, h)
  767. {
  768. var s = w * Math.max(0, Math.min(1, parseFloat(mxUtils.getValue(this.style, 'size', this.size))));
  769. var arcSize = mxUtils.getValue(this.style, mxConstants.STYLE_ARCSIZE, mxConstants.LINE_ARCSIZE) / 2;
  770. this.addPoints(c, [new mxPoint(s, 0), new mxPoint(w - s, 0), new mxPoint(w, 0.5 * h), new mxPoint(w - s, h),
  771. new mxPoint(s, h), new mxPoint(0, 0.5 * h)], this.isRounded, arcSize, true);
  772. };
  773. mxCellRenderer.registerShape('hexagon', HexagonShape);
  774. // Plus Shape
  775. function PlusShape()
  776. {
  777. mxRectangleShape.call(this);
  778. };
  779. mxUtils.extend(PlusShape, mxRectangleShape);
  780. PlusShape.prototype.isHtmlAllowed = function()
  781. {
  782. return false;
  783. };
  784. PlusShape.prototype.paintForeground = function(c, x, y, w, h)
  785. {
  786. var border = Math.min(w / 5, h / 5) + 1;
  787. c.begin();
  788. c.moveTo(x + w / 2, y + border);
  789. c.lineTo(x + w / 2, y + h - border);
  790. c.moveTo(x + border, y + h / 2);
  791. c.lineTo(x + w - border, y + h / 2);
  792. c.end();
  793. c.stroke();
  794. mxRectangleShape.prototype.paintForeground.apply(this, arguments);
  795. };
  796. mxCellRenderer.registerShape('plus', PlusShape);
  797. // Overrides painting of rhombus shape to allow for double style
  798. var mxRhombusPaintVertexShape = mxRhombus.prototype.paintVertexShape;
  799. mxRhombus.prototype.getLabelBounds = function(rect)
  800. {
  801. if (this.style['double'] == 1)
  802. {
  803. var margin = (Math.max(2, this.strokewidth + 1) * 2 + parseFloat(
  804. this.style[mxConstants.STYLE_MARGIN] || 0)) * this.scale;
  805. return new mxRectangle(rect.x + margin, rect.y + margin,
  806. rect.width - 2 * margin, rect.height - 2 * margin);
  807. }
  808. return rect;
  809. };
  810. mxRhombus.prototype.paintVertexShape = function(c, x, y, w, h)
  811. {
  812. mxRhombusPaintVertexShape.apply(this, arguments);
  813. if (!this.outline && this.style['double'] == 1)
  814. {
  815. var margin = Math.max(2, this.strokewidth + 1) * 2 +
  816. parseFloat(this.style[mxConstants.STYLE_MARGIN] || 0);
  817. x += margin;
  818. y += margin;
  819. w -= 2 * margin;
  820. h -= 2 * margin;
  821. if (w > 0 && h > 0)
  822. {
  823. c.setShadow(false);
  824. // Workaround for closure compiler bug where the lines with x and y above
  825. // are removed if arguments is used as second argument in call below.
  826. mxRhombusPaintVertexShape.apply(this, [c, x, y, w, h]);
  827. }
  828. }
  829. };
  830. // CompositeShape
  831. function ExtendedShape()
  832. {
  833. mxRectangleShape.call(this);
  834. };
  835. mxUtils.extend(ExtendedShape, mxRectangleShape);
  836. ExtendedShape.prototype.isHtmlAllowed = function()
  837. {
  838. return false;
  839. };
  840. ExtendedShape.prototype.getLabelBounds = function(rect)
  841. {
  842. if (this.style['double'] == 1)
  843. {
  844. var margin = (Math.max(2, this.strokewidth + 1) + parseFloat(
  845. this.style[mxConstants.STYLE_MARGIN] || 0)) * this.scale;
  846. return new mxRectangle(rect.x + margin, rect.y + margin,
  847. rect.width - 2 * margin, rect.height - 2 * margin);
  848. }
  849. return rect;
  850. };
  851. ExtendedShape.prototype.paintForeground = function(c, x, y, w, h)
  852. {
  853. if (this.style != null)
  854. {
  855. if (!this.outline && this.style['double'] == 1)
  856. {
  857. var margin = Math.max(2, this.strokewidth + 1) + parseFloat(this.style[mxConstants.STYLE_MARGIN] || 0);
  858. x += margin;
  859. y += margin;
  860. w -= 2 * margin;
  861. h -= 2 * margin;
  862. if (w > 0 && h > 0)
  863. {
  864. mxRectangleShape.prototype.paintBackground.apply(this, arguments);
  865. }
  866. }
  867. c.setDashed(false);
  868. // Draws the symbols defined in the style. The symbols are
  869. // numbered from 1...n. Possible postfixes are align,
  870. // verticalAlign, spacing, arcSpacing, width, height
  871. var counter = 0;
  872. var shape = null;
  873. do
  874. {
  875. shape = mxCellRenderer.defaultShapes[this.style['symbol' + counter]];
  876. if (shape != null)
  877. {
  878. var align = this.style['symbol' + counter + 'Align'];
  879. var valign = this.style['symbol' + counter + 'VerticalAlign'];
  880. var width = this.style['symbol' + counter + 'Width'];
  881. var height = this.style['symbol' + counter + 'Height'];
  882. var spacing = this.style['symbol' + counter + 'Spacing'] || 0;
  883. var vspacing = this.style['symbol' + counter + 'VSpacing'] || spacing;
  884. var arcspacing = this.style['symbol' + counter + 'ArcSpacing'];
  885. if (arcspacing != null)
  886. {
  887. var arcSize = this.getArcSize(w + this.strokewidth, h + this.strokewidth) * arcspacing;
  888. spacing += arcSize;
  889. vspacing += arcSize;
  890. }
  891. var x2 = x;
  892. var y2 = y;
  893. if (align == mxConstants.ALIGN_CENTER)
  894. {
  895. x2 += (w - width) / 2;
  896. }
  897. else if (align == mxConstants.ALIGN_RIGHT)
  898. {
  899. x2 += w - width - spacing;
  900. }
  901. else
  902. {
  903. x2 += spacing;
  904. }
  905. if (valign == mxConstants.ALIGN_MIDDLE)
  906. {
  907. y2 += (h - height) / 2;
  908. }
  909. else if (valign == mxConstants.ALIGN_BOTTOM)
  910. {
  911. y2 += h - height - vspacing;
  912. }
  913. else
  914. {
  915. y2 += vspacing;
  916. }
  917. c.save();
  918. // Small hack to pass style along into subshape
  919. var tmp = new shape();
  920. // TODO: Clone style and override settings (eg. strokewidth)
  921. tmp.style = this.style;
  922. shape.prototype.paintVertexShape.call(tmp, c, x2, y2, width, height);
  923. c.restore();
  924. }
  925. counter++;
  926. }
  927. while (shape != null);
  928. }
  929. // Paints glass effect
  930. mxRectangleShape.prototype.paintForeground.apply(this, arguments);
  931. };
  932. mxCellRenderer.registerShape('ext', ExtendedShape);
  933. // Tape Shape, supports size style
  934. function MessageShape()
  935. {
  936. mxCylinder.call(this);
  937. };
  938. mxUtils.extend(MessageShape, mxCylinder);
  939. MessageShape.prototype.redrawPath = function(path, x, y, w, h, isForeground)
  940. {
  941. if (isForeground)
  942. {
  943. path.moveTo(0, 0);
  944. path.lineTo(w / 2, h / 2);
  945. path.lineTo(w, 0);
  946. path.end();
  947. }
  948. else
  949. {
  950. path.moveTo(0, 0);
  951. path.lineTo(w, 0);
  952. path.lineTo(w, h);
  953. path.lineTo(0, h);
  954. path.close();
  955. }
  956. };
  957. mxCellRenderer.registerShape('message', MessageShape);
  958. // UML Actor Shape
  959. function UmlActorShape()
  960. {
  961. mxShape.call(this);
  962. };
  963. mxUtils.extend(UmlActorShape, mxShape);
  964. UmlActorShape.prototype.paintBackground = function(c, x, y, w, h)
  965. {
  966. c.translate(x, y);
  967. // Head
  968. c.ellipse(w / 4, 0, w / 2, h / 4);
  969. c.fillAndStroke();
  970. c.begin();
  971. c.moveTo(w / 2, h / 4);
  972. c.lineTo(w / 2, 2 * h / 3);
  973. // Arms
  974. c.moveTo(w / 2, h / 3);
  975. c.lineTo(0, h / 3);
  976. c.moveTo(w / 2, h / 3);
  977. c.lineTo(w, h / 3);
  978. // Legs
  979. c.moveTo(w / 2, 2 * h / 3);
  980. c.lineTo(0, h);
  981. c.moveTo(w / 2, 2 * h / 3);
  982. c.lineTo(w, h);
  983. c.end();
  984. c.stroke();
  985. };
  986. // Replaces existing actor shape
  987. mxCellRenderer.registerShape('umlActor', UmlActorShape);
  988. // UML Boundary Shape
  989. function UmlBoundaryShape()
  990. {
  991. mxShape.call(this);
  992. };
  993. mxUtils.extend(UmlBoundaryShape, mxShape);
  994. UmlBoundaryShape.prototype.getLabelMargins = function(rect)
  995. {
  996. return new mxRectangle(rect.width / 6, 0, 0, 0);
  997. };
  998. UmlBoundaryShape.prototype.paintBackground = function(c, x, y, w, h)
  999. {
  1000. c.translate(x, y);
  1001. // Base line
  1002. c.begin();
  1003. c.moveTo(0, h / 4);
  1004. c.lineTo(0, h * 3 / 4);
  1005. c.end();
  1006. c.stroke();
  1007. // Horizontal line
  1008. c.begin();
  1009. c.moveTo(0, h / 2);
  1010. c.lineTo(w / 6, h / 2);
  1011. c.end();
  1012. c.stroke();
  1013. // Circle
  1014. c.ellipse(w / 6, 0, w * 5 / 6, h);
  1015. c.fillAndStroke();
  1016. };
  1017. // Replaces existing actor shape
  1018. mxCellRenderer.registerShape('umlBoundary', UmlBoundaryShape);
  1019. // UML Entity Shape
  1020. function UmlEntityShape()
  1021. {
  1022. mxEllipse.call(this);
  1023. };
  1024. mxUtils.extend(UmlEntityShape, mxEllipse);
  1025. UmlEntityShape.prototype.paintVertexShape = function(c, x, y, w, h)
  1026. {
  1027. mxEllipse.prototype.paintVertexShape.apply(this, arguments);
  1028. c.begin();
  1029. c.moveTo(x + w / 8, y + h);
  1030. c.lineTo(x + w * 7 / 8, y + h);
  1031. c.end();
  1032. c.stroke();
  1033. };
  1034. mxCellRenderer.registerShape('umlEntity', UmlEntityShape);
  1035. // UML Destroy Shape
  1036. function UmlDestroyShape()
  1037. {
  1038. mxShape.call(this);
  1039. };
  1040. mxUtils.extend(UmlDestroyShape, mxShape);
  1041. UmlDestroyShape.prototype.paintVertexShape = function(c, x, y, w, h)
  1042. {
  1043. c.translate(x, y);
  1044. c.begin();
  1045. c.moveTo(w, 0);
  1046. c.lineTo(0, h);
  1047. c.moveTo(0, 0);
  1048. c.lineTo(w, h);
  1049. c.end();
  1050. c.stroke();
  1051. };
  1052. mxCellRenderer.registerShape('umlDestroy', UmlDestroyShape);
  1053. // UML Control Shape
  1054. function UmlControlShape()
  1055. {
  1056. mxShape.call(this);
  1057. };
  1058. mxUtils.extend(UmlControlShape, mxShape);
  1059. UmlControlShape.prototype.getLabelBounds = function(rect)
  1060. {
  1061. return new mxRectangle(rect.x, rect.y + rect.height / 8, rect.width, rect.height * 7 / 8);
  1062. };
  1063. UmlControlShape.prototype.paintBackground = function(c, x, y, w, h)
  1064. {
  1065. c.translate(x, y);
  1066. // Upper line
  1067. c.begin();
  1068. c.moveTo(w * 3 / 8, h / 8 * 1.1);
  1069. c.lineTo(w * 5 / 8, 0);
  1070. c.end();
  1071. c.stroke();
  1072. // Circle
  1073. c.ellipse(0, h / 8, w, h * 7 / 8);
  1074. c.fillAndStroke();
  1075. };
  1076. UmlControlShape.prototype.paintForeground = function(c, x, y, w, h)
  1077. {
  1078. // Lower line
  1079. c.begin();
  1080. c.moveTo(w * 3 / 8, h / 8 * 1.1);
  1081. c.lineTo(w * 5 / 8, h / 4);
  1082. c.end();
  1083. c.stroke();
  1084. };
  1085. // Replaces existing actor shape
  1086. mxCellRenderer.registerShape('umlControl', UmlControlShape);
  1087. // UML Lifeline Shape
  1088. function UmlLifeline()
  1089. {
  1090. mxRectangleShape.call(this);
  1091. };
  1092. mxUtils.extend(UmlLifeline, mxRectangleShape);
  1093. UmlLifeline.prototype.size = 40;
  1094. UmlLifeline.prototype.isHtmlAllowed = function()
  1095. {
  1096. return false;
  1097. };
  1098. UmlLifeline.prototype.getLabelBounds = function(rect)
  1099. {
  1100. var size = Math.max(0, Math.min(rect.height, parseFloat(
  1101. mxUtils.getValue(this.style, 'size', this.size)) * this.scale));
  1102. return new mxRectangle(rect.x, rect.y, rect.width, size);
  1103. };
  1104. UmlLifeline.prototype.paintBackground = function(c, x, y, w, h)
  1105. {
  1106. var size = Math.max(0, Math.min(h, parseFloat(mxUtils.getValue(this.style, 'size', this.size))));
  1107. var participant = mxUtils.getValue(this.style, 'participant');
  1108. if (participant == null || this.state == null)
  1109. {
  1110. mxRectangleShape.prototype.paintBackground.call(this, c, x, y, w, size);
  1111. }
  1112. else
  1113. {
  1114. var ctor = this.state.view.graph.cellRenderer.getShape(participant);
  1115. if (ctor != null && ctor != UmlLifeline)
  1116. {
  1117. var shape = new ctor();
  1118. shape.apply(this.state);
  1119. c.save();
  1120. shape.paintVertexShape(c, x, y, w, size);
  1121. c.restore();
  1122. }
  1123. }
  1124. if (size < h)
  1125. {
  1126. c.setDashed(true);
  1127. c.begin();
  1128. c.moveTo(x + w / 2, y + size);
  1129. c.lineTo(x + w / 2, y + h);
  1130. c.end();
  1131. c.stroke();
  1132. }
  1133. };
  1134. UmlLifeline.prototype.paintForeground = function(c, x, y, w, h)
  1135. {
  1136. var size = Math.max(0, Math.min(h, parseFloat(mxUtils.getValue(this.style, 'size', this.size))));
  1137. mxRectangleShape.prototype.paintForeground.call(this, c, x, y, w, Math.min(h, size));
  1138. };
  1139. mxCellRenderer.registerShape('umlLifeline', UmlLifeline);
  1140. // UML Frame Shape
  1141. function UmlFrame()
  1142. {
  1143. mxShape.call(this);
  1144. };
  1145. mxUtils.extend(UmlFrame, mxShape);
  1146. UmlFrame.prototype.width = 60;
  1147. UmlFrame.prototype.height = 30;
  1148. UmlFrame.prototype.corner = 10;
  1149. UmlFrame.prototype.getLabelMargins = function(rect)
  1150. {
  1151. return new mxRectangle(0, 0,
  1152. rect.width - (parseFloat(mxUtils.getValue(this.style, 'width', this.width) * this.scale)),
  1153. rect.height - (parseFloat(mxUtils.getValue(this.style, 'height', this.height) * this.scale)));
  1154. };
  1155. UmlFrame.prototype.paintBackground = function(c, x, y, w, h)
  1156. {
  1157. var co = this.corner;
  1158. var w0 = Math.min(w, Math.max(co, parseFloat(mxUtils.getValue(this.style, 'width', this.width))));
  1159. var h0 = Math.min(h, Math.max(co * 1.5, parseFloat(mxUtils.getValue(this.style, 'height', this.height))));
  1160. var bg = mxUtils.getValue(this.style, mxConstants.STYLE_SWIMLANE_FILLCOLOR, mxConstants.NONE);
  1161. if (bg != mxConstants.NONE)
  1162. {
  1163. c.setFillColor(bg);
  1164. c.rect(x, y, w, h);
  1165. c.fill();
  1166. }
  1167. if (this.fill != null && this.fill != mxConstants.NONE && this.gradient && this.gradient != mxConstants.NONE)
  1168. {
  1169. var b = this.getGradientBounds(c, x, y, w, h);
  1170. c.setGradient(this.fill, this.gradient, x, y, w, h, this.gradientDirection);
  1171. }
  1172. else
  1173. {
  1174. c.setFillColor(this.fill);
  1175. }
  1176. c.begin();
  1177. c.moveTo(x, y);
  1178. c.lineTo(x + w0, y);
  1179. c.lineTo(x + w0, y + Math.max(0, h0 - co * 1.5));
  1180. c.lineTo(x + Math.max(0, w0 - co), y + h0);
  1181. c.lineTo(x, y + h0);
  1182. c.close();
  1183. c.fillAndStroke();
  1184. c.begin();
  1185. c.moveTo(x + w0, y);
  1186. c.lineTo(x + w, y);
  1187. c.lineTo(x + w, y + h);
  1188. c.lineTo(x, y + h);
  1189. c.lineTo(x, y + h0);
  1190. c.stroke();
  1191. };
  1192. mxCellRenderer.registerShape('umlFrame', UmlFrame);
  1193. mxPerimeter.LifelinePerimeter = function (bounds, vertex, next, orthogonal)
  1194. {
  1195. var size = UmlLifeline.prototype.size;
  1196. if (vertex != null)
  1197. {
  1198. size = mxUtils.getValue(vertex.style, 'size', size) * vertex.view.scale;
  1199. }
  1200. var sw = (parseFloat(vertex.style[mxConstants.STYLE_STROKEWIDTH] || 1) * vertex.view.scale / 2) - 1;
  1201. if (next.x < bounds.getCenterX())
  1202. {
  1203. sw += 1;
  1204. sw *= -1;
  1205. }
  1206. return new mxPoint(bounds.getCenterX() + sw, Math.min(bounds.y + bounds.height,
  1207. Math.max(bounds.y + size, next.y)));
  1208. };
  1209. mxStyleRegistry.putValue('lifelinePerimeter', mxPerimeter.LifelinePerimeter);
  1210. mxPerimeter.OrthogonalPerimeter = function (bounds, vertex, next, orthogonal)
  1211. {
  1212. orthogonal = true;
  1213. return mxPerimeter.RectanglePerimeter.apply(this, arguments);
  1214. };
  1215. mxStyleRegistry.putValue('orthogonalPerimeter', mxPerimeter.OrthogonalPerimeter);
  1216. mxPerimeter.BackbonePerimeter = function (bounds, vertex, next, orthogonal)
  1217. {
  1218. var sw = (parseFloat(vertex.style[mxConstants.STYLE_STROKEWIDTH] || 1) * vertex.view.scale / 2) - 1;
  1219. if (vertex.style['backboneSize'] != null)
  1220. {
  1221. sw += (parseFloat(vertex.style['backboneSize']) * vertex.view.scale / 2) - 1;
  1222. }
  1223. if (vertex.style[mxConstants.STYLE_DIRECTION] == 'south' ||
  1224. vertex.style[mxConstants.STYLE_DIRECTION] == 'north')
  1225. {
  1226. if (next.x < bounds.getCenterX())
  1227. {
  1228. sw += 1;
  1229. sw *= -1;
  1230. }
  1231. return new mxPoint(bounds.getCenterX() + sw, Math.min(bounds.y + bounds.height,
  1232. Math.max(bounds.y, next.y)));
  1233. }
  1234. else
  1235. {
  1236. if (next.y < bounds.getCenterY())
  1237. {
  1238. sw += 1;
  1239. sw *= -1;
  1240. }
  1241. return new mxPoint(Math.min(bounds.x + bounds.width, Math.max(bounds.x, next.x)),
  1242. bounds.getCenterY() + sw);
  1243. }
  1244. };
  1245. mxStyleRegistry.putValue('backbonePerimeter', mxPerimeter.BackbonePerimeter);
  1246. // Callout Perimeter
  1247. mxPerimeter.CalloutPerimeter = function (bounds, vertex, next, orthogonal)
  1248. {
  1249. return mxPerimeter.RectanglePerimeter(mxUtils.getDirectedBounds(bounds, new mxRectangle(0, 0, 0,
  1250. Math.max(0, Math.min(bounds.height, parseFloat(mxUtils.getValue(vertex.style, 'size',
  1251. CalloutShape.prototype.size)) * vertex.view.scale))),
  1252. vertex.style), vertex, next, orthogonal);
  1253. };
  1254. mxStyleRegistry.putValue('calloutPerimeter', mxPerimeter.CalloutPerimeter);
  1255. // Parallelogram Perimeter
  1256. mxPerimeter.ParallelogramPerimeter = function (bounds, vertex, next, orthogonal)
  1257. {
  1258. var size = ParallelogramShape.prototype.size;
  1259. if (vertex != null)
  1260. {
  1261. size = mxUtils.getValue(vertex.style, 'size', size);
  1262. }
  1263. var x = bounds.x;
  1264. var y = bounds.y;
  1265. var w = bounds.width;
  1266. var h = bounds.height;
  1267. var direction = (vertex != null) ? mxUtils.getValue(
  1268. vertex.style, mxConstants.STYLE_DIRECTION,
  1269. mxConstants.DIRECTION_EAST) : mxConstants.DIRECTION_EAST;
  1270. var vertical = direction == mxConstants.DIRECTION_NORTH ||
  1271. direction == mxConstants.DIRECTION_SOUTH;
  1272. var points;
  1273. if (vertical)
  1274. {
  1275. var dy = h * Math.max(0, Math.min(1, size));
  1276. points = [new mxPoint(x, y), new mxPoint(x + w, y + dy),
  1277. new mxPoint(x + w, y + h), new mxPoint(x, y + h - dy), new mxPoint(x, y)];
  1278. }
  1279. else
  1280. {
  1281. var dx = w * Math.max(0, Math.min(1, size));
  1282. points = [new mxPoint(x + dx, y), new mxPoint(x + w, y),
  1283. new mxPoint(x + w - dx, y + h), new mxPoint(x, y + h), new mxPoint(x + dx, y)];
  1284. }
  1285. var cx = bounds.getCenterX();
  1286. var cy = bounds.getCenterY();
  1287. var p1 = new mxPoint(cx, cy);
  1288. if (orthogonal)
  1289. {
  1290. if (next.x < x || next.x > x + w)
  1291. {
  1292. p1.y = next.y;
  1293. }
  1294. else
  1295. {
  1296. p1.x = next.x;
  1297. }
  1298. }
  1299. return mxUtils.getPerimeterPoint(points, p1, next);
  1300. };
  1301. mxStyleRegistry.putValue('parallelogramPerimeter', mxPerimeter.ParallelogramPerimeter);
  1302. // Trapezoid Perimeter
  1303. mxPerimeter.TrapezoidPerimeter = function (bounds, vertex, next, orthogonal)
  1304. {
  1305. var size = TrapezoidShape.prototype.size;
  1306. if (vertex != null)
  1307. {
  1308. size = mxUtils.getValue(vertex.style, 'size', size);
  1309. }
  1310. var x = bounds.x;
  1311. var y = bounds.y;
  1312. var w = bounds.width;
  1313. var h = bounds.height;
  1314. var direction = (vertex != null) ? mxUtils.getValue(
  1315. vertex.style, mxConstants.STYLE_DIRECTION,
  1316. mxConstants.DIRECTION_EAST) : mxConstants.DIRECTION_EAST;
  1317. var points;
  1318. if (direction == mxConstants.DIRECTION_EAST)
  1319. {
  1320. var dx = w * Math.max(0, Math.min(1, size));
  1321. points = [new mxPoint(x + dx, y), new mxPoint(x + w - dx, y),
  1322. new mxPoint(x + w, y + h), new mxPoint(x, y + h), new mxPoint(x + dx, y)];
  1323. }
  1324. else if (direction == mxConstants.DIRECTION_WEST)
  1325. {
  1326. var dx = w * Math.max(0, Math.min(1, size));
  1327. points = [new mxPoint(x, y), new mxPoint(x + w, y),
  1328. new mxPoint(x + w - dx, y + h), new mxPoint(x + dx, y + h), new mxPoint(x, y)];
  1329. }
  1330. else if (direction == mxConstants.DIRECTION_NORTH)
  1331. {
  1332. var dy = h * Math.max(0, Math.min(1, size));
  1333. points = [new mxPoint(x, y + dy), new mxPoint(x + w, y),
  1334. new mxPoint(x + w, y + h), new mxPoint(x, y + h - dy), new mxPoint(x, y + dy)];
  1335. }
  1336. else
  1337. {
  1338. var dy = h * Math.max(0, Math.min(1, size));
  1339. points = [new mxPoint(x, y), new mxPoint(x + w, y + dy),
  1340. new mxPoint(x + w, y + h - dy), new mxPoint(x, y + h), new mxPoint(x, y)];
  1341. }
  1342. var cx = bounds.getCenterX();
  1343. var cy = bounds.getCenterY();
  1344. var p1 = new mxPoint(cx, cy);
  1345. if (orthogonal)
  1346. {
  1347. if (next.x < x || next.x > x + w)
  1348. {
  1349. p1.y = next.y;
  1350. }
  1351. else
  1352. {
  1353. p1.x = next.x;
  1354. }
  1355. }
  1356. return mxUtils.getPerimeterPoint(points, p1, next);
  1357. };
  1358. mxStyleRegistry.putValue('trapezoidPerimeter', mxPerimeter.TrapezoidPerimeter);
  1359. // Step Perimeter
  1360. mxPerimeter.StepPerimeter = function (bounds, vertex, next, orthogonal)
  1361. {
  1362. var fixed = mxUtils.getValue(vertex.style, 'fixedSize', '0') != '0';
  1363. var size = (fixed) ? StepShape.prototype.fixedSize : StepShape.prototype.size;
  1364. if (vertex != null)
  1365. {
  1366. size = mxUtils.getValue(vertex.style, 'size', size);
  1367. }
  1368. var x = bounds.x;
  1369. var y = bounds.y;
  1370. var w = bounds.width;
  1371. var h = bounds.height;
  1372. var cx = bounds.getCenterX();
  1373. var cy = bounds.getCenterY();
  1374. var direction = (vertex != null) ? mxUtils.getValue(
  1375. vertex.style, mxConstants.STYLE_DIRECTION,
  1376. mxConstants.DIRECTION_EAST) : mxConstants.DIRECTION_EAST;
  1377. var points;
  1378. if (direction == mxConstants.DIRECTION_EAST)
  1379. {
  1380. var dx = (fixed) ? Math.max(0, Math.min(w, size)) : w * Math.max(0, Math.min(1, size));
  1381. points = [new mxPoint(x, y), new mxPoint(x + w - dx, y), new mxPoint(x + w, cy),
  1382. new mxPoint(x + w - dx, y + h), new mxPoint(x, y + h),
  1383. new mxPoint(x + dx, cy), new mxPoint(x, y)];
  1384. }
  1385. else if (direction == mxConstants.DIRECTION_WEST)
  1386. {
  1387. var dx = (fixed) ? Math.max(0, Math.min(w, size)) : w * Math.max(0, Math.min(1, size));
  1388. points = [new mxPoint(x + dx, y), new mxPoint(x + w, y), new mxPoint(x + w - dx, cy),
  1389. new mxPoint(x + w, y + h), new mxPoint(x + dx, y + h),
  1390. new mxPoint(x, cy), new mxPoint(x + dx, y)];
  1391. }
  1392. else if (direction == mxConstants.DIRECTION_NORTH)
  1393. {
  1394. var dy = (fixed) ? Math.max(0, Math.min(h, size)) : h * Math.max(0, Math.min(1, size));
  1395. points = [new mxPoint(x, y + dy), new mxPoint(cx, y), new mxPoint(x + w, y + dy),
  1396. new mxPoint(x + w, y + h), new mxPoint(cx, y + h - dy),
  1397. new mxPoint(x, y + h), new mxPoint(x, y + dy)];
  1398. }
  1399. else
  1400. {
  1401. var dy = (fixed) ? Math.max(0, Math.min(h, size)) : h * Math.max(0, Math.min(1, size));
  1402. points = [new mxPoint(x, y), new mxPoint(cx, y + dy), new mxPoint(x + w, y),
  1403. new mxPoint(x + w, y + h - dy), new mxPoint(cx, y + h),
  1404. new mxPoint(x, y + h - dy), new mxPoint(x, y)];
  1405. }
  1406. var p1 = new mxPoint(cx, cy);
  1407. if (orthogonal)
  1408. {
  1409. if (next.x < x || next.x > x + w)
  1410. {
  1411. p1.y = next.y;
  1412. }
  1413. else
  1414. {
  1415. p1.x = next.x;
  1416. }
  1417. }
  1418. return mxUtils.getPerimeterPoint(points, p1, next);
  1419. };
  1420. mxStyleRegistry.putValue('stepPerimeter', mxPerimeter.StepPerimeter);
  1421. // Hexagon Perimeter 2 (keep existing one)
  1422. mxPerimeter.HexagonPerimeter2 = function (bounds, vertex, next, orthogonal)
  1423. {
  1424. var size = HexagonShape.prototype.size;
  1425. if (vertex != null)
  1426. {
  1427. size = mxUtils.getValue(vertex.style, 'size', size);
  1428. }
  1429. var x = bounds.x;
  1430. var y = bounds.y;
  1431. var w = bounds.width;
  1432. var h = bounds.height;
  1433. var cx = bounds.getCenterX();
  1434. var cy = bounds.getCenterY();
  1435. var direction = (vertex != null) ? mxUtils.getValue(
  1436. vertex.style, mxConstants.STYLE_DIRECTION,
  1437. mxConstants.DIRECTION_EAST) : mxConstants.DIRECTION_EAST;
  1438. var vertical = direction == mxConstants.DIRECTION_NORTH ||
  1439. direction == mxConstants.DIRECTION_SOUTH;
  1440. var points;
  1441. if (vertical)
  1442. {
  1443. var dy = h * Math.max(0, Math.min(1, size));
  1444. points = [new mxPoint(cx, y), new mxPoint(x + w, y + dy), new mxPoint(x + w, y + h - dy),
  1445. new mxPoint(cx, y + h), new mxPoint(x, y + h - dy),
  1446. new mxPoint(x, y + dy), new mxPoint(cx, y)];
  1447. }
  1448. else
  1449. {
  1450. var dx = w * Math.max(0, Math.min(1, size));
  1451. points = [new mxPoint(x + dx, y), new mxPoint(x + w - dx, y), new mxPoint(x + w, cy),
  1452. new mxPoint(x + w - dx, y + h), new mxPoint(x + dx, y + h),
  1453. new mxPoint(x, cy), new mxPoint(x + dx, y)];
  1454. }
  1455. var p1 = new mxPoint(cx, cy);
  1456. if (orthogonal)
  1457. {
  1458. if (next.x < x || next.x > x + w)
  1459. {
  1460. p1.y = next.y;
  1461. }
  1462. else
  1463. {
  1464. p1.x = next.x;
  1465. }
  1466. }
  1467. return mxUtils.getPerimeterPoint(points, p1, next);
  1468. };
  1469. mxStyleRegistry.putValue('hexagonPerimeter2', mxPerimeter.HexagonPerimeter2);
  1470. // Lollipop Shape
  1471. function LollipopShape()
  1472. {
  1473. mxShape.call(this);
  1474. };
  1475. mxUtils.extend(LollipopShape, mxShape);
  1476. LollipopShape.prototype.size = 10;
  1477. LollipopShape.prototype.paintBackground = function(c, x, y, w, h)
  1478. {
  1479. var sz = parseFloat(mxUtils.getValue(this.style, 'size', this.size));
  1480. c.translate(x, y);
  1481. c.ellipse((w - sz) / 2, 0, sz, sz);
  1482. c.fillAndStroke();
  1483. c.begin();
  1484. c.moveTo(w / 2, sz);
  1485. c.lineTo(w / 2, h);
  1486. c.end();
  1487. c.stroke();
  1488. };
  1489. mxCellRenderer.registerShape('lollipop', LollipopShape);
  1490. // Lollipop Shape
  1491. function RequiresShape()
  1492. {
  1493. mxShape.call(this);
  1494. };
  1495. mxUtils.extend(RequiresShape, mxShape);
  1496. RequiresShape.prototype.size = 10;
  1497. RequiresShape.prototype.inset = 2;
  1498. RequiresShape.prototype.paintBackground = function(c, x, y, w, h)
  1499. {
  1500. var sz = parseFloat(mxUtils.getValue(this.style, 'size', this.size));
  1501. var inset = parseFloat(mxUtils.getValue(this.style, 'inset', this.inset)) + this.strokewidth;
  1502. c.translate(x, y);
  1503. c.begin();
  1504. c.moveTo(w / 2, sz + inset);
  1505. c.lineTo(w / 2, h);
  1506. c.end();
  1507. c.stroke();
  1508. c.begin();
  1509. c.moveTo((w - sz) / 2 - inset, sz / 2);
  1510. c.quadTo((w - sz) / 2 - inset, sz + inset, w / 2, sz + inset);
  1511. c.quadTo((w + sz) / 2 + inset, sz + inset, (w + sz) / 2 + inset, sz / 2);
  1512. c.end();
  1513. c.stroke();
  1514. };
  1515. mxCellRenderer.registerShape('requires', RequiresShape);
  1516. // Component shape
  1517. function ComponentShape()
  1518. {
  1519. mxCylinder.call(this);
  1520. };
  1521. mxUtils.extend(ComponentShape, mxCylinder);
  1522. ComponentShape.prototype.jettyWidth = 32;
  1523. ComponentShape.prototype.jettyHeight = 12;
  1524. ComponentShape.prototype.redrawPath = function(path, x, y, w, h, isForeground)
  1525. {
  1526. var dx = parseFloat(mxUtils.getValue(this.style, 'jettyWidth', this.jettyWidth));
  1527. var dy = parseFloat(mxUtils.getValue(this.style, 'jettyHeight', this.jettyHeight));
  1528. var x0 = dx / 2;
  1529. var x1 = x0 + dx / 2;
  1530. var y0 = 0.3 * h - dy / 2;
  1531. var y1 = 0.7 * h - dy / 2;
  1532. if (isForeground)
  1533. {
  1534. path.moveTo(x0, y0);
  1535. path.lineTo(x1, y0);
  1536. path.lineTo(x1, y0 + dy);
  1537. path.lineTo(x0, y0 + dy);
  1538. path.moveTo(x0, y1);
  1539. path.lineTo(x1, y1);
  1540. path.lineTo(x1, y1 + dy);
  1541. path.lineTo(x0, y1 + dy);
  1542. path.end();
  1543. }
  1544. else
  1545. {
  1546. path.moveTo(x0, 0);
  1547. path.lineTo(w, 0);
  1548. path.lineTo(w, h);
  1549. path.lineTo(x0, h);
  1550. path.lineTo(x0, y1 + dy);
  1551. path.lineTo(0, y1 + dy);
  1552. path.lineTo(0, y1);
  1553. path.lineTo(x0, y1);
  1554. path.lineTo(x0, y0 + dy);
  1555. path.lineTo(0, y0 + dy);
  1556. path.lineTo(0, y0);
  1557. path.lineTo(x0, y0);
  1558. path.close();
  1559. path.end();
  1560. }
  1561. };
  1562. mxCellRenderer.registerShape('component', ComponentShape);
  1563. // State Shapes derives from double ellipse
  1564. function StateShape()
  1565. {
  1566. mxDoubleEllipse.call(this);
  1567. };
  1568. mxUtils.extend(StateShape, mxDoubleEllipse);
  1569. StateShape.prototype.outerStroke = true;
  1570. StateShape.prototype.paintVertexShape = function(c, x, y, w, h)
  1571. {
  1572. var inset = Math.min(4, Math.min(w / 5, h / 5));
  1573. if (w > 0 && h > 0)
  1574. {
  1575. c.ellipse(x + inset, y + inset, w - 2 * inset, h - 2 * inset);
  1576. c.fillAndStroke();
  1577. }
  1578. c.setShadow(false);
  1579. if (this.outerStroke)
  1580. {
  1581. c.ellipse(x, y, w, h);
  1582. c.stroke();
  1583. }
  1584. };
  1585. mxCellRenderer.registerShape('endState', StateShape);
  1586. function StartStateShape()
  1587. {
  1588. StateShape.call(this);
  1589. };
  1590. mxUtils.extend(StartStateShape, StateShape);
  1591. StartStateShape.prototype.outerStroke = false;
  1592. mxCellRenderer.registerShape('startState', StartStateShape);
  1593. // Link shape
  1594. function LinkShape()
  1595. {
  1596. mxArrowConnector.call(this);
  1597. this.spacing = 0;
  1598. };
  1599. mxUtils.extend(LinkShape, mxArrowConnector);
  1600. LinkShape.prototype.defaultWidth = 4;
  1601. LinkShape.prototype.isOpenEnded = function()
  1602. {
  1603. return true;
  1604. };
  1605. LinkShape.prototype.getEdgeWidth = function()
  1606. {
  1607. return mxUtils.getNumber(this.style, 'width', this.defaultWidth) + Math.max(0, this.strokewidth - 1);
  1608. };
  1609. LinkShape.prototype.isArrowRounded = function()
  1610. {
  1611. return this.isRounded;
  1612. };
  1613. // Registers the link shape
  1614. mxCellRenderer.registerShape('link', LinkShape);
  1615. // Generic arrow
  1616. function FlexArrowShape()
  1617. {
  1618. mxArrowConnector.call(this);
  1619. this.spacing = 0;
  1620. };
  1621. mxUtils.extend(FlexArrowShape, mxArrowConnector);
  1622. FlexArrowShape.prototype.defaultWidth = 10;
  1623. FlexArrowShape.prototype.defaultArrowWidth = 20;
  1624. FlexArrowShape.prototype.getStartArrowWidth = function()
  1625. {
  1626. return this.getEdgeWidth() + mxUtils.getNumber(this.style, 'startWidth', this.defaultArrowWidth);
  1627. };
  1628. FlexArrowShape.prototype.getEndArrowWidth = function()
  1629. {
  1630. return this.getEdgeWidth() + mxUtils.getNumber(this.style, 'endWidth', this.defaultArrowWidth);;
  1631. };
  1632. FlexArrowShape.prototype.getEdgeWidth = function()
  1633. {
  1634. return mxUtils.getNumber(this.style, 'width', this.defaultWidth) + Math.max(0, this.strokewidth - 1);
  1635. };
  1636. // Registers the link shape
  1637. mxCellRenderer.registerShape('flexArrow', FlexArrowShape);
  1638. // Manual Input shape
  1639. function ManualInputShape()
  1640. {
  1641. mxActor.call(this);
  1642. };
  1643. mxUtils.extend(ManualInputShape, mxActor);
  1644. ManualInputShape.prototype.size = 30;
  1645. ManualInputShape.prototype.redrawPath = function(c, x, y, w, h)
  1646. {
  1647. var s = Math.min(h, parseFloat(mxUtils.getValue(this.style, 'size', this.size)));
  1648. var arcSize = mxUtils.getValue(this.style, mxConstants.STYLE_ARCSIZE, mxConstants.LINE_ARCSIZE) / 2;
  1649. this.addPoints(c, [new mxPoint(0, h), new mxPoint(0, s), new mxPoint(w, 0), new mxPoint(w, h)],
  1650. this.isRounded, arcSize, true);
  1651. c.end();
  1652. };
  1653. mxCellRenderer.registerShape('manualInput', ManualInputShape);
  1654. // Internal storage
  1655. function InternalStorageShape()
  1656. {
  1657. mxRectangleShape.call(this);
  1658. };
  1659. mxUtils.extend(InternalStorageShape, mxRectangleShape);
  1660. InternalStorageShape.prototype.dx = 20;
  1661. InternalStorageShape.prototype.dy = 20;
  1662. InternalStorageShape.prototype.isHtmlAllowed = function()
  1663. {
  1664. return false;
  1665. };
  1666. InternalStorageShape.prototype.paintForeground = function(c, x, y, w, h)
  1667. {
  1668. mxRectangleShape.prototype.paintForeground.apply(this, arguments);
  1669. var inset = 0;
  1670. if (this.isRounded)
  1671. {
  1672. var f = mxUtils.getValue(this.style, mxConstants.STYLE_ARCSIZE,
  1673. mxConstants.RECTANGLE_ROUNDING_FACTOR * 100) / 100;
  1674. inset = Math.max(inset, Math.min(w * f, h * f));
  1675. }
  1676. var dx = Math.max(inset, Math.min(w, parseFloat(mxUtils.getValue(this.style, 'dx', this.dx))));
  1677. var dy = Math.max(inset, Math.min(h, parseFloat(mxUtils.getValue(this.style, 'dy', this.dy))));
  1678. c.begin();
  1679. c.moveTo(x, y + dy);
  1680. c.lineTo(x + w, y + dy);
  1681. c.end();
  1682. c.stroke();
  1683. c.begin();
  1684. c.moveTo(x + dx, y);
  1685. c.lineTo(x + dx, y + h);
  1686. c.end();
  1687. c.stroke();
  1688. };
  1689. mxCellRenderer.registerShape('internalStorage', InternalStorageShape);
  1690. // Internal storage
  1691. function CornerShape()
  1692. {
  1693. mxActor.call(this);
  1694. };
  1695. mxUtils.extend(CornerShape, mxActor);
  1696. CornerShape.prototype.dx = 20;
  1697. CornerShape.prototype.dy = 20;
  1698. // Corner
  1699. CornerShape.prototype.redrawPath = function(c, x, y, w, h)
  1700. {
  1701. var dx = Math.max(0, Math.min(w, parseFloat(mxUtils.getValue(this.style, 'dx', this.dx))));
  1702. var dy = Math.max(0, Math.min(h, parseFloat(mxUtils.getValue(this.style, 'dy', this.dy))));
  1703. var s = Math.min(w / 2, Math.min(h, parseFloat(mxUtils.getValue(this.style, 'size', this.size))));
  1704. var arcSize = mxUtils.getValue(this.style, mxConstants.STYLE_ARCSIZE, mxConstants.LINE_ARCSIZE) / 2;
  1705. this.addPoints(c, [new mxPoint(0, 0), new mxPoint(w, 0), new mxPoint(w, dy), new mxPoint(dx, dy),
  1706. new mxPoint(dx, h), new mxPoint(0, h)], this.isRounded, arcSize, true);
  1707. c.end();
  1708. };
  1709. mxCellRenderer.registerShape('corner', CornerShape);
  1710. // Crossbar shape
  1711. function CrossbarShape()
  1712. {
  1713. mxActor.call(this);
  1714. };
  1715. mxUtils.extend(CrossbarShape, mxActor);
  1716. CrossbarShape.prototype.redrawPath = function(c, x, y, w, h)
  1717. {
  1718. c.moveTo(0, 0);
  1719. c.lineTo(0, h);
  1720. c.end();
  1721. c.moveTo(w, 0);
  1722. c.lineTo(w, h);
  1723. c.end();
  1724. c.moveTo(0, h / 2);
  1725. c.lineTo(w, h / 2);
  1726. c.end();
  1727. };
  1728. mxCellRenderer.registerShape('crossbar', CrossbarShape);
  1729. // Internal storage
  1730. function TeeShape()
  1731. {
  1732. mxActor.call(this);
  1733. };
  1734. mxUtils.extend(TeeShape, mxActor);
  1735. TeeShape.prototype.dx = 20;
  1736. TeeShape.prototype.dy = 20;
  1737. // Corner
  1738. TeeShape.prototype.redrawPath = function(c, x, y, w, h)
  1739. {
  1740. var dx = Math.max(0, Math.min(w, parseFloat(mxUtils.getValue(this.style, 'dx', this.dx))));
  1741. var dy = Math.max(0, Math.min(h, parseFloat(mxUtils.getValue(this.style, 'dy', this.dy))));
  1742. var w2 = Math.abs(w - dx) / 2;
  1743. var s = Math.min(w / 2, Math.min(h, parseFloat(mxUtils.getValue(this.style, 'size', this.size))));
  1744. var arcSize = mxUtils.getValue(this.style, mxConstants.STYLE_ARCSIZE, mxConstants.LINE_ARCSIZE) / 2;
  1745. this.addPoints(c, [new mxPoint(0, 0), new mxPoint(w, 0), new mxPoint(w, dy), new mxPoint((w + dx) / 2, dy),
  1746. new mxPoint((w + dx) / 2, h), new mxPoint((w - dx) / 2, h), new mxPoint((w - dx) / 2, dy),
  1747. new mxPoint(0, dy)], this.isRounded, arcSize, true);
  1748. c.end();
  1749. };
  1750. mxCellRenderer.registerShape('tee', TeeShape);
  1751. // Arrow
  1752. function SingleArrowShape()
  1753. {
  1754. mxActor.call(this);
  1755. };
  1756. mxUtils.extend(SingleArrowShape, mxActor);
  1757. SingleArrowShape.prototype.arrowWidth = 0.3;
  1758. SingleArrowShape.prototype.arrowSize = 0.2;
  1759. SingleArrowShape.prototype.redrawPath = function(c, x, y, w, h)
  1760. {
  1761. var aw = h * Math.max(0, Math.min(1, parseFloat(mxUtils.getValue(this.style, 'arrowWidth', this.arrowWidth))));
  1762. var as = w * Math.max(0, Math.min(1, parseFloat(mxUtils.getValue(this.style, 'arrowSize', this.arrowSize))));
  1763. var at = (h - aw) / 2;
  1764. var ab = at + aw;
  1765. var arcSize = mxUtils.getValue(this.style, mxConstants.STYLE_ARCSIZE, mxConstants.LINE_ARCSIZE) / 2;
  1766. this.addPoints(c, [new mxPoint(0, at), new mxPoint(w - as, at), new mxPoint(w - as, 0), new mxPoint(w, h / 2),
  1767. new mxPoint(w - as, h), new mxPoint(w - as, ab), new mxPoint(0, ab)],
  1768. this.isRounded, arcSize, true);
  1769. c.end();
  1770. };
  1771. mxCellRenderer.registerShape('singleArrow', SingleArrowShape);
  1772. // Arrow
  1773. function DoubleArrowShape()
  1774. {
  1775. mxActor.call(this);
  1776. };
  1777. mxUtils.extend(DoubleArrowShape, mxActor);
  1778. DoubleArrowShape.prototype.redrawPath = function(c, x, y, w, h)
  1779. {
  1780. var aw = h * Math.max(0, Math.min(1, parseFloat(mxUtils.getValue(this.style, 'arrowWidth', SingleArrowShape.prototype.arrowWidth))));
  1781. var as = w * Math.max(0, Math.min(1, parseFloat(mxUtils.getValue(this.style, 'arrowSize', SingleArrowShape.prototype.arrowSize))));
  1782. var at = (h - aw) / 2;
  1783. var ab = at + aw;
  1784. var arcSize = mxUtils.getValue(this.style, mxConstants.STYLE_ARCSIZE, mxConstants.LINE_ARCSIZE) / 2;
  1785. this.addPoints(c, [new mxPoint(0, h / 2), new mxPoint(as, 0), new mxPoint(as, at), new mxPoint(w - as, at),
  1786. new mxPoint(w - as, 0), new mxPoint(w, h / 2), new mxPoint(w - as, h),
  1787. new mxPoint(w - as, ab), new mxPoint(as, ab), new mxPoint(as, h)],
  1788. this.isRounded, arcSize, true);
  1789. c.end();
  1790. };
  1791. mxCellRenderer.registerShape('doubleArrow', DoubleArrowShape);
  1792. // Data storage
  1793. function DataStorageShape()
  1794. {
  1795. mxActor.call(this);
  1796. };
  1797. mxUtils.extend(DataStorageShape, mxActor);
  1798. DataStorageShape.prototype.size = 0.1;
  1799. DataStorageShape.prototype.redrawPath = function(c, x, y, w, h)
  1800. {
  1801. var s = w * Math.max(0, Math.min(1, parseFloat(mxUtils.getValue(this.style, 'size', this.size))));
  1802. c.moveTo(s, 0);
  1803. c.lineTo(w, 0);
  1804. c.quadTo(w - s * 2, h / 2, w, h);
  1805. c.lineTo(s, h);
  1806. c.quadTo(s - s * 2, h / 2, s, 0);
  1807. c.close();
  1808. c.end();
  1809. };
  1810. mxCellRenderer.registerShape('dataStorage', DataStorageShape);
  1811. // Or
  1812. function OrShape()
  1813. {
  1814. mxActor.call(this);
  1815. };
  1816. mxUtils.extend(OrShape, mxActor);
  1817. OrShape.prototype.redrawPath = function(c, x, y, w, h)
  1818. {
  1819. c.moveTo(0, 0);
  1820. c.quadTo(w, 0, w, h / 2);
  1821. c.quadTo(w, h, 0, h);
  1822. c.close();
  1823. c.end();
  1824. };
  1825. mxCellRenderer.registerShape('or', OrShape);
  1826. // Xor
  1827. function XorShape()
  1828. {
  1829. mxActor.call(this);
  1830. };
  1831. mxUtils.extend(XorShape, mxActor);
  1832. XorShape.prototype.redrawPath = function(c, x, y, w, h)
  1833. {
  1834. c.moveTo(0, 0);
  1835. c.quadTo(w, 0, w, h / 2);
  1836. c.quadTo(w, h, 0, h);
  1837. c.quadTo(w / 2, h / 2, 0, 0);
  1838. c.close();
  1839. c.end();
  1840. };
  1841. mxCellRenderer.registerShape('xor', XorShape);
  1842. // Loop limit
  1843. function LoopLimitShape()
  1844. {
  1845. mxActor.call(this);
  1846. };
  1847. mxUtils.extend(LoopLimitShape, mxActor);
  1848. LoopLimitShape.prototype.size = 20;
  1849. LoopLimitShape.prototype.redrawPath = function(c, x, y, w, h)
  1850. {
  1851. var s = Math.min(w / 2, Math.min(h, parseFloat(mxUtils.getValue(this.style, 'size', this.size))));
  1852. var arcSize = mxUtils.getValue(this.style, mxConstants.STYLE_ARCSIZE, mxConstants.LINE_ARCSIZE) / 2;
  1853. this.addPoints(c, [new mxPoint(s, 0), new mxPoint(w - s, 0), new mxPoint(w, s * 0.8), new mxPoint(w, h),
  1854. new mxPoint(0, h), new mxPoint(0, s * 0.8)], this.isRounded, arcSize, true);
  1855. c.end();
  1856. };
  1857. mxCellRenderer.registerShape('loopLimit', LoopLimitShape);
  1858. // Off page connector
  1859. function OffPageConnectorShape()
  1860. {
  1861. mxActor.call(this);
  1862. };
  1863. mxUtils.extend(OffPageConnectorShape, mxActor);
  1864. OffPageConnectorShape.prototype.size = 3 / 8;
  1865. OffPageConnectorShape.prototype.redrawPath = function(c, x, y, w, h)
  1866. {
  1867. var s = h * Math.max(0, Math.min(1, parseFloat(mxUtils.getValue(this.style, 'size', this.size))));
  1868. var arcSize = mxUtils.getValue(this.style, mxConstants.STYLE_ARCSIZE, mxConstants.LINE_ARCSIZE) / 2;
  1869. this.addPoints(c, [new mxPoint(0, 0), new mxPoint(w, 0), new mxPoint(w, h - s), new mxPoint(w / 2, h),
  1870. new mxPoint(0, h - s)], this.isRounded, arcSize, true);
  1871. c.end();
  1872. };
  1873. mxCellRenderer.registerShape('offPageConnector', OffPageConnectorShape);
  1874. // Internal storage
  1875. function TapeDataShape()
  1876. {
  1877. mxEllipse.call(this);
  1878. };
  1879. mxUtils.extend(TapeDataShape, mxEllipse);
  1880. TapeDataShape.prototype.paintVertexShape = function(c, x, y, w, h)
  1881. {
  1882. mxEllipse.prototype.paintVertexShape.apply(this, arguments);
  1883. c.begin();
  1884. c.moveTo(x + w / 2, y + h);
  1885. c.lineTo(x + w, y + h);
  1886. c.end();
  1887. c.stroke();
  1888. };
  1889. mxCellRenderer.registerShape('tapeData', TapeDataShape);
  1890. // OrEllipseShape
  1891. function OrEllipseShape()
  1892. {
  1893. mxEllipse.call(this);
  1894. };
  1895. mxUtils.extend(OrEllipseShape, mxEllipse);
  1896. OrEllipseShape.prototype.paintVertexShape = function(c, x, y, w, h)
  1897. {
  1898. mxEllipse.prototype.paintVertexShape.apply(this, arguments);
  1899. c.setShadow(false);
  1900. c.begin();
  1901. c.moveTo(x, y + h / 2);
  1902. c.lineTo(x + w, y + h / 2);
  1903. c.end();
  1904. c.stroke();
  1905. c.begin();
  1906. c.moveTo(x + w / 2, y);
  1907. c.lineTo(x + w / 2, y + h);
  1908. c.end();
  1909. c.stroke();
  1910. };
  1911. mxCellRenderer.registerShape('orEllipse', OrEllipseShape);
  1912. // SumEllipseShape
  1913. function SumEllipseShape()
  1914. {
  1915. mxEllipse.call(this);
  1916. };
  1917. mxUtils.extend(SumEllipseShape, mxEllipse);
  1918. SumEllipseShape.prototype.paintVertexShape = function(c, x, y, w, h)
  1919. {
  1920. mxEllipse.prototype.paintVertexShape.apply(this, arguments);
  1921. var s2 = 0.145;
  1922. c.setShadow(false);
  1923. c.begin();
  1924. c.moveTo(x + w * s2, y + h * s2);
  1925. c.lineTo(x + w * (1 - s2), y + h * (1 - s2));
  1926. c.end();
  1927. c.stroke();
  1928. c.begin();
  1929. c.moveTo(x + w * (1 - s2), y + h * s2);
  1930. c.lineTo(x + w * s2, y + h * (1 - s2));
  1931. c.end();
  1932. c.stroke();
  1933. };
  1934. mxCellRenderer.registerShape('sumEllipse', SumEllipseShape);
  1935. // SortShape
  1936. function SortShape()
  1937. {
  1938. mxRhombus.call(this);
  1939. };
  1940. mxUtils.extend(SortShape, mxRhombus);
  1941. SortShape.prototype.paintVertexShape = function(c, x, y, w, h)
  1942. {
  1943. mxRhombus.prototype.paintVertexShape.apply(this, arguments);
  1944. c.setShadow(false);
  1945. c.begin();
  1946. c.moveTo(x, y + h / 2);
  1947. c.lineTo(x + w, y + h / 2);
  1948. c.end();
  1949. c.stroke();
  1950. };
  1951. mxCellRenderer.registerShape('sortShape', SortShape);
  1952. // CollateShape
  1953. function CollateShape()
  1954. {
  1955. mxEllipse.call(this);
  1956. };
  1957. mxUtils.extend(CollateShape, mxEllipse);
  1958. CollateShape.prototype.paintVertexShape = function(c, x, y, w, h)
  1959. {
  1960. c.begin();
  1961. c.moveTo(x, y);
  1962. c.lineTo(x + w, y);
  1963. c.lineTo(x + w / 2, y + h / 2);
  1964. c.close();
  1965. c.fillAndStroke();
  1966. c.begin();
  1967. c.moveTo(x, y + h);
  1968. c.lineTo(x + w, y + h);
  1969. c.lineTo(x + w / 2, y + h / 2);
  1970. c.close();
  1971. c.fillAndStroke();
  1972. };
  1973. mxCellRenderer.registerShape('collate', CollateShape);
  1974. // DimensionShape
  1975. function DimensionShape()
  1976. {
  1977. mxEllipse.call(this);
  1978. };
  1979. mxUtils.extend(DimensionShape, mxEllipse);
  1980. DimensionShape.prototype.paintVertexShape = function(c, x, y, w, h)
  1981. {
  1982. // Arrow size
  1983. var al = 10;
  1984. var cy = y + h - al / 2;
  1985. c.begin();
  1986. c.moveTo(x, y);
  1987. c.lineTo(x, y + h);
  1988. c.moveTo(x, cy);
  1989. c.lineTo(x + al, cy - al / 2);
  1990. c.moveTo(x, cy);
  1991. c.lineTo(x + al, cy + al / 2);
  1992. c.moveTo(x, cy);
  1993. c.lineTo(x + w, cy);
  1994. // Opposite side
  1995. c.moveTo(x + w, y);
  1996. c.lineTo(x + w, y + h);
  1997. c.moveTo(x + w, cy);
  1998. c.lineTo(x + w - al, cy - al / 2);
  1999. c.moveTo(x + w, cy);
  2000. c.lineTo(x + w - al, cy + al / 2);
  2001. c.end();
  2002. c.stroke();
  2003. };
  2004. mxCellRenderer.registerShape('dimension', DimensionShape);
  2005. // PartialRectangleShape
  2006. function PartialRectangleShape()
  2007. {
  2008. mxEllipse.call(this);
  2009. };
  2010. mxUtils.extend(PartialRectangleShape, mxEllipse);
  2011. PartialRectangleShape.prototype.paintVertexShape = function(c, x, y, w, h)
  2012. {
  2013. if (!this.outline)
  2014. {
  2015. c.setStrokeColor(null);
  2016. }
  2017. mxRectangleShape.prototype.paintBackground.apply(this, arguments);
  2018. if (this.style != null)
  2019. {
  2020. c.setStrokeColor(this.stroke);
  2021. c.rect(x, y, w, h);
  2022. c.fill();
  2023. c.begin();
  2024. c.moveTo(x, y);
  2025. if (mxUtils.getValue(this.style, 'top', '1') == '1')
  2026. {
  2027. c.lineTo(x + w, y);
  2028. }
  2029. else
  2030. {
  2031. c.moveTo(x + w, y);
  2032. }
  2033. if (mxUtils.getValue(this.style, 'right', '1') == '1')
  2034. {
  2035. c.lineTo(x + w, y + h);
  2036. }
  2037. else
  2038. {
  2039. c.moveTo(x + w, y + h);
  2040. }
  2041. if (mxUtils.getValue(this.style, 'bottom', '1') == '1')
  2042. {
  2043. c.lineTo(x, y + h);
  2044. }
  2045. else
  2046. {
  2047. c.moveTo(x, y + h);
  2048. }
  2049. if (mxUtils.getValue(this.style, 'left', '1') == '1')
  2050. {
  2051. c.lineTo(x, y - this.strokewidth / 2);
  2052. }
  2053. c.end();
  2054. c.stroke();
  2055. }
  2056. };
  2057. mxCellRenderer.registerShape('partialRectangle', PartialRectangleShape);
  2058. // LineEllipseShape
  2059. function LineEllipseShape()
  2060. {
  2061. mxEllipse.call(this);
  2062. };
  2063. mxUtils.extend(LineEllipseShape, mxEllipse);
  2064. LineEllipseShape.prototype.paintVertexShape = function(c, x, y, w, h)
  2065. {
  2066. mxEllipse.prototype.paintVertexShape.apply(this, arguments);
  2067. c.setShadow(false);
  2068. c.begin();
  2069. if (mxUtils.getValue(this.style, 'line') == 'vertical')
  2070. {
  2071. c.moveTo(x + w / 2, y);
  2072. c.lineTo(x + w / 2, y + h);
  2073. }
  2074. else
  2075. {
  2076. c.moveTo(x, y + h / 2);
  2077. c.lineTo(x + w, y + h / 2);
  2078. }
  2079. c.end();
  2080. c.stroke();
  2081. };
  2082. mxCellRenderer.registerShape('lineEllipse', LineEllipseShape);
  2083. // Delay
  2084. function DelayShape()
  2085. {
  2086. mxActor.call(this);
  2087. };
  2088. mxUtils.extend(DelayShape, mxActor);
  2089. DelayShape.prototype.redrawPath = function(c, x, y, w, h)
  2090. {
  2091. var dx = Math.min(w, h / 2);
  2092. c.moveTo(0, 0);
  2093. c.lineTo(w - dx, 0);
  2094. c.quadTo(w, 0, w, h / 2);
  2095. c.quadTo(w, h, w - dx, h);
  2096. c.lineTo(0, h);
  2097. c.close();
  2098. c.end();
  2099. };
  2100. mxCellRenderer.registerShape('delay', DelayShape);
  2101. // Cross Shape
  2102. function CrossShape()
  2103. {
  2104. mxActor.call(this);
  2105. };
  2106. mxUtils.extend(CrossShape, mxActor);
  2107. CrossShape.prototype.size = 0.2;
  2108. CrossShape.prototype.redrawPath = function(c, x, y, w, h)
  2109. {
  2110. var m = Math.min(h, w);
  2111. var size = Math.max(0, Math.min(m, m * parseFloat(mxUtils.getValue(this.style, 'size', this.size))));
  2112. var t = (h - size) / 2;
  2113. var b = t + size;
  2114. var l = (w - size) / 2;
  2115. var r = l + size;
  2116. c.moveTo(0, t);
  2117. c.lineTo(l, t);
  2118. c.lineTo(l, 0);
  2119. c.lineTo(r, 0);
  2120. c.lineTo(r, t);
  2121. c.lineTo(w, t);
  2122. c.lineTo(w, b);
  2123. c.lineTo(r, b);
  2124. c.lineTo(r, h);
  2125. c.lineTo(l, h);
  2126. c.lineTo(l, b);
  2127. c.lineTo(0, b);
  2128. c.close();
  2129. c.end();
  2130. };
  2131. mxCellRenderer.registerShape('cross', CrossShape);
  2132. // Display
  2133. function DisplayShape()
  2134. {
  2135. mxActor.call(this);
  2136. };
  2137. mxUtils.extend(DisplayShape, mxActor);
  2138. DisplayShape.prototype.size = 0.25;
  2139. DisplayShape.prototype.redrawPath = function(c, x, y, w, h)
  2140. {
  2141. var dx = Math.min(w, h / 2);
  2142. var s = Math.min(w - dx, Math.max(0, parseFloat(mxUtils.getValue(this.style, 'size', this.size))) * w);
  2143. c.moveTo(0, h / 2);
  2144. c.lineTo(s, 0);
  2145. c.lineTo(w - dx, 0);
  2146. c.quadTo(w, 0, w, h / 2);
  2147. c.quadTo(w, h, w - dx, h);
  2148. c.lineTo(s, h);
  2149. c.close();
  2150. c.end();
  2151. };
  2152. mxCellRenderer.registerShape('display', DisplayShape);
  2153. // FilledEdge shape
  2154. function FilledEdge()
  2155. {
  2156. mxConnector.call(this);
  2157. };
  2158. mxUtils.extend(FilledEdge, mxConnector);
  2159. FilledEdge.prototype.origPaintEdgeShape = FilledEdge.prototype.paintEdgeShape;
  2160. FilledEdge.prototype.paintEdgeShape = function(c, pts, rounded)
  2161. {
  2162. // Markers modify incoming points array
  2163. var temp = [];
  2164. for (var i = 0; i < pts.length; i++)
  2165. {
  2166. temp.push(mxUtils.clone(pts[i]));
  2167. }
  2168. // paintEdgeShape resets dashed to false
  2169. var dashed = c.state.dashed;
  2170. var fixDash = c.state.fixDash;
  2171. FilledEdge.prototype.origPaintEdgeShape.apply(this, [c, temp, rounded]);
  2172. if (c.state.strokeWidth >= 3)
  2173. {
  2174. var fillClr = mxUtils.getValue(this.style, 'fillColor', null);
  2175. if (fillClr != null)
  2176. {
  2177. c.setStrokeColor(fillClr);
  2178. c.setStrokeWidth(c.state.strokeWidth - 2);
  2179. c.setDashed(dashed, fixDash);
  2180. FilledEdge.prototype.origPaintEdgeShape.apply(this, [c, pts, rounded]);
  2181. }
  2182. }
  2183. };
  2184. // Registers the link shape
  2185. mxCellRenderer.registerShape('filledEdge', FilledEdge);
  2186. // Implements custom colors for shapes
  2187. if (typeof StyleFormatPanel !== 'undefined')
  2188. {
  2189. (function()
  2190. {
  2191. var styleFormatPanelGetCustomColors = StyleFormatPanel.prototype.getCustomColors;
  2192. StyleFormatPanel.prototype.getCustomColors = function()
  2193. {
  2194. var ss = this.format.getSelectionState();
  2195. var result = styleFormatPanelGetCustomColors.apply(this, arguments);
  2196. if (ss.style.shape == 'umlFrame')
  2197. {
  2198. result.push({title: mxResources.get('laneColor'), key: 'swimlaneFillColor', defaultValue: '#ffffff'});
  2199. }
  2200. return result;
  2201. };
  2202. })();
  2203. }
  2204. // Registers and defines the custom marker
  2205. mxMarker.addMarker('dash', function(c, shape, type, pe, unitX, unitY, size, source, sw, filled)
  2206. {
  2207. var nx = unitX * (size + sw + 1);
  2208. var ny = unitY * (size + sw + 1);
  2209. return function()
  2210. {
  2211. c.begin();
  2212. c.moveTo(pe.x - nx / 2 - ny / 2, pe.y - ny / 2 + nx / 2);
  2213. c.lineTo(pe.x + ny / 2 - 3 * nx / 2, pe.y - 3 * ny / 2 - nx / 2);
  2214. c.stroke();
  2215. };
  2216. });
  2217. // Registers and defines the custom marker
  2218. mxMarker.addMarker('cross', function(c, shape, type, pe, unitX, unitY, size, source, sw, filled)
  2219. {
  2220. var nx = unitX * (size + sw + 1);
  2221. var ny = unitY * (size + sw + 1);
  2222. return function()
  2223. {
  2224. c.begin();
  2225. c.moveTo(pe.x - nx / 2 - ny / 2, pe.y - ny / 2 + nx / 2);
  2226. c.lineTo(pe.x + ny / 2 - 3 * nx / 2, pe.y - 3 * ny / 2 - nx / 2);
  2227. c.moveTo(pe.x - nx / 2 + ny / 2, pe.y - ny / 2 - nx / 2);
  2228. c.lineTo(pe.x - ny / 2 - 3 * nx / 2, pe.y - 3 * ny / 2 + nx / 2);
  2229. c.stroke();
  2230. };
  2231. });
  2232. function circleMarker(c, shape, type, pe, unitX, unitY, size, source, sw, filled)
  2233. {
  2234. var a = size / 2;
  2235. var size = size + sw;
  2236. var pt = pe.clone();
  2237. pe.x -= unitX * (2 * size + sw);
  2238. pe.y -= unitY * (2 * size + sw);
  2239. unitX = unitX * (size + sw);
  2240. unitY = unitY * (size + sw);
  2241. return function()
  2242. {
  2243. c.ellipse(pt.x - unitX - size, pt.y - unitY - size, 2 * size, 2 * size);
  2244. if (filled)
  2245. {
  2246. c.fillAndStroke();
  2247. }
  2248. else
  2249. {
  2250. c.stroke();
  2251. }
  2252. };
  2253. };
  2254. mxMarker.addMarker('circle', circleMarker);
  2255. mxMarker.addMarker('circlePlus', function(c, shape, type, pe, unitX, unitY, size, source, sw, filled)
  2256. {
  2257. var pt = pe.clone();
  2258. var fn = circleMarker.apply(this, arguments);
  2259. var nx = unitX * (size + 2 * sw); // (size + sw + 1);
  2260. var ny = unitY * (size + 2 * sw); //(size + sw + 1);
  2261. return function()
  2262. {
  2263. fn.apply(this, arguments);
  2264. c.begin();
  2265. c.moveTo(pt.x - unitX * (sw), pt.y - unitY * (sw));
  2266. c.lineTo(pt.x - 2 * nx + unitX * (sw), pt.y - 2 * ny + unitY * (sw));
  2267. c.moveTo(pt.x - nx - ny + unitY * sw, pt.y - ny + nx - unitX * sw);
  2268. c.lineTo(pt.x + ny - nx - unitY * sw, pt.y - ny - nx + unitX * sw);
  2269. c.stroke();
  2270. };
  2271. });
  2272. mxMarker.addMarker('async', function(c, shape, type, pe, unitX, unitY, size, source, sw, filled)
  2273. {
  2274. // The angle of the forward facing arrow sides against the x axis is
  2275. // 26.565 degrees, 1/sin(26.565) = 2.236 / 2 = 1.118 ( / 2 allows for
  2276. // only half the strokewidth is processed ).
  2277. var endOffsetX = unitX * sw * 1.118;
  2278. var endOffsetY = unitY * sw * 1.118;
  2279. unitX = unitX * (size + sw);
  2280. unitY = unitY * (size + sw);
  2281. var pt = pe.clone();
  2282. pt.x -= endOffsetX;
  2283. pt.y -= endOffsetY;
  2284. var f = 1;
  2285. pe.x += -unitX * f - endOffsetX;
  2286. pe.y += -unitY * f - endOffsetY;
  2287. return function()
  2288. {
  2289. c.begin();
  2290. c.moveTo(pt.x, pt.y);
  2291. if (source)
  2292. {
  2293. c.lineTo(pt.x - unitX - unitY / 2, pt.y - unitY + unitX / 2);
  2294. }
  2295. else
  2296. {
  2297. c.lineTo(pt.x + unitY / 2 - unitX, pt.y - unitY - unitX / 2);
  2298. }
  2299. c.lineTo(pt.x - unitX, pt.y - unitY);
  2300. c.close();
  2301. if (filled)
  2302. {
  2303. c.fillAndStroke();
  2304. }
  2305. else
  2306. {
  2307. c.stroke();
  2308. }
  2309. };
  2310. });
  2311. function createOpenAsyncArrow(widthFactor)
  2312. {
  2313. widthFactor = (widthFactor != null) ? widthFactor : 2;
  2314. return function(c, shape, type, pe, unitX, unitY, size, source, sw, filled)
  2315. {
  2316. unitX = unitX * (size + sw);
  2317. unitY = unitY * (size + sw);
  2318. var pt = pe.clone();
  2319. return function()
  2320. {
  2321. c.begin();
  2322. c.moveTo(pt.x, pt.y);
  2323. if (source)
  2324. {
  2325. c.lineTo(pt.x - unitX - unitY / widthFactor, pt.y - unitY + unitX / widthFactor);
  2326. }
  2327. else
  2328. {
  2329. c.lineTo(pt.x + unitY / widthFactor - unitX, pt.y - unitY - unitX / widthFactor);
  2330. }
  2331. c.stroke();
  2332. };
  2333. }
  2334. };
  2335. mxMarker.addMarker('openAsync', createOpenAsyncArrow(2));
  2336. function arrow(canvas, shape, type, pe, unitX, unitY, size, source, sw, filled)
  2337. {
  2338. // The angle of the forward facing arrow sides against the x axis is
  2339. // 26.565 degrees, 1/sin(26.565) = 2.236 / 2 = 1.118 ( / 2 allows for
  2340. // only half the strokewidth is processed ).
  2341. var endOffsetX = unitX * sw * 1.118;
  2342. var endOffsetY = unitY * sw * 1.118;
  2343. unitX = unitX * (size + sw);
  2344. unitY = unitY * (size + sw);
  2345. var pt = pe.clone();
  2346. pt.x -= endOffsetX;
  2347. pt.y -= endOffsetY;
  2348. var f = (type != mxConstants.ARROW_CLASSIC && type != mxConstants.ARROW_CLASSIC_THIN) ? 1 : 3 / 4;
  2349. pe.x += -unitX * f - endOffsetX;
  2350. pe.y += -unitY * f - endOffsetY;
  2351. return function()
  2352. {
  2353. canvas.begin();
  2354. canvas.moveTo(pt.x, pt.y);
  2355. canvas.lineTo(pt.x - unitX - unitY / widthFactor, pt.y - unitY + unitX / widthFactor);
  2356. if (type == mxConstants.ARROW_CLASSIC || type == mxConstants.ARROW_CLASSIC_THIN)
  2357. {
  2358. canvas.lineTo(pt.x - unitX * 3 / 4, pt.y - unitY * 3 / 4);
  2359. }
  2360. canvas.lineTo(pt.x + unitY / widthFactor - unitX, pt.y - unitY - unitX / widthFactor);
  2361. canvas.close();
  2362. if (filled)
  2363. {
  2364. canvas.fillAndStroke();
  2365. }
  2366. else
  2367. {
  2368. canvas.stroke();
  2369. }
  2370. };
  2371. }
  2372. // Handlers are only added if mxVertexHandler is defined (ie. not in embedded graph)
  2373. if (typeof mxVertexHandler !== 'undefined')
  2374. {
  2375. function createHandle(state, keys, getPositionFn, setPositionFn, ignoreGrid, redrawEdges)
  2376. {
  2377. var handle = new mxHandle(state, null, mxVertexHandler.prototype.secondaryHandleImage);
  2378. handle.execute = function()
  2379. {
  2380. for (var i = 0; i < keys.length; i++)
  2381. {
  2382. this.copyStyle(keys[i]);
  2383. }
  2384. };
  2385. handle.getPosition = getPositionFn;
  2386. handle.setPosition = setPositionFn;
  2387. handle.ignoreGrid = (ignoreGrid != null) ? ignoreGrid : true;
  2388. // Overridden to update connected edges
  2389. if (redrawEdges)
  2390. {
  2391. var positionChanged = handle.positionChanged;
  2392. handle.positionChanged = function()
  2393. {
  2394. positionChanged.apply(this, arguments);
  2395. // Redraws connected edges TODO: Include child edges
  2396. state.view.invalidate(this.state.cell);
  2397. state.view.validate();
  2398. };
  2399. }
  2400. return handle;
  2401. };
  2402. function createArcHandle(state, yOffset)
  2403. {
  2404. return createHandle(state, [mxConstants.STYLE_ARCSIZE], function(bounds)
  2405. {
  2406. var tmp = (yOffset != null) ? yOffset : bounds.height / 8;
  2407. if (mxUtils.getValue(state.style, mxConstants.STYLE_ABSOLUTE_ARCSIZE, 0) == '1')
  2408. {
  2409. var arcSize = mxUtils.getValue(state.style, mxConstants.STYLE_ARCSIZE, mxConstants.LINE_ARCSIZE) / 2;
  2410. return new mxPoint(bounds.x + bounds.width - Math.min(bounds.width / 2, arcSize), bounds.y + tmp);
  2411. }
  2412. else
  2413. {
  2414. var arcSize = Math.max(0, parseFloat(mxUtils.getValue(state.style,
  2415. mxConstants.STYLE_ARCSIZE, mxConstants.RECTANGLE_ROUNDING_FACTOR * 100))) / 100;
  2416. return new mxPoint(bounds.x + bounds.width - Math.min(Math.max(bounds.width / 2, bounds.height / 2),
  2417. Math.min(bounds.width, bounds.height) * arcSize), bounds.y + tmp);
  2418. }
  2419. }, function(bounds, pt, me)
  2420. {
  2421. if (mxUtils.getValue(state.style, mxConstants.STYLE_ABSOLUTE_ARCSIZE, 0) == '1')
  2422. {
  2423. this.state.style[mxConstants.STYLE_ARCSIZE] = Math.round(Math.max(0, Math.min(bounds.width,
  2424. (bounds.x + bounds.width - pt.x) * 2)));
  2425. }
  2426. else
  2427. {
  2428. var f = Math.min(50, Math.max(0, (bounds.width - pt.x + bounds.x) * 100 /
  2429. Math.min(bounds.width, bounds.height)));
  2430. this.state.style[mxConstants.STYLE_ARCSIZE] = Math.round(f);
  2431. }
  2432. });
  2433. }
  2434. function createArcHandleFunction()
  2435. {
  2436. return function(state)
  2437. {
  2438. var handles = [];
  2439. if (mxUtils.getValue(state.style, mxConstants.STYLE_ROUNDED, false))
  2440. {
  2441. handles.push(createArcHandle(state));
  2442. }
  2443. return handles;
  2444. };
  2445. };
  2446. function createTrapezoidHandleFunction(max)
  2447. {
  2448. return function(state)
  2449. {
  2450. var handles = [createHandle(state, ['size'], function(bounds)
  2451. {
  2452. var size = Math.max(0, Math.min(max, parseFloat(mxUtils.getValue(this.state.style, 'size', TrapezoidShape.prototype.size))));
  2453. return new mxPoint(bounds.x + size * bounds.width * 0.75, bounds.y + bounds.height / 4);
  2454. }, function(bounds, pt)
  2455. {
  2456. this.state.style['size'] = Math.max(0, Math.min(max, (pt.x - bounds.x) / (bounds.width * 0.75)));
  2457. }, null, true)];
  2458. if (mxUtils.getValue(state.style, mxConstants.STYLE_ROUNDED, false))
  2459. {
  2460. handles.push(createArcHandle(state));
  2461. }
  2462. return handles;
  2463. };
  2464. };
  2465. function createDisplayHandleFunction(defaultValue, allowArcHandle, max, redrawEdges, fixedDefaultValue)
  2466. {
  2467. max = (max != null) ? max : 1;
  2468. return function(state)
  2469. {
  2470. var handles = [createHandle(state, ['size'], function(bounds)
  2471. {
  2472. var fixed = (fixedDefaultValue != null) ? mxUtils.getValue(this.state.style, 'fixedSize', '0') != '0' : null;
  2473. var size = parseFloat(mxUtils.getValue(this.state.style, 'size', (fixed) ? fixedDefaultValue : defaultValue));
  2474. return new mxPoint(bounds.x + Math.max(0, Math.min(bounds.width, size * ((fixed) ? 1 : bounds.width))), bounds.getCenterY());
  2475. }, function(bounds, pt, me)
  2476. {
  2477. var fixed = (fixedDefaultValue != null) ? mxUtils.getValue(this.state.style, 'fixedSize', '0') != '0' : null;
  2478. var size = (fixed) ? (pt.x - bounds.x) : Math.max(0, Math.min(max, (pt.x - bounds.x) / bounds.width));
  2479. if (fixed && !mxEvent.isAltDown(me.getEvent()))
  2480. {
  2481. size = state.view.graph.snap(size);
  2482. }
  2483. this.state.style['size'] = size;
  2484. }, null, redrawEdges)];
  2485. if (allowArcHandle && mxUtils.getValue(state.style, mxConstants.STYLE_ROUNDED, false))
  2486. {
  2487. handles.push(createArcHandle(state));
  2488. }
  2489. return handles;
  2490. };
  2491. };
  2492. function createCubeHandleFunction(factor, defaultValue, allowArcHandle)
  2493. {
  2494. return function(state)
  2495. {
  2496. var handles = [createHandle(state, ['size'], function(bounds)
  2497. {
  2498. var size = Math.max(0, Math.min(bounds.width, Math.min(bounds.height, parseFloat(
  2499. mxUtils.getValue(this.state.style, 'size', defaultValue))))) * factor;
  2500. return new mxPoint(bounds.x + size, bounds.y + size);
  2501. }, function(bounds, pt)
  2502. {
  2503. this.state.style['size'] = Math.round(Math.max(0, Math.min(Math.min(bounds.width, pt.x - bounds.x),
  2504. Math.min(bounds.height, pt.y - bounds.y))) / factor);
  2505. })];
  2506. if (allowArcHandle && mxUtils.getValue(state.style, mxConstants.STYLE_ROUNDED, false))
  2507. {
  2508. handles.push(createArcHandle(state));
  2509. }
  2510. return handles;
  2511. };
  2512. };
  2513. function createArrowHandleFunction(maxSize)
  2514. {
  2515. return function(state)
  2516. {
  2517. return [createHandle(state, ['arrowWidth', 'arrowSize'], function(bounds)
  2518. {
  2519. var aw = Math.max(0, Math.min(1, mxUtils.getValue(this.state.style, 'arrowWidth', SingleArrowShape.prototype.arrowWidth)));
  2520. var as = Math.max(0, Math.min(maxSize, mxUtils.getValue(this.state.style, 'arrowSize', SingleArrowShape.prototype.arrowSize)));
  2521. return new mxPoint(bounds.x + (1 - as) * bounds.width, bounds.y + (1 - aw) * bounds.height / 2);
  2522. }, function(bounds, pt)
  2523. {
  2524. this.state.style['arrowWidth'] = Math.max(0, Math.min(1, Math.abs(bounds.y + bounds.height / 2 - pt.y) / bounds.height * 2));
  2525. this.state.style['arrowSize'] = Math.max(0, Math.min(maxSize, (bounds.x + bounds.width - pt.x) / (bounds.width)));
  2526. })];
  2527. };
  2528. };
  2529. function createEdgeHandle(state, keys, start, getPosition, setPosition)
  2530. {
  2531. return createHandle(state, keys, function(bounds)
  2532. {
  2533. var pts = state.absolutePoints;
  2534. var n = pts.length - 1;
  2535. var tr = state.view.translate;
  2536. var s = state.view.scale;
  2537. var p0 = (start) ? pts[0] : pts[n];
  2538. var p1 = (start) ? pts[1] : pts[n - 1];
  2539. var dx = (start) ? p1.x - p0.x : p1.x - p0.x;
  2540. var dy = (start) ? p1.y - p0.y : p1.y - p0.y;
  2541. var dist = Math.sqrt(dx * dx + dy * dy);
  2542. var pt = getPosition.call(this, dist, dx / dist, dy / dist, p0, p1);
  2543. return new mxPoint(pt.x / s - tr.x, pt.y / s - tr.y);
  2544. }, function(bounds, pt, me)
  2545. {
  2546. var pts = state.absolutePoints;
  2547. var n = pts.length - 1;
  2548. var tr = state.view.translate;
  2549. var s = state.view.scale;
  2550. var p0 = (start) ? pts[0] : pts[n];
  2551. var p1 = (start) ? pts[1] : pts[n - 1];
  2552. var dx = (start) ? p1.x - p0.x : p1.x - p0.x;
  2553. var dy = (start) ? p1.y - p0.y : p1.y - p0.y;
  2554. var dist = Math.sqrt(dx * dx + dy * dy);
  2555. pt.x = (pt.x + tr.x) * s;
  2556. pt.y = (pt.y + tr.y) * s;
  2557. setPosition.call(this, dist, dx / dist, dy / dist, p0, p1, pt, me);
  2558. });
  2559. };
  2560. function createEdgeWidthHandle(state, start, spacing)
  2561. {
  2562. return createEdgeHandle(state, ['width'], start, function(dist, nx, ny, p0, p1)
  2563. {
  2564. var w = state.shape.getEdgeWidth() * state.view.scale + spacing;
  2565. return new mxPoint(p0.x + nx * dist / 4 + ny * w / 2, p0.y + ny * dist / 4 - nx * w / 2);
  2566. }, function(dist, nx, ny, p0, p1, pt)
  2567. {
  2568. var w = Math.sqrt(mxUtils.ptSegDistSq(p0.x, p0.y, p1.x, p1.y, pt.x, pt.y));
  2569. state.style['width'] = Math.round(w * 2) / state.view.scale - spacing;
  2570. });
  2571. };
  2572. function ptLineDistance(x1, y1, x2, y2, x0, y0)
  2573. {
  2574. return Math.abs((y2 - y1) * x0 - (x2 - x1) * y0 + x2 * y1 - y2 * x1) / Math.sqrt((y2 - y1) * (y2 - y1) + (x2 - x1) * (x2 - x1));
  2575. }
  2576. var handleFactory = {
  2577. 'link': function(state)
  2578. {
  2579. var spacing = 10;
  2580. return [createEdgeWidthHandle(state, true, spacing), createEdgeWidthHandle(state, false, spacing)];
  2581. },
  2582. 'flexArrow': function(state)
  2583. {
  2584. // Do not use state.shape.startSize/endSize since it is cached
  2585. var tol = state.view.graph.gridSize / state.view.scale;
  2586. var handles = [];
  2587. if (mxUtils.getValue(state.style, mxConstants.STYLE_STARTARROW, mxConstants.NONE) != mxConstants.NONE)
  2588. {
  2589. handles.push(createEdgeHandle(state, ['width', mxConstants.STYLE_STARTSIZE, mxConstants.STYLE_ENDSIZE], true, function(dist, nx, ny, p0, p1)
  2590. {
  2591. var w = (state.shape.getEdgeWidth() - state.shape.strokewidth) * state.view.scale;
  2592. var l = mxUtils.getNumber(state.style, mxConstants.STYLE_STARTSIZE, mxConstants.ARROW_SIZE / 5) * 3 * state.view.scale;
  2593. return new mxPoint(p0.x + nx * (l + state.shape.strokewidth * state.view.scale) + ny * w / 2,
  2594. p0.y + ny * (l + state.shape.strokewidth * state.view.scale) - nx * w / 2);
  2595. }, function(dist, nx, ny, p0, p1, pt, me)
  2596. {
  2597. var w = Math.sqrt(mxUtils.ptSegDistSq(p0.x, p0.y, p1.x, p1.y, pt.x, pt.y));
  2598. var l = mxUtils.ptLineDist(p0.x, p0.y, p0.x + ny, p0.y - nx, pt.x, pt.y);
  2599. state.style[mxConstants.STYLE_STARTSIZE] = Math.round((l - state.shape.strokewidth) * 100 / 3) / 100 / state.view.scale;
  2600. state.style['width'] = Math.round(w * 2) / state.view.scale;
  2601. // Applies to opposite side
  2602. if (mxEvent.isControlDown(me.getEvent()))
  2603. {
  2604. state.style[mxConstants.STYLE_ENDSIZE] = state.style[mxConstants.STYLE_STARTSIZE];
  2605. }
  2606. // Snaps to end geometry
  2607. if (!mxEvent.isAltDown(me.getEvent()))
  2608. {
  2609. if (Math.abs(parseFloat(state.style[mxConstants.STYLE_STARTSIZE]) - parseFloat(state.style[mxConstants.STYLE_ENDSIZE])) < tol / 6)
  2610. {
  2611. state.style[mxConstants.STYLE_STARTSIZE] = state.style[mxConstants.STYLE_ENDSIZE];
  2612. }
  2613. }
  2614. }));
  2615. handles.push(createEdgeHandle(state, ['startWidth', 'endWidth', mxConstants.STYLE_STARTSIZE, mxConstants.STYLE_ENDSIZE], true, function(dist, nx, ny, p0, p1)
  2616. {
  2617. var w = (state.shape.getStartArrowWidth() - state.shape.strokewidth) * state.view.scale;
  2618. var l = mxUtils.getNumber(state.style, mxConstants.STYLE_STARTSIZE, mxConstants.ARROW_SIZE / 5) * 3 * state.view.scale;
  2619. return new mxPoint(p0.x + nx * (l + state.shape.strokewidth * state.view.scale) + ny * w / 2,
  2620. p0.y + ny * (l + state.shape.strokewidth * state.view.scale) - nx * w / 2);
  2621. }, function(dist, nx, ny, p0, p1, pt, me)
  2622. {
  2623. var w = Math.sqrt(mxUtils.ptSegDistSq(p0.x, p0.y, p1.x, p1.y, pt.x, pt.y));
  2624. var l = mxUtils.ptLineDist(p0.x, p0.y, p0.x + ny, p0.y - nx, pt.x, pt.y);
  2625. state.style[mxConstants.STYLE_STARTSIZE] = Math.round((l - state.shape.strokewidth) * 100 / 3) / 100 / state.view.scale;
  2626. state.style['startWidth'] = Math.max(0, Math.round(w * 2) - state.shape.getEdgeWidth()) / state.view.scale;
  2627. // Applies to opposite side
  2628. if (mxEvent.isControlDown(me.getEvent()))
  2629. {
  2630. state.style[mxConstants.STYLE_ENDSIZE] = state.style[mxConstants.STYLE_STARTSIZE];
  2631. state.style['endWidth'] = state.style['startWidth'];
  2632. }
  2633. // Snaps to endWidth
  2634. if (!mxEvent.isAltDown(me.getEvent()))
  2635. {
  2636. if (Math.abs(parseFloat(state.style[mxConstants.STYLE_STARTSIZE]) - parseFloat(state.style[mxConstants.STYLE_ENDSIZE])) < tol / 6)
  2637. {
  2638. state.style[mxConstants.STYLE_STARTSIZE] = state.style[mxConstants.STYLE_ENDSIZE];
  2639. }
  2640. if (Math.abs(parseFloat(state.style['startWidth']) - parseFloat(state.style['endWidth'])) < tol)
  2641. {
  2642. state.style['startWidth'] = state.style['endWidth'];
  2643. }
  2644. }
  2645. }));
  2646. }
  2647. if (mxUtils.getValue(state.style, mxConstants.STYLE_ENDARROW, mxConstants.NONE) != mxConstants.NONE)
  2648. {
  2649. handles.push(createEdgeHandle(state, ['width', mxConstants.STYLE_STARTSIZE, mxConstants.STYLE_ENDSIZE], false, function(dist, nx, ny, p0, p1)
  2650. {
  2651. var w = (state.shape.getEdgeWidth() - state.shape.strokewidth) * state.view.scale;
  2652. var l = mxUtils.getNumber(state.style, mxConstants.STYLE_ENDSIZE, mxConstants.ARROW_SIZE / 5) * 3 * state.view.scale;
  2653. return new mxPoint(p0.x + nx * (l + state.shape.strokewidth * state.view.scale) - ny * w / 2,
  2654. p0.y + ny * (l + state.shape.strokewidth * state.view.scale) + nx * w / 2);
  2655. }, function(dist, nx, ny, p0, p1, pt, me)
  2656. {
  2657. var w = Math.sqrt(mxUtils.ptSegDistSq(p0.x, p0.y, p1.x, p1.y, pt.x, pt.y));
  2658. var l = mxUtils.ptLineDist(p0.x, p0.y, p0.x + ny, p0.y - nx, pt.x, pt.y);
  2659. state.style[mxConstants.STYLE_ENDSIZE] = Math.round((l - state.shape.strokewidth) * 100 / 3) / 100 / state.view.scale;
  2660. state.style['width'] = Math.round(w * 2) / state.view.scale;
  2661. // Applies to opposite side
  2662. if (mxEvent.isControlDown(me.getEvent()))
  2663. {
  2664. state.style[mxConstants.STYLE_STARTSIZE] = state.style[mxConstants.STYLE_ENDSIZE];
  2665. }
  2666. // Snaps to start geometry
  2667. if (!mxEvent.isAltDown(me.getEvent()))
  2668. {
  2669. if (Math.abs(parseFloat(state.style[mxConstants.STYLE_ENDSIZE]) - parseFloat(state.style[mxConstants.STYLE_STARTSIZE])) < tol / 6)
  2670. {
  2671. state.style[mxConstants.STYLE_ENDSIZE] = state.style[mxConstants.STYLE_STARTSIZE];
  2672. }
  2673. }
  2674. }));
  2675. handles.push(createEdgeHandle(state, ['startWidth', 'endWidth', mxConstants.STYLE_STARTSIZE, mxConstants.STYLE_ENDSIZE], false, function(dist, nx, ny, p0, p1)
  2676. {
  2677. var w = (state.shape.getEndArrowWidth() - state.shape.strokewidth) * state.view.scale;
  2678. var l = mxUtils.getNumber(state.style, mxConstants.STYLE_ENDSIZE, mxConstants.ARROW_SIZE / 5) * 3 * state.view.scale;
  2679. return new mxPoint(p0.x + nx * (l + state.shape.strokewidth * state.view.scale) - ny * w / 2,
  2680. p0.y + ny * (l + state.shape.strokewidth * state.view.scale) + nx * w / 2);
  2681. }, function(dist, nx, ny, p0, p1, pt, me)
  2682. {
  2683. var w = Math.sqrt(mxUtils.ptSegDistSq(p0.x, p0.y, p1.x, p1.y, pt.x, pt.y));
  2684. var l = mxUtils.ptLineDist(p0.x, p0.y, p0.x + ny, p0.y - nx, pt.x, pt.y);
  2685. state.style[mxConstants.STYLE_ENDSIZE] = Math.round((l - state.shape.strokewidth) * 100 / 3) / 100 / state.view.scale;
  2686. state.style['endWidth'] = Math.max(0, Math.round(w * 2) - state.shape.getEdgeWidth()) / state.view.scale;
  2687. // Applies to opposite side
  2688. if (mxEvent.isControlDown(me.getEvent()))
  2689. {
  2690. state.style[mxConstants.STYLE_STARTSIZE] = state.style[mxConstants.STYLE_ENDSIZE];
  2691. state.style['startWidth'] = state.style['endWidth'];
  2692. }
  2693. // Snaps to start geometry
  2694. if (!mxEvent.isAltDown(me.getEvent()))
  2695. {
  2696. if (Math.abs(parseFloat(state.style[mxConstants.STYLE_ENDSIZE]) - parseFloat(state.style[mxConstants.STYLE_STARTSIZE])) < tol / 6)
  2697. {
  2698. state.style[mxConstants.STYLE_ENDSIZE] = state.style[mxConstants.STYLE_STARTSIZE];
  2699. }
  2700. if (Math.abs(parseFloat(state.style['endWidth']) - parseFloat(state.style['startWidth'])) < tol)
  2701. {
  2702. state.style['endWidth'] = state.style['startWidth'];
  2703. }
  2704. }
  2705. }));
  2706. }
  2707. return handles;
  2708. },
  2709. 'swimlane': function(state)
  2710. {
  2711. var handles = [createHandle(state, [mxConstants.STYLE_STARTSIZE], function(bounds)
  2712. {
  2713. var size = parseFloat(mxUtils.getValue(state.style, mxConstants.STYLE_STARTSIZE, mxConstants.DEFAULT_STARTSIZE));
  2714. if (mxUtils.getValue(state.style, mxConstants.STYLE_HORIZONTAL, 1) == 1)
  2715. {
  2716. return new mxPoint(bounds.getCenterX(), bounds.y + Math.max(0, Math.min(bounds.height, size)));
  2717. }
  2718. else
  2719. {
  2720. return new mxPoint(bounds.x + Math.max(0, Math.min(bounds.width, size)), bounds.getCenterY());
  2721. }
  2722. }, function(bounds, pt)
  2723. {
  2724. state.style[mxConstants.STYLE_STARTSIZE] =
  2725. (mxUtils.getValue(this.state.style, mxConstants.STYLE_HORIZONTAL, 1) == 1) ?
  2726. Math.round(Math.max(0, Math.min(bounds.height, pt.y - bounds.y))) :
  2727. Math.round(Math.max(0, Math.min(bounds.width, pt.x - bounds.x)));
  2728. })];
  2729. if (mxUtils.getValue(state.style, mxConstants.STYLE_ROUNDED))
  2730. {
  2731. var size = parseFloat(mxUtils.getValue(state.style, mxConstants.STYLE_STARTSIZE, mxConstants.DEFAULT_STARTSIZE));
  2732. handles.push(createArcHandle(state, size / 2));
  2733. }
  2734. return handles;
  2735. },
  2736. 'label': createArcHandleFunction(),
  2737. 'ext': createArcHandleFunction(),
  2738. 'rectangle': createArcHandleFunction(),
  2739. 'triangle': createArcHandleFunction(),
  2740. 'rhombus': createArcHandleFunction(),
  2741. 'umlLifeline': function(state)
  2742. {
  2743. return [createHandle(state, ['size'], function(bounds)
  2744. {
  2745. var size = Math.max(0, Math.min(bounds.height, parseFloat(mxUtils.getValue(this.state.style, 'size', UmlLifeline.prototype.size))));
  2746. return new mxPoint(bounds.getCenterX(), bounds.y + size);
  2747. }, function(bounds, pt)
  2748. {
  2749. this.state.style['size'] = Math.round(Math.max(0, Math.min(bounds.height, pt.y - bounds.y)));
  2750. }, false)];
  2751. },
  2752. 'umlFrame': function(state)
  2753. {
  2754. var handles = [createHandle(state, ['width', 'height'], function(bounds)
  2755. {
  2756. var w0 = Math.max(UmlFrame.prototype.corner, Math.min(bounds.width, mxUtils.getValue(this.state.style, 'width', UmlFrame.prototype.width)));
  2757. var h0 = Math.max(UmlFrame.prototype.corner * 1.5, Math.min(bounds.height, mxUtils.getValue(this.state.style, 'height', UmlFrame.prototype.height)));
  2758. return new mxPoint(bounds.x + w0, bounds.y + h0);
  2759. }, function(bounds, pt)
  2760. {
  2761. this.state.style['width'] = Math.round(Math.max(UmlFrame.prototype.corner, Math.min(bounds.width, pt.x - bounds.x)));
  2762. this.state.style['height'] = Math.round(Math.max(UmlFrame.prototype.corner * 1.5, Math.min(bounds.height, pt.y - bounds.y)));
  2763. }, false)];
  2764. return handles;
  2765. },
  2766. 'process': function(state)
  2767. {
  2768. var handles = [createHandle(state, ['size'], function(bounds)
  2769. {
  2770. var size = Math.max(0, Math.min(0.5, parseFloat(mxUtils.getValue(this.state.style, 'size', ProcessShape.prototype.size))));
  2771. return new mxPoint(bounds.x + bounds.width * size, bounds.y + bounds.height / 4);
  2772. }, function(bounds, pt)
  2773. {
  2774. this.state.style['size'] = Math.max(0, Math.min(0.5, (pt.x - bounds.x) / bounds.width));
  2775. })];
  2776. if (mxUtils.getValue(state.style, mxConstants.STYLE_ROUNDED, false))
  2777. {
  2778. handles.push(createArcHandle(state));
  2779. }
  2780. return handles;
  2781. },
  2782. 'cross': function(state)
  2783. {
  2784. return [createHandle(state, ['size'], function(bounds)
  2785. {
  2786. var m = Math.min(bounds.width, bounds.height);
  2787. var size = Math.max(0, Math.min(1, mxUtils.getValue(this.state.style, 'size', CrossShape.prototype.size))) * m / 2;
  2788. return new mxPoint(bounds.getCenterX() - size, bounds.getCenterY() - size);
  2789. }, function(bounds, pt)
  2790. {
  2791. var m = Math.min(bounds.width, bounds.height);
  2792. this.state.style['size'] = Math.max(0, Math.min(1, Math.min((Math.max(0, bounds.getCenterY() - pt.y) / m) * 2,
  2793. (Math.max(0, bounds.getCenterX() - pt.x) / m) * 2)));
  2794. })];
  2795. },
  2796. 'note': function(state)
  2797. {
  2798. return [createHandle(state, ['size'], function(bounds)
  2799. {
  2800. var size = Math.max(0, Math.min(bounds.width, Math.min(bounds.height, parseFloat(
  2801. mxUtils.getValue(this.state.style, 'size', NoteShape.prototype.size)))));
  2802. return new mxPoint(bounds.x + bounds.width - size, bounds.y + size);
  2803. }, function(bounds, pt)
  2804. {
  2805. this.state.style['size'] = Math.round(Math.max(0, Math.min(Math.min(bounds.width, bounds.x + bounds.width - pt.x),
  2806. Math.min(bounds.height, pt.y - bounds.y))));
  2807. })];
  2808. },
  2809. 'manualInput': function(state)
  2810. {
  2811. var handles = [createHandle(state, ['size'], function(bounds)
  2812. {
  2813. var size = Math.max(0, Math.min(bounds.height, mxUtils.getValue(this.state.style, 'size', ManualInputShape.prototype.size)));
  2814. return new mxPoint(bounds.x + bounds.width / 4, bounds.y + size * 3 / 4);
  2815. }, function(bounds, pt)
  2816. {
  2817. this.state.style['size'] = Math.round(Math.max(0, Math.min(bounds.height, (pt.y - bounds.y) * 4 / 3)));
  2818. })];
  2819. if (mxUtils.getValue(state.style, mxConstants.STYLE_ROUNDED, false))
  2820. {
  2821. handles.push(createArcHandle(state));
  2822. }
  2823. return handles;
  2824. },
  2825. 'dataStorage': function(state)
  2826. {
  2827. return [createHandle(state, ['size'], function(bounds)
  2828. {
  2829. var size = Math.max(0, Math.min(1, parseFloat(mxUtils.getValue(this.state.style, 'size', DataStorageShape.prototype.size))));
  2830. return new mxPoint(bounds.x + (1 - size) * bounds.width, bounds.getCenterY());
  2831. }, function(bounds, pt)
  2832. {
  2833. this.state.style['size'] = Math.max(0, Math.min(1, (bounds.x + bounds.width - pt.x) / bounds.width));
  2834. })];
  2835. },
  2836. 'callout': function(state)
  2837. {
  2838. var handles = [createHandle(state, ['size', 'position'], function(bounds)
  2839. {
  2840. var size = Math.max(0, Math.min(bounds.height, mxUtils.getValue(this.state.style, 'size', CalloutShape.prototype.size)));
  2841. var position = Math.max(0, Math.min(1, mxUtils.getValue(this.state.style, 'position', CalloutShape.prototype.position)));
  2842. var base = Math.max(0, Math.min(bounds.width, mxUtils.getValue(this.state.style, 'base', CalloutShape.prototype.base)));
  2843. return new mxPoint(bounds.x + position * bounds.width, bounds.y + bounds.height - size);
  2844. }, function(bounds, pt)
  2845. {
  2846. var base = Math.max(0, Math.min(bounds.width, mxUtils.getValue(this.state.style, 'base', CalloutShape.prototype.base)));
  2847. this.state.style['size'] = Math.round(Math.max(0, Math.min(bounds.height, bounds.y + bounds.height - pt.y)));
  2848. this.state.style['position'] = Math.round(Math.max(0, Math.min(1, (pt.x - bounds.x) / bounds.width)) * 100) / 100;
  2849. }), createHandle(state, ['position2'], function(bounds)
  2850. {
  2851. var position2 = Math.max(0, Math.min(1, mxUtils.getValue(this.state.style, 'position2', CalloutShape.prototype.position2)));
  2852. return new mxPoint(bounds.x + position2 * bounds.width, bounds.y + bounds.height);
  2853. }, function(bounds, pt)
  2854. {
  2855. this.state.style['position2'] = Math.round(Math.max(0, Math.min(1, (pt.x - bounds.x) / bounds.width)) * 100) / 100;
  2856. }), createHandle(state, ['base'], function(bounds)
  2857. {
  2858. var size = Math.max(0, Math.min(bounds.height, mxUtils.getValue(this.state.style, 'size', CalloutShape.prototype.size)));
  2859. var position = Math.max(0, Math.min(1, mxUtils.getValue(this.state.style, 'position', CalloutShape.prototype.position)));
  2860. var base = Math.max(0, Math.min(bounds.width, mxUtils.getValue(this.state.style, 'base', CalloutShape.prototype.base)));
  2861. return new mxPoint(bounds.x + Math.min(bounds.width, position * bounds.width + base), bounds.y + bounds.height - size);
  2862. }, function(bounds, pt)
  2863. {
  2864. var position = Math.max(0, Math.min(1, mxUtils.getValue(this.state.style, 'position', CalloutShape.prototype.position)));
  2865. this.state.style['base'] = Math.round(Math.max(0, Math.min(bounds.width, pt.x - bounds.x - position * bounds.width)));
  2866. })];
  2867. if (mxUtils.getValue(state.style, mxConstants.STYLE_ROUNDED, false))
  2868. {
  2869. handles.push(createArcHandle(state));
  2870. }
  2871. return handles;
  2872. },
  2873. 'internalStorage': function(state)
  2874. {
  2875. var handles = [createHandle(state, ['dx', 'dy'], function(bounds)
  2876. {
  2877. var dx = Math.max(0, Math.min(bounds.width, mxUtils.getValue(this.state.style, 'dx', InternalStorageShape.prototype.dx)));
  2878. var dy = Math.max(0, Math.min(bounds.height, mxUtils.getValue(this.state.style, 'dy', InternalStorageShape.prototype.dy)));
  2879. return new mxPoint(bounds.x + dx, bounds.y + dy);
  2880. }, function(bounds, pt)
  2881. {
  2882. this.state.style['dx'] = Math.round(Math.max(0, Math.min(bounds.width, pt.x - bounds.x)));
  2883. this.state.style['dy'] = Math.round(Math.max(0, Math.min(bounds.height, pt.y - bounds.y)));
  2884. })];
  2885. if (mxUtils.getValue(state.style, mxConstants.STYLE_ROUNDED, false))
  2886. {
  2887. handles.push(createArcHandle(state));
  2888. }
  2889. return handles;
  2890. },
  2891. 'corner': function(state)
  2892. {
  2893. return [createHandle(state, ['dx', 'dy'], function(bounds)
  2894. {
  2895. var dx = Math.max(0, Math.min(bounds.width, mxUtils.getValue(this.state.style, 'dx', CornerShape.prototype.dx)));
  2896. var dy = Math.max(0, Math.min(bounds.height, mxUtils.getValue(this.state.style, 'dy', CornerShape.prototype.dy)));
  2897. return new mxPoint(bounds.x + dx, bounds.y + dy);
  2898. }, function(bounds, pt)
  2899. {
  2900. this.state.style['dx'] = Math.round(Math.max(0, Math.min(bounds.width, pt.x - bounds.x)));
  2901. this.state.style['dy'] = Math.round(Math.max(0, Math.min(bounds.height, pt.y - bounds.y)));
  2902. })];
  2903. },
  2904. 'tee': function(state)
  2905. {
  2906. return [createHandle(state, ['dx', 'dy'], function(bounds)
  2907. {
  2908. var dx = Math.max(0, Math.min(bounds.width, mxUtils.getValue(this.state.style, 'dx', TeeShape.prototype.dx)));
  2909. var dy = Math.max(0, Math.min(bounds.height, mxUtils.getValue(this.state.style, 'dy', TeeShape.prototype.dy)));
  2910. return new mxPoint(bounds.x + (bounds.width + dx) / 2, bounds.y + dy);
  2911. }, function(bounds, pt)
  2912. {
  2913. this.state.style['dx'] = Math.round(Math.max(0, Math.min(bounds.width / 2, (pt.x - bounds.x - bounds.width / 2)) * 2));
  2914. this.state.style['dy'] = Math.round(Math.max(0, Math.min(bounds.height, pt.y - bounds.y)));
  2915. })];
  2916. },
  2917. 'singleArrow': createArrowHandleFunction(1),
  2918. 'doubleArrow': createArrowHandleFunction(0.5),
  2919. 'folder': function(state)
  2920. {
  2921. return [createHandle(state, ['tabWidth', 'tabHeight'], function(bounds)
  2922. {
  2923. var tw = Math.max(0, Math.min(bounds.width, mxUtils.getValue(this.state.style, 'tabWidth', FolderShape.prototype.tabWidth)));
  2924. var th = Math.max(0, Math.min(bounds.height, mxUtils.getValue(this.state.style, 'tabHeight', FolderShape.prototype.tabHeight)));
  2925. if (mxUtils.getValue(this.state.style, 'tabPosition', FolderShape.prototype.tabPosition) == mxConstants.ALIGN_RIGHT)
  2926. {
  2927. tw = bounds.width - tw;
  2928. }
  2929. return new mxPoint(bounds.x + tw, bounds.y + th);
  2930. }, function(bounds, pt)
  2931. {
  2932. var tw = Math.max(0, Math.min(bounds.width, pt.x - bounds.x));
  2933. if (mxUtils.getValue(this.state.style, 'tabPosition', FolderShape.prototype.tabPosition) == mxConstants.ALIGN_RIGHT)
  2934. {
  2935. tw = bounds.width - tw;
  2936. }
  2937. this.state.style['tabWidth'] = Math.round(tw);
  2938. this.state.style['tabHeight'] = Math.round(Math.max(0, Math.min(bounds.height, pt.y - bounds.y)));
  2939. })];
  2940. },
  2941. 'document': function(state)
  2942. {
  2943. return [createHandle(state, ['size'], function(bounds)
  2944. {
  2945. var size = Math.max(0, Math.min(1, parseFloat(mxUtils.getValue(this.state.style, 'size', DocumentShape.prototype.size))));
  2946. return new mxPoint(bounds.x + 3 * bounds.width / 4, bounds.y + (1 - size) * bounds.height);
  2947. }, function(bounds, pt)
  2948. {
  2949. this.state.style['size'] = Math.max(0, Math.min(1, (bounds.y + bounds.height - pt.y) / bounds.height));
  2950. })];
  2951. },
  2952. 'tape': function(state)
  2953. {
  2954. return [createHandle(state, ['size'], function(bounds)
  2955. {
  2956. var size = Math.max(0, Math.min(1, parseFloat(mxUtils.getValue(this.state.style, 'size', TapeShape.prototype.size))));
  2957. return new mxPoint(bounds.getCenterX(), bounds.y + size * bounds.height / 2);
  2958. }, function(bounds, pt)
  2959. {
  2960. this.state.style['size'] = Math.max(0, Math.min(1, ((pt.y - bounds.y) / bounds.height) * 2));
  2961. })];
  2962. },
  2963. 'offPageConnector': function(state)
  2964. {
  2965. return [createHandle(state, ['size'], function(bounds)
  2966. {
  2967. var size = Math.max(0, Math.min(1, parseFloat(mxUtils.getValue(this.state.style, 'size', OffPageConnectorShape.prototype.size))));
  2968. return new mxPoint(bounds.getCenterX(), bounds.y + (1 - size) * bounds.height);
  2969. }, function(bounds, pt)
  2970. {
  2971. this.state.style['size'] = Math.max(0, Math.min(1, (bounds.y + bounds.height - pt.y) / bounds.height));
  2972. })];
  2973. },
  2974. 'step': createDisplayHandleFunction(StepShape.prototype.size, true, null, true, StepShape.prototype.fixedSize),
  2975. 'hexagon': createDisplayHandleFunction(HexagonShape.prototype.size, true, 0.5, true),
  2976. 'curlyBracket': createDisplayHandleFunction(CurlyBracketShape.prototype.size, false),
  2977. 'display': createDisplayHandleFunction(DisplayShape.prototype.size, false),
  2978. 'cube': createCubeHandleFunction(1, CubeShape.prototype.size, false),
  2979. 'card': createCubeHandleFunction(0.5, CardShape.prototype.size, true),
  2980. 'loopLimit': createCubeHandleFunction(0.5, LoopLimitShape.prototype.size, true),
  2981. 'trapezoid': createTrapezoidHandleFunction(0.5),
  2982. 'parallelogram': createTrapezoidHandleFunction(1)
  2983. };
  2984. // Exposes custom handles
  2985. Graph.createHandle = createHandle;
  2986. Graph.handleFactory = handleFactory;
  2987. mxVertexHandler.prototype.createCustomHandles = function()
  2988. {
  2989. // Not rotatable means locked
  2990. if (this.state.view.graph.getSelectionCount() == 1)
  2991. {
  2992. if (this.graph.isCellRotatable(this.state.cell))
  2993. // LATER: Make locked state independent of rotatable flag, fix toggle if default is false
  2994. //if (this.graph.isCellResizable(this.state.cell) || this.graph.isCellMovable(this.state.cell))
  2995. {
  2996. var name = this.state.style['shape'];
  2997. if (mxCellRenderer.defaultShapes[name] == null &&
  2998. mxStencilRegistry.getStencil(name) == null)
  2999. {
  3000. name = mxConstants.SHAPE_RECTANGLE;
  3001. }
  3002. var fn = handleFactory[name];
  3003. if (fn != null)
  3004. {
  3005. return fn(this.state);
  3006. }
  3007. }
  3008. }
  3009. return null;
  3010. };
  3011. mxEdgeHandler.prototype.createCustomHandles = function()
  3012. {
  3013. if (this.state.view.graph.getSelectionCount() == 1)
  3014. {
  3015. var name = this.state.style['shape'];
  3016. if (mxCellRenderer.defaultShapes[name] == null &&
  3017. mxStencilRegistry.getStencil(name) == null)
  3018. {
  3019. name = mxConstants.SHAPE_CONNECTOR;
  3020. }
  3021. var fn = handleFactory[name];
  3022. if (fn != null)
  3023. {
  3024. return fn(this.state);
  3025. }
  3026. }
  3027. return null;
  3028. }
  3029. }
  3030. else
  3031. {
  3032. // Dummy entries to avoid NPE in embed mode
  3033. Graph.createHandle = function() {};
  3034. Graph.handleFactory = {};
  3035. }
  3036. var isoHVector = new mxPoint(1, 0);
  3037. var isoVVector = new mxPoint(1, 0);
  3038. var alpha1 = mxUtils.toRadians(-30);
  3039. var cos1 = Math.cos(alpha1);
  3040. var sin1 = Math.sin(alpha1);
  3041. isoHVector = mxUtils.getRotatedPoint(isoHVector, cos1, sin1);
  3042. var alpha2 = mxUtils.toRadians(-150);
  3043. var cos2 = Math.cos(alpha2);
  3044. var sin2 = Math.sin(alpha2);
  3045. isoVVector = mxUtils.getRotatedPoint(isoVVector, cos2, sin2);
  3046. mxEdgeStyle.IsometricConnector = function (state, source, target, points, result)
  3047. {
  3048. var view = state.view;
  3049. var pt = (points != null && points.length > 0) ? points[0] : null;
  3050. var pts = state.absolutePoints;
  3051. var p0 = pts[0];
  3052. var pe = pts[pts.length-1];
  3053. if (pt != null)
  3054. {
  3055. pt = view.transformControlPoint(state, pt);
  3056. }
  3057. if (p0 == null)
  3058. {
  3059. if (source != null)
  3060. {
  3061. p0 = new mxPoint(source.getCenterX(), source.getCenterY());
  3062. }
  3063. }
  3064. if (pe == null)
  3065. {
  3066. if (target != null)
  3067. {
  3068. pe = new mxPoint(target.getCenterX(), target.getCenterY());
  3069. }
  3070. }
  3071. var a1 = isoHVector.x;
  3072. var a2 = isoHVector.y;
  3073. var b1 = isoVVector.x;
  3074. var b2 = isoVVector.y;
  3075. var elbow = mxUtils.getValue(state.style, 'elbow', 'horizontal') == 'horizontal';
  3076. if (pe != null && p0 != null)
  3077. {
  3078. var last = p0;
  3079. function isoLineTo(x, y, ignoreFirst)
  3080. {
  3081. var c1 = x - last.x;
  3082. var c2 = y - last.y;
  3083. // Solves for isometric base vectors
  3084. var h = (b2 * c1 - b1 * c2) / (a1 * b2 - a2 * b1);
  3085. var v = (a2 * c1 - a1 * c2) / (a2 * b1 - a1 * b2);
  3086. if (elbow)
  3087. {
  3088. if (ignoreFirst)
  3089. {
  3090. last = new mxPoint(last.x + a1 * h, last.y + a2 * h);
  3091. result.push(last);
  3092. }
  3093. last = new mxPoint(last.x + b1 * v, last.y + b2 * v);
  3094. result.push(last);
  3095. }
  3096. else
  3097. {
  3098. if (ignoreFirst)
  3099. {
  3100. last = new mxPoint(last.x + b1 * v, last.y + b2 * v);
  3101. result.push(last);
  3102. }
  3103. last = new mxPoint(last.x + a1 * h, last.y + a2 * h);
  3104. result.push(last);
  3105. }
  3106. };
  3107. if (pt == null)
  3108. {
  3109. pt = new mxPoint(p0.x + (pe.x - p0.x) / 2, p0.y + (pe.y - p0.y) / 2);
  3110. }
  3111. isoLineTo(pt.x, pt.y, true);
  3112. isoLineTo(pe.x, pe.y, false);
  3113. }
  3114. };
  3115. mxStyleRegistry.putValue('isometricEdgeStyle', mxEdgeStyle.IsometricConnector);
  3116. var graphCreateEdgeHandler = Graph.prototype.createEdgeHandler;
  3117. Graph.prototype.createEdgeHandler = function(state, edgeStyle)
  3118. {
  3119. if (edgeStyle == mxEdgeStyle.IsometricConnector)
  3120. {
  3121. var handler = new mxElbowEdgeHandler(state);
  3122. handler.snapToTerminals = false;
  3123. return handler;
  3124. }
  3125. return graphCreateEdgeHandler.apply(this, arguments);
  3126. };
  3127. // Defines connection points for all shapes
  3128. IsoRectangleShape.prototype.constraints = [];
  3129. IsoCubeShape.prototype.constraints = [];
  3130. CalloutShape.prototype.constraints = [];
  3131. mxRectangleShape.prototype.constraints = [new mxConnectionConstraint(new mxPoint(0.25, 0), true),
  3132. new mxConnectionConstraint(new mxPoint(0.5, 0), true),
  3133. new mxConnectionConstraint(new mxPoint(0.75, 0), true),
  3134. new mxConnectionConstraint(new mxPoint(0, 0.25), true),
  3135. new mxConnectionConstraint(new mxPoint(0, 0.5), true),
  3136. new mxConnectionConstraint(new mxPoint(0, 0.75), true),
  3137. new mxConnectionConstraint(new mxPoint(1, 0.25), true),
  3138. new mxConnectionConstraint(new mxPoint(1, 0.5), true),
  3139. new mxConnectionConstraint(new mxPoint(1, 0.75), true),
  3140. new mxConnectionConstraint(new mxPoint(0.25, 1), true),
  3141. new mxConnectionConstraint(new mxPoint(0.5, 1), true),
  3142. new mxConnectionConstraint(new mxPoint(0.75, 1), true)];
  3143. mxEllipse.prototype.constraints = [new mxConnectionConstraint(new mxPoint(0, 0), true), new mxConnectionConstraint(new mxPoint(1, 0), true),
  3144. new mxConnectionConstraint(new mxPoint(0, 1), true), new mxConnectionConstraint(new mxPoint(1, 1), true),
  3145. new mxConnectionConstraint(new mxPoint(0.5, 0), true), new mxConnectionConstraint(new mxPoint(0.5, 1), true),
  3146. new mxConnectionConstraint(new mxPoint(0, 0.5), true), new mxConnectionConstraint(new mxPoint(1, 0.5))];
  3147. mxLabel.prototype.constraints = mxRectangleShape.prototype.constraints;
  3148. mxImageShape.prototype.constraints = mxRectangleShape.prototype.constraints;
  3149. mxSwimlane.prototype.constraints = mxRectangleShape.prototype.constraints;
  3150. PlusShape.prototype.constraints = mxRectangleShape.prototype.constraints;
  3151. NoteShape.prototype.constraints = mxRectangleShape.prototype.constraints;
  3152. CardShape.prototype.constraints = mxRectangleShape.prototype.constraints;
  3153. CubeShape.prototype.constraints = mxRectangleShape.prototype.constraints;
  3154. FolderShape.prototype.constraints = mxRectangleShape.prototype.constraints;
  3155. InternalStorageShape.prototype.constraints = mxRectangleShape.prototype.constraints;
  3156. DataStorageShape.prototype.constraints = mxRectangleShape.prototype.constraints;
  3157. TapeDataShape.prototype.constraints = mxEllipse.prototype.constraints;
  3158. OrEllipseShape.prototype.constraints = mxEllipse.prototype.constraints;
  3159. SumEllipseShape.prototype.constraints = mxEllipse.prototype.constraints;
  3160. LineEllipseShape.prototype.constraints = mxEllipse.prototype.constraints;
  3161. ManualInputShape.prototype.constraints = mxRectangleShape.prototype.constraints;
  3162. DelayShape.prototype.constraints = mxRectangleShape.prototype.constraints;
  3163. DisplayShape.prototype.constraints = mxRectangleShape.prototype.constraints;
  3164. LoopLimitShape.prototype.constraints = mxRectangleShape.prototype.constraints;
  3165. OffPageConnectorShape.prototype.constraints = mxRectangleShape.prototype.constraints;
  3166. mxCylinder.prototype.constraints = [new mxConnectionConstraint(new mxPoint(0.15, 0.05), false),
  3167. new mxConnectionConstraint(new mxPoint(0.5, 0), true),
  3168. new mxConnectionConstraint(new mxPoint(0.85, 0.05), false),
  3169. new mxConnectionConstraint(new mxPoint(0, 0.3), true),
  3170. new mxConnectionConstraint(new mxPoint(0, 0.5), true),
  3171. new mxConnectionConstraint(new mxPoint(0, 0.7), true),
  3172. new mxConnectionConstraint(new mxPoint(1, 0.3), true),
  3173. new mxConnectionConstraint(new mxPoint(1, 0.5), true),
  3174. new mxConnectionConstraint(new mxPoint(1, 0.7), true),
  3175. new mxConnectionConstraint(new mxPoint(0.15, 0.95), false),
  3176. new mxConnectionConstraint(new mxPoint(0.5, 1), true),
  3177. new mxConnectionConstraint(new mxPoint(0.85, 0.95), false)];
  3178. UmlActorShape.prototype.constraints = [new mxConnectionConstraint(new mxPoint(0.25, 0.1), false),
  3179. new mxConnectionConstraint(new mxPoint(0.5, 0), false),
  3180. new mxConnectionConstraint(new mxPoint(0.75, 0.1), false),
  3181. new mxConnectionConstraint(new mxPoint(0, 1/3), false),
  3182. new mxConnectionConstraint(new mxPoint(0, 1), false),
  3183. new mxConnectionConstraint(new mxPoint(1, 1/3), false),
  3184. new mxConnectionConstraint(new mxPoint(1, 1), false),
  3185. new mxConnectionConstraint(new mxPoint(0.5, 0.5), false)];
  3186. ComponentShape.prototype.constraints = [new mxConnectionConstraint(new mxPoint(0.25, 0), true),
  3187. new mxConnectionConstraint(new mxPoint(0.5, 0), true),
  3188. new mxConnectionConstraint(new mxPoint(0.75, 0), true),
  3189. new mxConnectionConstraint(new mxPoint(0, 0.3), true),
  3190. new mxConnectionConstraint(new mxPoint(0, 0.7), true),
  3191. new mxConnectionConstraint(new mxPoint(1, 0.25), true),
  3192. new mxConnectionConstraint(new mxPoint(1, 0.5), true),
  3193. new mxConnectionConstraint(new mxPoint(1, 0.75), true),
  3194. new mxConnectionConstraint(new mxPoint(0.25, 1), true),
  3195. new mxConnectionConstraint(new mxPoint(0.5, 1), true),
  3196. new mxConnectionConstraint(new mxPoint(0.75, 1), true)];
  3197. mxActor.prototype.constraints = [new mxConnectionConstraint(new mxPoint(0.5, 0), true),
  3198. new mxConnectionConstraint(new mxPoint(0.25, 0.2), false),
  3199. new mxConnectionConstraint(new mxPoint(0.1, 0.5), false),
  3200. new mxConnectionConstraint(new mxPoint(0, 0.75), true),
  3201. new mxConnectionConstraint(new mxPoint(0.75, 0.25), false),
  3202. new mxConnectionConstraint(new mxPoint(0.9, 0.5), false),
  3203. new mxConnectionConstraint(new mxPoint(1, 0.75), true),
  3204. new mxConnectionConstraint(new mxPoint(0.25, 1), true),
  3205. new mxConnectionConstraint(new mxPoint(0.5, 1), true),
  3206. new mxConnectionConstraint(new mxPoint(0.75, 1), true)];
  3207. SwitchShape.prototype.constraints = [new mxConnectionConstraint(new mxPoint(0, 0), false),
  3208. new mxConnectionConstraint(new mxPoint(0.5, 0.25), false),
  3209. new mxConnectionConstraint(new mxPoint(1, 0), false),
  3210. new mxConnectionConstraint(new mxPoint(0.25, 0.5), false),
  3211. new mxConnectionConstraint(new mxPoint(0.75, 0.5), false),
  3212. new mxConnectionConstraint(new mxPoint(0, 1), false),
  3213. new mxConnectionConstraint(new mxPoint(0.5, 0.75), false),
  3214. new mxConnectionConstraint(new mxPoint(1, 1), false)];
  3215. TapeShape.prototype.constraints = [new mxConnectionConstraint(new mxPoint(0, 0.35), false),
  3216. new mxConnectionConstraint(new mxPoint(0, 0.5), false),
  3217. new mxConnectionConstraint(new mxPoint(0, 0.65), false),
  3218. new mxConnectionConstraint(new mxPoint(1, 0.35), false),
  3219. new mxConnectionConstraint(new mxPoint(1, 0.5), false),
  3220. new mxConnectionConstraint(new mxPoint(1, 0.65), false),
  3221. new mxConnectionConstraint(new mxPoint(0.25, 1), false),
  3222. new mxConnectionConstraint(new mxPoint(0.75, 0), false)];
  3223. StepShape.prototype.constraints = [new mxConnectionConstraint(new mxPoint(0.25, 0), true),
  3224. new mxConnectionConstraint(new mxPoint(0.5, 0), true),
  3225. new mxConnectionConstraint(new mxPoint(0.75, 0), true),
  3226. new mxConnectionConstraint(new mxPoint(0.25, 1), true),
  3227. new mxConnectionConstraint(new mxPoint(0.5, 1), true),
  3228. new mxConnectionConstraint(new mxPoint(0.75, 1), true),
  3229. new mxConnectionConstraint(new mxPoint(0, 0.25), true),
  3230. new mxConnectionConstraint(new mxPoint(0, 0.5), true),
  3231. new mxConnectionConstraint(new mxPoint(0, 0.75), true),
  3232. new mxConnectionConstraint(new mxPoint(1, 0.25), true),
  3233. new mxConnectionConstraint(new mxPoint(1, 0.5), true),
  3234. new mxConnectionConstraint(new mxPoint(1, 0.75), true)];
  3235. mxLine.prototype.constraints = [new mxConnectionConstraint(new mxPoint(0, 0.5), false),
  3236. new mxConnectionConstraint(new mxPoint(0.25, 0.5), false),
  3237. new mxConnectionConstraint(new mxPoint(0.75, 0.5), false),
  3238. new mxConnectionConstraint(new mxPoint(1, 0.5), false)];
  3239. LollipopShape.prototype.constraints = [new mxConnectionConstraint(new mxPoint(0.5, 0), false),
  3240. new mxConnectionConstraint(new mxPoint(0.5, 1), false)];
  3241. mxDoubleEllipse.prototype.constraints = mxEllipse.prototype.constraints;
  3242. mxRhombus.prototype.constraints = mxEllipse.prototype.constraints;
  3243. mxTriangle.prototype.constraints = [new mxConnectionConstraint(new mxPoint(0, 0.25), true),
  3244. new mxConnectionConstraint(new mxPoint(0, 0.5), true),
  3245. new mxConnectionConstraint(new mxPoint(0, 0.75), true),
  3246. new mxConnectionConstraint(new mxPoint(0.5, 0), true),
  3247. new mxConnectionConstraint(new mxPoint(0.5, 1), true),
  3248. new mxConnectionConstraint(new mxPoint(1, 0.5), true)];
  3249. mxHexagon.prototype.constraints = [new mxConnectionConstraint(new mxPoint(0.375, 0), true),
  3250. new mxConnectionConstraint(new mxPoint(0.5, 0), true),
  3251. new mxConnectionConstraint(new mxPoint(0.625, 0), true),
  3252. new mxConnectionConstraint(new mxPoint(0, 0.25), true),
  3253. new mxConnectionConstraint(new mxPoint(0, 0.5), true),
  3254. new mxConnectionConstraint(new mxPoint(0, 0.75), true),
  3255. new mxConnectionConstraint(new mxPoint(1, 0.25), true),
  3256. new mxConnectionConstraint(new mxPoint(1, 0.5), true),
  3257. new mxConnectionConstraint(new mxPoint(1, 0.75), true),
  3258. new mxConnectionConstraint(new mxPoint(0.375, 1), true),
  3259. new mxConnectionConstraint(new mxPoint(0.5, 1), true),
  3260. new mxConnectionConstraint(new mxPoint(0.625, 1), true)];
  3261. mxCloud.prototype.constraints = [new mxConnectionConstraint(new mxPoint(0.25, 0.25), false),
  3262. new mxConnectionConstraint(new mxPoint(0.4, 0.1), false),
  3263. new mxConnectionConstraint(new mxPoint(0.16, 0.55), false),
  3264. new mxConnectionConstraint(new mxPoint(0.07, 0.4), false),
  3265. new mxConnectionConstraint(new mxPoint(0.31, 0.8), false),
  3266. new mxConnectionConstraint(new mxPoint(0.13, 0.77), false),
  3267. new mxConnectionConstraint(new mxPoint(0.8, 0.8), false),
  3268. new mxConnectionConstraint(new mxPoint(0.55, 0.95), false),
  3269. new mxConnectionConstraint(new mxPoint(0.875, 0.5), false),
  3270. new mxConnectionConstraint(new mxPoint(0.96, 0.7), false),
  3271. new mxConnectionConstraint(new mxPoint(0.625, 0.2), false),
  3272. new mxConnectionConstraint(new mxPoint(0.88, 0.25), false)];
  3273. ParallelogramShape.prototype.constraints = mxRectangleShape.prototype.constraints;
  3274. TrapezoidShape.prototype.constraints = mxRectangleShape.prototype.constraints;
  3275. DocumentShape.prototype.constraints = [new mxConnectionConstraint(new mxPoint(0.25, 0), true),
  3276. new mxConnectionConstraint(new mxPoint(0.5, 0), true),
  3277. new mxConnectionConstraint(new mxPoint(0.75, 0), true),
  3278. new mxConnectionConstraint(new mxPoint(0, 0.25), true),
  3279. new mxConnectionConstraint(new mxPoint(0, 0.5), true),
  3280. new mxConnectionConstraint(new mxPoint(0, 0.75), true),
  3281. new mxConnectionConstraint(new mxPoint(1, 0.25), true),
  3282. new mxConnectionConstraint(new mxPoint(1, 0.5), true),
  3283. new mxConnectionConstraint(new mxPoint(1, 0.75), true)];
  3284. mxArrow.prototype.constraints = null;
  3285. TeeShape.prototype.constraints = null;
  3286. CornerShape.prototype.constraints = null;
  3287. CrossbarShape.prototype.constraints = [new mxConnectionConstraint(new mxPoint(0, 0), false),
  3288. new mxConnectionConstraint(new mxPoint(0, 0.5), false),
  3289. new mxConnectionConstraint(new mxPoint(0, 1), false),
  3290. new mxConnectionConstraint(new mxPoint(0.25, 0.5), false),
  3291. new mxConnectionConstraint(new mxPoint(0.5, 0.5), false),
  3292. new mxConnectionConstraint(new mxPoint(0.75, 0.5), false),
  3293. new mxConnectionConstraint(new mxPoint(1, 0), false),
  3294. new mxConnectionConstraint(new mxPoint(1, 0.5), false),
  3295. new mxConnectionConstraint(new mxPoint(1, 1), false)];
  3296. SingleArrowShape.prototype.constraints = [new mxConnectionConstraint(new mxPoint(0, 0.5), false),
  3297. new mxConnectionConstraint(new mxPoint(1, 0.5), false)];
  3298. DoubleArrowShape.prototype.constraints = [new mxConnectionConstraint(new mxPoint(0, 0.5), false),
  3299. new mxConnectionConstraint(new mxPoint(1, 0.5), false)];
  3300. CrossShape.prototype.constraints = [new mxConnectionConstraint(new mxPoint(0, 0.5), false),
  3301. new mxConnectionConstraint(new mxPoint(1, 0.5), false),
  3302. new mxConnectionConstraint(new mxPoint(0.5, 0), false),
  3303. new mxConnectionConstraint(new mxPoint(0.5, 1), false)];
  3304. UmlLifeline.prototype.constraints = null;
  3305. OrShape.prototype.constraints = [new mxConnectionConstraint(new mxPoint(0, 0.25), false),
  3306. new mxConnectionConstraint(new mxPoint(0, 0.5), false),
  3307. new mxConnectionConstraint(new mxPoint(0, 0.75), false),
  3308. new mxConnectionConstraint(new mxPoint(1, 0.5), false),
  3309. new mxConnectionConstraint(new mxPoint(0.7, 0.1), false),
  3310. new mxConnectionConstraint(new mxPoint(0.7, 0.9), false)];
  3311. XorShape.prototype.constraints = [new mxConnectionConstraint(new mxPoint(0.175, 0.25), false),
  3312. new mxConnectionConstraint(new mxPoint(0.25, 0.5), false),
  3313. new mxConnectionConstraint(new mxPoint(0.175, 0.75), false),
  3314. new mxConnectionConstraint(new mxPoint(1, 0.5), false),
  3315. new mxConnectionConstraint(new mxPoint(0.7, 0.1), false),
  3316. new mxConnectionConstraint(new mxPoint(0.7, 0.9), false)];
  3317. })();