diff --git a/README.md b/README.md index 720f3f1..0aa468f 100644 --- a/README.md +++ b/README.md @@ -79,6 +79,8 @@ http://sebastien.drouyer.com/jquery.flowchart-demo/ * __toConnector:__ ID of the connector the link goes to. * __toSubConnector:__ (optional) If it is a multiple connector, which subconnector is it. * __color:__ Color of the link. If undefined, default value is the same as `defaultLinkColor`. + + * __linkRestrictions:__ (optional, default: `[]`) If not empty, define which links are allowed. Same structure as `links`. * __operatorTypes:__ (optional) Hash allowing you to define common operator types in order to not repeat the properties key. Key define the operator's type ID and the value define the properties (same structure as `data.operators.properties`). diff --git a/jquery.flowchart.css b/jquery.flowchart.css index ac15f3f..7ae4fbe 100644 --- a/jquery.flowchart.css +++ b/jquery.flowchart.css @@ -106,7 +106,8 @@ .flowchart-operator { position: absolute; - width: 140px; + min-width: 140px; + max-width: 250px; border: 1px solid #CCCCCC; background: #FAFAFA; pointer-events: initial; diff --git a/jquery.flowchart.js b/jquery.flowchart.js index 5c6ef03..f2363d3 100644 --- a/jquery.flowchart.js +++ b/jquery.flowchart.js @@ -22,12 +22,6 @@ $(function () { onOperatorUnselect: function () { return true; }, - onOperatorMouseOver: function (operatorId) { - return true; - }, - onOperatorMouseOut: function (operatorId) { - return true; - }, onLinkSelect: function (linkId) { return true; }, @@ -107,7 +101,8 @@ $(function () { _unitVariables: function () { this.data = { operators: {}, - links: {} + links: {}, + linkRestrictions: {} }; this.objs = { layers: { @@ -137,7 +132,7 @@ $(function () { }); - this.objs.layers.operators.on('pointerdown mousedown touchstart', '.flowchart-operator', function (e) { + this.objs.layers.operators.on('touchdown mousedown touchstart', '.flowchart-operator', function (e) { e.stopImmediatePropagation(); }); @@ -170,13 +165,6 @@ $(function () { self.selectLink($(this).data('link_id')); }); - this.objs.layers.operators.on('mouseover', '.flowchart-operator', function (e) { - self._operatorMouseOver($(this).data('operator_id')); - }); - - this.objs.layers.operators.on('mouseout', '.flowchart-operator', function (e) { - self._operatorMouseOut($(this).data('operator_id')); - }); }, @@ -187,6 +175,11 @@ $(function () { this.data.operatorTypes = data.operatorTypes; } + this.data.linkRestrictions = []; + if(typeof data.linkRestrictions != 'undefined' && data.linkRestrictions.length>0) { + this.data.linkRestrictions = data.linkRestrictions; + } + this.data.operators = {}; for (var operatorId in data.operators) { if (data.operators.hasOwnProperty(operatorId)) { @@ -217,6 +210,11 @@ $(function () { return; } + var restrictionLinkIndex = this._indexOfLinkGranted(linkData); + if(restrictionLinkIndex == -1) { + return; + } + var subConnectors = this._getSubConnectors(linkData); var fromSubConnector = subConnectors[0]; var toSubConnector = subConnectors[1]; @@ -246,11 +244,45 @@ $(function () { this._autoCreateSubConnector(linkData.fromOperator, linkData.fromConnector, 'outputs', fromSubConnector); this._autoCreateSubConnector(linkData.toOperator, linkData.toConnector, 'inputs', toSubConnector); + //try to colorize link with restriction link data + if(restrictionLinkIndex!=null) { + var restriction = this.data.linkRestrictions[restrictionLinkIndex]; + if(typeof restriction.color != 'undefined') { + linkData.color = restriction.color; + } + } + this.data.links[linkId] = linkData; - this._drawLink(linkId); - + this._drawLink(linkId) this.callbackEvent('afterChange', ['link_create']); }, + + /** Search into this.data.linkRestrictions if the given link is granted + * Return null if linkRestrictions is disabled (empty array) + * Return -1 if the link is forbidden, and the index into the link restriction array otherwise + */ + _indexOfLinkGranted: function(linkData) { + if(this.data.linkRestrictions.length == 0) { + return null; + } + + var linkRestrictions = this.data.linkRestrictions; + + for(var i=0; i'); $operator_connector.appendTo($operator_connector_set); @@ -550,9 +585,9 @@ $(function () { var $operator_connector_small_arrow = $('
'); $operator_connector_small_arrow.appendTo($operator_connector); - fullElement.connectors[connectorKey].push($operator_connector); - fullElement.connectorArrows[connectorKey].push($operator_connector_arrow); - fullElement.connectorSmallArrows[connectorKey].push($operator_connector_small_arrow); + fullElement[connectorType].connectors[connectorKey].push($operator_connector); + fullElement[connectorType].connectorArrows[connectorKey].push($operator_connector_arrow); + fullElement[connectorType].connectorSmallArrows[connectorKey].push($operator_connector_small_arrow); }, getOperatorElement: function (operatorData) { @@ -667,20 +702,23 @@ $(function () { _connectorClicked: function (operator, connector, subConnector, connectorCategory) { if (connectorCategory == 'outputs') { + this._restoreGrantedConnectorsColor(); var d = new Date(); // var currentTime = d.getTime(); this.lastOutputConnectorClicked = { operator: operator, connector: connector, - subConnector: subConnector + subConnector: subConnector, + grantedConnectors: this._getGrantedConnectors(operator, connector) }; this.objs.layers.temporaryLink.show(); - var position = this.getConnectorPosition(operator, connector, subConnector); + var position = this.getConnectorPosition(operator, connector, subConnector, connectorCategory); var x = position.x + position.width; var y = position.y; this.objs.temporaryLink.setAttribute('x1', x.toString()); this.objs.temporaryLink.setAttribute('y1', y.toString()); this._mousemove(x, y); + this._colorizeGrantedConnectors(); } if (connectorCategory == 'inputs' && this.lastOutputConnectorClicked != null) { var linkData = { @@ -692,12 +730,74 @@ $(function () { toSubConnector: subConnector }; - this.addLink(linkData); this._unsetTemporaryLink(); + this.addLink(linkData); + } + }, + + _getGrantedConnectors: function(operatorId, connector) { + var operatorType = this.data.operators[operatorId].type; + if(typeof operatorType=='undefined' || this.data.linkRestrictions.length==0) { + return []; + } + + var grantedLinks = this.data.linkRestrictions.filter(function(r) { + return operatorType==r.fromOperatorType && connector==r.fromConnector; + }); + + var grantedConnectors = []; + + for(var l in grantedLinks) { + var link = grantedLinks[l]; + + for(var opId in this.data.operators) { + var operator = this.data.operators[opId]; + if(operator.type == link.toOperatorType) { + var arrows = operator.internal.els.inputs.connectorArrows[link.toConnector]; + + if(arrows!=undefined) { + arrows = arrows.map(function(sa) { + return {els: sa, oldColor: sa.css('border-left-color')}; + }); + + grantedConnectors.push({ + color: typeof link.color=='undefined' ? this.options.defaultLinkColor : link.color, + arrows: arrows + }); + } + } + } + } + + return grantedConnectors; + }, + + _colorizeGrantedConnectors: function() { + if(this.lastOutputConnectorClicked != null) { + var grantedConnectors = this.lastOutputConnectorClicked.grantedConnectors; + + grantedConnectors.forEach(function(l) { + l.arrows.forEach(function(sa) { + sa.els.css('border-left-color', l.color); + }); + }); + } + }, + + _restoreGrantedConnectorsColor: function() { + if(this.lastOutputConnectorClicked != null) { + var grantedConnectors = this.lastOutputConnectorClicked.grantedConnectors; + + grantedConnectors.forEach(function(l) { + l.arrows.forEach(function(sa) { + sa.els.css('border-left-color', sa.oldColor); + }); + }); } }, _unsetTemporaryLink: function () { + this._restoreGrantedConnectorsColor(); this.lastOutputConnectorClicked = null; this.objs.layers.temporaryLink.hide(); }, @@ -911,7 +1011,8 @@ $(function () { }, _cleanMultipleConnectors: function (operator, connector, linkFromTo) { - if (!this.data.operators[operator].properties[linkFromTo == 'from' ? 'outputs' : 'inputs'][connector].multiple) { + var connectorType = linkFromTo == 'from' ? 'outputs' : 'inputs'; + if (!this.data.operators[operator].properties[connectorType][connector].multiple) { return; } @@ -961,10 +1062,12 @@ $(function () { }, getData: function () { - var keys = ['operators', 'links']; + var keys = ['operators', 'links', 'linkRestrictions']; var data = {}; data.operators = $.extend(true, {}, this.data.operators); data.links = $.extend(true, {}, this.data.links); + data.linkRestrictions = $.extend(true, [], this.data.linkRestrictions); + for (var keyI in keys) { if (keys.hasOwnProperty(keyI)) { var key = keys[keyI]; @@ -1009,10 +1112,6 @@ $(function () { this.redrawLinksLayer(); this.callbackEvent('afterChange', ['operator_data_change']); }, - - doesOperatorExists: function (operatorId) { - return typeof this.data.operators[operatorId] != 'undefined'; - }, getOperatorData: function (operatorId) { var data = $.extend(true, {}, this.data.operators[operatorId]); @@ -1028,7 +1127,8 @@ $(function () { operatorProperties = operatorData.properties; } return $.extend({}, typeProperties, operatorProperties); - } else { + } + else { return operatorData.properties; } }, @@ -1038,3 +1138,4 @@ $(function () { } }); }); +//# sourceURL=jquery-flowchart.js \ No newline at end of file diff --git a/jquery.flowchart.min.css b/jquery.flowchart.min.css index 459a2d1..5eb05b9 100644 --- a/jquery.flowchart.min.css +++ b/jquery.flowchart.min.css @@ -1 +1 @@ -.flowchart-container{position:relative;overflow:hidden}.flowchart-links-layer,.flowchart-operators-layer,.flowchart-temporary-link-layer{position:absolute;top:0;left:0;width:100%;height:100%}.flowchart-operator-inputs .flowchart-operator-connector-arrow,.flowchart-operator-inputs .flowchart-operator-connector-small-arrow{left:-1px}.flowchart-operators-layer,.flowchart-temporary-link-layer{pointer-events:none}.flowchart-temporary-link-layer{display:none}.flowchart-link,.flowchart-operator{cursor:default}.flowchart-operator-connector{position:relative;padding-top:5px;padding-bottom:5px}.flowchart-operator-connector-label{font-size:small}.flowchart-operator-inputs .flowchart-operator-connector-label{margin-left:14px}.flowchart-operator-outputs .flowchart-operator-connector-label{text-align:right;margin-right:5px}.flowchart-operator-connector-arrow{width:0;height:0;border-top:10px solid transparent;border-bottom:10px solid transparent;border-left:10px solid #ccc;position:absolute;top:0}.flowchart-operator-connector-small-arrow{width:0;height:0;border-top:5px solid transparent;border-bottom:5px solid transparent;border-left:5px solid transparent;position:absolute;top:5px;pointer-events:none}.flowchart-operator-connector:hover .flowchart-operator-connector-arrow{border-left:10px solid #999}.flowchart-operator-outputs .flowchart-operator-connector-arrow{right:-10px}.flowchart-operator-outputs .flowchart-operator-connector-small-arrow{right:-7px}.unselectable{-moz-user-select:none;-khtml-user-select:none;-webkit-user-select:none;-ms-user-select:none;user-select:none}.flowchart-operator{position:absolute;width:140px;border:1px solid #CCC;background:#FAFAFA;pointer-events:initial}.flowchart-operator.hover{border-color:#999}.flowchart-operator.selected{border-color:#555}.flowchart-operator .flowchart-operator-title{width:100%;padding:5px;font-weight:700;box-sizing:border-box;border-bottom:1px solid #DDD;background:#F0F0F0;height:auto;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;cursor:move}.flowchart-operator .flowchart-operator-inputs-outputs{display:table;width:100%;margin-top:5px;margin-bottom:5px}.flowchart-default-operator .flowchart-operator-outputs,.flowchart-operator .flowchart-operator-inputs{display:table-cell;width:50%} \ No newline at end of file +.flowchart-container{position:relative;overflow:hidden}.flowchart-links-layer,.flowchart-operators-layer,.flowchart-temporary-link-layer{position:absolute;top:0;left:0;width:100%;height:100%}.flowchart-operators-layer,.flowchart-temporary-link-layer{pointer-events:none}.flowchart-temporary-link-layer{display:none}.flowchart-link,.flowchart-operator{cursor:default}.flowchart-operator-connector{position:relative;padding-top:5px;padding-bottom:5px}.flowchart-operator-connector-label{font-size:small}.flowchart-operator-inputs .flowchart-operator-connector-label{margin-left:14px}.flowchart-operator-outputs .flowchart-operator-connector-label{text-align:right;margin-right:5px}.flowchart-operator-connector-arrow{width:0;height:0;border-top:10px solid transparent;border-bottom:10px solid transparent;border-left:10px solid #ccc;position:absolute;top:0}.flowchart-operator-connector-small-arrow{width:0;height:0;border-top:5px solid transparent;border-bottom:5px solid transparent;border-left:5px solid transparent;position:absolute;top:5px;pointer-events:none}.flowchart-operator-connector:hover .flowchart-operator-connector-arrow{border-left:10px solid #999}.flowchart-operator-inputs .flowchart-operator-connector-arrow{left:-1px}.flowchart-operator-outputs .flowchart-operator-connector-arrow{right:-10px}.flowchart-operator-inputs .flowchart-operator-connector-small-arrow{left:-1px}.flowchart-operator-outputs .flowchart-operator-connector-small-arrow{right:-7px}.unselectable{-moz-user-select:none;-khtml-user-select:none;-webkit-user-select:none;-ms-user-select:none;user-select:none}.flowchart-operator{position:absolute;min-width:140px;max-width:250px;border:1px solid #CCC;background:#FAFAFA;pointer-events:initial}.flowchart-operator.hover{border-color:#999}.flowchart-operator.selected{border-color:#555}.flowchart-operator .flowchart-operator-title{width:100%;padding:5px;font-weight:700;box-sizing:border-box;border-bottom:1px solid #DDD;background:#F0F0F0;height:auto;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;cursor:move}.flowchart-operator .flowchart-operator-inputs-outputs{display:table;width:100%;margin-top:5px;margin-bottom:5px}.flowchart-operator .flowchart-operator-inputs,.flowchart-default-operator .flowchart-operator-outputs{display:table-cell;width:50%} \ No newline at end of file diff --git a/jquery.flowchart.min.js b/jquery.flowchart.min.js index cbc0e69..a99d2f5 100644 --- a/jquery.flowchart.min.js +++ b/jquery.flowchart.min.js @@ -1 +1 @@ -$(function(){$.widget("flowchart.flowchart",{options:{canUserEditLinks:!0,canUserMoveOperators:!0,data:{},distanceFromArrow:3,defaultOperatorClass:"flowchart-default-operator",defaultLinkColor:"#3366ff",defaultSelectedLinkColor:"black",linkWidth:10,grid:20,multipleLinksOnOutput:!1,multipleLinksOnInput:!1,linkVerticalDecal:0,onOperatorSelect:function(t){return!0},onOperatorUnselect:function(){return!0},onOperatorMouseOver:function(t){return!0},onOperatorMouseOut:function(t){return!0},onLinkSelect:function(t){return!0},onLinkUnselect:function(){return!0},onOperatorCreate:function(t,e,r){return!0},onLinkCreate:function(t,e){return!0},onOperatorDelete:function(t){return!0},onLinkDelete:function(t,e){return!0},onOperatorMoved:function(t,e){},onAfterChange:function(t){}},data:null,objs:null,maskNum:0,linkNum:0,operatorNum:0,lastOutputConnectorClicked:null,selectedOperatorId:null,selectedLinkId:null,positionRatio:1,globalId:null,_create:function(){"undefined"==typeof document.__flowchartNumber?document.__flowchartNumber=0:document.__flowchartNumber++,this.globalId=document.__flowchartNumber,this._unitVariables(),this.element.addClass("flowchart-container"),this.objs.layers.links=$(''),this.objs.layers.links.appendTo(this.element),this.objs.layers.operators=$('
'),this.objs.layers.operators.appendTo(this.element),this.objs.layers.temporaryLink=$(''),this.objs.layers.temporaryLink.appendTo(this.element);var t=document.createElementNS("http://www.w3.org/2000/svg","line");t.setAttribute("x1","0"),t.setAttribute("y1","0"),t.setAttribute("x2","0"),t.setAttribute("y2","0"),t.setAttribute("stroke-dasharray","6,6"),t.setAttribute("stroke-width","4"),t.setAttribute("stroke","black"),t.setAttribute("fill","none"),this.objs.layers.temporaryLink[0].appendChild(t),this.objs.temporaryLink=t,this._initEvents(),"undefined"!=typeof this.options.data&&this.setData(this.options.data)},_unitVariables:function(){this.data={operators:{},links:{}},this.objs={layers:{operators:null,temporaryLink:null,links:null},linksContext:null,temporaryLink:null}},_initEvents:function(){var t=this;this.element.mousemove(function(e){var r=$(this),o=r.offset();t._mousemove((e.pageX-o.left)/t.positionRatio,(e.pageY-o.top)/t.positionRatio,e)}),this.element.click(function(e){var r=$(this),o=r.offset();t._click((e.pageX-o.left)/t.positionRatio,(e.pageY-o.top)/t.positionRatio,e)}),this.objs.layers.operators.on("pointerdown mousedown touchstart",".flowchart-operator",function(t){t.stopImmediatePropagation()}),this.objs.layers.operators.on("click",".flowchart-operator",function(e){0==$(e.target).closest(".flowchart-operator-connector").length&&t.selectOperator($(this).data("operator_id"))}),this.objs.layers.operators.on("click",".flowchart-operator-connector",function(){var e=$(this);t.options.canUserEditLinks&&t._connectorClicked(e.closest(".flowchart-operator").data("operator_id"),e.data("connector"),e.data("sub_connector"),e.closest(".flowchart-operator-connector-set").data("connector_type"))}),this.objs.layers.links.on("mousedown touchstart",".flowchart-link",function(t){t.stopImmediatePropagation()}),this.objs.layers.links.on("mouseover",".flowchart-link",function(){t._connecterMouseOver($(this).data("link_id"))}),this.objs.layers.links.on("mouseout",".flowchart-link",function(){t._connecterMouseOut($(this).data("link_id"))}),this.objs.layers.links.on("click",".flowchart-link",function(){t.selectLink($(this).data("link_id"))}),this.objs.layers.operators.on("mouseover",".flowchart-operator",function(e){t._operatorMouseOver($(this).data("operator_id"))}),this.objs.layers.operators.on("mouseout",".flowchart-operator",function(e){t._operatorMouseOut($(this).data("operator_id"))})},setData:function(t){this._clearOperatorsLayer(),this.data.operatorTypes={},"undefined"!=typeof t.operatorTypes&&(this.data.operatorTypes=t.operatorTypes),this.data.operators={};for(var e in t.operators)t.operators.hasOwnProperty(e)&&this.createOperator(e,t.operators[e]);this.data.links={};for(var r in t.links)t.links.hasOwnProperty(r)&&this.createLink(r,t.links[r]);this.redrawLinksLayer()},addLink:function(t){for(;"undefined"!=typeof this.data.links[this.linkNum];)this.linkNum++;return this.createLink(this.linkNum,t),this.linkNum},createLink:function(t,e){var r=$.extend(!0,{},e);if(this.callbackEvent("linkCreate",[t,r])){var o=this._getSubConnectors(r),n=o[0],a=o[1],i=this.options.multipleLinksOnOutput,s=this.options.multipleLinksOnInput;if(!i||!s)for(var l in this.data.links)if(this.data.links.hasOwnProperty(l)){var c=this.data.links[l],p=this._getSubConnectors(c),u=p[0],h=p[1];if(!i&&c.fromOperator==r.fromOperator&&c.fromConnector==r.fromConnector&&u==n){this.deleteLink(l);continue}s||c.toOperator!=r.toOperator||c.toConnector!=r.toConnector||h!=a||this.deleteLink(l)}this._autoCreateSubConnector(r.fromOperator,r.fromConnector,"outputs",n),this._autoCreateSubConnector(r.toOperator,r.toConnector,"inputs",a),this.data.links[t]=r,this._drawLink(t),this.callbackEvent("afterChange",["link_create"])}},_autoCreateSubConnector:function(t,e,r,o){var n=this.data.operators[t].properties[r][e];if(n.multiple)for(var a=this.data.operators[t].internal.els,i=this.data.operators[t].internal.els.connectors[e].length,s=i;o+2>s;s++)this._createSubConnector(e,n,a)},redrawLinksLayer:function(){this._clearLinksLayer();for(var t in this.data.links)this.data.links.hasOwnProperty(t)&&this._drawLink(t)},_clearLinksLayer:function(){this.objs.layers.links.empty(),this.objs.layers.operators.find(".flowchart-operator-connector-small-arrow").css("border-left-color","transparent")},_clearOperatorsLayer:function(){this.objs.layers.operators.empty()},getConnectorPosition:function(t,e,r){var o=this.data.operators[t],n=o.internal.els.connectorArrows[e][r],a=n.offset(),i=this.element.offset(),s=(a.left-i.left)/this.positionRatio,l=parseInt(n.css("border-top-width")),c=(a.top-i.top-1)/this.positionRatio+parseInt(n.css("border-left-width"));return{x:s,width:l,y:c}},getLinkMainColor:function(t){var e=this.options.defaultLinkColor,r=this.data.links[t];return"undefined"!=typeof r.color&&(e=r.color),e},setLinkMainColor:function(t,e){this.data.links[t].color=e,this.callbackEvent("afterChange",["link_change_main_color"])},_drawLink:function(t){var e=this.data.links[t];"undefined"==typeof e.internal&&(e.internal={}),e.internal.els={};var r=e.fromOperator,o=e.fromConnector,n=e.toOperator,a=e.toConnector,i=this._getSubConnectors(e),s=i[0],l=i[1],p=(this.getLinkMainColor(t),this.data.operators[r]),u=this.data.operators[n],h=p.internal.els.connectorSmallArrows[o][s],d=u.internal.els.connectorSmallArrows[a][l];e.internal.els.fromSmallConnector=h,e.internal.els.toSmallConnector=d;var f=document.createElementNS("http://www.w3.org/2000/svg","g");this.objs.layers.links[0].appendChild(f),e.internal.els.overallGroup=f;var v=document.createElementNS("http://www.w3.org/2000/svg","mask"),k="fc_mask_"+this.globalId+"_"+this.maskNum;this.maskNum++,v.setAttribute("id",k),f.appendChild(v);var m=document.createElementNS("http://www.w3.org/2000/svg","rect");m.setAttribute("x","0"),m.setAttribute("y","0"),m.setAttribute("width","100%"),m.setAttribute("height","100%"),m.setAttribute("stroke","none"),m.setAttribute("fill","white"),v.appendChild(m);var C=document.createElementNS("http://www.w3.org/2000/svg","polygon");C.setAttribute("stroke","none"),C.setAttribute("fill","black"),v.appendChild(C),e.internal.els.mask=C;var b=document.createElementNS("http://www.w3.org/2000/svg","g");b.setAttribute("class","flowchart-link"),b.setAttribute("data-link_id",t),f.appendChild(b);var w=document.createElementNS("http://www.w3.org/2000/svg","path");w.setAttribute("stroke-width",this.options.linkWidth.toString()),w.setAttribute("fill","none"),b.appendChild(w),e.internal.els.path=w;var O=document.createElementNS("http://www.w3.org/2000/svg","rect");O.setAttribute("stroke","none"),O.setAttribute("mask","url(#"+k+")"),b.appendChild(O),e.internal.els.rect=O,this._refreshLinkPositions(t),this.uncolorizeLink(t)},_getSubConnectors:function(t){var e=0;"undefined"!=typeof t.fromSubConnector&&(e=t.fromSubConnector);var r=0;return"undefined"!=typeof t.toSubConnector&&(r=t.toSubConnector),[e,r]},_refreshLinkPositions:function(t){var e=this.data.links[t],r=this._getSubConnectors(e),o=r[0],n=r[1],a=this.getConnectorPosition(e.fromOperator,e.fromConnector,o),i=this.getConnectorPosition(e.toOperator,e.toConnector,n),s=a.x,l=a.width,c=a.y,p=i.x,u=i.y;c+=this.options.linkVerticalDecal,u+=this.options.linkVerticalDecal;var h=this.options.distanceFromArrow;e.internal.els.mask.setAttribute("points",s+","+(c-l-h)+" "+(s+l+h)+","+c+" "+s+","+(c+l+h));var d=s+l+h,f=p+1,v=Math.min(100,Math.max(Math.abs(d-f)/2,Math.abs(c-u)));e.internal.els.path.setAttribute("d","M"+d+","+c+" C"+(s+l+h+v)+","+c+" "+(p-v)+","+u+" "+f+","+u),e.internal.els.rect.setAttribute("x",s),e.internal.els.rect.setAttribute("y",c-this.options.linkWidth/2),e.internal.els.rect.setAttribute("width",l+h+1),e.internal.els.rect.setAttribute("height",this.options.linkWidth)},getOperatorCompleteData:function(t){"undefined"==typeof t.internal&&(t.internal={}),this._refreshInternalProperties(t);var e=$.extend(!0,{},t.internal.properties);for(var r in e.inputs)e.inputs.hasOwnProperty(r)&&null==e.inputs[r]&&delete e.inputs[r];for(var o in e.outputs)e.outputs.hasOwnProperty(o)&&null==e.outputs[o]&&delete e.outputs[o];return"undefined"==typeof e["class"]&&(e["class"]=this.options.defaultOperatorClass),e},_getOperatorFullElement:function(t){function d(t,e,r,o){var n=$('
');n.data("connector_type",o),n.appendTo(r),l[t]=[],c[t]=[],u[t]=[],p[t]=n,s._createSubConnector(t,e,h)}var e=this.getOperatorCompleteData(t),r=$('
');r.addClass(e["class"]);var o=$('
');o.html(e.title),o.appendTo(r);var n=$('
');n.appendTo(r);var a=$('
');a.appendTo(n);var i=$('
');i.appendTo(n);var s=this,l={},c={},p={},u={},h={operator:r,title:o,connectorSets:p,connectors:u,connectorArrows:l,connectorSmallArrows:c};for(var f in e.inputs)e.inputs.hasOwnProperty(f)&&d(f,e.inputs[f],a,"inputs");for(var v in e.outputs)e.outputs.hasOwnProperty(v)&&d(v,e.outputs[v],i,"outputs");return h},_createSubConnector:function(t,e,r){var o=r.connectorSets[t],n=r.connectors[t].length,a=$('
');a.appendTo(o),a.data("connector",t),a.data("sub_connector",n);var i=$('
');i.text(e.label.replace("(:i)",n+1)),i.appendTo(a);var s=$('
');s.appendTo(a);var l=$('
');l.appendTo(a),r.connectors[t].push(a),r.connectorArrows[t].push(s),r.connectorSmallArrows[t].push(l)},getOperatorElement:function(t){var e=this._getOperatorFullElement(t);return e.operator},addOperator:function(t){for(;"undefined"!=typeof this.data.operators[this.operatorNum];)this.operatorNum++;return this.createOperator(this.operatorNum,t),this.operatorNum},createOperator:function(t,e){function a(t,r){e.top=r.top,e.left=r.left;for(var o in n.data.links)if(n.data.links.hasOwnProperty(o)){var a=n.data.links[o];(a.fromOperator==t||a.toOperator==t)&&n._refreshLinkPositions(o)}}e.internal={},this._refreshInternalProperties(e);var r=this._getOperatorFullElement(e);if(!this.callbackEvent("operatorCreate",[t,e,r]))return!1;var o=this.options.grid;o&&(e.top=Math.round(e.top/o)*o,e.left=Math.round(e.left/o)*o),r.operator.appendTo(this.objs.layers.operators),r.operator.css({top:e.top,left:e.left}),r.operator.data("operator_id",t),this.data.operators[t]=e,this.data.operators[t].internal.els=r,t==this.selectedOperatorId&&this._addSelectedClass(t);var n=this;if(this.options.canUserMoveOperators){var i,s;r.operator.draggable({containment:e.internal.properties.uncontained?!1:this.element,handle:".flowchart-operator-title",start:function(t,e){if(null!=n.lastOutputConnectorClicked)return void t.preventDefault();var r=n.element.offset();i=(t.pageX-r.left)/n.positionRatio-parseInt($(t.target).css("left")),s=(t.pageY-r.top)/n.positionRatio-parseInt($(t.target).css("top"))},drag:function(t,o){if(n.options.grid){var l=n.options.grid,c=n.element.offset();if(o.position.left=Math.round(((t.pageX-c.left)/n.positionRatio-i)/l)*l,o.position.top=Math.round(((t.pageY-c.top)/n.positionRatio-s)/l)*l,!e.internal.properties.uncontained){var p=$(this);o.position.left=Math.min(Math.max(o.position.left,0),n.element.width()-p.outerWidth()),o.position.top=Math.min(Math.max(o.position.top,0),n.element.height()-p.outerHeight())}o.offset.left=Math.round(o.position.left+c.left),o.offset.top=Math.round(o.position.top+c.top),r.operator.css({left:o.position.left,top:o.position.top})}a($(this).data("operator_id"),o.position)},stop:function(t,e){n._unsetTemporaryLink();var o=$(this).data("operator_id");a(o,e.position),r.operator.css({height:"auto"}),n.callbackEvent("operatorMoved",[o,e.position]),n.callbackEvent("afterChange",["operator_moved"])}})}this.callbackEvent("afterChange",["operator_create"])},_connectorClicked:function(t,e,r,o){if("outputs"==o){new Date;this.lastOutputConnectorClicked={operator:t,connector:e,subConnector:r},this.objs.layers.temporaryLink.show();var a=this.getConnectorPosition(t,e,r),i=a.x+a.width,s=a.y;this.objs.temporaryLink.setAttribute("x1",i.toString()),this.objs.temporaryLink.setAttribute("y1",s.toString()),this._mousemove(i,s)}if("inputs"==o&&null!=this.lastOutputConnectorClicked){var l={fromOperator:this.lastOutputConnectorClicked.operator,fromConnector:this.lastOutputConnectorClicked.connector,fromSubConnector:this.lastOutputConnectorClicked.subConnector,toOperator:t,toConnector:e,toSubConnector:r};this.addLink(l),this._unsetTemporaryLink()}},_unsetTemporaryLink:function(){this.lastOutputConnectorClicked=null,this.objs.layers.temporaryLink.hide()},_mousemove:function(t,e,r){null!=this.lastOutputConnectorClicked&&(this.objs.temporaryLink.setAttribute("x2",t),this.objs.temporaryLink.setAttribute("y2",e))},_click:function(t,e,r){var o=$(r.target);0==o.closest(".flowchart-operator-connector").length&&this._unsetTemporaryLink(),0==o.closest(".flowchart-operator").length&&this.unselectOperator(),0==o.closest(".flowchart-link").length&&this.unselectLink()},_removeSelectedClassOperators:function(){this.objs.layers.operators.find(".flowchart-operator").removeClass("selected")},unselectOperator:function(){if(null!=this.selectedOperatorId){if(!this.callbackEvent("operatorUnselect",[]))return;this._removeSelectedClassOperators(),this.selectedOperatorId=null}},_addSelectedClass:function(t){this.data.operators[t].internal.els.operator.addClass("selected")},callbackEvent:function(t,e){var r="on"+t.charAt(0).toUpperCase()+t.slice(1),o=this.options[r].apply(this,e);if(o!==!1){var n={result:o};this.element.trigger(t,e.concat([n])),o=n.result}return o},selectOperator:function(t){this.callbackEvent("operatorSelect",[t])&&(this.unselectLink(),this._removeSelectedClassOperators(),this._addSelectedClass(t),this.selectedOperatorId=t)},addClassOperator:function(t,e){this.data.operators[t].internal.els.operator.addClass(e)},removeClassOperator:function(t,e){this.data.operators[t].internal.els.operator.removeClass(e)},removeClassOperators:function(t){this.objs.layers.operators.find(".flowchart-operator").removeClass(t)},_addHoverClassOperator:function(t){this.data.operators[t].internal.els.operator.addClass("hover")},_removeHoverClassOperators:function(){this.objs.layers.operators.find(".flowchart-operator").removeClass("hover")},_operatorMouseOver:function(t){this.callbackEvent("operatorMouseOver",[t])&&this._addHoverClassOperator(t)},_operatorMouseOut:function(t){this.callbackEvent("operatorMouseOut",[t])&&this._removeHoverClassOperators()},getSelectedOperatorId:function(){return this.selectedOperatorId},getSelectedLinkId:function(){return this.selectedLinkId},_shadeColor:function(t,e){var r=parseInt(t.slice(1),16),o=0>e?0:255,n=0>e?-1*e:e,a=r>>16,i=r>>8&255,s=255&r;return"#"+(16777216+65536*(Math.round((o-a)*n)+a)+256*(Math.round((o-i)*n)+i)+(Math.round((o-s)*n)+s)).toString(16).slice(1)},colorizeLink:function(t,e){var r=this.data.links[t];r.internal.els.path.setAttribute("stroke",e),r.internal.els.rect.setAttribute("fill",e),r.internal.els.fromSmallConnector.css("border-left-color",e),r.internal.els.toSmallConnector.css("border-left-color",e)},uncolorizeLink:function(t){this.colorizeLink(t,this.getLinkMainColor(t))},_connecterMouseOver:function(t){this.selectedLinkId!=t&&this.colorizeLink(t,this._shadeColor(this.getLinkMainColor(t),-.4))},_connecterMouseOut:function(t){this.selectedLinkId!=t&&this.uncolorizeLink(t)},unselectLink:function(){if(null!=this.selectedLinkId){if(!this.callbackEvent("linkUnselect",[]))return;this.uncolorizeLink(this.selectedLinkId,this.options.defaultSelectedLinkColor),this.selectedLinkId=null}},selectLink:function(t){this.unselectLink(),this.callbackEvent("linkSelect",[t])&&(this.unselectOperator(),this.selectedLinkId=t,this.colorizeLink(t,this.options.defaultSelectedLinkColor))},deleteOperator:function(t){this._deleteOperator(t,!1)},_deleteOperator:function(t,e){if(!this.callbackEvent("operatorDelete",[t,e]))return!1;if(!e)for(var r in this.data.links)if(this.data.links.hasOwnProperty(r)){var o=this.data.links[r];(o.fromOperator==t||o.toOperator==t)&&this._deleteLink(r,!0)}e||t!=this.selectedOperatorId||this.unselectOperator(),this.data.operators[t].internal.els.operator.remove(),delete this.data.operators[t],this.callbackEvent("afterChange",["operator_delete"])},deleteLink:function(t){this._deleteLink(t,!1)},_deleteLink:function(t,e){if(this.selectedLinkId==t&&this.unselectLink(),this.callbackEvent("linkDelete",[t,e])||e){this.colorizeLink(t,"transparent");var r=this.data.links[t],o=r.fromOperator,n=r.fromConnector,a=r.toOperator,i=r.toConnector;r.internal.els.overallGroup.remove(),delete this.data.links[t],this._cleanMultipleConnectors(o,n,"from"),this._cleanMultipleConnectors(a,i,"to"),this.callbackEvent("afterChange",["link_delete"])}},_cleanMultipleConnectors:function(t,e,r){if(this.data.operators[t].properties["from"==r?"outputs":"inputs"][e].multiple){var o=-1,n=r+"Operator",a=r+"Connector",i=r+"SubConnector",s=this.data.operators[t].internal.els,l=s.connectors[e],c=l.length;for(var p in this.data.links)if(this.data.links.hasOwnProperty(p)){var u=this.data.links[p];u[n]==t&&u[a]==e&&od;d++)l[l.length-1].remove(),l.pop(),s.connectorArrows[e].pop(),s.connectorSmallArrows[e].pop()}},deleteSelected:function(){null!=this.selectedLinkId&&this.deleteLink(this.selectedLinkId),null!=this.selectedOperatorId&&this.deleteOperator(this.selectedOperatorId)},setPositionRatio:function(t){this.positionRatio=t},getPositionRatio:function(){return this.positionRatio},getData:function(){var t=["operators","links"],e={};e.operators=$.extend(!0,{},this.data.operators),e.links=$.extend(!0,{},this.data.links);for(var r in t)if(t.hasOwnProperty(r)){var o=t[r];for(var n in e[o])e[o].hasOwnProperty(n)&&delete e[o][n].internal}return e.operatorTypes=this.data.operatorTypes,e},setOperatorTitle:function(t,e){this.data.operators[t].internal.els.title.html(e),"undefined"==typeof this.data.operators[t].properties&&(this.data.operators[t].properties={}),this.data.operators[t].properties.title=e,this._refreshInternalProperties(this.data.operators[t]),this.callbackEvent("afterChange",["operator_title_change"])},getOperatorTitle:function(t){return this.data.operators[t].internal.properties.title},setOperatorData:function(t,e){var r=this.getOperatorCompleteData(e);for(var o in this.data.links)if(this.data.links.hasOwnProperty(o)){var n=this.data.links[o];(n.fromOperator==t&&"undefined"==typeof r.outputs[n.fromConnector]||n.toOperator==t&&"undefined"==typeof r.inputs[n.toConnector])&&this._deleteLink(o,!0)}this._deleteOperator(t,!0),this.createOperator(t,e),this.redrawLinksLayer(),this.callbackEvent("afterChange",["operator_data_change"])},doesOperatorExists:function(t){return"undefined"!=typeof this.data.operators[t]},getOperatorData:function(t){var e=$.extend(!0,{},this.data.operators[t]);return delete e.internal,e},getOperatorFullProperties:function(t){if("undefined"!=typeof t.type){var e=this.data.operatorTypes[t.type],r={};return"undefined"!=typeof t.properties&&(r=t.properties),$.extend({},e,r)}return t.properties},_refreshInternalProperties:function(t){t.internal.properties=this.getOperatorFullProperties(t)}})}); \ No newline at end of file +$(function(){$.widget("flowchart.flowchart",{options:{canUserEditLinks:!0,canUserMoveOperators:!0,data:{},distanceFromArrow:3,defaultOperatorClass:"flowchart-default-operator",defaultLinkColor:"#3366ff",defaultSelectedLinkColor:"black",linkWidth:10,grid:20,multipleLinksOnOutput:!1,multipleLinksOnInput:!1,linkVerticalDecal:0,onOperatorSelect:function(){return!0},onOperatorUnselect:function(){return!0},onLinkSelect:function(){return!0},onLinkUnselect:function(){return!0},onOperatorCreate:function(){return!0},onLinkCreate:function(){return!0},onOperatorDelete:function(){return!0},onLinkDelete:function(){return!0},onOperatorMoved:function(){},onAfterChange:function(){}},data:null,objs:null,maskNum:0,linkNum:0,operatorNum:0,lastOutputConnectorClicked:null,selectedOperatorId:null,selectedLinkId:null,positionRatio:1,globalId:null,_create:function(){"undefined"==typeof document.__flowchartNumber?document.__flowchartNumber=0:document.__flowchartNumber++,this.globalId=document.__flowchartNumber,this._unitVariables(),this.element.addClass("flowchart-container"),this.objs.layers.links=$(''),this.objs.layers.links.appendTo(this.element),this.objs.layers.operators=$('
'),this.objs.layers.operators.appendTo(this.element),this.objs.layers.temporaryLink=$(''),this.objs.layers.temporaryLink.appendTo(this.element);var a=document.createElementNS("http://www.w3.org/2000/svg","line");a.setAttribute("x1","0"),a.setAttribute("y1","0"),a.setAttribute("x2","0"),a.setAttribute("y2","0"),a.setAttribute("stroke-dasharray","6,6"),a.setAttribute("stroke-width","4"),a.setAttribute("stroke","black"),a.setAttribute("fill","none"),this.objs.layers.temporaryLink[0].appendChild(a),this.objs.temporaryLink=a,this._initEvents(),"undefined"!=typeof this.options.data&&this.setData(this.options.data)},_unitVariables:function(){this.data={operators:{},links:{},linkRestrictions:{}},this.objs={layers:{operators:null,temporaryLink:null,links:null},linksContext:null,temporaryLink:null}},_initEvents:function(){var a=this;this.element.mousemove(function(b){var c=$(this),d=c.offset();a._mousemove((b.pageX-d.left)/a.positionRatio,(b.pageY-d.top)/a.positionRatio,b)}),this.element.click(function(b){var c=$(this),d=c.offset();a._click((b.pageX-d.left)/a.positionRatio,(b.pageY-d.top)/a.positionRatio,b)}),this.objs.layers.operators.on("touchdown mousedown touchstart",".flowchart-operator",function(a){a.stopImmediatePropagation()}),this.objs.layers.operators.on("click",".flowchart-operator",function(b){0==$(b.target).closest(".flowchart-operator-connector").length&&a.selectOperator($(this).data("operator_id"))}),this.objs.layers.operators.on("click",".flowchart-operator-connector",function(){var b=$(this);a.options.canUserEditLinks&&a._connectorClicked(b.closest(".flowchart-operator").data("operator_id"),b.data("connector"),b.data("sub_connector"),b.closest(".flowchart-operator-connector-set").data("connector_type"))}),this.objs.layers.links.on("mousedown touchstart",".flowchart-link",function(a){a.stopImmediatePropagation()}),this.objs.layers.links.on("mouseover",".flowchart-link",function(){a._connecterMouseOver($(this).data("link_id"))}),this.objs.layers.links.on("mouseout",".flowchart-link",function(){a._connecterMouseOut($(this).data("link_id"))}),this.objs.layers.links.on("click",".flowchart-link",function(){a.selectLink($(this).data("link_id"))})},setData:function(a){this._clearOperatorsLayer(),this.data.operatorTypes={},"undefined"!=typeof a.operatorTypes&&(this.data.operatorTypes=a.operatorTypes),this.data.linkRestrictions=[],"undefined"!=typeof a.linkRestrictions&&a.linkRestrictions.length>0&&(this.data.linkRestrictions=a.linkRestrictions),this.data.operators={};for(var b in a.operators)a.operators.hasOwnProperty(b)&&this.createOperator(b,a.operators[b]);this.data.links={};for(var c in a.links)a.links.hasOwnProperty(c)&&this.createLink(c,a.links[c]);this.redrawLinksLayer()},addLink:function(a){for(;"undefined"!=typeof this.data.links[this.linkNum];)this.linkNum++;return this.createLink(this.linkNum,a),this.linkNum},createLink:function(a,b){var c=$.extend(!0,{},b);if(this.callbackEvent("linkCreate",[a,c])){var d=this._indexOfLinkGranted(c);if(-1!=d){var e=this._getSubConnectors(c),f=e[0],g=e[1],h=this.options.multipleLinksOnOutput,i=this.options.multipleLinksOnInput;if(!h||!i)for(var j in this.data.links)if(this.data.links.hasOwnProperty(j)){var k=this.data.links[j],l=this._getSubConnectors(k),m=l[0],n=l[1];if(!h&&k.fromOperator==c.fromOperator&&k.fromConnector==c.fromConnector&&m==f){this.deleteLink(j);continue}i||k.toOperator!=c.toOperator||k.toConnector!=c.toConnector||n!=g||this.deleteLink(j)}if(this._autoCreateSubConnector(c.fromOperator,c.fromConnector,"outputs",f),this._autoCreateSubConnector(c.toOperator,c.toConnector,"inputs",g),null!=d){var o=this.data.linkRestrictions[d];"undefined"!=typeof o.color&&(c.color=o.color)}this.data.links[a]=c,this._drawLink(a),this.callbackEvent("afterChange",["link_create"])}}},_indexOfLinkGranted:function(a){if(0==this.data.linkRestrictions.length)return null;for(var b=this.data.linkRestrictions,c=0;ch;h++)this._createSubConnector(b,e,f,c)},redrawLinksLayer:function(){this._clearLinksLayer();for(var a in this.data.links)this.data.links.hasOwnProperty(a)&&this._drawLink(a)},_clearLinksLayer:function(){this.objs.layers.links.empty(),this.objs.layers.operators.find(".flowchart-operator-connector-small-arrow").css("border-left-color","transparent")},_clearOperatorsLayer:function(){this.objs.layers.operators.empty()},getConnectorPosition:function(a,b,c,d){var e=this.data.operators[a],f=e.internal.els[d].connectorArrows[b][c],g=f.offset(),h=this.element.offset(),i=(g.left-h.left)/this.positionRatio,j=parseInt(f.css("border-top-width")),k=(g.top-h.top-1)/this.positionRatio+parseInt(f.css("border-left-width"));return{x:i,width:j,y:k}},getLinkMainColor:function(a){var b=this.options.defaultLinkColor,c=this.data.links[a];return"undefined"!=typeof c.color&&(b=c.color),b},setLinkMainColor:function(a,b){this.data.links[a].color=b,this.callbackEvent("afterChange",["link_change_main_color"])},_drawLink:function(a){var b=this.data.links[a];"undefined"==typeof b.internal&&(b.internal={}),b.internal.els={};var c=b.fromOperator,d=b.fromConnector,e=b.toOperator,f=b.toConnector,g=this._getSubConnectors(b),h=g[0],i=g[1],j=(this.getLinkMainColor(a),this.data.operators[c]),k=this.data.operators[e],l=j.internal.els.outputs.connectorSmallArrows[d][h],m=k.internal.els.inputs.connectorSmallArrows[f][i];b.internal.els.fromSmallConnector=l,b.internal.els.toSmallConnector=m;var n=document.createElementNS("http://www.w3.org/2000/svg","g");this.objs.layers.links[0].appendChild(n),b.internal.els.overallGroup=n;var o=document.createElementNS("http://www.w3.org/2000/svg","mask"),p="fc_mask_"+this.globalId+"_"+this.maskNum;this.maskNum++,o.setAttribute("id",p),n.appendChild(o);var q=document.createElementNS("http://www.w3.org/2000/svg","rect");q.setAttribute("x","0"),q.setAttribute("y","0"),q.setAttribute("width","100%"),q.setAttribute("height","100%"),q.setAttribute("stroke","none"),q.setAttribute("fill","white"),o.appendChild(q);var r=document.createElementNS("http://www.w3.org/2000/svg","polygon");r.setAttribute("stroke","none"),r.setAttribute("fill","black"),o.appendChild(r),b.internal.els.mask=r;var s=document.createElementNS("http://www.w3.org/2000/svg","g");s.setAttribute("class","flowchart-link"),s.setAttribute("data-link_id",a),n.appendChild(s);var t=document.createElementNS("http://www.w3.org/2000/svg","path");t.setAttribute("stroke-width",this.options.linkWidth.toString()),t.setAttribute("fill","none"),s.appendChild(t),b.internal.els.path=t;var u=document.createElementNS("http://www.w3.org/2000/svg","rect");u.setAttribute("stroke","none"),u.setAttribute("mask","url(#"+p+")"),s.appendChild(u),b.internal.els.rect=u,this._refreshLinkPositions(a),this.uncolorizeLink(a)},_getSubConnectors:function(a){var b=0;"undefined"!=typeof a.fromSubConnector&&(b=a.fromSubConnector);var c=0;return"undefined"!=typeof a.toSubConnector&&(c=a.toSubConnector),[b,c]},_refreshLinkPositions:function(a){var b=this.data.links[a],c=this._getSubConnectors(b),d=c[0],e=c[1],f=this.getConnectorPosition(b.fromOperator,b.fromConnector,d,"outputs"),g=this.getConnectorPosition(b.toOperator,b.toConnector,e,"inputs"),h=f.x,i=f.width,j=f.y,k=g.x,l=g.y;j+=this.options.linkVerticalDecal,l+=this.options.linkVerticalDecal;var m=this.options.distanceFromArrow;b.internal.els.mask.setAttribute("points",h+","+(j-i-m)+" "+(h+i+m)+","+j+" "+h+","+(j+i+m));var n=h+i+m,o=k+1,p=Math.min(100,Math.max(Math.abs(n-o)/2,Math.abs(j-l)));b.internal.els.path.setAttribute("d","M"+n+","+j+" C"+(h+i+m+p)+","+j+" "+(k-p)+","+l+" "+o+","+l),b.internal.els.rect.setAttribute("x",h),b.internal.els.rect.setAttribute("y",j-this.options.linkWidth/2),b.internal.els.rect.setAttribute("width",i+m+1),b.internal.els.rect.setAttribute("height",this.options.linkWidth)},getOperatorCompleteData:function(a){"undefined"==typeof a.internal&&(a.internal={}),this._refreshInternalProperties(a);var b=$.extend(!0,{},a.internal.properties);for(var c in b.inputs)b.inputs.hasOwnProperty(c)&&null==b.inputs[c]&&delete b.inputs[c];for(var d in b.outputs)b.outputs.hasOwnProperty(d)&&null==b.outputs[d]&&delete b.outputs[d];return"undefined"==typeof b.class&&(b.class=this.options.defaultOperatorClass),b},_getOperatorFullElement:function(a){function b(a,b,c,d){var e=$('
');e.data("connector_type",d),e.appendTo(c),j[d].connectorArrows[a]=[],j[d].connectorSmallArrows[a]=[],j[d].connectors[a]=[],j[d].connectorSets[a]=e,i._createSubConnector(a,b,j,d)}var c=this.getOperatorCompleteData(a),d=$('
');d.addClass(c.class);var e=$('
');e.html(c.title),e.appendTo(d);var f=$('
');f.appendTo(d);var g=$('
');g.appendTo(f);var h=$('
');h.appendTo(f);var i=this,j={operator:d,title:e,inputs:{connectorSets:{},connectors:{},connectorArrows:{},connectorSmallArrows:{}},outputs:{connectorSets:{},connectors:{},connectorArrows:{},connectorSmallArrows:{}}};for(var k in c.inputs)c.inputs.hasOwnProperty(k)&&b(k,c.inputs[k],g,"inputs");for(var l in c.outputs)c.outputs.hasOwnProperty(l)&&b(l,c.outputs[l],h,"outputs");return j},_createSubConnector:function(a,b,c,d){var e=c[d].connectorSets[a],f=c[d].connectors[a].length,g=$('
');g.appendTo(e),g.data("connector",a),g.data("sub_connector",f);var h=$('
');h.text(b.label.replace("(:i)",f+1)),h.appendTo(g);var i=$('
');i.appendTo(g);var j=$('
');j.appendTo(g),c[d].connectors[a].push(g),c[d].connectorArrows[a].push(i),c[d].connectorSmallArrows[a].push(j)},getOperatorElement:function(a){var b=this._getOperatorFullElement(a);return b.operator},addOperator:function(a){for(;"undefined"!=typeof this.data.operators[this.operatorNum];)this.operatorNum++;return this.createOperator(this.operatorNum,a),this.operatorNum},createOperator:function(a,b){function c(a,c){b.top=c.top,b.left=c.left;for(var d in f.data.links)if(f.data.links.hasOwnProperty(d)){var e=f.data.links[d];(e.fromOperator==a||e.toOperator==a)&&f._refreshLinkPositions(d)}}b.internal={},this._refreshInternalProperties(b);var d=this._getOperatorFullElement(b);if(!this.callbackEvent("operatorCreate",[a,b,d]))return!1;var e=this.options.grid;e&&(b.top=Math.round(b.top/e)*e,b.left=Math.round(b.left/e)*e),d.operator.appendTo(this.objs.layers.operators),d.operator.css({top:b.top,left:b.left}),d.operator.data("operator_id",a),this.data.operators[a]=b,this.data.operators[a].internal.els=d,a==this.selectedOperatorId&&this._addSelectedClass(a);var f=this;if(this.options.canUserMoveOperators){var g,h;d.operator.draggable({containment:b.internal.properties.uncontained?!1:this.element,handle:".flowchart-operator-title",start:function(a){if(null!=f.lastOutputConnectorClicked)return void a.preventDefault();var b=f.element.offset();g=(a.pageX-b.left)/f.positionRatio-parseInt($(a.target).css("left")),h=(a.pageY-b.top)/f.positionRatio-parseInt($(a.target).css("top"))},drag:function(a,e){if(f.options.grid){var i=f.options.grid,j=f.element.offset();if(e.position.left=Math.round(((a.pageX-j.left)/f.positionRatio-g)/i)*i,e.position.top=Math.round(((a.pageY-j.top)/f.positionRatio-h)/i)*i,!b.internal.properties.uncontained){var k=$(this);e.position.left=Math.min(Math.max(e.position.left,0),f.element.width()-k.outerWidth()),e.position.top=Math.min(Math.max(e.position.top,0),f.element.height()-k.outerHeight())}e.offset.left=Math.round(e.position.left+j.left),e.offset.top=Math.round(e.position.top+j.top),d.operator.css({left:e.position.left,top:e.position.top})}c($(this).data("operator_id"),e.position)},stop:function(a,b){f._unsetTemporaryLink();var e=$(this).data("operator_id");c(e,b.position),d.operator.css({height:"auto"}),f.callbackEvent("operatorMoved",[e,b.position]),f.callbackEvent("afterChange",["operator_moved"])}})}this.callbackEvent("afterChange",["operator_create"])},_connectorClicked:function(a,b,c,d){if("outputs"==d){this._restoreGrantedConnectorsColor();{new Date}this.lastOutputConnectorClicked={operator:a,connector:b,subConnector:c,grantedConnectors:this._getGrantedConnectors(a,b)},this.objs.layers.temporaryLink.show();var e=this.getConnectorPosition(a,b,c,d),f=e.x+e.width,g=e.y;this.objs.temporaryLink.setAttribute("x1",f.toString()),this.objs.temporaryLink.setAttribute("y1",g.toString()),this._mousemove(f,g),this._colorizeGrantedConnectors()}if("inputs"==d&&null!=this.lastOutputConnectorClicked){var h={fromOperator:this.lastOutputConnectorClicked.operator,fromConnector:this.lastOutputConnectorClicked.connector,fromSubConnector:this.lastOutputConnectorClicked.subConnector,toOperator:a,toConnector:b,toSubConnector:c};this._unsetTemporaryLink(),this.addLink(h)}},_getGrantedConnectors:function(a,b){var c=this.data.operators[a].type;if("undefined"==typeof c||0==this.data.linkRestrictions.length)return[];var d=this.data.linkRestrictions.filter(function(a){return c==a.fromOperatorType&&b==a.fromConnector}),e=[];for(var f in d){var g=d[f];for(var h in this.data.operators){var i=this.data.operators[h];if(i.type==g.toOperatorType){var j=i.internal.els.inputs.connectorArrows[g.toConnector];void 0!=j&&(j=j.map(function(a){return{els:a,oldColor:a.css("border-left-color")}}),e.push({color:"undefined"==typeof g.color?this.options.defaultLinkColor:g.color,arrows:j}))}}}return e},_colorizeGrantedConnectors:function(){if(null!=this.lastOutputConnectorClicked){var a=this.lastOutputConnectorClicked.grantedConnectors;a.forEach(function(a){a.arrows.forEach(function(b){b.els.css("border-left-color",a.color)})})}},_restoreGrantedConnectorsColor:function(){if(null!=this.lastOutputConnectorClicked){var a=this.lastOutputConnectorClicked.grantedConnectors;a.forEach(function(a){a.arrows.forEach(function(a){a.els.css("border-left-color",a.oldColor)})})}},_unsetTemporaryLink:function(){this._restoreGrantedConnectorsColor(),this.lastOutputConnectorClicked=null,this.objs.layers.temporaryLink.hide()},_mousemove:function(a,b){null!=this.lastOutputConnectorClicked&&(this.objs.temporaryLink.setAttribute("x2",a),this.objs.temporaryLink.setAttribute("y2",b))},_click:function(a,b,c){var d=$(c.target);0==d.closest(".flowchart-operator-connector").length&&this._unsetTemporaryLink(),0==d.closest(".flowchart-operator").length&&this.unselectOperator(),0==d.closest(".flowchart-link").length&&this.unselectLink()},_removeSelectedClassOperators:function(){this.objs.layers.operators.find(".flowchart-operator").removeClass("selected")},unselectOperator:function(){if(null!=this.selectedOperatorId){if(!this.callbackEvent("operatorUnselect",[]))return;this._removeSelectedClassOperators(),this.selectedOperatorId=null}},_addSelectedClass:function(a){this.data.operators[a].internal.els.operator.addClass("selected")},callbackEvent:function(a,b){var c="on"+a.charAt(0).toUpperCase()+a.slice(1),d=this.options[c].apply(this,b);if(d!==!1){var e={result:d};this.element.trigger(a,b.concat([e])),d=e.result}return d},selectOperator:function(a){this.callbackEvent("operatorSelect",[a])&&(this.unselectLink(),this._removeSelectedClassOperators(),this._addSelectedClass(a),this.selectedOperatorId=a)},addClassOperator:function(a,b){this.data.operators[a].internal.els.operator.addClass(b)},removeClassOperator:function(a,b){this.data.operators[a].internal.els.operator.removeClass(b)},removeClassOperators:function(a){this.objs.layers.operators.find(".flowchart-operator").removeClass(a)},_addHoverClassOperator:function(a){this.data.operators[a].internal.els.operator.addClass("hover")},_removeHoverClassOperators:function(){this.objs.layers.operators.find(".flowchart-operator").removeClass("hover")},_operatorMouseOver:function(a){this.callbackEvent("operatorMouseOver",[a])&&this._addHoverClassOperator(a)},_operatorMouseOut:function(a){this.callbackEvent("operatorMouseOut",[a])&&this._removeHoverClassOperators()},getSelectedOperatorId:function(){return this.selectedOperatorId},getSelectedLinkId:function(){return this.selectedLinkId},_shadeColor:function(a,b){var c=parseInt(a.slice(1),16),d=0>b?0:255,e=0>b?-1*b:b,f=c>>16,g=c>>8&255,h=255&c;return"#"+(16777216+65536*(Math.round((d-f)*e)+f)+256*(Math.round((d-g)*e)+g)+(Math.round((d-h)*e)+h)).toString(16).slice(1)},colorizeLink:function(a,b){var c=this.data.links[a];c.internal.els.path.setAttribute("stroke",b),c.internal.els.rect.setAttribute("fill",b),c.internal.els.fromSmallConnector.css("border-left-color",b),c.internal.els.toSmallConnector.css("border-left-color",b)},uncolorizeLink:function(a){this.colorizeLink(a,this.getLinkMainColor(a))},_connecterMouseOver:function(a){this.selectedLinkId!=a&&this.colorizeLink(a,this._shadeColor(this.getLinkMainColor(a),-.4))},_connecterMouseOut:function(a){this.selectedLinkId!=a&&this.uncolorizeLink(a)},unselectLink:function(){if(null!=this.selectedLinkId){if(!this.callbackEvent("linkUnselect",[]))return;this.uncolorizeLink(this.selectedLinkId,this.options.defaultSelectedLinkColor),this.selectedLinkId=null}},selectLink:function(a){this.unselectLink(),this.callbackEvent("linkSelect",[a])&&(this.unselectOperator(),this.selectedLinkId=a,this.colorizeLink(a,this.options.defaultSelectedLinkColor))},deleteOperator:function(a){this._deleteOperator(a,!1)},_deleteOperator:function(a,b){if(!this.callbackEvent("operatorDelete",[a,b]))return!1;if(!b)for(var c in this.data.links)if(this.data.links.hasOwnProperty(c)){var d=this.data.links[c];(d.fromOperator==a||d.toOperator==a)&&this._deleteLink(c,!0)}b||a!=this.selectedOperatorId||this.unselectOperator(),this.data.operators[a].internal.els.operator.remove(),delete this.data.operators[a],this.callbackEvent("afterChange",["operator_delete"])},deleteLink:function(a){this._deleteLink(a,!1)},_deleteLink:function(a,b){if(this.selectedLinkId==a&&this.unselectLink(),this.callbackEvent("linkDelete",[a,b])||b){this.colorizeLink(a,"transparent");var c=this.data.links[a],d=c.fromOperator,e=c.fromConnector,f=c.toOperator,g=c.toConnector;c.internal.els.overallGroup.remove(),delete this.data.links[a],this._cleanMultipleConnectors(d,e,"from"),this._cleanMultipleConnectors(f,g,"to"),this.callbackEvent("afterChange",["link_delete"])}},_cleanMultipleConnectors:function(a,b,c){var d="from"==c?"outputs":"inputs";if(this.data.operators[a].properties[d][b].multiple){var e=-1,f=c+"Operator",g=c+"Connector",h=c+"SubConnector",i=this.data.operators[a].internal.els,j=i.connectors[b],k=j.length;for(var l in this.data.links)if(this.data.links.hasOwnProperty(l)){var m=this.data.links[l];m[f]==a&&m[g]==b&&eo;o++)j[j.length-1].remove(),j.pop(),i.connectorArrows[b].pop(),i.connectorSmallArrows[b].pop()}},deleteSelected:function(){null!=this.selectedLinkId&&this.deleteLink(this.selectedLinkId),null!=this.selectedOperatorId&&this.deleteOperator(this.selectedOperatorId)},setPositionRatio:function(a){this.positionRatio=a},getPositionRatio:function(){return this.positionRatio},getData:function(){var a=["operators","links","linkRestrictions"],b={};b.operators=$.extend(!0,{},this.data.operators),b.links=$.extend(!0,{},this.data.links),b.linkRestrictions=$.extend(!0,[],this.data.linkRestrictions);for(var c in a)if(a.hasOwnProperty(c)){var d=a[c];for(var e in b[d])b[d].hasOwnProperty(e)&&delete b[d][e].internal}return b.operatorTypes=this.data.operatorTypes,b},setOperatorTitle:function(a,b){this.data.operators[a].internal.els.title.html(b),"undefined"==typeof this.data.operators[a].properties&&(this.data.operators[a].properties={}),this.data.operators[a].properties.title=b,this._refreshInternalProperties(this.data.operators[a]),this.callbackEvent("afterChange",["operator_title_change"])},getOperatorTitle:function(a){return this.data.operators[a].internal.properties.title},setOperatorData:function(a,b){var c=this.getOperatorCompleteData(b);for(var d in this.data.links)if(this.data.links.hasOwnProperty(d)){var e=this.data.links[d];(e.fromOperator==a&&"undefined"==typeof c.outputs[e.fromConnector]||e.toOperator==a&&"undefined"==typeof c.inputs[e.toConnector])&&this._deleteLink(d,!0)}this._deleteOperator(a,!0),this.createOperator(a,b),this.redrawLinksLayer(),this.callbackEvent("afterChange",["operator_data_change"])},getOperatorData:function(a){var b=$.extend(!0,{},this.data.operators[a]);return delete b.internal,b},getOperatorFullProperties:function(a){if("undefined"!=typeof a.type){var b=this.data.operatorTypes[a.type],c={};return"undefined"!=typeof a.properties&&(c=a.properties),$.extend({},b,c)}return a.properties},_refreshInternalProperties:function(a){a.internal.properties=this.getOperatorFullProperties(a)}})}); \ No newline at end of file