UNPKG

mxgraph-map-fix

Version:

mxGraph is a fully client side JavaScript diagramming library that uses SVG and HTML for rendering.

1,896 lines (1,629 loc) 120 kB
/** * Copyright (c) 2006-2015, JGraph Ltd */ /** * Registers shapes. */ (function() { // Cube Shape, supports size style function CubeShape() { mxCylinder.call(this); }; mxUtils.extend(CubeShape, mxCylinder); CubeShape.prototype.size = 20; CubeShape.prototype.redrawPath = function(path, x, y, w, h, isForeground) { var s = Math.max(0, Math.min(w, Math.min(h, parseFloat(mxUtils.getValue(this.style, 'size', this.size))))); if (isForeground) { path.moveTo(s, h); path.lineTo(s, s); path.lineTo(0, 0); path.moveTo(s, s); path.lineTo(w, s); path.end(); } else { path.moveTo(0, 0); path.lineTo(w - s, 0); path.lineTo(w, s); path.lineTo(w, h); path.lineTo(s, h); path.lineTo(0, h - s); path.lineTo(0, 0); path.close(); path.end(); } }; CubeShape.prototype.getLabelMargins = function(rect) { if (mxUtils.getValue(this.style, 'boundedLbl', false)) { var s = parseFloat(mxUtils.getValue(this.style, 'size', this.size)) * this.scale; return new mxRectangle(s, s, 0, 0); } return null; }; mxCellRenderer.registerShape('cube', CubeShape); var tan30 = Math.tan(mxUtils.toRadians(30)); var tan30Dx = (0.5 - tan30) / 2; // Cube Shape, supports size style function IsoRectangleShape() { mxActor.call(this); }; mxUtils.extend(IsoRectangleShape, mxActor); IsoRectangleShape.prototype.size = 20; IsoRectangleShape.prototype.redrawPath = function(path, x, y, w, h) { var m = Math.min(w, h / tan30); path.translate((w - m) / 2, (h - m) / 2 + m / 4); path.moveTo(0, 0.25 * m); path.lineTo(0.5 * m, m * tan30Dx); path.lineTo(m, 0.25 * m); path.lineTo(0.5 * m, (0.5 - tan30Dx) * m); path.lineTo(0, 0.25 * m); path.close(); path.end(); }; mxCellRenderer.registerShape('isoRectangle', IsoRectangleShape); // Cube Shape, supports size style function IsoCubeShape() { mxCylinder.call(this); }; mxUtils.extend(IsoCubeShape, mxCylinder); IsoCubeShape.prototype.size = 20; IsoCubeShape.prototype.redrawPath = function(path, x, y, w, h, isForeground) { var m = Math.min(w, h / (0.5 + tan30)); if (isForeground) { path.moveTo(0, 0.25 * m); path.lineTo(0.5 * m, (0.5 - tan30Dx) * m); path.lineTo(m, 0.25 * m); path.moveTo(0.5 * m, (0.5 - tan30Dx) * m); path.lineTo(0.5 * m, (1 - tan30Dx) * m); path.end(); } else { path.translate((w - m) / 2, (h - m) / 2); path.moveTo(0, 0.25 * m); path.lineTo(0.5 * m, m * tan30Dx); path.lineTo(m, 0.25 * m); path.lineTo(m, 0.75 * m); path.lineTo(0.5 * m, (1 - tan30Dx) * m); path.lineTo(0, 0.75 * m); path.close(); path.end(); } }; mxCellRenderer.registerShape('isoCube', IsoCubeShape); // DataStore Shape, supports size style function DataStoreShape() { mxCylinder.call(this); }; mxUtils.extend(DataStoreShape, mxCylinder); DataStoreShape.prototype.redrawPath = function(c, x, y, w, h, isForeground) { var dy = Math.min(h / 2, Math.round(h / 8) + this.strokewidth - 1); if ((isForeground && this.fill != null) || (!isForeground && this.fill == null)) { c.moveTo(0, dy); c.curveTo(0, 2 * dy, w, 2 * dy, w, dy); // Needs separate shapes for correct hit-detection if (!isForeground) { c.stroke(); c.begin(); } c.translate(0, dy / 2); c.moveTo(0, dy); c.curveTo(0, 2 * dy, w, 2 * dy, w, dy); // Needs separate shapes for correct hit-detection if (!isForeground) { c.stroke(); c.begin(); } c.translate(0, dy / 2); c.moveTo(0, dy); c.curveTo(0, 2 * dy, w, 2 * dy, w, dy); // Needs separate shapes for correct hit-detection if (!isForeground) { c.stroke(); c.begin(); } c.translate(0, -dy); } if (!isForeground) { c.moveTo(0, dy); c.curveTo(0, -dy / 3, w, -dy / 3, w, dy); c.lineTo(w, h - dy); c.curveTo(w, h + dy / 3, 0, h + dy / 3, 0, h - dy); c.close(); } }; DataStoreShape.prototype.getLabelMargins = function(rect) { return new mxRectangle(0, 2.5 * Math.min(rect.height / 2, Math.round(rect.height / 8) + this.strokewidth - 1) * this.scale, 0, 0); } mxCellRenderer.registerShape('datastore', DataStoreShape); // Note Shape, supports size style function NoteShape() { mxCylinder.call(this); }; mxUtils.extend(NoteShape, mxCylinder); NoteShape.prototype.size = 30; NoteShape.prototype.redrawPath = function(path, x, y, w, h, isForeground) { var s = Math.max(0, Math.min(w, Math.min(h, parseFloat(mxUtils.getValue(this.style, 'size', this.size))))); if (isForeground) { path.moveTo(w - s, 0); path.lineTo(w - s, s); path.lineTo(w, s); path.end(); } else { path.moveTo(0, 0); path.lineTo(w - s, 0); path.lineTo(w, s); path.lineTo(w, h); path.lineTo(0, h); path.lineTo(0, 0); path.close(); path.end(); } }; mxCellRenderer.registerShape('note', NoteShape); // Note Shape, supports size style function SwitchShape() { mxActor.call(this); }; mxUtils.extend(SwitchShape, mxActor); SwitchShape.prototype.redrawPath = function(c, x, y, w, h) { var curve = 0.5; c.moveTo(0, 0); c.quadTo(w / 2, h * curve, w, 0); c.quadTo(w * (1 - curve), h / 2, w, h); c.quadTo(w / 2, h * (1 - curve), 0, h); c.quadTo(w * curve, h / 2, 0, 0); c.end(); }; mxCellRenderer.registerShape('switch', SwitchShape); // Folder Shape, supports tabWidth, tabHeight styles function FolderShape() { mxCylinder.call(this); }; mxUtils.extend(FolderShape, mxCylinder); FolderShape.prototype.tabWidth = 60; FolderShape.prototype.tabHeight = 20; FolderShape.prototype.tabPosition = 'right'; FolderShape.prototype.redrawPath = function(path, x, y, w, h, isForeground) { var dx = Math.max(0, Math.min(w, parseFloat(mxUtils.getValue(this.style, 'tabWidth', this.tabWidth)))); var dy = Math.max(0, Math.min(h, parseFloat(mxUtils.getValue(this.style, 'tabHeight', this.tabHeight)))); var tp = mxUtils.getValue(this.style, 'tabPosition', this.tabPosition); if (isForeground) { if (tp == 'left') { path.moveTo(0, dy); path.lineTo(dx, dy); } // Right is default else { path.moveTo(w - dx, dy); path.lineTo(w, dy); } path.end(); } else { if (tp == 'left') { path.moveTo(0, 0); path.lineTo(dx, 0); path.lineTo(dx, dy); path.lineTo(w, dy); } // Right is default else { path.moveTo(0, dy); path.lineTo(w - dx, dy); path.lineTo(w - dx, 0); path.lineTo(w, 0); } path.lineTo(w, h); path.lineTo(0, h); path.lineTo(0, dy); path.close(); path.end(); } }; mxCellRenderer.registerShape('folder', FolderShape); // Card shape function CardShape() { mxActor.call(this); }; mxUtils.extend(CardShape, mxActor); CardShape.prototype.size = 30; CardShape.prototype.redrawPath = function(c, x, y, w, h) { var s = Math.max(0, Math.min(w, Math.min(h, parseFloat(mxUtils.getValue(this.style, 'size', this.size))))); var arcSize = mxUtils.getValue(this.style, mxConstants.STYLE_ARCSIZE, mxConstants.LINE_ARCSIZE) / 2; this.addPoints(c, [new mxPoint(s, 0), new mxPoint(w, 0), new mxPoint(w, h), new mxPoint(0, h), new mxPoint(0, s)], this.isRounded, arcSize, true); c.end(); }; mxCellRenderer.registerShape('card', CardShape); // Tape shape function TapeShape() { mxActor.call(this); }; mxUtils.extend(TapeShape, mxActor); TapeShape.prototype.size = 0.4; TapeShape.prototype.redrawPath = function(c, x, y, w, h) { var dy = h * Math.max(0, Math.min(1, parseFloat(mxUtils.getValue(this.style, 'size', this.size)))); var fy = 1.4; c.moveTo(0, dy / 2); c.quadTo(w / 4, dy * fy, w / 2, dy / 2); c.quadTo(w * 3 / 4, dy * (1 - fy), w, dy / 2); c.lineTo(w, h - dy / 2); c.quadTo(w * 3 / 4, h - dy * fy, w / 2, h - dy / 2); c.quadTo(w / 4, h - dy * (1 - fy), 0, h - dy / 2); c.lineTo(0, dy / 2); c.close(); c.end(); }; TapeShape.prototype.getLabelBounds = function(rect) { if (mxUtils.getValue(this.style, 'boundedLbl', false)) { var size = mxUtils.getValue(this.style, 'size', this.size); var w = rect.width; var h = rect.height; if (this.direction == null || this.direction == mxConstants.DIRECTION_EAST || this.direction == mxConstants.DIRECTION_WEST) { var dy = h * size; return new mxRectangle(rect.x, rect.y + dy, w, h - 2 * dy); } else { var dx = w * size; return new mxRectangle(rect.x + dx, rect.y, w - 2 * dx, h); } } return rect; }; mxCellRenderer.registerShape('tape', TapeShape); // Document shape function DocumentShape() { mxActor.call(this); }; mxUtils.extend(DocumentShape, mxActor); DocumentShape.prototype.size = 0.3; DocumentShape.prototype.getLabelMargins = function(rect) { if (mxUtils.getValue(this.style, 'boundedLbl', false)) { return new mxRectangle(0, 0, 0, parseFloat(mxUtils.getValue( this.style, 'size', this.size)) * rect.height); } return null; }; DocumentShape.prototype.redrawPath = function(c, x, y, w, h) { var dy = h * Math.max(0, Math.min(1, parseFloat(mxUtils.getValue(this.style, 'size', this.size)))); var fy = 1.4; c.moveTo(0, 0); c.lineTo(w, 0); c.lineTo(w, h - dy / 2); c.quadTo(w * 3 / 4, h - dy * fy, w / 2, h - dy / 2); c.quadTo(w / 4, h - dy * (1 - fy), 0, h - dy / 2); c.lineTo(0, dy / 2); c.close(); c.end(); }; mxCellRenderer.registerShape('document', DocumentShape); mxCylinder.prototype.getLabelMargins = function(rect) { if (mxUtils.getValue(this.style, 'boundedLbl', false)) { return new mxRectangle(0, Math.min(this.maxHeight * this.scale, rect.height * 0.3), 0, 0); } return null; }; // Parallelogram shape function ParallelogramShape() { mxActor.call(this); }; mxUtils.extend(ParallelogramShape, mxActor); ParallelogramShape.prototype.size = 0.2; ParallelogramShape.prototype.redrawPath = function(c, x, y, w, h) { var dx = w * Math.max(0, Math.min(1, parseFloat(mxUtils.getValue(this.style, 'size', this.size)))); var arcSize = mxUtils.getValue(this.style, mxConstants.STYLE_ARCSIZE, mxConstants.LINE_ARCSIZE) / 2; this.addPoints(c, [new mxPoint(0, h), new mxPoint(dx, 0), new mxPoint(w, 0), new mxPoint(w - dx, h)], this.isRounded, arcSize, true); c.end(); }; mxCellRenderer.registerShape('parallelogram', ParallelogramShape); // Trapezoid shape function TrapezoidShape() { mxActor.call(this); }; mxUtils.extend(TrapezoidShape, mxActor); TrapezoidShape.prototype.size = 0.2; TrapezoidShape.prototype.redrawPath = function(c, x, y, w, h) { var dx = w * Math.max(0, Math.min(0.5, parseFloat(mxUtils.getValue(this.style, 'size', this.size)))); var arcSize = mxUtils.getValue(this.style, mxConstants.STYLE_ARCSIZE, mxConstants.LINE_ARCSIZE) / 2; this.addPoints(c, [new mxPoint(0, h), new mxPoint(dx, 0), new mxPoint(w - dx, 0), new mxPoint(w, h)], this.isRounded, arcSize, true); }; mxCellRenderer.registerShape('trapezoid', TrapezoidShape); // Curly Bracket shape function CurlyBracketShape() { mxActor.call(this); }; mxUtils.extend(CurlyBracketShape, mxActor); CurlyBracketShape.prototype.size = 0.5; CurlyBracketShape.prototype.redrawPath = function(c, x, y, w, h) { c.setFillColor(null); var s = w * Math.max(0, Math.min(1, parseFloat(mxUtils.getValue(this.style, 'size', this.size)))); var arcSize = mxUtils.getValue(this.style, mxConstants.STYLE_ARCSIZE, mxConstants.LINE_ARCSIZE) / 2; this.addPoints(c, [new mxPoint(w, 0), new mxPoint(s, 0), new mxPoint(s, h / 2), new mxPoint(0, h / 2), new mxPoint(s, h / 2), new mxPoint(s, h), new mxPoint(w, h)], this.isRounded, arcSize, false); c.end(); }; mxCellRenderer.registerShape('curlyBracket', CurlyBracketShape); // Parallel marker shape function ParallelMarkerShape() { mxActor.call(this); }; mxUtils.extend(ParallelMarkerShape, mxActor); ParallelMarkerShape.prototype.redrawPath = function(c, x, y, w, h) { c.setStrokeWidth(1); c.setFillColor(this.stroke); var w2 = w / 5; c.rect(0, 0, w2, h); c.fillAndStroke(); c.rect(2 * w2, 0, w2, h); c.fillAndStroke(); c.rect(4 * w2, 0, w2, h); c.fillAndStroke(); }; mxCellRenderer.registerShape('parallelMarker', ParallelMarkerShape); /** * Adds handJiggle style (jiggle=n sets jiggle) */ function HandJiggle(canvas, defaultVariation) { this.canvas = canvas; // Avoids "spikes" in the output this.canvas.setLineJoin('round'); this.canvas.setLineCap('round'); this.defaultVariation = defaultVariation; this.originalLineTo = this.canvas.lineTo; this.canvas.lineTo = mxUtils.bind(this, HandJiggle.prototype.lineTo); this.originalMoveTo = this.canvas.moveTo; this.canvas.moveTo = mxUtils.bind(this, HandJiggle.prototype.moveTo); this.originalClose = this.canvas.close; this.canvas.close = mxUtils.bind(this, HandJiggle.prototype.close); this.originalQuadTo = this.canvas.quadTo; this.canvas.quadTo = mxUtils.bind(this, HandJiggle.prototype.quadTo); this.originalCurveTo = this.canvas.curveTo; this.canvas.curveTo = mxUtils.bind(this, HandJiggle.prototype.curveTo); this.originalArcTo = this.canvas.arcTo; this.canvas.arcTo = mxUtils.bind(this, HandJiggle.prototype.arcTo); }; HandJiggle.prototype.moveTo = function(endX, endY) { this.originalMoveTo.apply(this.canvas, arguments); this.lastX = endX; this.lastY = endY; this.firstX = endX; this.firstY = endY; }; HandJiggle.prototype.close = function() { if (this.firstX != null && this.firstY != null) { this.lineTo(this.firstX, this.firstY); this.originalClose.apply(this.canvas, arguments); } this.originalClose.apply(this.canvas, arguments); }; HandJiggle.prototype.quadTo = function(x1, y1, x2, y2) { this.originalQuadTo.apply(this.canvas, arguments); this.lastX = x2; this.lastY = y2; }; HandJiggle.prototype.curveTo = function(x1, y1, x2, y2, x3, y3) { this.originalCurveTo.apply(this.canvas, arguments); this.lastX = x3; this.lastY = y3; }; HandJiggle.prototype.arcTo = function(rx, ry, angle, largeArcFlag, sweepFlag, x, y) { this.originalArcTo.apply(this.canvas, arguments); this.lastX = x; this.lastY = y; }; HandJiggle.prototype.lineTo = function(endX, endY) { // LATER: Check why this.canvas.lastX cannot be used if (this.lastX != null && this.lastY != null) { var dx = Math.abs(endX - this.lastX); var dy = Math.abs(endY - this.lastY); var dist = Math.sqrt(dx * dx + dy * dy); if (dist < 2) { this.originalLineTo.apply(this.canvas, arguments); this.lastX = endX; this.lastY = endY; return; } var segs = Math.round(dist / 10); var variation = this.defaultVariation; if (segs < 5) { segs = 5; variation /= 3; } function sign(x) { return typeof x === 'number' ? x ? x < 0 ? -1 : 1 : x === x ? 0 : NaN : NaN; } var stepX = sign(endX - this.lastX) * dx / segs; var stepY = sign(endY - this.lastY) * dy / segs; var fx = dx / dist; var fy = dy / dist; for (var s = 0; s < segs; s++) { var x = stepX * s + this.lastX; var y = stepY * s + this.lastY; var offset = (Math.random() - 0.5) * variation; this.originalLineTo.call(this.canvas, x - offset * fy, y - offset * fx); } this.originalLineTo.call(this.canvas, endX, endY); this.lastX = endX; this.lastY = endY; } else { this.originalLineTo.apply(this.canvas, arguments); this.lastX = endX; this.lastY = endY; } }; HandJiggle.prototype.destroy = function() { this.canvas.lineTo = this.originalLineTo; this.canvas.moveTo = this.originalMoveTo; this.canvas.close = this.originalClose; this.canvas.quadTo = this.originalQuadTo; this.canvas.curveTo = this.originalCurveTo; this.canvas.arcTo = this.originalArcTo; }; // Installs hand jiggle in all shapes var mxShapePaint0 = mxShape.prototype.paint; mxShape.prototype.defaultJiggle = 1.5; mxShape.prototype.paint = function(c) { // NOTE: getValue does not return a boolean value so !('0') would return true here and below if (this.style != null && mxUtils.getValue(this.style, 'comic', '0') != '0' && c.handHiggle == null) { c.handJiggle = new HandJiggle(c, mxUtils.getValue(this.style, 'jiggle', this.defaultJiggle)); } mxShapePaint0.apply(this, arguments); if (c.handJiggle != null) { c.handJiggle.destroy(); delete c.handJiggle; } }; // Sets default jiggle for diamond mxRhombus.prototype.defaultJiggle = 2; /** * Overrides to avoid call to rect */ var mxRectangleShapeIsHtmlAllowed0 = mxRectangleShape.prototype.isHtmlAllowed; mxRectangleShape.prototype.isHtmlAllowed = function() { return (this.style == null || mxUtils.getValue(this.style, 'comic', '0') == '0') && mxRectangleShapeIsHtmlAllowed0.apply(this, arguments); }; var mxRectangleShapePaintBackground0 = mxRectangleShape.prototype.paintBackground; mxRectangleShape.prototype.paintBackground = function(c, x, y, w, h) { if (c.handJiggle == null) { mxRectangleShapePaintBackground0.apply(this, arguments); } else { var events = true; if (this.style != null) { events = mxUtils.getValue(this.style, mxConstants.STYLE_POINTER_EVENTS, '1') == '1'; } if (events || (this.fill != null && this.fill != mxConstants.NONE) || (this.stroke != null && this.stroke != mxConstants.NONE)) { if (!events && (this.fill == null || this.fill == mxConstants.NONE)) { c.pointerEvents = false; } c.begin(); if (this.isRounded) { var r = 0; if (mxUtils.getValue(this.style, mxConstants.STYLE_ABSOLUTE_ARCSIZE, 0) == '1') { r = Math.min(w / 2, Math.min(h / 2, mxUtils.getValue(this.style, mxConstants.STYLE_ARCSIZE, mxConstants.LINE_ARCSIZE) / 2)); } else { var f = mxUtils.getValue(this.style, mxConstants.STYLE_ARCSIZE, mxConstants.RECTANGLE_ROUNDING_FACTOR * 100) / 100; r = Math.min(w * f, h * f); } c.moveTo(x + r, y); c.lineTo(x + w - r, y); c.quadTo(x + w, y, x + w, y + r); c.lineTo(x + w, y + h - r); c.quadTo(x + w, y + h, x + w - r, y + h); c.lineTo(x + r, y + h); c.quadTo(x, y + h, x, y + h - r); c.lineTo(x, y + r); c.quadTo(x, y, x + r, y); } else { c.moveTo(x, y); c.lineTo(x + w, y); c.lineTo(x + w, y + h); c.lineTo(x, y + h); c.lineTo(x, y); } // LATER: Check if close is needed here c.close(); c.end(); c.fillAndStroke(); } } }; /** * Disables glass effect with hand jiggle. */ var mxRectangleShapePaintForeground0 = mxRectangleShape.prototype.paintForeground; mxRectangleShape.prototype.paintForeground = function(c, x, y, w, h) { if (c.handJiggle == null) { mxRectangleShapePaintForeground0.apply(this, arguments); } }; // End of hand jiggle integration // Process Shape function ProcessShape() { mxRectangleShape.call(this); }; mxUtils.extend(ProcessShape, mxRectangleShape); ProcessShape.prototype.size = 0.1; ProcessShape.prototype.isHtmlAllowed = function() { return false; }; ProcessShape.prototype.getLabelBounds = function(rect) { if (mxUtils.getValue(this.state.style, mxConstants.STYLE_HORIZONTAL, true) == (this.direction == null || this.direction == mxConstants.DIRECTION_EAST || this.direction == mxConstants.DIRECTION_WEST)) { var w = rect.width; var h = rect.height; var r = new mxRectangle(rect.x, rect.y, w, h); var inset = w * Math.max(0, Math.min(1, parseFloat(mxUtils.getValue(this.style, 'size', this.size)))); if (this.isRounded) { var f = mxUtils.getValue(this.style, mxConstants.STYLE_ARCSIZE, mxConstants.RECTANGLE_ROUNDING_FACTOR * 100) / 100; inset = Math.max(inset, Math.min(w * f, h * f)); } r.x += Math.round(inset); r.width -= Math.round(2 * inset); return r; } return rect; }; ProcessShape.prototype.paintForeground = function(c, x, y, w, h) { var inset = w * Math.max(0, Math.min(1, parseFloat(mxUtils.getValue(this.style, 'size', this.size)))); if (this.isRounded) { var f = mxUtils.getValue(this.style, mxConstants.STYLE_ARCSIZE, mxConstants.RECTANGLE_ROUNDING_FACTOR * 100) / 100; inset = Math.max(inset, Math.min(w * f, h * f)); } // Crisp rendering of inner lines inset = Math.round(inset); c.begin(); c.moveTo(x + inset, y); c.lineTo(x + inset, y + h); c.moveTo(x + w - inset, y); c.lineTo(x + w - inset, y + h); c.end(); c.stroke(); mxRectangleShape.prototype.paintForeground.apply(this, arguments); }; mxCellRenderer.registerShape('process', ProcessShape); // Transparent Shape function TransparentShape() { mxRectangleShape.call(this); }; mxUtils.extend(TransparentShape, mxRectangleShape); TransparentShape.prototype.paintBackground = function(c, x, y, w, h) { c.setFillColor(mxConstants.NONE); c.rect(x, y, w, h); c.fill(); }; TransparentShape.prototype.paintForeground = function(c, x, y, w, h) { }; mxCellRenderer.registerShape('transparent', TransparentShape); // Callout shape function CalloutShape() { mxActor.call(this); }; mxUtils.extend(CalloutShape, mxHexagon); CalloutShape.prototype.size = 30; CalloutShape.prototype.position = 0.5; CalloutShape.prototype.position2 = 0.5; CalloutShape.prototype.base = 20; CalloutShape.prototype.getLabelMargins = function() { return new mxRectangle(0, 0, 0, parseFloat(mxUtils.getValue( this.style, 'size', this.size)) * this.scale); }; CalloutShape.prototype.redrawPath = function(c, x, y, w, h) { var arcSize = mxUtils.getValue(this.style, mxConstants.STYLE_ARCSIZE, mxConstants.LINE_ARCSIZE) / 2; var s = Math.max(0, Math.min(h, parseFloat(mxUtils.getValue(this.style, 'size', this.size)))); var dx = w * Math.max(0, Math.min(1, parseFloat(mxUtils.getValue(this.style, 'position', this.position)))); var dx2 = w * Math.max(0, Math.min(1, parseFloat(mxUtils.getValue(this.style, 'position2', this.position2)))); var base = Math.max(0, Math.min(w, parseFloat(mxUtils.getValue(this.style, 'base', this.base)))); this.addPoints(c, [new mxPoint(0, 0), new mxPoint(w, 0), new mxPoint(w, h - s), new mxPoint(Math.min(w, dx + base), h - s), new mxPoint(dx2, h), new mxPoint(Math.max(0, dx), h - s), new mxPoint(0, h - s)], this.isRounded, arcSize, true, [4]); }; mxCellRenderer.registerShape('callout', CalloutShape); // Step shape function StepShape() { mxActor.call(this); }; mxUtils.extend(StepShape, mxActor); StepShape.prototype.size = 0.2; StepShape.prototype.fixedSize = 20; StepShape.prototype.redrawPath = function(c, x, y, w, h) { var fixed = mxUtils.getValue(this.style, 'fixedSize', '0') != '0'; var s = (fixed) ? Math.max(0, Math.min(w, parseFloat(mxUtils.getValue(this.style, 'size', this.fixedSize)))) : w * Math.max(0, Math.min(1, parseFloat(mxUtils.getValue(this.style, 'size', this.size)))); var arcSize = mxUtils.getValue(this.style, mxConstants.STYLE_ARCSIZE, mxConstants.LINE_ARCSIZE) / 2; this.addPoints(c, [new mxPoint(0, 0), new mxPoint(w - s, 0), new mxPoint(w, h / 2), new mxPoint(w - s, h), new mxPoint(0, h), new mxPoint(s, h / 2)], this.isRounded, arcSize, true); c.end(); }; mxCellRenderer.registerShape('step', StepShape); // Hexagon shape function HexagonShape() { mxActor.call(this); }; mxUtils.extend(HexagonShape, mxHexagon); HexagonShape.prototype.size = 0.25; HexagonShape.prototype.redrawPath = function(c, x, y, w, h) { var s = w * Math.max(0, Math.min(1, parseFloat(mxUtils.getValue(this.style, 'size', this.size)))); var arcSize = mxUtils.getValue(this.style, mxConstants.STYLE_ARCSIZE, mxConstants.LINE_ARCSIZE) / 2; this.addPoints(c, [new mxPoint(s, 0), new mxPoint(w - s, 0), new mxPoint(w, 0.5 * h), new mxPoint(w - s, h), new mxPoint(s, h), new mxPoint(0, 0.5 * h)], this.isRounded, arcSize, true); }; mxCellRenderer.registerShape('hexagon', HexagonShape); // Plus Shape function PlusShape() { mxRectangleShape.call(this); }; mxUtils.extend(PlusShape, mxRectangleShape); PlusShape.prototype.isHtmlAllowed = function() { return false; }; PlusShape.prototype.paintForeground = function(c, x, y, w, h) { var border = Math.min(w / 5, h / 5) + 1; c.begin(); c.moveTo(x + w / 2, y + border); c.lineTo(x + w / 2, y + h - border); c.moveTo(x + border, y + h / 2); c.lineTo(x + w - border, y + h / 2); c.end(); c.stroke(); mxRectangleShape.prototype.paintForeground.apply(this, arguments); }; mxCellRenderer.registerShape('plus', PlusShape); // Overrides painting of rhombus shape to allow for double style var mxRhombusPaintVertexShape = mxRhombus.prototype.paintVertexShape; mxRhombus.prototype.getLabelBounds = function(rect) { if (this.style['double'] == 1) { var margin = (Math.max(2, this.strokewidth + 1) * 2 + parseFloat( this.style[mxConstants.STYLE_MARGIN] || 0)) * this.scale; return new mxRectangle(rect.x + margin, rect.y + margin, rect.width - 2 * margin, rect.height - 2 * margin); } return rect; }; mxRhombus.prototype.paintVertexShape = function(c, x, y, w, h) { mxRhombusPaintVertexShape.apply(this, arguments); if (!this.outline && this.style['double'] == 1) { var margin = Math.max(2, this.strokewidth + 1) * 2 + parseFloat(this.style[mxConstants.STYLE_MARGIN] || 0); x += margin; y += margin; w -= 2 * margin; h -= 2 * margin; if (w > 0 && h > 0) { c.setShadow(false); // Workaround for closure compiler bug where the lines with x and y above // are removed if arguments is used as second argument in call below. mxRhombusPaintVertexShape.apply(this, [c, x, y, w, h]); } } }; // CompositeShape function ExtendedShape() { mxRectangleShape.call(this); }; mxUtils.extend(ExtendedShape, mxRectangleShape); ExtendedShape.prototype.isHtmlAllowed = function() { return false; }; ExtendedShape.prototype.getLabelBounds = function(rect) { if (this.style['double'] == 1) { var margin = (Math.max(2, this.strokewidth + 1) + parseFloat( this.style[mxConstants.STYLE_MARGIN] || 0)) * this.scale; return new mxRectangle(rect.x + margin, rect.y + margin, rect.width - 2 * margin, rect.height - 2 * margin); } return rect; }; ExtendedShape.prototype.paintForeground = function(c, x, y, w, h) { if (this.style != null) { if (!this.outline && this.style['double'] == 1) { var margin = Math.max(2, this.strokewidth + 1) + parseFloat(this.style[mxConstants.STYLE_MARGIN] || 0); x += margin; y += margin; w -= 2 * margin; h -= 2 * margin; if (w > 0 && h > 0) { mxRectangleShape.prototype.paintBackground.apply(this, arguments); } } c.setDashed(false); // Draws the symbols defined in the style. The symbols are // numbered from 1...n. Possible postfixes are align, // verticalAlign, spacing, arcSpacing, width, height var counter = 0; var shape = null; do { shape = mxCellRenderer.defaultShapes[this.style['symbol' + counter]]; if (shape != null) { var align = this.style['symbol' + counter + 'Align']; var valign = this.style['symbol' + counter + 'VerticalAlign']; var width = this.style['symbol' + counter + 'Width']; var height = this.style['symbol' + counter + 'Height']; var spacing = this.style['symbol' + counter + 'Spacing'] || 0; var vspacing = this.style['symbol' + counter + 'VSpacing'] || spacing; var arcspacing = this.style['symbol' + counter + 'ArcSpacing']; if (arcspacing != null) { var arcSize = this.getArcSize(w + this.strokewidth, h + this.strokewidth) * arcspacing; spacing += arcSize; vspacing += arcSize; } var x2 = x; var y2 = y; if (align == mxConstants.ALIGN_CENTER) { x2 += (w - width) / 2; } else if (align == mxConstants.ALIGN_RIGHT) { x2 += w - width - spacing; } else { x2 += spacing; } if (valign == mxConstants.ALIGN_MIDDLE) { y2 += (h - height) / 2; } else if (valign == mxConstants.ALIGN_BOTTOM) { y2 += h - height - vspacing; } else { y2 += vspacing; } c.save(); // Small hack to pass style along into subshape var tmp = new shape(); // TODO: Clone style and override settings (eg. strokewidth) tmp.style = this.style; shape.prototype.paintVertexShape.call(tmp, c, x2, y2, width, height); c.restore(); } counter++; } while (shape != null); } // Paints glass effect mxRectangleShape.prototype.paintForeground.apply(this, arguments); }; mxCellRenderer.registerShape('ext', ExtendedShape); // Tape Shape, supports size style function MessageShape() { mxCylinder.call(this); }; mxUtils.extend(MessageShape, mxCylinder); MessageShape.prototype.redrawPath = function(path, x, y, w, h, isForeground) { if (isForeground) { path.moveTo(0, 0); path.lineTo(w / 2, h / 2); path.lineTo(w, 0); path.end(); } else { path.moveTo(0, 0); path.lineTo(w, 0); path.lineTo(w, h); path.lineTo(0, h); path.close(); } }; mxCellRenderer.registerShape('message', MessageShape); // UML Actor Shape function UmlActorShape() { mxShape.call(this); }; mxUtils.extend(UmlActorShape, mxShape); UmlActorShape.prototype.paintBackground = function(c, x, y, w, h) { c.translate(x, y); // Head c.ellipse(w / 4, 0, w / 2, h / 4); c.fillAndStroke(); c.begin(); c.moveTo(w / 2, h / 4); c.lineTo(w / 2, 2 * h / 3); // Arms c.moveTo(w / 2, h / 3); c.lineTo(0, h / 3); c.moveTo(w / 2, h / 3); c.lineTo(w, h / 3); // Legs c.moveTo(w / 2, 2 * h / 3); c.lineTo(0, h); c.moveTo(w / 2, 2 * h / 3); c.lineTo(w, h); c.end(); c.stroke(); }; // Replaces existing actor shape mxCellRenderer.registerShape('umlActor', UmlActorShape); // UML Boundary Shape function UmlBoundaryShape() { mxShape.call(this); }; mxUtils.extend(UmlBoundaryShape, mxShape); UmlBoundaryShape.prototype.getLabelMargins = function(rect) { return new mxRectangle(rect.width / 6, 0, 0, 0); }; UmlBoundaryShape.prototype.paintBackground = function(c, x, y, w, h) { c.translate(x, y); // Base line c.begin(); c.moveTo(0, h / 4); c.lineTo(0, h * 3 / 4); c.end(); c.stroke(); // Horizontal line c.begin(); c.moveTo(0, h / 2); c.lineTo(w / 6, h / 2); c.end(); c.stroke(); // Circle c.ellipse(w / 6, 0, w * 5 / 6, h); c.fillAndStroke(); }; // Replaces existing actor shape mxCellRenderer.registerShape('umlBoundary', UmlBoundaryShape); // UML Entity Shape function UmlEntityShape() { mxEllipse.call(this); }; mxUtils.extend(UmlEntityShape, mxEllipse); UmlEntityShape.prototype.paintVertexShape = function(c, x, y, w, h) { mxEllipse.prototype.paintVertexShape.apply(this, arguments); c.begin(); c.moveTo(x + w / 8, y + h); c.lineTo(x + w * 7 / 8, y + h); c.end(); c.stroke(); }; mxCellRenderer.registerShape('umlEntity', UmlEntityShape); // UML Destroy Shape function UmlDestroyShape() { mxShape.call(this); }; mxUtils.extend(UmlDestroyShape, mxShape); UmlDestroyShape.prototype.paintVertexShape = function(c, x, y, w, h) { c.translate(x, y); c.begin(); c.moveTo(w, 0); c.lineTo(0, h); c.moveTo(0, 0); c.lineTo(w, h); c.end(); c.stroke(); }; mxCellRenderer.registerShape('umlDestroy', UmlDestroyShape); // UML Control Shape function UmlControlShape() { mxShape.call(this); }; mxUtils.extend(UmlControlShape, mxShape); UmlControlShape.prototype.getLabelBounds = function(rect) { return new mxRectangle(rect.x, rect.y + rect.height / 8, rect.width, rect.height * 7 / 8); }; UmlControlShape.prototype.paintBackground = function(c, x, y, w, h) { c.translate(x, y); // Upper line c.begin(); c.moveTo(w * 3 / 8, h / 8 * 1.1); c.lineTo(w * 5 / 8, 0); c.end(); c.stroke(); // Circle c.ellipse(0, h / 8, w, h * 7 / 8); c.fillAndStroke(); }; UmlControlShape.prototype.paintForeground = function(c, x, y, w, h) { // Lower line c.begin(); c.moveTo(w * 3 / 8, h / 8 * 1.1); c.lineTo(w * 5 / 8, h / 4); c.end(); c.stroke(); }; // Replaces existing actor shape mxCellRenderer.registerShape('umlControl', UmlControlShape); // UML Lifeline Shape function UmlLifeline() { mxRectangleShape.call(this); }; mxUtils.extend(UmlLifeline, mxRectangleShape); UmlLifeline.prototype.size = 40; UmlLifeline.prototype.isHtmlAllowed = function() { return false; }; UmlLifeline.prototype.getLabelBounds = function(rect) { var size = Math.max(0, Math.min(rect.height, parseFloat( mxUtils.getValue(this.style, 'size', this.size)) * this.scale)); return new mxRectangle(rect.x, rect.y, rect.width, size); }; UmlLifeline.prototype.paintBackground = function(c, x, y, w, h) { var size = Math.max(0, Math.min(h, parseFloat(mxUtils.getValue(this.style, 'size', this.size)))); var participant = mxUtils.getValue(this.style, 'participant'); if (participant == null || this.state == null) { mxRectangleShape.prototype.paintBackground.call(this, c, x, y, w, size); } else { var ctor = this.state.view.graph.cellRenderer.getShape(participant); if (ctor != null && ctor != UmlLifeline) { var shape = new ctor(); shape.apply(this.state); c.save(); shape.paintVertexShape(c, x, y, w, size); c.restore(); } } if (size < h) { c.setDashed(true); c.begin(); c.moveTo(x + w / 2, y + size); c.lineTo(x + w / 2, y + h); c.end(); c.stroke(); } }; UmlLifeline.prototype.paintForeground = function(c, x, y, w, h) { var size = Math.max(0, Math.min(h, parseFloat(mxUtils.getValue(this.style, 'size', this.size)))); mxRectangleShape.prototype.paintForeground.call(this, c, x, y, w, Math.min(h, size)); }; mxCellRenderer.registerShape('umlLifeline', UmlLifeline); // UML Frame Shape function UmlFrame() { mxShape.call(this); }; mxUtils.extend(UmlFrame, mxShape); UmlFrame.prototype.width = 60; UmlFrame.prototype.height = 30; UmlFrame.prototype.corner = 10; UmlFrame.prototype.getLabelMargins = function(rect) { return new mxRectangle(0, 0, rect.width - (parseFloat(mxUtils.getValue(this.style, 'width', this.width) * this.scale)), rect.height - (parseFloat(mxUtils.getValue(this.style, 'height', this.height) * this.scale))); }; UmlFrame.prototype.paintBackground = function(c, x, y, w, h) { var co = this.corner; var w0 = Math.min(w, Math.max(co, parseFloat(mxUtils.getValue(this.style, 'width', this.width)))); var h0 = Math.min(h, Math.max(co * 1.5, parseFloat(mxUtils.getValue(this.style, 'height', this.height)))); c.begin(); c.moveTo(x, y); c.lineTo(x + w0, y); c.lineTo(x + w0, y + Math.max(0, h0 - co * 1.5)); c.lineTo(x + Math.max(0, w0 - co), y + h0); c.lineTo(x, y + h0); c.close(); c.fillAndStroke(); c.begin(); c.moveTo(x + w0, y); c.lineTo(x + w, y); c.lineTo(x + w, y + h); c.lineTo(x, y + h); c.lineTo(x, y + h0); c.stroke(); }; mxCellRenderer.registerShape('umlFrame', UmlFrame); mxPerimeter.LifelinePerimeter = function (bounds, vertex, next, orthogonal) { var size = UmlLifeline.prototype.size; if (vertex != null) { size = mxUtils.getValue(vertex.style, 'size', size) * vertex.view.scale; } var sw = (parseFloat(vertex.style[mxConstants.STYLE_STROKEWIDTH] || 1) * vertex.view.scale / 2) - 1; if (next.x < bounds.getCenterX()) { sw += 1; sw *= -1; } return new mxPoint(bounds.getCenterX() + sw, Math.min(bounds.y + bounds.height, Math.max(bounds.y + size, next.y))); }; mxStyleRegistry.putValue('lifelinePerimeter', mxPerimeter.LifelinePerimeter); mxPerimeter.OrthogonalPerimeter = function (bounds, vertex, next, orthogonal) { orthogonal = true; return mxPerimeter.RectanglePerimeter.apply(this, arguments); }; mxStyleRegistry.putValue('orthogonalPerimeter', mxPerimeter.OrthogonalPerimeter); mxPerimeter.BackbonePerimeter = function (bounds, vertex, next, orthogonal) { var sw = (parseFloat(vertex.style[mxConstants.STYLE_STROKEWIDTH] || 1) * vertex.view.scale / 2) - 1; if (vertex.style['backboneSize'] != null) { sw += (parseFloat(vertex.style['backboneSize']) * vertex.view.scale / 2) - 1; } if (vertex.style[mxConstants.STYLE_DIRECTION] == 'south' || vertex.style[mxConstants.STYLE_DIRECTION] == 'north') { if (next.x < bounds.getCenterX()) { sw += 1; sw *= -1; } return new mxPoint(bounds.getCenterX() + sw, Math.min(bounds.y + bounds.height, Math.max(bounds.y, next.y))); } else { if (next.y < bounds.getCenterY()) { sw += 1; sw *= -1; } return new mxPoint(Math.min(bounds.x + bounds.width, Math.max(bounds.x, next.x)), bounds.getCenterY() + sw); } }; mxStyleRegistry.putValue('backbonePerimeter', mxPerimeter.BackbonePerimeter); // Callout Perimeter mxPerimeter.CalloutPerimeter = function (bounds, vertex, next, orthogonal) { return mxPerimeter.RectanglePerimeter(mxUtils.getDirectedBounds(bounds, new mxRectangle(0, 0, 0, Math.max(0, Math.min(bounds.height, parseFloat(mxUtils.getValue(vertex.style, 'size', CalloutShape.prototype.size)) * vertex.view.scale))), vertex.style), vertex, next, orthogonal); }; mxStyleRegistry.putValue('calloutPerimeter', mxPerimeter.CalloutPerimeter); // Parallelogram Perimeter mxPerimeter.ParallelogramPerimeter = function (bounds, vertex, next, orthogonal) { var size = ParallelogramShape.prototype.size; if (vertex != null) { size = mxUtils.getValue(vertex.style, 'size', size); } var x = bounds.x; var y = bounds.y; var w = bounds.width; var h = bounds.height; var direction = (vertex != null) ? mxUtils.getValue( vertex.style, mxConstants.STYLE_DIRECTION, mxConstants.DIRECTION_EAST) : mxConstants.DIRECTION_EAST; var vertical = direction == mxConstants.DIRECTION_NORTH || direction == mxConstants.DIRECTION_SOUTH; var points; if (vertical) { var dy = h * Math.max(0, Math.min(1, size)); points = [new mxPoint(x, y), new mxPoint(x + w, y + dy), new mxPoint(x + w, y + h), new mxPoint(x, y + h - dy), new mxPoint(x, y)]; } else { var dx = w * Math.max(0, Math.min(1, size)); points = [new mxPoint(x + dx, y), new mxPoint(x + w, y), new mxPoint(x + w - dx, y + h), new mxPoint(x, y + h), new mxPoint(x + dx, y)]; } var cx = bounds.getCenterX(); var cy = bounds.getCenterY(); var p1 = new mxPoint(cx, cy); if (orthogonal) { if (next.x < x || next.x > x + w) { p1.y = next.y; } else { p1.x = next.x; } } return mxUtils.getPerimeterPoint(points, p1, next); }; mxStyleRegistry.putValue('parallelogramPerimeter', mxPerimeter.ParallelogramPerimeter); // Trapezoid Perimeter mxPerimeter.TrapezoidPerimeter = function (bounds, vertex, next, orthogonal) { var size = TrapezoidShape.prototype.size; if (vertex != null) { size = mxUtils.getValue(vertex.style, 'size', size); } var x = bounds.x; var y = bounds.y; var w = bounds.width; var h = bounds.height; var direction = (vertex != null) ? mxUtils.getValue( vertex.style, mxConstants.STYLE_DIRECTION, mxConstants.DIRECTION_EAST) : mxConstants.DIRECTION_EAST; var points; if (direction == mxConstants.DIRECTION_EAST) { var dx = w * Math.max(0, Math.min(1, size)); points = [new mxPoint(x + dx, y), new mxPoint(x + w - dx, y), new mxPoint(x + w, y + h), new mxPoint(x, y + h), new mxPoint(x + dx, y)]; } else if (direction == mxConstants.DIRECTION_WEST) { var dx = w * Math.max(0, Math.min(1, size)); points = [new mxPoint(x, y), new mxPoint(x + w, y), new mxPoint(x + w - dx, y + h), new mxPoint(x + dx, y + h), new mxPoint(x, y)]; } else if (direction == mxConstants.DIRECTION_NORTH) { var dy = h * Math.max(0, Math.min(1, size)); points = [new mxPoint(x, y + dy), new mxPoint(x + w, y), new mxPoint(x + w, y + h), new mxPoint(x, y + h - dy), new mxPoint(x, y + dy)]; } else { var dy = h * Math.max(0, Math.min(1, size)); points = [new mxPoint(x, y), new mxPoint(x + w, y + dy), new mxPoint(x + w, y + h - dy), new mxPoint(x, y + h), new mxPoint(x, y)]; } var cx = bounds.getCenterX(); var cy = bounds.getCenterY(); var p1 = new mxPoint(cx, cy); if (orthogonal) { if (next.x < x || next.x > x + w) { p1.y = next.y; } else { p1.x = next.x; } } return mxUtils.getPerimeterPoint(points, p1, next); }; mxStyleRegistry.putValue('trapezoidPerimeter', mxPerimeter.TrapezoidPerimeter); // Step Perimeter mxPerimeter.StepPerimeter = function (bounds, vertex, next, orthogonal) { var fixed = mxUtils.getValue(vertex.style, 'fixedSize', '0') != '0'; var size = (fixed) ? StepShape.prototype.fixedSize : StepShape.prototype.size; if (vertex != null) { size = mxUtils.getValue(vertex.style, 'size', size); } var x = bounds.x; var y = bounds.y; var w = bounds.width; var h = bounds.height; var cx = bounds.getCenterX(); var cy = bounds.getCenterY(); var direction = (vertex != null) ? mxUtils.getValue( vertex.style, mxConstants.STYLE_DIRECTION, mxConstants.DIRECTION_EAST) : mxConstants.DIRECTION_EAST; var points; if (direction == mxConstants.DIRECTION_EAST) { var dx = (fixed) ? Math.max(0, Math.min(w, size)) : w * Math.max(0, Math.min(1, size)); points = [new mxPoint(x, y), new mxPoint(x + w - dx, y), new mxPoint(x + w, cy), new mxPoint(x + w - dx, y + h), new mxPoint(x, y + h), new mxPoint(x + dx, cy), new mxPoint(x, y)]; } else if (direction == mxConstants.DIRECTION_WEST) { var dx = (fixed) ? Math.max(0, Math.min(w, size)) : w * Math.max(0, Math.min(1, size)); points = [new mxPoint(x + dx, y), new mxPoint(x + w, y), new mxPoint(x + w - dx, cy), new mxPoint(x + w, y + h), new mxPoint(x + dx, y + h), new mxPoint(x, cy), new mxPoint(x + dx, y)]; } else if (direction == mxConstants.DIRECTION_NORTH) { var dy = (fixed) ? Math.max(0, Math.min(h, size)) : h * Math.max(0, Math.min(1, size)); points = [new mxPoint(x, y + dy), new mxPoint(cx, y), new mxPoint(x + w, y + dy), new mxPoint(x + w, y + h), new mxPoint(cx, y + h - dy), new mxPoint(x, y + h), new mxPoint(x, y + dy)]; } else { var dy = (fixed) ? Math.max(0, Math.min(h, size)) : h * Math.max(0, Math.min(1, size)); points = [new mxPoint(x, y), new mxPoint(cx, y + dy), new mxPoint(x + w, y), new mxPoint(x + w, y + h - dy), new mxPoint(cx, y + h), new mxPoint(x, y + h - dy), new mxPoint(x, y)]; } var p1 = new mxPoint(cx, cy); if (orthogonal) { if (next.x < x || next.x > x + w) { p1.y = next.y; } else { p1.x = next.x; } } return mxUtils.getPerimeterPoint(points, p1, next); }; mxStyleRegistry.putValue('stepPerimeter', mxPerimeter.StepPerimeter); // Hexagon Perimeter 2 (keep existing one) mxPerimeter.HexagonPerimeter2 = function (bounds, vertex, next, orthogonal) { var size = HexagonShape.prototype.size; if (vertex != null) { size = mxUtils.getValue(vertex.style, 'size', size); } var x = bounds.x; var y = bounds.y; var w = bounds.width; var h = bounds.height; var cx = bounds.getCenterX(); var cy = bounds.getCenterY(); var direction = (vertex != null) ? mxUtils.getValue( vertex.style, mxConstants.STYLE_DIRECTION, mxConstants.DIRECTION_EAST) : mxConstants.DIRECTION_EAST; var vertical = direction == mxConstants.DIRECTION_NORTH || direction == mxConstants.DIRECTION_SOUTH; var points; if (vertical) { var dy = h * Math.max(0, Math.min(1, size)); points = [new mxPoint(cx, y), new mxPoint(x + w, y + dy), new mxPoint(x + w, y + h - dy), new mxPoint(cx, y + h), new mxPoint(x, y + h - dy), new mxPoint(x, y + dy), new mxPoint(cx, y)]; } else { var dx = w * Math.max(0, Math.min(1, size)); points = [new mxPoint(x + dx, y), new mxPoint(x + w - dx, y), new mxPoint(x + w, cy), new mxPoint(x + w - dx, y + h), new mxPoint(x + dx, y + h), new mxPoint(x, cy), new mxPoint(x + dx, y)]; } var p1 = new mxPoint(cx, cy); if (orthogonal) { if (next.x < x || next.x > x + w) { p1.y = next.y; } else { p1.x = next.x; } } return mxUtils.getPerimeterPoint(points, p1, next); }; mxStyleRegistry.putValue('hexagonPerimeter2', mxPerimeter.HexagonPerimeter2); // Lollipop Shape function LollipopShape() { mxShape.call(this); }; mxUtils.extend(LollipopShape, mxShape); LollipopShape.prototype.size = 10; LollipopShape.prototype.paintBackground = function(c, x, y, w, h) { var sz = parseFloat(mxUtils.getValue(this.style, 'size', this.size)); c.translate(x, y); c.ellipse((w - sz) / 2, 0, sz, sz); c.fillAndStroke(); c.begin(); c.moveTo(w / 2, sz); c.lineTo(w / 2, h); c.end(); c.stroke(); }; mxCellRenderer.registerShape('lollipop', LollipopShape); // Lollipop Shape function RequiresShape() { mxShape.call(this); }; mxUtils.extend(RequiresShape, mxShape); RequiresShape.prototype.size = 10; RequiresShape.prototype.inset = 2; RequiresShape.prototype.paintBackground = function(c, x, y, w, h) { var sz = parseFloat(mxUtils.getValue(this.style, 'size', this.size)); var inset = parseFloat(mxUtils.getValue(this.style, 'inset', this.inset)) + this.strokewidth; c.translate(x, y); c.begin(); c.moveTo(w / 2, sz + inset); c.lineTo(w / 2, h); c.end(); c.stroke(); c.begin(); c.moveTo((w - sz) / 2 - inset, sz / 2); c.quadTo((w - sz) / 2 - inset, sz + inset, w / 2, sz + inset); c.quadTo((w + sz) / 2 + inset, sz + inset, (w + sz) / 2 + inset, sz / 2); c.end(); c.stroke(); }; mxCellRenderer.registerShape('requires', RequiresShape); // Component shape function ComponentShape() { mxCylinder.call(this); }; mxUtils.extend(ComponentShape, mxCylinder); ComponentShape.prototype.jettyWidth = 32; ComponentShape.prototype.jettyHeight = 12; ComponentShape.prototype.redrawPath = function(path, x, y, w, h, isForeground) { var dx = parseFloat(mxUtils.getValue(this.style, 'jettyWidth', this.jettyWidth)); var dy = parseFloat(mxUtils.getValue(this.style, 'jettyHeight', this.jettyHeight)); var x0 = dx / 2; var x1 = x0 + dx / 2; var y0 = 0.3 * h - dy / 2; var y1 = 0.7 * h - dy / 2; if (isForeground) { path.moveTo(x0, y0); path.lineTo(x1, y0); path.lineTo(x1, y0 + dy); path.lineTo(x0, y0 + dy); path.moveTo(x0, y1); path.lineTo(x1, y1); path.lineTo(x1, y1 + dy); path.lineTo(x0, y1 + dy); path.end(); } else { path.moveTo(x0, 0); path.lineTo(w, 0); path.lineTo(w, h); path.lineTo(x0, h); path.lineTo(x0, y1 + dy); path.lineTo(0, y1 + dy); path.lineTo(0, y1); path.lineTo(x0, y1); path.lineTo(x0, y0 + dy); path.lineTo(0, y0 + dy); path.lineTo(0, y0); path.lineTo(x0, y0); path.close(); path.end(); } }; mxCellRenderer.registerShape('component', ComponentShape); // State Shapes derives from double ellipse function StateShape() { mxDoubleEllipse.call(this); }; mxUtils.extend(StateShape, mxDoubleEllipse); StateShape.prototype.outerStroke = true; StateShape.prototype.paintVertexShape = function(c, x, y, w, h) { var inset = Math.min(4, Math.min(w / 5, h / 5)); if (w > 0 && h > 0) { c.ellipse(x + inset, y + inset, w - 2 * inset, h - 2 * inset); c.fillAndStroke(); } c.setShadow(false); if (this.outerStroke) { c.ellipse(x, y, w, h); c.stroke(); } }; mxCellRenderer.registerShape('endState', StateShape); function StartStateShape() { StateShape.call(this); }; mxUtils.extend(StartStateShape, StateShape); StartStateShape.prototype.outerStroke = false; mxCellRenderer.registerShape('startState', StartStateShape); // Link shape function LinkShape() { mxArrowConnector.call(this); this.spacing = 0; }; mxUtils.extend(LinkShape, mxArrowConnector); LinkShape.prototype.defaultWidth = 4; LinkShape.prototype.isOpenEnded = function() { return true; }; LinkShape.prototype.getEdgeWidth = function() { return mxUtils.getNumber(this.style, 'width', this.defaultWidth) + Math.max(0, this.strokewidth - 1); }; LinkShape.prototype.isArrowRounded = function() { return this.isRounded; }; // Registers the link shape mxCellRenderer.registerShape('link', LinkShape); // Generic arrow function FlexArrowShape() { mxArrowConnector.call(this); this.spacing = 0; }; mxUtils.extend(FlexArrowShape, mxArrowConnector); FlexArrowShape.prototype.defaultWidth = 10; FlexArrowShape.prototype.defaultArrowWidth = 20; FlexArrowShape.prototype.getStartArrowWidth = function() { return this.getEdgeWidth() + mxUtils.getNumber(this.style, 'startWidth', this.defaultArrowWidth); }; FlexArrowShape.prototype.getEndArrowWidth = function() { return this.getEdgeWidth() + mxUtils.getNumber(this.style, 'endWidth', this.defaultArrowWidth);; }; FlexArrowShape.prototype.getEdgeWidth = function() { return mxUtils.getNumber(this.style, 'width', this.defaultWidth) + Math.max(0, this.strokewidth - 1); }; // Registers the link shape mxCellRenderer.registerShape('flexArrow', FlexArrowShape); // Manual Input shape function ManualInputShape() { mxActor.call(this); }; mxUtils.extend(ManualInputShape, mxActor); ManualInputShape.prototype.size = 30; ManualInputShape.prototype.redrawPath = function(c, x, y, w,