Shapes.js 104 KB

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