/** * Copyright (c) 2006-2015, JGraph Ltd * Copyright (c) 2006-2015, Gaudenz Alder */ /** * Class: mxSwimlane * * Extends to implement a swimlane shape. This shape is registered * under in . Use the * to define the size of the title * region, for the content area fill, * to draw an additional vertical separator * and to hide the line between the title * region and the content area. The affects * the orientation of this shape, not only its label. * * Constructor: mxSwimlane * * Constructs a new swimlane shape. * * Parameters: * * bounds - that defines the bounds. This is stored in * . * fill - String that defines the fill color. This is stored in . * stroke - String that defines the stroke color. This is stored in . * strokewidth - Optional integer that defines the stroke width. Default is * 1. This is stored in . */ function mxSwimlane(bounds, fill, stroke, strokewidth) { mxShape.call(this); this.bounds = bounds; this.fill = fill; this.stroke = stroke; this.strokewidth = (strokewidth != null) ? strokewidth : 1; }; /** * Extends mxShape. */ mxUtils.extend(mxSwimlane, mxShape); /** * Variable: imageSize * * Default imagewidth and imageheight if an image but no imagewidth * and imageheight are defined in the style. Value is 16. */ mxSwimlane.prototype.imageSize = 16; /** * Function: isRoundable * * Adds roundable support. */ mxSwimlane.prototype.isRoundable = function(c, x, y, w, h) { return true; }; /** * Function: getTitleSize * * Returns the title size. */ mxSwimlane.prototype.getTitleSize = function() { return Math.max(0, mxUtils.getValue(this.style, mxConstants.STYLE_STARTSIZE, mxConstants.DEFAULT_STARTSIZE)); }; /** * Function: getLabelBounds * * Returns the bounding box for the label. */ mxSwimlane.prototype.getLabelBounds = function(rect) { var start = this.getTitleSize(); var bounds = new mxRectangle(rect.x, rect.y, rect.width, rect.height); var horizontal = this.isHorizontal(); var flipH = mxUtils.getValue(this.style, mxConstants.STYLE_FLIPH, 0) == 1; var flipV = mxUtils.getValue(this.style, mxConstants.STYLE_FLIPV, 0) == 1; // East is default var shapeVertical = (this.direction == mxConstants.DIRECTION_NORTH || this.direction == mxConstants.DIRECTION_SOUTH); var realHorizontal = horizontal == !shapeVertical; var realFlipH = !realHorizontal && flipH != (this.direction == mxConstants.DIRECTION_SOUTH || this.direction == mxConstants.DIRECTION_WEST); var realFlipV = realHorizontal && flipV != (this.direction == mxConstants.DIRECTION_SOUTH || this.direction == mxConstants.DIRECTION_WEST); // Shape is horizontal if (!shapeVertical) { var tmp = Math.min(bounds.height, start * this.scale); if (realFlipH || realFlipV) { bounds.y += bounds.height - tmp; } bounds.height = tmp; } else { var tmp = Math.min(bounds.width, start * this.scale); if (realFlipH || realFlipV) { bounds.x += bounds.width - tmp; } bounds.width = tmp; } return bounds; }; /** * Function: getGradientBounds * * Returns the bounding box for the gradient box for this shape. */ mxSwimlane.prototype.getGradientBounds = function(c, x, y, w, h) { var start = this.getTitleSize(); if (this.isHorizontal()) { start = Math.min(start, h); return new mxRectangle(x, y, w, start); } else { start = Math.min(start, w); return new mxRectangle(x, y, start, h); } }; /** * Function: getSwimlaneArcSize * * Returns the arcsize for the swimlane. */ mxSwimlane.prototype.getSwimlaneArcSize = function(w, h, start) { if (mxUtils.getValue(this.style, mxConstants.STYLE_ABSOLUTE_ARCSIZE, 0) == '1') { return 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; return start * f * 3; } }; /** * Function: isHorizontal * * Paints the swimlane vertex shape. */ mxSwimlane.prototype.isHorizontal = function() { return mxUtils.getValue(this.style, mxConstants.STYLE_HORIZONTAL, 1) == 1; }; /** * Function: paintVertexShape * * Paints the swimlane vertex shape. */ mxSwimlane.prototype.paintVertexShape = function(c, x, y, w, h) { var start = this.getTitleSize(); var fill = mxUtils.getValue(this.style, mxConstants.STYLE_SWIMLANE_FILLCOLOR, mxConstants.NONE); var swimlaneLine = mxUtils.getValue(this.style, mxConstants.STYLE_SWIMLANE_LINE, 1) == 1; var r = 0; if (this.isHorizontal()) { start = Math.min(start, h); } else { start = Math.min(start, w); } c.translate(x, y); if (!this.isRounded) { this.paintSwimlane(c, x, y, w, h, start, fill, swimlaneLine); } else { r = this.getSwimlaneArcSize(w, h, start); r = Math.min(((this.isHorizontal()) ? h : w) - start, Math.min(start, r)); this.paintRoundedSwimlane(c, x, y, w, h, start, r, fill, swimlaneLine); } var sep = mxUtils.getValue(this.style, mxConstants.STYLE_SEPARATORCOLOR, mxConstants.NONE); this.paintSeparator(c, x, y, w, h, start, sep); if (this.image != null) { var bounds = this.getImageBounds(x, y, w, h); c.image(bounds.x - x, bounds.y - y, bounds.width, bounds.height, this.image, false, false, false); } if (this.glass) { c.setShadow(false); this.paintGlassEffect(c, 0, 0, w, start, r); } }; /** * Function: paintSwimlane * * Paints the swimlane vertex shape. */ mxSwimlane.prototype.paintSwimlane = function(c, x, y, w, h, start, fill, swimlaneLine) { c.begin(); 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)) { c.pointerEvents = false; } if (this.isHorizontal()) { c.moveTo(0, start); c.lineTo(0, 0); c.lineTo(w, 0); c.lineTo(w, start); c.fillAndStroke(); if (start < h) { if (fill == mxConstants.NONE || !events) { c.pointerEvents = false; } if (fill != mxConstants.NONE) { c.setFillColor(fill); } c.begin(); c.moveTo(0, start); c.lineTo(0, h); c.lineTo(w, h); c.lineTo(w, start); if (fill == mxConstants.NONE) { c.stroke(); } else { c.fillAndStroke(); } } } else { c.moveTo(start, 0); c.lineTo(0, 0); c.lineTo(0, h); c.lineTo(start, h); c.fillAndStroke(); if (start < w) { if (fill == mxConstants.NONE || !events) { c.pointerEvents = false; } if (fill != mxConstants.NONE) { c.setFillColor(fill); } c.begin(); c.moveTo(start, 0); c.lineTo(w, 0); c.lineTo(w, h); c.lineTo(start, h); if (fill == mxConstants.NONE) { c.stroke(); } else { c.fillAndStroke(); } } } if (swimlaneLine) { this.paintDivider(c, x, y, w, h, start, fill == mxConstants.NONE); } }; /** * Function: paintRoundedSwimlane * * Paints the swimlane vertex shape. */ mxSwimlane.prototype.paintRoundedSwimlane = function(c, x, y, w, h, start, r, fill, swimlaneLine) { c.begin(); 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)) { c.pointerEvents = false; } if (this.isHorizontal()) { c.moveTo(w, start); c.lineTo(w, r); c.quadTo(w, 0, w - Math.min(w / 2, r), 0); c.lineTo(Math.min(w / 2, r), 0); c.quadTo(0, 0, 0, r); c.lineTo(0, start); c.fillAndStroke(); if (start < h) { if (fill == mxConstants.NONE || !events) { c.pointerEvents = false; } if (fill != mxConstants.NONE) { c.setFillColor(fill); } c.begin(); c.moveTo(0, start); c.lineTo(0, h - r); c.quadTo(0, h, Math.min(w / 2, r), h); c.lineTo(w - Math.min(w / 2, r), h); c.quadTo(w, h, w, h - r); c.lineTo(w, start); if (fill == mxConstants.NONE) { c.stroke(); } else { c.fillAndStroke(); } } } else { c.moveTo(start, 0); c.lineTo(r, 0); c.quadTo(0, 0, 0, Math.min(h / 2, r)); c.lineTo(0, h - Math.min(h / 2, r)); c.quadTo(0, h, r, h); c.lineTo(start, h); c.fillAndStroke(); if (start < w) { if (fill == mxConstants.NONE || !events) { c.pointerEvents = false; } if (fill != mxConstants.NONE) { c.setFillColor(fill); } c.begin(); c.moveTo(start, h); c.lineTo(w - r, h); c.quadTo(w, h, w, h - Math.min(h / 2, r)); c.lineTo(w, Math.min(h / 2, r)); c.quadTo(w, 0, w - r, 0); c.lineTo(start, 0); if (fill == mxConstants.NONE) { c.stroke(); } else { c.fillAndStroke(); } } } if (swimlaneLine) { this.paintDivider(c, x, y, w, h, start, fill == mxConstants.NONE); } }; /** * Function: paintDivider * * Paints the divider between swimlane title and content area. */ mxSwimlane.prototype.paintDivider = function(c, x, y, w, h, start, shadow) { if (!shadow) { c.setShadow(false); } c.begin(); if (this.isHorizontal()) { c.moveTo(0, start); c.lineTo(w, start); } else { c.moveTo(start, 0); c.lineTo(start, h); } c.stroke(); }; /** * Function: paintSeparator * * Paints the vertical or horizontal separator line between swimlanes. */ mxSwimlane.prototype.paintSeparator = function(c, x, y, w, h, start, color) { if (color != mxConstants.NONE) { c.setStrokeColor(color); c.setDashed(true); c.begin(); if (this.isHorizontal()) { c.moveTo(w, start); c.lineTo(w, h); } else { c.moveTo(start, 0); c.lineTo(w, 0); } c.stroke(); c.setDashed(false); } }; /** * Function: getImageBounds * * Paints the swimlane vertex shape. */ mxSwimlane.prototype.getImageBounds = function(x, y, w, h) { if (this.isHorizontal()) { return new mxRectangle(x + w - this.imageSize, y, this.imageSize, this.imageSize); } else { return new mxRectangle(x, y, this.imageSize, this.imageSize); } };