| /** |
| * Copyright (c) 2006-2015, JGraph Ltd |
| * Copyright (c) 2006-2015, Gaudenz Alder |
| */ |
| /** |
| * Class: mxMultiplicity |
| * |
| * Defines invalid connections along with the error messages that they produce. |
| * To add or remove rules on a graph, you must add/remove instances of this |
| * class to <mxGraph.multiplicities>. |
| * |
| * Example: |
| * |
| * (code) |
| * graph.multiplicities.push(new mxMultiplicity( |
| * true, 'rectangle', null, null, 0, 2, ['circle'], |
| * 'Only 2 targets allowed', |
| * 'Only circle targets allowed')); |
| * (end) |
| * |
| * Defines a rule where each rectangle must be connected to no more than 2 |
| * circles and no other types of targets are allowed. |
| * |
| * Constructor: mxMultiplicity |
| * |
| * Instantiate class mxMultiplicity in order to describe allowed |
| * connections in a graph. Not all constraints can be enforced while |
| * editing, some must be checked at validation time. The <countError> and |
| * <typeError> are treated as resource keys in <mxResources>. |
| * |
| * Parameters: |
| * |
| * source - Boolean indicating if this rule applies to the source or target |
| * terminal. |
| * type - Type of the source or target terminal that this rule applies to. |
| * See <type> for more information. |
| * attr - Optional attribute name to match the source or target terminal. |
| * value - Optional attribute value to match the source or target terminal. |
| * min - Minimum number of edges for this rule. Default is 1. |
| * max - Maximum number of edges for this rule. n means infinite. Default |
| * is n. |
| * validNeighbors - Array of types of the opposite terminal for which this |
| * rule applies. |
| * countError - Error to be displayed for invalid number of edges. |
| * typeError - Error to be displayed for invalid opposite terminals. |
| * validNeighborsAllowed - Optional boolean indicating if the array of |
| * opposite types should be valid or invalid. |
| */ |
| function mxMultiplicity(source, type, attr, value, min, max, |
| validNeighbors, countError, typeError, validNeighborsAllowed) |
| { |
| this.source = source; |
| this.type = type; |
| this.attr = attr; |
| this.value = value; |
| this.min = (min != null) ? min : 0; |
| this.max = (max != null) ? max : 'n'; |
| this.validNeighbors = validNeighbors; |
| this.countError = mxResources.get(countError) || countError; |
| this.typeError = mxResources.get(typeError) || typeError; |
| this.validNeighborsAllowed = (validNeighborsAllowed != null) ? |
| validNeighborsAllowed : true; |
| }; |
| |
| /** |
| * Variable: type |
| * |
| * Defines the type of the source or target terminal. The type is a string |
| * passed to <mxUtils.isNode> together with the source or target vertex |
| * value as the first argument. |
| */ |
| mxMultiplicity.prototype.type = null; |
| |
| /** |
| * Variable: attr |
| * |
| * Optional string that specifies the attributename to be passed to |
| * <mxUtils.isNode> to check if the rule applies to a cell. |
| */ |
| mxMultiplicity.prototype.attr = null; |
| |
| /** |
| * Variable: value |
| * |
| * Optional string that specifies the value of the attribute to be passed |
| * to <mxUtils.isNode> to check if the rule applies to a cell. |
| */ |
| mxMultiplicity.prototype.value = null; |
| |
| /** |
| * Variable: source |
| * |
| * Boolean that specifies if the rule is applied to the source or target |
| * terminal of an edge. |
| */ |
| mxMultiplicity.prototype.source = null; |
| |
| /** |
| * Variable: min |
| * |
| * Defines the minimum number of connections for which this rule applies. |
| * Default is 0. |
| */ |
| mxMultiplicity.prototype.min = null; |
| |
| /** |
| * Variable: max |
| * |
| * Defines the maximum number of connections for which this rule applies. |
| * A value of 'n' means unlimited times. Default is 'n'. |
| */ |
| mxMultiplicity.prototype.max = null; |
| |
| /** |
| * Variable: validNeighbors |
| * |
| * Holds an array of strings that specify the type of neighbor for which |
| * this rule applies. The strings are used in <mxCell.is> on the opposite |
| * terminal to check if the rule applies to the connection. |
| */ |
| mxMultiplicity.prototype.validNeighbors = null; |
| |
| /** |
| * Variable: validNeighborsAllowed |
| * |
| * Boolean indicating if the list of validNeighbors are those that are allowed |
| * for this rule or those that are not allowed for this rule. |
| */ |
| mxMultiplicity.prototype.validNeighborsAllowed = true; |
| |
| /** |
| * Variable: countError |
| * |
| * Holds the localized error message to be displayed if the number of |
| * connections for which the rule applies is smaller than <min> or greater |
| * than <max>. |
| */ |
| mxMultiplicity.prototype.countError = null; |
| |
| /** |
| * Variable: typeError |
| * |
| * Holds the localized error message to be displayed if the type of the |
| * neighbor for a connection does not match the rule. |
| */ |
| mxMultiplicity.prototype.typeError = null; |
| |
| /** |
| * Function: check |
| * |
| * Checks the multiplicity for the given arguments and returns the error |
| * for the given connection or null if the multiplicity does not apply. |
| * |
| * Parameters: |
| * |
| * graph - Reference to the enclosing <mxGraph> instance. |
| * edge - <mxCell> that represents the edge to validate. |
| * source - <mxCell> that represents the source terminal. |
| * target - <mxCell> that represents the target terminal. |
| * sourceOut - Number of outgoing edges from the source terminal. |
| * targetIn - Number of incoming edges for the target terminal. |
| */ |
| mxMultiplicity.prototype.check = function(graph, edge, source, target, sourceOut, targetIn) |
| { |
| var error = ''; |
| |
| if ((this.source && this.checkTerminal(graph, source, edge)) || |
| (!this.source && this.checkTerminal(graph, target, edge))) |
| { |
| if (this.countError != null && |
| ((this.source && (this.max == 0 || (sourceOut >= this.max))) || |
| (!this.source && (this.max == 0 || (targetIn >= this.max))))) |
| { |
| error += this.countError + '\n'; |
| } |
| |
| if (this.validNeighbors != null && this.typeError != null && this.validNeighbors.length > 0) |
| { |
| var isValid = this.checkNeighbors(graph, edge, source, target); |
| |
| if (!isValid) |
| { |
| error += this.typeError + '\n'; |
| } |
| } |
| } |
| |
| return (error.length > 0) ? error : null; |
| }; |
| |
| /** |
| * Function: checkNeighbors |
| * |
| * Checks if there are any valid neighbours in <validNeighbors>. This is only |
| * called if <validNeighbors> is a non-empty array. |
| */ |
| mxMultiplicity.prototype.checkNeighbors = function(graph, edge, source, target) |
| { |
| var sourceValue = graph.model.getValue(source); |
| var targetValue = graph.model.getValue(target); |
| var isValid = !this.validNeighborsAllowed; |
| var valid = this.validNeighbors; |
| |
| for (var j = 0; j < valid.length; j++) |
| { |
| if (this.source && |
| this.checkType(graph, targetValue, valid[j])) |
| { |
| isValid = this.validNeighborsAllowed; |
| break; |
| } |
| else if (!this.source && |
| this.checkType(graph, sourceValue, valid[j])) |
| { |
| isValid = this.validNeighborsAllowed; |
| break; |
| } |
| } |
| |
| return isValid; |
| }; |
| |
| /** |
| * Function: checkTerminal |
| * |
| * Checks the given terminal cell and returns true if this rule applies. The |
| * given cell is the source or target of the given edge, depending on |
| * <source>. This implementation uses <checkType> on the terminal's value. |
| */ |
| mxMultiplicity.prototype.checkTerminal = function(graph, terminal, edge) |
| { |
| var value = graph.model.getValue(terminal); |
| |
| return this.checkType(graph, value, this.type, this.attr, this.value); |
| }; |
| |
| /** |
| * Function: checkType |
| * |
| * Checks the type of the given value. |
| */ |
| mxMultiplicity.prototype.checkType = function(graph, value, type, attr, attrValue) |
| { |
| if (value != null) |
| { |
| if (!isNaN(value.nodeType)) // Checks if value is a DOM node |
| { |
| return mxUtils.isNode(value, type, attr, attrValue); |
| } |
| else |
| { |
| return value == type; |
| } |
| } |
| |
| return false; |
| }; |