1/**
2 * $Id: mxER.js,v 1.6 2013/05/17 13:46:41 mate Exp $
3 * Copyright (c) 2006-2010, JGraph Ltd
4 */
5
6//TODO markers.html probably isn't needed, because it was used for testing during development before the new canvas was introduced
7
8//**********************************************************************************************************************************************************
9//Entity
10//**********************************************************************************************************************************************************
11/**
12 * Extends mxShape.
13 */
14function mxShapeEREntity(bounds, fill, stroke, strokewidth)
15{
16	mxShape.call(this);
17	this.bounds = bounds;
18	this.fill = fill;
19	this.stroke = stroke;
20	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
21};
22
23/**
24 * Extends mxShape.
25 */
26mxUtils.extend(mxShapeEREntity, mxShape);
27
28/**
29 * Function: paintVertexShape
30 *
31 * Paints the vertex shape.
32 */
33mxShapeEREntity.prototype.paintVertexShape = function(c, x, y, w, h)
34{
35	var mainText = mxUtils.getValue(this.style, 'buttonText', 'Entity');
36	var fontColor = mxUtils.getValue(this.style, 'textColor', '#666666');
37	var fontSize = mxUtils.getValue(this.style, mxConstants.STYLE_FONTSIZE, '17');
38	c.translate(x, y);
39	var rSize = 10;
40	w = Math.max(w, 2 * rSize);
41	h = Math.max(h, 2 * rSize);
42	this.background(c, x, y, w, h, rSize, fontColor);
43	c.setShadow(false);
44	this.mainText(c, x, y, w, h, mainText, fontSize, fontColor);
45};
46
47mxShapeEREntity.prototype.background = function(c, x, y, w, h, rSize, fontColor)
48{
49	var buttonStyle = mxUtils.getValue(this.style, 'buttonStyle', 'round').toString();
50
51	if (buttonStyle === 'round')
52	{
53		c.begin();
54		c.moveTo(0, rSize);
55		c.arcTo(rSize, rSize, 0, 0, 1, rSize, 0);
56		c.lineTo(w - rSize, 0);
57		c.arcTo(rSize, rSize, 0, 0, 1, w, rSize);
58		c.lineTo(w, h - rSize);
59		c.arcTo(rSize, rSize, 0, 0, 1, w - rSize, h);
60		c.lineTo(rSize, h);
61		c.arcTo(rSize, rSize, 0, 0, 1, 0, h - rSize);
62		c.close();
63		c.fillAndStroke();
64	}
65	else if (buttonStyle === 'rect')
66	{
67		c.begin();
68		c.moveTo(0, 0);
69		c.lineTo(w, 0);
70		c.lineTo(w, h);
71		c.lineTo(0, h);
72		c.close();
73		c.fillAndStroke();
74	}
75	else if (buttonStyle === 'dblFrame')
76	{
77		var fillColor = mxUtils.getValue(this.style, mxConstants.STYLE_FILLCOLOR, '#ffffff');
78		c.setFillColor(fillColor);
79		c.begin();
80		c.moveTo(0, 0);
81		c.lineTo(w, 0);
82		c.lineTo(w, h);
83		c.lineTo(0, h);
84		c.close();
85		c.fillAndStroke();
86		rSize = Math.min(w, h);
87		c.begin();
88		c.moveTo(rSize * 0.1, rSize * 0.1);
89		c.lineTo(w - rSize * 0.1, rSize * 0.1);
90		c.lineTo(w - rSize * 0.1, h - rSize * 0.1);
91		c.lineTo(rSize * 0.1, h - rSize * 0.1);
92		c.close();
93		c.stroke();
94	}
95
96};
97
98mxShapeEREntity.prototype.mainText = function(c, x, y, w, h, text, fontSize, fontColor)
99{
100	c.begin();
101	c.setFontSize(fontSize);
102	c.setFontColor(fontColor);
103	c.text(w * 0.5, h * 0.5, 0, 0, text, mxConstants.ALIGN_CENTER, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
104};
105
106mxCellRenderer.registerShape('mxgraph.er.entity', mxShapeEREntity);
107
108mxShapeEREntity.prototype.constraints = [
109                                           new mxConnectionConstraint(new mxPoint(0.25, 0), true),
110                                           new mxConnectionConstraint(new mxPoint(0.5, 0), true),
111                                           new mxConnectionConstraint(new mxPoint(0.75, 0), true),
112                                           new mxConnectionConstraint(new mxPoint(0, 0.25), true),
113                                           new mxConnectionConstraint(new mxPoint(0, 0.5), true),
114                                           new mxConnectionConstraint(new mxPoint(0, 0.75), true),
115                                           new mxConnectionConstraint(new mxPoint(1, 0.25), true),
116                                           new mxConnectionConstraint(new mxPoint(1, 0.5), true),
117                                           new mxConnectionConstraint(new mxPoint(1, 0.75), true),
118                                           new mxConnectionConstraint(new mxPoint(0.25, 1), true),
119                                           new mxConnectionConstraint(new mxPoint(0.5, 1), true),
120                                           new mxConnectionConstraint(new mxPoint(0.75, 1), true)
121                                           ];
122
123//**********************************************************************************************************************************************************
124//Entity Extended
125//**********************************************************************************************************************************************************
126/**
127 * Extends mxShape.
128 */
129function mxShapeEREntityExt(bounds, fill, stroke, strokewidth)
130{
131	mxShape.call(this);
132	this.bounds = bounds;
133	this.fill = fill;
134	this.stroke = stroke;
135	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
136};
137
138/**
139 * Extends mxShape.
140 */
141mxUtils.extend(mxShapeEREntityExt, mxShape);
142
143/**
144 * Function: paintVertexShape
145 *
146 * Paints the vertex shape.
147 */
148mxShapeEREntityExt.prototype.paintVertexShape = function(c, x, y, w, h)
149{
150	var mainText = mxUtils.getValue(this.style, 'buttonText', 'Entity');
151	var attributes = mxUtils.getValue(this.style, 'subText', '+ attribute 1,+ attribute 2,+ attribute 3').toString().split(',');
152	var strokeColor = mxUtils.getValue(this.style, mxConstants.STYLE_STROKECOLOR, '#666666');
153	var fontSize = mxUtils.getValue(this.style, mxConstants.STYLE_FONTSIZE, '17');
154	var mainColor = mxUtils.getValue(this.style, mxConstants.STYLE_FILLCOLOR, '#008cff');
155	var attrColor = mxUtils.getValue(this.style, 'fillColor2', '#ffffff');
156	var maxTextWidth = 0;
157	c.translate(x, y);
158	var rSize = 10;
159	var barY = fontSize * 1.25;
160
161	for (var i = 0; i < attributes.length; i++)
162	{
163		var currWidth = mxUtils.getSizeForString(attributes[i], fontSize, mxConstants.DEFAULT_FONTFAMILY).width;
164
165		if (currWidth > maxTextWidth)
166		{
167			maxTextWidth = currWidth;
168		}
169	}
170
171	w = Math.max(w, 2 * rSize, maxTextWidth + rSize);
172	h = Math.max(h, 2 * rSize, (attributes.length + 1) * barY);
173	this.background(c, x, y, w, h, rSize);
174	c.setShadow(false);
175	this.shapes(c, x, y, w, h, fontSize, mainColor, attrColor, rSize, barY);
176	this.mainText(c, x, y, w, h, mainText, fontSize, attrColor);
177	this.attrText(c, x, y, w, h, attributes, fontSize, strokeColor, barY, rSize);
178};
179
180mxShapeEREntityExt.prototype.background = function(c, x, y, w, h, rSize)
181{
182	var buttonStyle = mxUtils.getValue(this.style, 'buttonStyle', 'round').toString();
183	c.begin();
184
185	if (buttonStyle === 'round')
186	{
187		c.moveTo(0, rSize);
188		c.arcTo(rSize, rSize, 0, 0, 1, rSize, 0);
189		c.lineTo(w - rSize, 0);
190		c.arcTo(rSize, rSize, 0, 0, 1, w, rSize);
191		c.lineTo(w, h - rSize);
192		c.arcTo(rSize, rSize, 0, 0, 1, w - rSize, h);
193		c.lineTo(rSize, h);
194		c.arcTo(rSize, rSize, 0, 0, 1, 0, h - rSize);
195	}
196	else if (buttonStyle === 'rect')
197	{
198		c.moveTo(0, 0);
199		c.lineTo(w, 0);
200		c.lineTo(w, h);
201		c.lineTo(0, h);
202	}
203
204	c.close();
205	c.fillAndStroke();
206};
207
208mxShapeEREntityExt.prototype.mainText = function(c, x, y, w, h, text, fontSize, fontColor)
209{
210	c.begin();
211	c.setFontSize(fontSize);
212	c.setFontColor(fontColor);
213	c.text(w * 0.5, fontSize * 0.5, 0, 0, text, mxConstants.ALIGN_CENTER, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
214};
215
216mxShapeEREntityExt.prototype.shapes = function(c, x, y, w, h, fontSize, mainColor, attrColor, rSize, barY)
217{
218	var buttonStyle = mxUtils.getValue(this.style, 'buttonStyle', 'round').toString();
219
220	if (buttonStyle === 'round')
221	{
222		c.begin();
223		c.moveTo(0, rSize);
224		c.arcTo(rSize, rSize, 0, 0, 1, rSize, 0);
225		c.lineTo(w - rSize, 0);
226		c.arcTo(rSize, rSize, 0, 0, 1, w, rSize);
227		c.lineTo(w, barY);
228		c.lineTo(0, barY);
229		c.close();
230		c.fill();
231
232		c.setFillColor(attrColor);
233		c.begin();
234		c.moveTo(w, barY);
235		c.lineTo(w, h - rSize);
236		c.arcTo(rSize, rSize, 0, 0, 1, w - rSize, h);
237		c.lineTo(rSize, h);
238		c.arcTo(rSize, rSize, 0, 0, 1, 0, h - rSize);
239		c.lineTo(0, barY);
240		c.close();
241		c.fill();
242	}
243	else if (buttonStyle === 'rect')
244	{
245		c.begin();
246		c.moveTo(0, 0);
247		c.lineTo(w, 0);
248		c.lineTo(w, barY);
249		c.lineTo(0, barY);
250		c.close();
251		c.fill();
252
253		c.setFillColor(attrColor);
254		c.begin();
255		c.moveTo(0, barY);
256		c.lineTo(w, barY);
257		c.lineTo(w, h);
258		c.lineTo(0, h);
259		c.close();
260		c.fill();
261	}
262
263	c.begin();
264
265	if (buttonStyle === 'round')
266	{
267		c.moveTo(0, rSize);
268		c.arcTo(rSize, rSize, 0, 0, 1, rSize, 0);
269		c.lineTo(w - rSize, 0);
270		c.arcTo(rSize, rSize, 0, 0, 1, w, rSize);
271		c.lineTo(w, h - rSize);
272		c.arcTo(rSize, rSize, 0, 0, 1, w - rSize, h);
273		c.lineTo(rSize, h);
274		c.arcTo(rSize, rSize, 0, 0, 1, 0, h - rSize);
275	}
276	else if (buttonStyle === 'rect')
277	{
278		c.moveTo(0, 0);
279		c.lineTo(w, 0);
280		c.lineTo(w, h);
281		c.lineTo(0, h);
282	}
283
284	c.close();
285	c.stroke();
286};
287
288mxShapeEREntityExt.prototype.attrText = function(c, x, y, w, h, attributes, fontSize, fontColor, barY, rSize)
289{
290	for (var i = 0; i < attributes.length; i++)
291	{
292		c.begin();
293		c.setFontSize(fontSize);
294		c.setFontColor(fontColor);
295		c.text(rSize * 0.5, (i + 1.5) * barY, 0, 0, attributes[i], mxConstants.ALIGN_LEFT, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
296	}
297};
298
299mxCellRenderer.registerShape('mxgraph.er.entityExt', mxShapeEREntityExt);
300
301mxShapeEREntityExt.prototype.constraints = [
302                                         new mxConnectionConstraint(new mxPoint(0.25, 0), true),
303                                         new mxConnectionConstraint(new mxPoint(0.5, 0), true),
304                                         new mxConnectionConstraint(new mxPoint(0.75, 0), true),
305                                         new mxConnectionConstraint(new mxPoint(0, 0.25), true),
306                                         new mxConnectionConstraint(new mxPoint(0, 0.5), true),
307                                         new mxConnectionConstraint(new mxPoint(0, 0.75), true),
308                                         new mxConnectionConstraint(new mxPoint(1, 0.25), true),
309                                         new mxConnectionConstraint(new mxPoint(1, 0.5), true),
310                                         new mxConnectionConstraint(new mxPoint(1, 0.75), true),
311                                         new mxConnectionConstraint(new mxPoint(0.25, 1), true),
312                                         new mxConnectionConstraint(new mxPoint(0.5, 1), true),
313                                         new mxConnectionConstraint(new mxPoint(0.75, 1), true)
314                                         ];
315
316//**********************************************************************************************************************************************************
317//Attribute
318//**********************************************************************************************************************************************************
319/**
320 * Extends mxShape.
321 */
322function mxShapeERAttribute(bounds, fill, stroke, strokewidth)
323{
324	mxShape.call(this);
325	this.bounds = bounds;
326	this.fill = fill;
327	this.stroke = stroke;
328	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
329};
330
331/**
332 * Extends mxShape.
333 */
334mxUtils.extend(mxShapeERAttribute, mxShape);
335
336/**
337 * Function: paintVertexShape
338 *
339 * Paints the vertex shape.
340 */
341mxShapeERAttribute.prototype.paintVertexShape = function(c, x, y, w, h)
342{
343	var mainText = mxUtils.getValue(this.style, 'buttonText', 'Entity');
344	var fontColor = mxUtils.getValue(this.style, 'textColor', '#666666');
345	var fontSize = mxUtils.getValue(this.style, mxConstants.STYLE_FONTSIZE, '17');
346	c.translate(x, y);
347	var rSize = 10;
348	w = Math.max(w, 2 * rSize);
349	h = Math.max(h, 2 * rSize);
350	this.background(c, x, y, w, h, rSize, fontColor);
351	c.setShadow(false);
352	this.mainText(c, x, y, w, h, mainText, fontSize, fontColor);
353};
354
355mxShapeERAttribute.prototype.background = function(c, x, y, w, h, rSize, fontColor)
356{
357	var buttonStyle = mxUtils.getValue(this.style, 'buttonStyle', 'simple').toString();
358
359	if (buttonStyle === 'simple')
360	{
361		c.begin();
362		c.ellipse(0, 0, w, h);
363		c.fillAndStroke();
364	}
365	else if (buttonStyle === 'dblFrame')
366	{
367		var fillColor = mxUtils.getValue(this.style, mxConstants.STYLE_FILLCOLOR, '#666666');
368		c.setFillColor(fillColor);
369		c.begin();
370		c.ellipse(0, 0, w, h);
371		c.fillAndStroke();
372		rSize = Math.min(w, h);
373		c.begin();
374		c.ellipse(rSize * 0.1, rSize * 0.1, w - rSize * 0.2, h - rSize * 0.2);
375		c.stroke();
376	}
377};
378
379mxShapeERAttribute.prototype.mainText = function(c, x, y, w, h, text, fontSize, fontColor)
380{
381	c.begin();
382	c.setFontSize(fontSize);
383	c.setFontColor(fontColor);
384	c.text(w * 0.5, h * 0.5, 0, 0, text, mxConstants.ALIGN_CENTER, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
385};
386
387mxCellRenderer.registerShape('mxgraph.er.attribute', mxShapeERAttribute);
388
389mxShapeERAttribute.prototype.constraints = [
390                                                 new mxConnectionConstraint(new mxPoint(0.144, 0.144), false),
391                                                 new mxConnectionConstraint(new mxPoint(0.856, 0.144), false),
392                                                 new mxConnectionConstraint(new mxPoint(0.856, 0.856), false),
393                                                 new mxConnectionConstraint(new mxPoint(0.144, 0.856), false),
394                                                 new mxConnectionConstraint(new mxPoint(0, 0.5), true),
395                                                 new mxConnectionConstraint(new mxPoint(1, 0.5), true),
396                                                 new mxConnectionConstraint(new mxPoint(0.5, 0), true),
397                                                 new mxConnectionConstraint(new mxPoint(0.5, 1), true)
398                                                 ];
399
400//**********************************************************************************************************************************************************
401//Has
402//**********************************************************************************************************************************************************
403/**
404 * Extends mxShape.
405 */
406function mxShapeERHas(bounds, fill, stroke, strokewidth)
407{
408	mxShape.call(this);
409	this.bounds = bounds;
410	this.fill = fill;
411	this.stroke = stroke;
412	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
413};
414
415/**
416 * Extends mxShape.
417 */
418mxUtils.extend(mxShapeERHas, mxShape);
419
420/**
421 * Function: paintVertexShape
422 *
423 * Paints the vertex shape.
424 */
425mxShapeERHas.prototype.paintVertexShape = function(c, x, y, w, h)
426{
427	var mainText = mxUtils.getValue(this.style, 'buttonText', 'Entity');
428	var fontColor = mxUtils.getValue(this.style, 'textColor', '#666666');
429	var fontSize = mxUtils.getValue(this.style, mxConstants.STYLE_FONTSIZE, '17');
430	c.translate(x, y);
431	var rSize = 10;
432	w = Math.max(w, 2 * rSize);
433	h = Math.max(h, 2 * rSize);
434	this.background(c, x, y, w, h, rSize, fontColor);
435	c.setShadow(false);
436	this.mainText(c, x, y, w, h, mainText, fontSize, fontColor);
437};
438
439mxShapeERHas.prototype.background = function(c, x, y, w, h, rSize, fontColor)
440{
441	var buttonStyle = mxUtils.getValue(this.style, 'buttonStyle', 'rhombus').toString();
442
443	if (buttonStyle === 'rhombus')
444	{
445		c.begin();
446		c.moveTo(0, h * 0.5);
447		c.lineTo(w * 0.5, 0);
448		c.lineTo(w, h * 0.5);
449		c.lineTo(w * 0.5, h);
450		c.close();
451		c.fillAndStroke();
452	}
453	else if (buttonStyle === 'dblFrame')
454	{
455		var fillColor = mxUtils.getValue(this.style, mxConstants.STYLE_FILLCOLOR, '#666666');
456		c.setFillColor(fillColor);
457		c.begin();
458		c.moveTo(0, h * 0.5);
459		c.lineTo(w * 0.5, 0);
460		c.lineTo(w, h * 0.5);
461		c.lineTo(w * 0.5, h);
462		c.close();
463		c.fillAndStroke();
464		c.begin();
465		c.moveTo(w * 0.1, h * 0.5);
466		c.lineTo(w * 0.5, h * 0.1);
467		c.lineTo(w * 0.9, h * 0.5);
468		c.lineTo(w * 0.5, h * 0.9);
469		c.close();
470		c.stroke();
471	}
472};
473
474mxShapeERHas.prototype.mainText = function(c, x, y, w, h, text, fontSize, fontColor)
475{
476	c.begin();
477	c.setFontSize(fontSize);
478	c.setFontColor(fontColor);
479	c.text(w * 0.5, h * 0.5, 0, 0, text, mxConstants.ALIGN_CENTER, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
480};
481
482mxCellRenderer.registerShape('mxgraph.er.has', mxShapeERHas);
483
484mxShapeERHas.prototype.constraints = [
485                                      new mxConnectionConstraint(new mxPoint(0.5, 0), true),
486                                      new mxConnectionConstraint(new mxPoint(0.5, 1), true),
487                                      new mxConnectionConstraint(new mxPoint(0, 0.5), true),
488                                      new mxConnectionConstraint(new mxPoint(1, 0.5), true),
489                                      new mxConnectionConstraint(new mxPoint(0.25, 0.25), false),
490                                      new mxConnectionConstraint(new mxPoint(0.25, 0.75), false),
491                                      new mxConnectionConstraint(new mxPoint(0.75, 0.25), false),
492                                      new mxConnectionConstraint(new mxPoint(0.75, 0.75), false)
493                                      ];
494
495//**********************************************************************************************************************************************************
496//Cloud
497//**********************************************************************************************************************************************************
498/**
499 * Extends mxShape.
500 */
501function mxShapeERCloud(bounds, fill, stroke, strokewidth)
502{
503	mxShape.call(this);
504	this.bounds = bounds;
505	this.fill = fill;
506	this.stroke = stroke;
507	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
508};
509
510/**
511 * Extends mxShape.
512 */
513mxUtils.extend(mxShapeERCloud, mxShape);
514
515/**
516 * Function: paintVertexShape
517 *
518 * Paints the vertex shape.
519 */
520mxShapeERCloud.prototype.paintVertexShape = function(c, x, y, w, h)
521{
522	var mainText = mxUtils.getValue(this.style, 'buttonText', 'Entity');
523	var fontColor = mxUtils.getValue(this.style, 'textColor', '#666666');
524	var fontSize = mxUtils.getValue(this.style, mxConstants.STYLE_FONTSIZE, '17');
525	c.translate(x, y);
526	var rSize = 10;
527	w = Math.max(w, 2 * rSize);
528	h = Math.max(h, 2 * rSize);
529	this.background(c, x, y, w, h, rSize, fontColor);
530	c.setShadow(false);
531	this.mainText(c, x, y, w, h, mainText, fontSize, fontColor);
532};
533
534mxShapeERCloud.prototype.background = function(c, x, y, w, h, rSize, fontColor)
535{
536	c.begin();
537	c.moveTo(0.25 * w, 0.25 * h);
538	c.curveTo(0.05 * w, 0.25 * h, 0, 0.5 * h, 0.16 * w, 0.55 * h);
539	c.curveTo(0, 0.66 * h, 0.18 * w, 0.9 * h, 0.31 * w, 0.8 * h);
540	c.curveTo(0.4 * w, h, 0.7 * w, h, 0.8 * w, 0.8 * h);
541	c.curveTo(w, 0.8 * h, w, 0.6 * h, 0.875 * w, 0.5 * h);
542	c.curveTo(w, 0.3 * h, 0.8 * w, 0.1 * h, 0.625 * w, 0.2 * h);
543	c.curveTo(0.5 * w, 0.05 * h, 0.3 * w, 0.05 * h, 0.25 * w, 0.25 * h);
544	c.fillAndStroke();
545};
546
547mxShapeERCloud.prototype.mainText = function(c, x, y, w, h, text, fontSize, fontColor)
548{
549	c.begin();
550	c.setFontSize(fontSize);
551	c.setFontColor(fontColor);
552	c.text(w * 0.5, h * 0.5, 0, 0, text, mxConstants.ALIGN_CENTER, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
553};
554
555mxCellRenderer.registerShape('mxgraph.er.cloud', mxShapeERCloud);
556
557mxShapeERCloud.prototype.constraints = [
558                                        new mxConnectionConstraint(new mxPoint(0.08, 0.5), false),
559                                        new mxConnectionConstraint(new mxPoint(0.9, 0.5), false),
560                                        new mxConnectionConstraint(new mxPoint(0.5, 0.1), false),
561                                        new mxConnectionConstraint(new mxPoint(0.5, 0.92), false),
562                                        new mxConnectionConstraint(new mxPoint(0.24, 0.24), false),
563                                        new mxConnectionConstraint(new mxPoint(0.22, 0.8), false),
564                                        new mxConnectionConstraint(new mxPoint(0.81, 0.2), false),
565                                        new mxConnectionConstraint(new mxPoint(0.78, 0.78), false)
566                                      ];
567
568//**********************************************************************************************************************************************************
569//Hierarchy (LEGACY)
570//**********************************************************************************************************************************************************
571/**
572 * Extends mxShape.
573 */
574function mxShapeERHierarchy(bounds, fill, stroke, strokewidth)
575{
576	mxShape.call(this);
577	this.bounds = bounds;
578	this.fill = fill;
579	this.stroke = stroke;
580	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
581};
582
583/**
584 * Extends mxShape.
585 */
586mxUtils.extend(mxShapeERHierarchy, mxShape);
587
588/**
589 * Function: paintVertexShape
590 *
591 * Paints the vertex shape.
592 */
593mxShapeERHierarchy.prototype.paintVertexShape = function(c, x, y, w, h)
594{
595	var mainText = mxUtils.getValue(this.style, 'buttonText', 'main').toString().split(',');
596	var subText = mxUtils.getValue(this.style, 'subText', 'sub').toString().split(',');
597	var fontColor = mxUtils.getValue(this.style, 'textColor', '#666666');
598	var fontSize = mxUtils.getValue(this.style, mxConstants.STYLE_FONTSIZE, '17');
599	c.translate(x, y);
600	var rSize = 10;
601	w = Math.max(w, 2 * rSize);
602	h = Math.max(h, 2 * rSize);
603	this.background(c, x, y, w, h, rSize, fontColor);
604	c.setShadow(false);
605	this.shapeText(c, x, y, w, h, mainText, subText, fontSize, fontColor);
606};
607
608mxShapeERHierarchy.prototype.background = function(c, x, y, w, h, rSize, fontColor)
609{
610	var buttonStyle = mxUtils.getValue(this.style, 'buttonStyle', 'round').toString();
611
612	if (buttonStyle === 'round')
613	{
614		c.begin();
615		c.moveTo(0, rSize);
616		c.arcTo(rSize, rSize, 0, 0, 1, rSize, 0);
617		c.lineTo(w - rSize, 0);
618		c.arcTo(rSize, rSize, 0, 0, 1, w, rSize);
619		c.lineTo(w, h - rSize);
620		c.arcTo(rSize, rSize, 0, 0, 1, w - rSize, h);
621		c.lineTo(rSize, h);
622		c.arcTo(rSize, rSize, 0, 0, 1, 0, h - rSize);
623		c.close();
624		c.fillAndStroke();
625	}
626	else if (buttonStyle === 'rect')
627	{
628		c.begin();
629		c.moveTo(0, 0);
630		c.lineTo(w, 0);
631		c.lineTo(w, h);
632		c.lineTo(0, h);
633		c.close();
634		c.fillAndStroke();
635	}
636	else if (buttonStyle === 'dblFrame')
637	{
638		var fillColor = mxUtils.getValue(this.style, mxConstants.STYLE_FILLCOLOR, '#666666');
639		c.setFillColor(fillColor);
640		c.begin();
641		c.moveTo(0, 0);
642		c.lineTo(w, 0);
643		c.lineTo(w, h);
644		c.lineTo(0, h);
645		c.close();
646		c.fillAndStroke();
647		rSize = Math.min(w, h);
648		c.begin();
649		c.moveTo(rSize * 0.1, rSize * 0.1);
650		c.lineTo(w - rSize * 0.1, rSize * 0.1);
651		c.lineTo(w - rSize * 0.1, h - rSize * 0.1);
652		c.lineTo(rSize * 0.1, h - rSize * 0.1);
653		c.close();
654		c.stroke();
655	}
656
657	var trX = 0;
658	var trY = 0;
659
660	if (buttonStyle === 'round')
661	{
662		trX = w * 0.5;
663		trY = rSize;
664		c.translate(trX, trY);
665		w = w * 0.5 - rSize;
666		h = h - 2 * rSize;
667		c.begin();
668		c.moveTo(0, rSize);
669		c.arcTo(rSize, rSize, 0, 0, 1, rSize, 0);
670		c.lineTo(w - rSize, 0);
671		c.arcTo(rSize, rSize, 0, 0, 1, w, rSize);
672		c.lineTo(w, h - rSize);
673		c.arcTo(rSize, rSize, 0, 0, 1, w - rSize, h);
674		c.lineTo(rSize, h);
675		c.arcTo(rSize, rSize, 0, 0, 1, 0, h - rSize);
676		c.close();
677		c.fillAndStroke();
678	}
679	else if (buttonStyle === 'rect')
680	{
681		trX = w * 0.5;
682		trY = rSize;
683		c.translate(trX, trY);
684		w = w * 0.5 - rSize;
685		h = h - 2 * rSize;
686		c.begin();
687		c.moveTo(0, 0);
688		c.lineTo(w, 0);
689		c.lineTo(w, h);
690		c.lineTo(0, h);
691		c.close();
692		c.fillAndStroke();
693	}
694	else if (buttonStyle === 'dblFrame')
695	{
696		trX = w * 0.5;
697		trY = rSize * 0.15;
698		c.translate(trX, trY);
699		w = w * 0.5 - rSize * 0.15;
700		h = h - rSize * 0.3;
701		var fillColor = mxUtils.getValue(this.style, mxConstants.STYLE_FILLCOLOR, '#666666');
702		c.setFillColor(fillColor);
703		c.begin();
704		c.moveTo(0, 0);
705		c.lineTo(w, 0);
706		c.lineTo(w, h);
707		c.lineTo(0, h);
708		c.close();
709		c.fillAndStroke();
710		rSize = Math.min(w, h);
711		c.begin();
712		c.moveTo(rSize * 0.1, rSize * 0.1);
713		c.lineTo(w - rSize * 0.1, rSize * 0.1);
714		c.lineTo(w - rSize * 0.1, h - rSize * 0.1);
715		c.lineTo(rSize * 0.1, h - rSize * 0.1);
716		c.close();
717		c.stroke();
718	}
719
720	c.translate(- trX, - trY);
721
722};
723
724mxShapeERHierarchy.prototype.shapeText = function(c, x, y, w, h, text, subText, fontSize, fontColor, rSize)
725{
726	c.begin();
727	c.setFontSize(fontSize);
728	c.setFontColor(fontColor);
729	c.text(w * 0.25, (h - fontSize) * 0.5, 0, 0, text[0], mxConstants.ALIGN_CENTER, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
730	c.text(w * 0.25, (h + fontSize) * 0.5, 0, 0, text[1], mxConstants.ALIGN_CENTER, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
731	c.text(w * 0.7, (h - fontSize) * 0.5, 0, 0, subText[0], mxConstants.ALIGN_CENTER, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
732	c.text(w * 0.7, (h + fontSize) * 0.5, 0, 0, subText[1], mxConstants.ALIGN_CENTER, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
733};
734
735mxCellRenderer.registerShape('mxgraph.er.hierarchy', mxShapeERHierarchy);
736
737mxShapeERHierarchy.prototype.constraints = [
738                                         new mxConnectionConstraint(new mxPoint(0.25, 0), true),
739                                         new mxConnectionConstraint(new mxPoint(0.5, 0), true),
740                                         new mxConnectionConstraint(new mxPoint(0.75, 0), true),
741                                         new mxConnectionConstraint(new mxPoint(0, 0.25), true),
742                                         new mxConnectionConstraint(new mxPoint(0, 0.5), true),
743                                         new mxConnectionConstraint(new mxPoint(0, 0.75), true),
744                                         new mxConnectionConstraint(new mxPoint(1, 0.25), true),
745                                         new mxConnectionConstraint(new mxPoint(1, 0.5), true),
746                                         new mxConnectionConstraint(new mxPoint(1, 0.75), true),
747                                         new mxConnectionConstraint(new mxPoint(0.25, 1), true),
748                                         new mxConnectionConstraint(new mxPoint(0.5, 1), true),
749                                         new mxConnectionConstraint(new mxPoint(0.75, 1), true)
750                                         ];
751
752//**********************************************************************************************************************************************************
753//Note
754//**********************************************************************************************************************************************************
755/**
756 * Extends mxShape.
757 */
758function mxShapeERNote(bounds, fill, stroke, strokewidth)
759{
760	mxShape.call(this);
761	this.bounds = bounds;
762	this.fill = fill;
763	this.stroke = stroke;
764	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
765};
766
767/**
768 * Extends mxShape.
769 */
770mxUtils.extend(mxShapeERNote, mxShape);
771
772/**
773 * Function: paintVertexShape
774 *
775 * Paints the vertex shape.
776 */
777mxShapeERNote.prototype.paintVertexShape = function(c, x, y, w, h)
778{
779	var mainText = mxUtils.getValue(this.style, 'buttonText', 'Entity');
780	var fontColor = mxUtils.getValue(this.style, 'textColor', '#666666');
781	var fontSize = mxUtils.getValue(this.style, mxConstants.STYLE_FONTSIZE, '17');
782	var backColor = mxUtils.getValue(this.style, 'fillColor2', '#ffffff');
783	c.translate(x, y);
784	var flipSize = 20;
785	w = Math.max(w, flipSize * 2);
786	h = Math.max(h, flipSize * 2);
787	this.background(c, x, y, w, h, flipSize);
788	c.setShadow(false);
789	this.flipShape(c, x, y, w, h, flipSize, backColor);
790	this.mainText(c, x, y, w, h, mainText, fontSize, fontColor);
791};
792
793mxShapeERNote.prototype.background = function(c, x, y, w, h, flipSize)
794{
795	c.begin();
796	c.moveTo(0, 0);
797	c.lineTo(w - flipSize, 0);
798	c.lineTo(w, flipSize);
799	c.lineTo(w, h);
800	c.lineTo(0, h);
801	c.close();
802	c.fillAndStroke();
803};
804
805mxShapeERNote.prototype.flipShape = function(c, x, y, w, h, flipSize, backColor)
806{
807	c.setLineJoin('round');
808	c.setFillColor(backColor);
809	c.begin();
810	c.moveTo(w - flipSize, 0);
811	c.lineTo(w, flipSize);
812	c.lineTo(w - flipSize, flipSize);
813	c.close();
814	c.fillAndStroke();
815};
816
817mxShapeERNote.prototype.mainText = function(c, x, y, w, h, text, fontSize, fontColor)
818{
819	c.begin();
820	c.setFontSize(fontSize);
821	c.setFontColor(fontColor);
822	c.text(w * 0.5, h * 0.5, 0, 0, text, mxConstants.ALIGN_CENTER, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
823};
824
825mxCellRenderer.registerShape('mxgraph.er.note', mxShapeERNote);
826
827mxShapeERNote.prototype.constraints = [
828                                           new mxConnectionConstraint(new mxPoint(0, 0), true),
829                                           new mxConnectionConstraint(new mxPoint(0, 1), true),
830                                           new mxConnectionConstraint(new mxPoint(1, 1), true),
831                                           new mxConnectionConstraint(new mxPoint(0.25, 0), true),
832                                           new mxConnectionConstraint(new mxPoint(0.5, 0), true),
833                                           new mxConnectionConstraint(new mxPoint(0.75, 0), true),
834                                           new mxConnectionConstraint(new mxPoint(0, 0.25), true),
835                                           new mxConnectionConstraint(new mxPoint(0, 0.5), true),
836                                           new mxConnectionConstraint(new mxPoint(0, 0.75), true),
837                                           new mxConnectionConstraint(new mxPoint(1, 0.25), true),
838                                           new mxConnectionConstraint(new mxPoint(1, 0.5), true),
839                                           new mxConnectionConstraint(new mxPoint(1, 0.75), true),
840                                           new mxConnectionConstraint(new mxPoint(0.25, 1), true),
841                                           new mxConnectionConstraint(new mxPoint(0.5, 1), true),
842                                           new mxConnectionConstraint(new mxPoint(0.75, 1), true)
843                                           ];
844
845//**********************************************************************************************************************************************************
846//Chen's Notation Legend (LEGACY)
847//**********************************************************************************************************************************************************
848/**
849 * Extends mxShape.
850 */
851function mxShapeERChen(bounds, fill, stroke, strokewidth)
852{
853	mxShape.call(this);
854	this.bounds = bounds;
855	this.fill = fill;
856	this.stroke = stroke;
857	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
858};
859
860/**
861 * Extends mxShape.
862 */
863mxUtils.extend(mxShapeERChen, mxShape);
864
865/**
866 * Function: paintVertexShape
867 *
868 * Paints the vertex shape.
869 */
870mxShapeERChen.prototype.paintVertexShape = function(c, x, y, w, h)
871{
872	var fontColor = mxUtils.getValue(this.style, 'textColor', '#666666');
873	var fontSize = mxUtils.getValue(this.style, mxConstants.STYLE_FONTSIZE, '17');
874	c.translate(x, y);
875	var flipSize = 20;
876	w = Math.max(w, flipSize * 2);
877	h = Math.max(h, flipSize * 2);
878	this.background(c, x, y, w, h);
879	c.setShadow(false);
880	this.foreground(c, x, y, w, h, fontSize, fontColor);
881};
882
883mxShapeERChen.prototype.background = function(c, x, y, w, h)
884{
885	c.begin();
886	c.moveTo(0, 0);
887	c.lineTo(w, 0);
888	c.lineTo(w, h);
889	c.lineTo(0, h);
890	c.close();
891	c.fillAndStroke();
892};
893
894mxShapeERChen.prototype.foreground = function(c, x, y, w, h, fontSize, fontColor)
895{
896	c.begin();
897	c.moveTo(0, h * 0.25);
898	c.lineTo(w, h * 0.25);
899	c.moveTo(0, h * 0.5);
900	c.lineTo(w, h * 0.5);
901	c.moveTo(0, h * 0.75);
902	c.lineTo(w, h * 0.75);
903
904	c.moveTo(w * 0.25, h * 0.5);
905	c.lineTo(w * 0.25, h);
906
907	c.moveTo(w * 0.5, h * 0.25);
908	c.lineTo(w * 0.5, h);
909
910	c.moveTo(w * 0.75, h * 0.5);
911	c.lineTo(w * 0.75, h);
912	c.stroke();
913
914	c.begin();
915	c.setFontSize(fontSize);
916	c.setFontColor(fontColor);
917	c.text(w * 0.5, h * 0.125, 0, 0, 'ERD Peter Chen\'s Notation', mxConstants.ALIGN_CENTER, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
918
919	c.setFontSize(fontSize * 0.85);
920	c.text(w * 0.25, h * 0.375, 0, 0, 'Cardinality', mxConstants.ALIGN_CENTER, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
921	c.text(w * 0.75, h * 0.375, 0, 0, 'Optionality', mxConstants.ALIGN_CENTER, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
922
923	c.setFontSize(fontSize * 0.7);
924	c.text(w * 0.125, h * 0.625, 0, 0, '1', mxConstants.ALIGN_CENTER, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
925	c.text(w * 0.375, h * 0.625, 0, 0, 'One', mxConstants.ALIGN_CENTER, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
926	c.text(w * 0.625, h * 0.625, 0, 0, '0', mxConstants.ALIGN_CENTER, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
927	c.text(w * 0.875, h * 0.625, 0, 0, 'Optional', mxConstants.ALIGN_CENTER, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
928
929	c.text(w * 0.125, h * 0.875, 0, 0, 'N', mxConstants.ALIGN_CENTER, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
930	c.text(w * 0.375, h * 0.875, 0, 0, 'Many', mxConstants.ALIGN_CENTER, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
931	c.text(w * 0.625, h * 0.875, 0, 0, '1', mxConstants.ALIGN_CENTER, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
932	c.text(w * 0.875, h * 0.875, 0, 0, 'Mandatory', mxConstants.ALIGN_CENTER, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
933};
934
935mxCellRenderer.registerShape('mxgraph.er.chens', mxShapeERChen);
936
937mxShapeERChen.prototype.constraints = [
938                                       new mxConnectionConstraint(new mxPoint(0, 0), true),
939                                       new mxConnectionConstraint(new mxPoint(1, 0), true),
940                                       new mxConnectionConstraint(new mxPoint(0, 1), true),
941                                       new mxConnectionConstraint(new mxPoint(1, 1), true),
942                                       new mxConnectionConstraint(new mxPoint(0.25, 0), true),
943                                       new mxConnectionConstraint(new mxPoint(0.5, 0), true),
944                                       new mxConnectionConstraint(new mxPoint(0.75, 0), true),
945                                       new mxConnectionConstraint(new mxPoint(0, 0.25), true),
946                                       new mxConnectionConstraint(new mxPoint(0, 0.5), true),
947                                       new mxConnectionConstraint(new mxPoint(0, 0.75), true),
948                                       new mxConnectionConstraint(new mxPoint(1, 0.25), true),
949                                       new mxConnectionConstraint(new mxPoint(1, 0.5), true),
950                                       new mxConnectionConstraint(new mxPoint(1, 0.75), true),
951                                       new mxConnectionConstraint(new mxPoint(0.25, 1), true),
952                                       new mxConnectionConstraint(new mxPoint(0.5, 1), true),
953                                       new mxConnectionConstraint(new mxPoint(0.75, 1), true)
954                                       ];
955
956//**********************************************************************************************************************************************************
957//Bachman's Notation Legend (LEGACY)
958//**********************************************************************************************************************************************************
959/**
960 * Extends mxShape.
961 */
962function mxShapeERBachman(bounds, fill, stroke, strokewidth)
963{
964	mxShape.call(this);
965	this.bounds = bounds;
966	this.fill = fill;
967	this.stroke = stroke;
968	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
969};
970
971/**
972 * Extends mxShape.
973 */
974mxUtils.extend(mxShapeERBachman, mxShape);
975
976/**
977 * Function: paintVertexShape
978 *
979 * Paints the vertex shape.
980 */
981mxShapeERBachman.prototype.paintVertexShape = function(c, x, y, w, h)
982{
983	var fontColor = mxUtils.getValue(this.style, 'textColor', '#666666');
984	var fontSize = mxUtils.getValue(this.style, mxConstants.STYLE_FONTSIZE, '17');
985	c.translate(x, y);
986	this.background(c, x, y, w, h);
987	c.setShadow(false);
988	this.foreground(c, x, y, w, h, fontSize, fontColor);
989};
990
991mxShapeERBachman.prototype.background = function(c, x, y, w, h)
992{
993	c.begin();
994	c.moveTo(0, 0);
995	c.lineTo(w, 0);
996	c.lineTo(w, h);
997	c.lineTo(0, h);
998	c.close();
999	c.fillAndStroke();
1000};
1001
1002mxShapeERBachman.prototype.foreground = function(c, x, y, w, h, fontSize, fontColor)
1003{
1004	c.begin();
1005	c.moveTo(0, h * 0.125);
1006	c.lineTo(w, h * 0.125);
1007	c.moveTo(0, h * 0.25);
1008	c.lineTo(w, h * 0.25);
1009	c.moveTo(0, h * 0.375);
1010	c.lineTo(w, h * 0.375);
1011	c.moveTo(0, h * 0.5);
1012	c.lineTo(w, h * 0.5);
1013	c.moveTo(0, h * 0.625);
1014	c.lineTo(w, h * 0.625);
1015	c.moveTo(0, h * 0.75);
1016	c.lineTo(w, h * 0.75);
1017	c.moveTo(0, h * 0.875);
1018	c.lineTo(w, h * 0.875);
1019
1020	c.moveTo(w * 0.5, h * 0.125);
1021	c.lineTo(w * 0.5, h);
1022	c.stroke();
1023
1024	c.begin();
1025	c.setFontSize(fontSize);
1026	c.setFontColor(fontColor);
1027	c.text(w * 0.5, h * 0.0625, 0, 0, 'ERD Bachman\'s Notation', mxConstants.ALIGN_CENTER, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
1028
1029	c.setFontSize(fontSize * 0.85);
1030	c.text(w * 0.52, h * 0.1875, 0, 0, 'Relationship', mxConstants.ALIGN_LEFT, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
1031	c.text(w * 0.52, h * 0.3125, 0, 0, 'Cardinality (One)', mxConstants.ALIGN_LEFT, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
1032	c.text(w * 0.52, h * 0.4375, 0, 0, 'Cardinality (Many)', mxConstants.ALIGN_LEFT, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
1033	c.text(w * 0.52, h * 0.5625, 0, 0, 'Mandatory, One', mxConstants.ALIGN_LEFT, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
1034	c.text(w * 0.52, h * 0.6875, 0, 0, 'Mandatory, Many', mxConstants.ALIGN_LEFT, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
1035	c.text(w * 0.52, h * 0.8125, 0, 0, 'Optional, One', mxConstants.ALIGN_LEFT, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
1036	c.text(w * 0.52, h * 0.9375, 0, 0, 'Optional, Many', mxConstants.ALIGN_LEFT, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
1037
1038	var textWidth = mxUtils.getSizeForString('has/forms', fontSize, mxConstants.DEFAULT_FONTFAMILY).width;
1039	c.begin();
1040	c.moveTo(w * 0.04, h * 0.1875);
1041	c.lineTo(w * 0.25  - textWidth * 0.5, h * 0.1875);
1042	c.moveTo(w * 0.25  + textWidth * 0.5, h * 0.1875);
1043	c.lineTo(w * 0.46, h * 0.1875);
1044
1045	c.text(w * 0.25, h * 0.1875, 0, 0, 'has/forms', mxConstants.ALIGN_CENTER, mxConstants.ALIGN_MIDDLE, 0, null, true, 0, 0);
1046
1047	c.moveTo(w * 0.04, h * 0.3125);
1048	c.lineTo(w * 0.46, h * 0.3125);
1049
1050	c.moveTo(w * 0.04, h * 0.4375);
1051	c.lineTo(w * 0.46, h * 0.4375);
1052	c.moveTo(w * 0.46, h * 0.4050);
1053	c.lineTo(w * 0.4, h * 0.4375);
1054	c.lineTo(w * 0.46, h * 0.47);
1055
1056	c.moveTo(w * 0.04, h * 0.5625);
1057	c.lineTo(w * 0.46, h * 0.5625);
1058	c.moveTo(w * 0.38, h * 0.53);
1059	c.lineTo(w * 0.38, h * 0.595);
1060
1061	c.moveTo(w * 0.04, h * 0.6875);
1062	c.lineTo(w * 0.46, h * 0.6875);
1063	c.moveTo(w * 0.46, h * 0.655);
1064	c.lineTo(w * 0.4, h * 0.6875);
1065	c.lineTo(w * 0.46, h * 0.72);
1066	c.moveTo(w * 0.38, h * 0.655);
1067	c.lineTo(w * 0.38, h * 0.72);
1068
1069	c.moveTo(w * 0.04, h * 0.8125);
1070	c.lineTo(w * 0.46, h * 0.8125);
1071
1072	c.moveTo(w * 0.04, h * 0.9375);
1073	c.lineTo(w * 0.46, h * 0.9375);
1074	c.moveTo(w * 0.46, h * 0.9050);
1075	c.lineTo(w * 0.4, h * 0.9375);
1076	c.lineTo(w * 0.46, h * 0.97);
1077
1078	c.stroke();
1079
1080	var ellSize = h / 15;
1081	c.begin();
1082	c.ellipse(w * 0.46 - ellSize, h * 0.8125 - ellSize * 0.5, ellSize, ellSize);
1083	c.fillAndStroke();
1084
1085	c.begin();
1086	c.ellipse(w * 0.4 - ellSize, h * 0.9375 - ellSize * 0.5, ellSize, ellSize);
1087	c.fillAndStroke();
1088};
1089
1090mxCellRenderer.registerShape('mxgraph.er.bachmans', mxShapeERBachman);
1091
1092mxShapeERBachman.prototype.constraints = [
1093                                       new mxConnectionConstraint(new mxPoint(0, 0), true),
1094                                       new mxConnectionConstraint(new mxPoint(1, 0), true),
1095                                       new mxConnectionConstraint(new mxPoint(0, 1), true),
1096                                       new mxConnectionConstraint(new mxPoint(1, 1), true),
1097                                       new mxConnectionConstraint(new mxPoint(0.25, 0), true),
1098                                       new mxConnectionConstraint(new mxPoint(0.5, 0), true),
1099                                       new mxConnectionConstraint(new mxPoint(0.75, 0), true),
1100                                       new mxConnectionConstraint(new mxPoint(0, 0.25), true),
1101                                       new mxConnectionConstraint(new mxPoint(0, 0.5), true),
1102                                       new mxConnectionConstraint(new mxPoint(0, 0.75), true),
1103                                       new mxConnectionConstraint(new mxPoint(1, 0.25), true),
1104                                       new mxConnectionConstraint(new mxPoint(1, 0.5), true),
1105                                       new mxConnectionConstraint(new mxPoint(1, 0.75), true),
1106                                       new mxConnectionConstraint(new mxPoint(0.25, 1), true),
1107                                       new mxConnectionConstraint(new mxPoint(0.5, 1), true),
1108                                       new mxConnectionConstraint(new mxPoint(0.75, 1), true)
1109                                       ];
1110
1111//**********************************************************************************************************************************************************
1112//Information Engineering Notation Legend (LEGACY)
1113//**********************************************************************************************************************************************************
1114/**
1115 * Extends mxShape.
1116 */
1117function mxShapeERInfEng(bounds, fill, stroke, strokewidth)
1118{
1119	mxShape.call(this);
1120	this.bounds = bounds;
1121	this.fill = fill;
1122	this.stroke = stroke;
1123	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
1124};
1125
1126/**
1127 * Extends mxShape.
1128 */
1129mxUtils.extend(mxShapeERInfEng, mxShape);
1130
1131/**
1132 * Function: paintVertexShape
1133 *
1134 * Paints the vertex shape.
1135 */
1136mxShapeERInfEng.prototype.paintVertexShape = function(c, x, y, w, h)
1137{
1138	var fontColor = mxUtils.getValue(this.style, 'textColor', '#666666');
1139	var fontSize = mxUtils.getValue(this.style, mxConstants.STYLE_FONTSIZE, '17');
1140	c.translate(x, y);
1141	w = Math.max(w, h / 1.5);
1142	h = Math.max(h, fontSize * 5);
1143	this.background(c, x, y, w, h);
1144	c.setShadow(false);
1145	this.foreground(c, x, y, w, h, fontSize, fontColor);
1146};
1147
1148mxShapeERInfEng.prototype.background = function(c, x, y, w, h)
1149{
1150	c.begin();
1151	c.moveTo(0, 0);
1152	c.lineTo(w, 0);
1153	c.lineTo(w, h);
1154	c.lineTo(0, h);
1155	c.close();
1156	c.fillAndStroke();
1157};
1158
1159mxShapeERInfEng.prototype.foreground = function(c, x, y, w, h, fontSize, fontColor)
1160{
1161	c.begin();
1162	c.moveTo(0, h * 0.2);
1163	c.lineTo(w, h * 0.2);
1164	c.moveTo(0, h * 0.4);
1165	c.lineTo(w, h * 0.4);
1166	c.moveTo(0, h * 0.6);
1167	c.lineTo(w, h * 0.6);
1168	c.moveTo(0, h * 0.8);
1169	c.lineTo(w, h * 0.8);
1170
1171	c.moveTo(w * 0.5, h * 0.2);
1172	c.lineTo(w * 0.5, h);
1173	c.stroke();
1174
1175	c.begin();
1176	c.setFontSize(fontSize);
1177	c.setFontColor(fontColor);
1178	c.text(w * 0.5, h * 0.1, 0, 0, 'ERD Information Engineering Notation', mxConstants.ALIGN_CENTER, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
1179
1180	c.setFontSize(fontSize * 0.85);
1181	c.text(w * 0.52, h * 0.3, 0, 0, 'Zero or one', mxConstants.ALIGN_LEFT, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
1182	c.text(w * 0.52, h * 0.5, 0, 0, 'One only', mxConstants.ALIGN_LEFT, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
1183	c.text(w * 0.52, h * 0.7, 0, 0, 'Zero or more', mxConstants.ALIGN_LEFT, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
1184	c.text(w * 0.52, h * 0.9, 0, 0, 'One or more', mxConstants.ALIGN_LEFT, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
1185
1186	var ellSize = h / 12;
1187
1188	c.begin();
1189	c.moveTo(w * 0.04, h * 0.3);
1190	c.lineTo(w * 0.46, h * 0.3);
1191	c.moveTo(w * 0.46 - ellSize, h * 0.25);
1192	c.lineTo(w * 0.46 - ellSize, h * 0.35);
1193
1194	c.moveTo(w * 0.04, h * 0.5);
1195	c.lineTo(w * 0.46, h * 0.5);
1196	c.moveTo(w * 0.46 - ellSize * 2, h * 0.45);
1197	c.lineTo(w * 0.46 - ellSize * 2, h * 0.55);
1198	c.moveTo(w * 0.46 - ellSize * 2.5, h * 0.45);
1199	c.lineTo(w * 0.46 - ellSize * 2.5, h * 0.55);
1200
1201	c.moveTo(w * 0.04, h * 0.7);
1202	c.lineTo(w * 0.46, h * 0.7);
1203	c.moveTo(w * 0.46, h * 0.65);
1204	c.lineTo(w * 0.46 - ellSize * 2, h * 0.7);
1205	c.lineTo(w * 0.46, h * 0.75);
1206	c.stroke();
1207
1208	c.moveTo(w * 0.04, h * 0.9);
1209	c.lineTo(w * 0.46, h * 0.9);
1210	c.moveTo(w * 0.46, h * 0.85);
1211	c.lineTo(w * 0.46 - ellSize * 2, h * 0.9);
1212	c.lineTo(w * 0.46, h * 0.95);
1213	c.moveTo(w * 0.46 - ellSize * 2.5, h * 0.85);
1214	c.lineTo(w * 0.46 - ellSize * 2.5, h * 0.95);
1215	c.stroke();
1216
1217	c.begin();
1218	c.ellipse(w * 0.46 - ellSize * 3, h * 0.3 - ellSize * 0.5, ellSize, ellSize);
1219	c.fillAndStroke();
1220
1221	c.begin();
1222	c.ellipse(w * 0.46 - ellSize * 3, h * 0.7 - ellSize * 0.5, ellSize, ellSize);
1223	c.fillAndStroke();
1224};
1225
1226mxCellRenderer.registerShape('mxgraph.er.ie', mxShapeERInfEng);
1227
1228mxShapeERInfEng.prototype.constraints = [
1229                                          new mxConnectionConstraint(new mxPoint(0, 0), true),
1230                                          new mxConnectionConstraint(new mxPoint(1, 0), true),
1231                                          new mxConnectionConstraint(new mxPoint(0, 1), true),
1232                                          new mxConnectionConstraint(new mxPoint(1, 1), true),
1233                                          new mxConnectionConstraint(new mxPoint(0.25, 0), true),
1234                                          new mxConnectionConstraint(new mxPoint(0.5, 0), true),
1235                                          new mxConnectionConstraint(new mxPoint(0.75, 0), true),
1236                                          new mxConnectionConstraint(new mxPoint(0, 0.25), true),
1237                                          new mxConnectionConstraint(new mxPoint(0, 0.5), true),
1238                                          new mxConnectionConstraint(new mxPoint(0, 0.75), true),
1239                                          new mxConnectionConstraint(new mxPoint(1, 0.25), true),
1240                                          new mxConnectionConstraint(new mxPoint(1, 0.5), true),
1241                                          new mxConnectionConstraint(new mxPoint(1, 0.75), true),
1242                                          new mxConnectionConstraint(new mxPoint(0.25, 1), true),
1243                                          new mxConnectionConstraint(new mxPoint(0.5, 1), true),
1244                                          new mxConnectionConstraint(new mxPoint(0.75, 1), true)
1245                                          ];
1246
1247// ER markers
1248mxMarker.addMarker('ERone', function(c, shape, type, pe, unitX, unitY, size, source, sw, filled)
1249{
1250	var nx = unitX * (size + sw + 1);
1251	var ny = unitY * (size + sw + 1);
1252
1253	return function()
1254	{
1255		c.begin();
1256		c.moveTo(pe.x - nx / 2 - ny / 2, pe.y - ny / 2 + nx / 2);
1257		c.lineTo(pe.x - nx / 2 + ny / 2, pe.y - ny / 2 - nx / 2);
1258		c.stroke();
1259	};
1260});
1261
1262mxMarker.addMarker('ERmandOne', function(c, shape, type, pe, unitX, unitY, size, source, sw, filled)
1263{
1264	var nx = unitX * (size + sw + 1);
1265	var ny = unitY * (size + sw + 1);
1266
1267	return function()
1268	{
1269		c.begin();
1270		c.moveTo(pe.x - nx / 2 - ny / 2, pe.y - ny / 2 + nx / 2);
1271		c.lineTo(pe.x - nx / 2 + ny / 2, pe.y - ny / 2 - nx / 2);
1272		c.moveTo(pe.x - nx - ny / 2, pe.y - ny + nx / 2);
1273		c.lineTo(pe.x - nx + ny / 2, pe.y - ny - nx / 2);
1274		c.stroke();
1275	};
1276});
1277
1278mxMarker.addMarker('ERmany', function(c, shape, type, pe, unitX, unitY, size, source, sw, filled)
1279{
1280	var nx = unitX * (size + sw + 1);
1281	var ny = unitY * (size + sw + 1);
1282
1283	return function()
1284	{
1285		c.begin();
1286		c.moveTo(pe.x + ny / 2, pe.y - nx / 2);
1287		c.lineTo(pe.x - nx, pe.y - ny);
1288		c.lineTo(pe.x - ny / 2, pe.y + nx / 2);
1289		c.stroke();
1290	};
1291});
1292
1293mxMarker.addMarker('ERoneToMany', function(c, shape, type, pe, unitX, unitY, size, source, sw, filled)
1294{
1295	var nx = unitX * (size + sw + 1);
1296	var ny = unitY * (size + sw + 1);
1297
1298	return function()
1299	{
1300		c.begin();
1301		c.moveTo(pe.x - nx - ny / 2, pe.y - ny + nx / 2);
1302		c.lineTo(pe.x - nx + ny / 2, pe.y - ny - nx / 2);
1303		c.moveTo(pe.x + ny / 2, pe.y - nx / 2);
1304		c.lineTo(pe.x - nx, pe.y - ny);
1305		c.lineTo(pe.x - ny / 2, pe.y + nx / 2);
1306		c.stroke();
1307	};
1308});
1309
1310mxMarker.addMarker('ERzeroToMany', function(c, shape, type, pe, unitX, unitY, size, source, sw, filled)
1311{
1312	var nx = unitX * (size + sw + 1);
1313	var ny = unitY * (size + sw + 1);
1314	var a = size / 2;
1315	var px = pe.x;
1316	var py = pe.y;
1317
1318	if (!filled)
1319	{
1320		pe.x -= 2 * nx - unitX * sw / 2;
1321		pe.y -= 2 * ny - unitY * sw / 2;
1322	}
1323
1324	return function()
1325	{
1326		c.begin();
1327		c.ellipse(px - 1.5 * nx - a, py - 1.5 * ny - a, 2 * a, 2 * a);
1328
1329		if (filled)
1330		{
1331			// TODO not sure if this is ok, because by default, markers use strokeColor for filling
1332			var oldColor = mxUtils.getValue(shape.style, mxConstants.STYLE_STROKECOLOR, '#666666');
1333
1334			c.setFillColor('#ffffff');
1335			c.fillAndStroke();
1336			c.setFillColor(oldColor);
1337		}
1338		else
1339		{
1340			c.stroke();
1341		}
1342
1343		c.begin();
1344		c.moveTo(px + ny / 2, py - nx / 2);
1345		c.lineTo(px - nx, py - ny);
1346		c.lineTo(px - ny / 2, py + nx / 2);
1347
1348		if (!filled)
1349		{
1350			c.moveTo(px - nx, py - ny);
1351			c.lineTo(px, py);
1352		}
1353
1354		c.stroke();
1355	};
1356});
1357
1358mxMarker.addMarker('ERzeroToOne', function(c, shape, type, pe, unitX, unitY, size, source, sw, filled)
1359{
1360	var nx = unitX * (size + sw + 1);
1361	var ny = unitY * (size + sw + 1);
1362	var a = size / 2;
1363	var px = pe.x;
1364	var py = pe.y;
1365
1366	if (!filled)
1367	{
1368		pe.x -= 2 * nx - unitX * sw / 2;
1369		pe.y -= 2 * ny - unitY * sw / 2;
1370	}
1371
1372	return function()
1373	{
1374		c.begin();
1375		c.ellipse(px - 1.5 * nx - a, py - 1.5 * ny - a, 2 * a, 2 * a);
1376
1377		if (filled)
1378		{
1379			// TODO not sure if this is ok, because by default, markers use strokeColor for filling
1380			var oldColor = mxUtils.getValue(shape.style, mxConstants.STYLE_STROKECOLOR, '#666666');
1381
1382			c.setFillColor('#ffffff');
1383			c.fillAndStroke();
1384			c.setFillColor(oldColor);
1385		}
1386		else
1387		{
1388			c.stroke();
1389		}
1390
1391		c.begin();
1392		c.moveTo(px - nx / 2 - ny / 2, py - ny / 2 + nx / 2);
1393		c.lineTo(px - nx / 2 + ny / 2, py - ny / 2 - nx / 2);
1394
1395		if (!filled)
1396		{
1397			c.moveTo(px - nx  - unitX * sw / 2, py - ny - unitY * sw / 2);
1398			c.lineTo(px, py);
1399		}
1400
1401		c.stroke();
1402	};
1403});
1404
1405//**********************************************************************************************************************************************************
1406//Rounded rectangle (adjustable rounding)
1407//**********************************************************************************************************************************************************
1408/**
1409* Extends mxShape.
1410*/
1411function mxShapeERRRect(bounds, fill, stroke, strokewidth)
1412{
1413	mxShape.call(this);
1414	this.bounds = bounds;
1415	this.fill = fill;
1416	this.stroke = stroke;
1417	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
1418};
1419
1420/**
1421* Extends mxShape.
1422*/
1423mxUtils.extend(mxShapeERRRect, mxShape);
1424
1425mxShapeERRRect.prototype.cst = {
1426		RRECT : 'mxgraph.er.rrect',
1427		R_SIZE : 'rSize'
1428};
1429
1430mxShapeERRRect.prototype.customProperties = [
1431	{name: 'rSize', dispName: 'Rounding Size', type: 'float'},
1432];
1433
1434/**
1435* Function: paintVertexShape
1436*
1437* Paints the vertex shape.
1438*/
1439mxShapeERRRect.prototype.paintVertexShape = function(c, x, y, w, h)
1440{
1441	c.translate(x, y);
1442
1443	var rSize = parseInt(mxUtils.getValue(this.style, mxShapeERRRect.prototype.cst.R_SIZE, '10'));
1444	c.roundrect(0, 0, w, h, rSize);
1445	c.fillAndStroke();
1446};
1447
1448mxCellRenderer.registerShape(mxShapeERRRect.prototype.cst.RRECT, mxShapeERRRect);
1449
1450mxShapeERRRect.prototype.constraints = [
1451                                            new mxConnectionConstraint(new mxPoint(0.25, 0), true),
1452                                            new mxConnectionConstraint(new mxPoint(0.5, 0), true),
1453                                            new mxConnectionConstraint(new mxPoint(0.75, 0), true),
1454                                            new mxConnectionConstraint(new mxPoint(0, 0.25), true),
1455                                            new mxConnectionConstraint(new mxPoint(0, 0.5), true),
1456                                            new mxConnectionConstraint(new mxPoint(0, 0.75), true),
1457                                            new mxConnectionConstraint(new mxPoint(1, 0.25), true),
1458                                            new mxConnectionConstraint(new mxPoint(1, 0.5), true),
1459                                            new mxConnectionConstraint(new mxPoint(1, 0.75), true),
1460                                            new mxConnectionConstraint(new mxPoint(0.25, 1), true),
1461                                            new mxConnectionConstraint(new mxPoint(0.5, 1), true),
1462                                            new mxConnectionConstraint(new mxPoint(0.75, 1), true)
1463                                            ];
1464
1465//**********************************************************************************************************************************************************
1466//Anchor (a dummy shape without visuals used for anchoring)
1467//**********************************************************************************************************************************************************
1468/**
1469* Extends mxShape.
1470*/
1471function mxShapeERAnchor(bounds, fill, stroke, strokewidth)
1472{
1473	mxShape.call(this);
1474	this.bounds = bounds;
1475};
1476
1477/**
1478* Extends mxShape.
1479*/
1480mxUtils.extend(mxShapeERAnchor, mxShape);
1481
1482mxShapeERAnchor.prototype.cst = {
1483		ANCHOR : 'mxgraph.er.anchor'
1484};
1485
1486
1487
1488/**
1489* Function: paintVertexShape
1490*
1491* Paints the vertex shape.
1492*/
1493mxShapeERAnchor.prototype.paintVertexShape = function(c, x, y, w, h)
1494{
1495};
1496
1497mxCellRenderer.registerShape(mxShapeERAnchor.prototype.cst.ANCHOR, mxShapeERAnchor);
1498
1499