/** * Copyright (c) 2006-2015, JGraph Ltd * Copyright (c) 2006-2015, Gaudenz Alder */ /** * Class: mxConnector * * Extends to implement a connector shape. The connector * shape allows for arrow heads on either side. * * This shape is registered under in * . * * Constructor: mxConnector * * Constructs a new connector shape. * * Parameters: * * points - Array of that define the points. This is stored in * . * stroke - String that defines the stroke color. This is stored in . * Default is 'black'. * strokewidth - Optional integer that defines the stroke width. Default is * 1. This is stored in . */ function mxConnector(points, stroke, strokewidth) { mxPolyline.call(this, points, stroke, strokewidth); }; /** * Extends mxPolyline. */ mxUtils.extend(mxConnector, mxPolyline); /** * Function: updateBoundingBox * * Updates the for this shape using and * and stores the result in . */ mxConnector.prototype.updateBoundingBox = function() { this.useSvgBoundingBox = this.style != null && this.style[mxConstants.STYLE_CURVED] == 1; mxShape.prototype.updateBoundingBox.apply(this, arguments); }; /** * Function: paintEdgeShape * * Paints the line shape. */ mxConnector.prototype.paintEdgeShape = function(c, pts) { // The indirection via functions for markers is needed in // order to apply the offsets before painting the line and // paint the markers after painting the line. var sourceMarker = this.createMarker(c, pts, true); var targetMarker = this.createMarker(c, pts, false); mxPolyline.prototype.paintEdgeShape.apply(this, arguments); // Disables shadows, dashed styles and fixes fill color for markers c.setFillColor(this.stroke); c.setShadow(false); c.setDashed(false); if (sourceMarker != null) { sourceMarker(); } if (targetMarker != null) { targetMarker(); } }; /** * Function: createMarker * * Prepares the marker by adding offsets in pts and returning a function to * paint the marker. */ mxConnector.prototype.createMarker = function(c, pts, source) { var result = null; var n = pts.length; var type = mxUtils.getValue(this.style, (source) ? mxConstants.STYLE_STARTARROW : mxConstants.STYLE_ENDARROW); var p0 = (source) ? pts[1] : pts[n - 2]; var pe = (source) ? pts[0] : pts[n - 1]; if (type != null && p0 != null && pe != null) { var count = 1; // Uses next non-overlapping point while (count < n - 1 && Math.round(p0.x - pe.x) == 0 && Math.round(p0.y - pe.y) == 0) { p0 = (source) ? pts[1 + count] : pts[n - 2 - count]; count++; } // Computes the norm and the inverse norm var dx = pe.x - p0.x; var dy = pe.y - p0.y; var dist = Math.max(1, Math.sqrt(dx * dx + dy * dy)); var unitX = dx / dist; var unitY = dy / dist; var size = mxUtils.getNumber(this.style, (source) ? mxConstants.STYLE_STARTSIZE : mxConstants.STYLE_ENDSIZE, mxConstants.DEFAULT_MARKERSIZE); // Allow for stroke width in the end point used and the // orthogonal vectors describing the direction of the marker var filled = this.style[(source) ? mxConstants.STYLE_STARTFILL : mxConstants.STYLE_ENDFILL] != 0; result = mxMarker.createMarker(c, this, type, pe, unitX, unitY, size, source, this.strokewidth, filled); } return result; }; /** * Function: augmentBoundingBox * * Augments the bounding box with the strokewidth and shadow offsets. */ mxConnector.prototype.augmentBoundingBox = function(bbox) { mxShape.prototype.augmentBoundingBox.apply(this, arguments); // Adds marker sizes var size = 0; if (mxUtils.getValue(this.style, mxConstants.STYLE_STARTARROW, mxConstants.NONE) != mxConstants.NONE) { size = mxUtils.getNumber(this.style, mxConstants.STYLE_STARTSIZE, mxConstants.DEFAULT_MARKERSIZE) + 1; } if (mxUtils.getValue(this.style, mxConstants.STYLE_ENDARROW, mxConstants.NONE) != mxConstants.NONE) { size = Math.max(size, mxUtils.getNumber(this.style, mxConstants.STYLE_ENDSIZE, mxConstants.DEFAULT_MARKERSIZE)) + 1; } bbox.grow(size * this.scale); };