@projectstorm/react-diagrams-routing
Version:
This package adds dagre integration for laying out nodes and links
2 lines • 16.6 kB
JavaScript
!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports["projectstorm/react-diagrams-routing"]=e():t["projectstorm/react-diagrams-routing"]=e()}(self,(()=>(()=>{"use strict";var t={n:e=>{var i=e&&e.__esModule?()=>e.default:()=>e;return t.d(i,{a:i}),i},d:(e,i)=>{for(var n in i)t.o(i,n)&&!t.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:i[n]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e),r:t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})}},e={};t.r(e),t.d(e,{DagreEngine:()=>V,PathFinding:()=>c,PathFindingLinkFactory:()=>G,PathFindingLinkModel:()=>s,PathFindingLinkWidget:()=>d,RightAngleLinkFactory:()=>b,RightAngleLinkModel:()=>D,RightAngleLinkWidget:()=>Y});const i=require("react"),n=require("@projectstorm/react-diagrams-defaults");class s extends n.DefaultLinkModel{constructor(t={}){super(Object.assign({type:G.NAME},t))}performanceTune(){return!1}}const r=require("lodash/first");var o=t.n(r);const a=require("lodash/last");var h=t.n(a);const g=require("pathfinding"),l=new g.JumpPointFinder({heuristic:g.Heuristic.manhattan,diagonalMovement:g.DiagonalMovement.Never});class c{constructor(t){this.instance=l,this.factory=t}calculateDirectPath(t,e){const i=this.factory.getCanvasMatrix(),n=new g.Grid(i);return l.findPath(this.factory.translateRoutingX(Math.floor(t.getX()/this.factory.ROUTING_SCALING_FACTOR)),this.factory.translateRoutingY(Math.floor(t.getY()/this.factory.ROUTING_SCALING_FACTOR)),this.factory.translateRoutingX(Math.floor(e.getX()/this.factory.ROUTING_SCALING_FACTOR)),this.factory.translateRoutingY(Math.floor(e.getY()/this.factory.ROUTING_SCALING_FACTOR)),n)}calculateLinkStartEndCoords(t,e){const i=e.findIndex((e=>!!t[e[1]]&&0===t[e[1]][e[0]])),n=e.length-1-e.slice().reverse().findIndex((e=>!!t[e[1]]&&0===t[e[1]][e[0]]));if(-1===i||-1===n)return;const s=e.slice(0,i),r=e.slice(n);return{start:{x:e[i][0],y:e[i][1]},end:{x:e[n][0],y:e[n][1]},pathToStart:s,pathToEnd:r}}calculateDynamicPath(t,e,i,n,s){const r=new g.Grid(t),o=l.findPath(e.x,e.y,i.x,i.y,r),a=n.concat(o,s).map((t=>[this.factory.translateRoutingX(t[0],!0),this.factory.translateRoutingY(t[1],!0)]));return g.Util.compressPath(a)}}class d extends i.Component{constructor(t){super(t),this.refPaths=[],this.state={selected:!1},this.pathFinding=new c(this.props.factory)}componentDidUpdate(){this.props.link.setRenderedPaths(this.refPaths.map((t=>t.current)))}componentDidMount(){this.props.link.setRenderedPaths(this.refPaths.map((t=>t.current)))}componentWillUnmount(){this.props.link.setRenderedPaths([])}generateLink(t,e){const s=i.createRef();return this.refPaths.push(s),i.createElement(n.DefaultLinkSegmentWidget,{key:`link-${e}`,path:t,selected:this.state.selected,diagramEngine:this.props.diagramEngine,factory:this.props.diagramEngine.getFactoryForLink(this.props.link),link:this.props.link,forwardRef:s,onSelection:t=>{this.setState({selected:t})},extras:{}})}render(){this.refPaths=[];var t=this.props.link.getPoints(),e=[];const n=this.pathFinding.calculateDirectPath(o()(t),h()(t)),s=this.props.factory.getRoutingMatrix(),r=this.pathFinding.calculateLinkStartEndCoords(s,n);if(r){const{start:t,end:i,pathToStart:n,pathToEnd:o}=r,a=this.pathFinding.calculateDynamicPath(s,t,i,n,o);e.push(this.generateLink(this.props.factory.generateDynamicPath(a),"0"))}return i.createElement(i.Fragment,null,e)}}const u=require("lodash/cloneDeep");var p=t.n(u);const P=require("lodash/concat");var f=t.n(P);const m=require("lodash/defer");var M=t.n(m);const k=require("lodash/flatMap");var R=t.n(k);const v=require("lodash/get");var A=t.n(v);const x=require("lodash/minBy");var y=t.n(x);const I=require("lodash/maxBy");var L=t.n(I);const N=require("lodash/range");var _=t.n(N);const C=require("lodash/reduce");var F=t.n(C);const T=require("lodash/values");var O=t.n(T);const w=require("paths-js/path"),E=require("@projectstorm/react-canvas-core");class G extends n.DefaultLinkFactory{constructor(){super(G.NAME),this.ROUTING_SCALING_FACTOR=5,this.canvasMatrix=[],this.routingMatrix=[],this.hAdjustmentFactor=0,this.vAdjustmentFactor=0,this.calculateMatrixDimensions=()=>{const t=O()(this.engine.getModel().getNodes()).map((t=>({x:t.getX(),width:t.width,y:t.getY(),height:t.height}))),e=O()(this.engine.getModel().getLinks()),i=R()(e.map((t=>[t.getSourcePort(),t.getTargetPort()]))).filter((t=>null!==t)).map((t=>({x:t.getX(),width:t.width,y:t.getY(),height:t.height}))),n=R()(e.map((t=>t.getPoints()))).map((t=>({x:t.getX(),width:0,y:t.getY(),height:0}))),s=(t,e)=>F()(e,((e,i)=>e+A()(t,i,0)),0),r=this.engine.getCanvas(),o=f()(t,i,n),a=Math.floor(Math.min(A()(y()(o,"x"),"x",0),0)/this.ROUTING_SCALING_FACTOR)*this.ROUTING_SCALING_FACTOR,h=L()(o,(t=>s(t,["x","width"]))),g=Math.max(s(h,["x","width"]),r.offsetWidth),l=y()(o,"y"),c=Math.floor(Math.min(A()(l,"y",0),0)/this.ROUTING_SCALING_FACTOR)*this.ROUTING_SCALING_FACTOR,d=L()(o,(t=>s(t,["y","height"]))),u=Math.max(s(d,["y","height"]),r.offsetHeight);return{width:Math.ceil(Math.abs(a)+g),hAdjustmentFactor:Math.abs(a)/this.ROUTING_SCALING_FACTOR+1,height:Math.ceil(Math.abs(c)+u),vAdjustmentFactor:Math.abs(c)/this.ROUTING_SCALING_FACTOR+1}},this.markNodes=t=>{O()(this.engine.getModel().getNodes()).forEach((e=>{const i=Math.floor(e.getX()/this.ROUTING_SCALING_FACTOR),n=Math.ceil((e.getX()+e.width)/this.ROUTING_SCALING_FACTOR),s=Math.floor(e.getY()/this.ROUTING_SCALING_FACTOR),r=Math.ceil((e.getY()+e.height)/this.ROUTING_SCALING_FACTOR);for(let e=i-1;e<=n+1;e++)for(let i=s-1;i<r+1;i++)this.markMatrixPoint(t,this.translateRoutingX(e),this.translateRoutingY(i))}))},this.markPorts=t=>{R()(O()(this.engine.getModel().getLinks()).map((t=>[].concat(t.getSourcePort(),t.getTargetPort())))).filter((t=>null!==t)).forEach((e=>{const i=Math.floor(e.x/this.ROUTING_SCALING_FACTOR),n=Math.ceil((e.x+e.width)/this.ROUTING_SCALING_FACTOR),s=Math.floor(e.y/this.ROUTING_SCALING_FACTOR),r=Math.ceil((e.y+e.height)/this.ROUTING_SCALING_FACTOR);for(let e=i-1;e<=n+1;e++)for(let i=s-1;i<r+1;i++)this.markMatrixPoint(t,this.translateRoutingX(e),this.translateRoutingY(i))}))},this.markMatrixPoint=(t,e,i)=>{void 0!==t[i]&&void 0!==t[i][e]&&(t[i][e]=1)}}setDiagramEngine(t){super.setDiagramEngine(t),t.getStateMachine().registerListener({stateChanged:e=>{if(e.newState instanceof E.AbstractDisplacementState){const e=t.getActionEventBus().registerAction(new E.Action({type:E.InputType.MOUSE_UP,fire:()=>{this.calculateRoutingMatrix(),t.repaintCanvas(),e()}}))}}}),this.listener=t.registerListener({canvasReady:()=>{M()((()=>{this.calculateRoutingMatrix(),t.repaintCanvas()}))}})}setFactoryBank(t){super.setFactoryBank(t),!t&&this.listener&&this.listener.deregister()}generateReactWidget(t){return i.createElement(d,{diagramEngine:this.engine,link:t.model,factory:this})}generateModel(t){return new s}getCanvasMatrix(){return 0===this.canvasMatrix.length&&this.calculateCanvasMatrix(),this.canvasMatrix}calculateCanvasMatrix(){const{width:t,hAdjustmentFactor:e,height:i,vAdjustmentFactor:n}=this.calculateMatrixDimensions();this.hAdjustmentFactor=e,this.vAdjustmentFactor=n;const s=Math.ceil(t/this.ROUTING_SCALING_FACTOR),r=Math.ceil(i/this.ROUTING_SCALING_FACTOR);this.canvasMatrix=_()(0,r).map((()=>new Array(s).fill(0)))}getRoutingMatrix(){return 0===this.routingMatrix.length&&this.calculateRoutingMatrix(),this.routingMatrix}calculateRoutingMatrix(){const t=p()(this.getCanvasMatrix());this.markNodes(t),this.markPorts(t),this.routingMatrix=t}translateRoutingX(t,e=!1){return t+this.hAdjustmentFactor*(e?-1:1)}translateRoutingY(t,e=!1){return t+this.vAdjustmentFactor*(e?-1:1)}generateDynamicPath(t){let e=w();return e=e.moveto(t[0][0]*this.ROUTING_SCALING_FACTOR,t[0][1]*this.ROUTING_SCALING_FACTOR),t.slice(1).forEach((t=>{e=e.lineto(t[0]*this.ROUTING_SCALING_FACTOR,t[1]*this.ROUTING_SCALING_FACTOR)})),e.print()}}G.NAME="pathfinding";const S=require("@projectstorm/react-diagrams-core"),X=require("@projectstorm/geometry");class Y extends i.Component{constructor(t){super(t),this.handleMove=function(t){this.draggingEvent(t,this.dragging_index)}.bind(this),this.handleUp=function(t){this.setState({canDrag:!1,selected:!1}),window.removeEventListener("mousemove",this.handleMove),window.removeEventListener("mouseup",this.handleUp)}.bind(this),this.refPaths=[],this.state={selected:!1,canDrag:!1},this.dragging_index=0}componentDidUpdate(){this.props.link.setRenderedPaths(this.refPaths.map((t=>t.current)))}componentDidMount(){this.props.link.setRenderedPaths(this.refPaths.map((t=>t.current)))}componentWillUnmount(){this.props.link.setRenderedPaths([])}generateLink(t,e,s){const r=i.createRef();return this.refPaths.push(r),i.createElement(n.DefaultLinkSegmentWidget,{key:`link-${s}`,path:t,selected:this.state.selected,diagramEngine:this.props.diagramEngine,factory:this.props.diagramEngine.getFactoryForLink(this.props.link),link:this.props.link,forwardRef:r,onSelection:t=>{this.setState({selected:t})},extras:e})}calculatePositions(t,e,i,n){if(0===i){let e=new S.PointModel({link:this.props.link,position:new X.Point(t[i].getX(),t[i].getY())});return this.props.link.addPoint(e,i),void this.dragging_index++}if(i===t.length-2){let e=new S.PointModel({link:this.props.link,position:new X.Point(t[i+1].getX(),t[i+1].getY())});return void this.props.link.addPoint(e,i+1)}if(i-2>0){let s={[i-2]:t[i-2].getPosition(),[i+1]:t[i+1].getPosition(),[i-1]:t[i-1].getPosition()};if(Math.abs(s[i-1][n]-s[i+1][n])<5)return s[i-2][n]=this.props.diagramEngine.getRelativeMousePoint(e)[n],s[i+1][n]=this.props.diagramEngine.getRelativeMousePoint(e)[n],t[i-2].setPosition(s[i-2]),t[i+1].setPosition(s[i+1]),t[i-1].remove(),t[i-1].remove(),this.dragging_index--,void this.dragging_index--}if(i+2<t.length-2){let s={[i+3]:t[i+3].getPosition(),[i+2]:t[i+2].getPosition(),[i+1]:t[i+1].getPosition(),[i]:t[i].getPosition()};if(Math.abs(s[i+1][n]-s[i+2][n])<5)return s[i][n]=this.props.diagramEngine.getRelativeMousePoint(e)[n],s[i+3][n]=this.props.diagramEngine.getRelativeMousePoint(e)[n],t[i].setPosition(s[i]),t[i+3].setPosition(s[i+3]),t[i+1].remove(),void t[i+1].remove()}let s={[i]:t[i].getPosition(),[i+1]:t[i+1].getPosition()};s[i][n]=this.props.diagramEngine.getRelativeMousePoint(e)[n],s[i+1][n]=this.props.diagramEngine.getRelativeMousePoint(e)[n],t[i].setPosition(s[i]),t[i+1].setPosition(s[i+1])}draggingEvent(t,e){let i=this.props.link.getPoints(),n=Math.abs(i[e].getX()-i[e+1].getX()),s=Math.abs(i[e].getY()-i[e+1].getY());0===n?this.calculatePositions(i,t,e,"x"):0===s&&this.calculatePositions(i,t,e,"y"),this.props.link.setFirstAndLastPathsDirection()}render(){let t=this.props.link.getPoints(),e=[],n=t[0],s=t[t.length-1],r=!1;n.getX()>s.getX()&&(n=t[t.length-1],s=t[0],r=!0);let o=Math.abs(t[0].getY()-t[t.length-1].getY());if(null===this.props.link.getTargetPort()&&2===t.length)[...Array(2)].forEach((t=>{this.props.link.addPoint(new S.PointModel({link:this.props.link,position:new X.Point(n.getX(),s.getY())}),1)})),this.props.link.setManuallyFirstAndLastPathsDirection(!0,!0);else if(null===this.props.link.getTargetPort()&&null!==this.props.link.getSourcePort())t[1].setPosition(s.getX()+(n.getX()-s.getX())/2,r?s.getY():n.getY()),t[2].setPosition(s.getX()+(n.getX()-s.getX())/2,r?n.getY():s.getY());else if(!this.state.canDrag&&t.length>2)for(let e=1;e<t.length;e+=t.length-2)e-1==0?this.props.link.getFirstPathXdirection()?t[e].setPosition(t[e].getX(),t[e-1].getY()):t[e].setPosition(t[e-1].getX(),t[e].getY()):this.props.link.getLastPathXdirection()?t[e-1].setPosition(t[e-1].getX(),t[e].getY()):t[e-1].setPosition(t[e].getX(),t[e-1].getY());2!==t.length||0===o||this.state.canDrag||this.props.link.addPoint(new S.PointModel({link:this.props.link,position:new X.Point(n.getX(),s.getY())}));for(let i=0;i<t.length-1;i++)e.push(this.generateLink(S.LinkWidget.generateLinePath(t[i],t[i+1]),{"data-linkid":this.props.link.getID(),"data-point":i,onMouseDown:t=>{0===t.button&&(this.setState({canDrag:!0}),this.dragging_index=i,window.addEventListener("mousemove",this.handleMove),window.addEventListener("mouseup",this.handleUp))},onMouseEnter:t=>{this.setState({selected:!0}),this.props.link.lastHoverIndexOfPath=i}},i));return this.refPaths=[],i.createElement("g",{"data-default-link-test":this.props.link.getOptions().testName},e)}}Y.defaultProps={color:"red",width:3,link:null,smooth:!1,diagramEngine:null,factory:null};class D extends n.DefaultLinkModel{constructor(t={}){super(Object.assign({type:b.NAME},t)),this.lastHoverIndexOfPath=0,this._lastPathXdirection=!1,this._firstPathXdirection=!1}setFirstAndLastPathsDirection(){let t=this.getPoints();for(let e=1;e<t.length;e+=t.length-2){let i=Math.abs(t[e].getX()-t[e-1].getX()),n=Math.abs(t[e].getY()-t[e-1].getY());e-1==0?this._firstPathXdirection=i>n:this._lastPathXdirection=i>n}}addPoint(t,e=1){return super.addPoint(t,e),this.setFirstAndLastPathsDirection(),t}deserialize(t){super.deserialize(t),this.setFirstAndLastPathsDirection()}setManuallyFirstAndLastPathsDirection(t,e){this._firstPathXdirection=t,this._lastPathXdirection=e}getLastPathXdirection(){return this._lastPathXdirection}getFirstPathXdirection(){return this._firstPathXdirection}setWidth(t){this.options.width=t,this.fireEvent({width:t},"widthChanged")}setColor(t){this.options.color=t,this.fireEvent({color:t},"colorChanged")}}class b extends n.DefaultLinkFactory{constructor(){super(b.NAME)}generateModel(t){return new D}generateReactWidget(t){return i.createElement(Y,{diagramEngine:this.engine,link:t.model,factory:this})}}b.NAME="rightAngle";const U=require("dagre"),j=require("lodash/every");var q=t.n(j);const W=require("lodash/findIndex");var B=t.n(W);const H=require("lodash/forEach");var z=t.n(H);const $=require("lodash/map");var J=t.n($);const K=require("lodash/sortBy");var Q=t.n(K);class V{constructor(t={}){this.options=t}redistribute(t){var e=new U.graphlib.Graph({multigraph:!0,compound:!0});e.setGraph(this.options.graph||{}),e.setDefaultEdgeLabel((function(){return{}})),z()(t.getNodes(),(t=>{e.setNode(t.getID(),{width:t.width,height:t.height})})),z()(t.getLinks(),(t=>{t.getSourcePort()&&t.getTargetPort()&&e.setEdge({v:t.getSourcePort().getNode().getID(),w:t.getTargetPort().getNode().getID(),name:t.getID()})})),U.layout(e),e.nodes().forEach((i=>{const n=e.node(i);t.getNode(i).setPosition(n.x-n.width/2,n.y-n.height/2)})),this.options.includeLinks&&e.edges().forEach((i=>{const n=e.edge(i),s=t.getLink(i.name),r=[s.getFirstPoint()];for(let t=1;t<n.points.length-1;t++)r.push(new S.PointModel({link:s,position:new X.Point(n.points[t].x,n.points[t].y)}));s.setPoints(r.concat(s.getLastPoint()))}))}refreshLinks(t){const{nodeMargin:e}=this.options,i=t.getNodes(),n=t.getLinks();let s=-1;const r={},o={};let a=[];z()(i,(t=>{const i=t.getX()+t.width/2;q()(a,(t=>Math.abs(i-t)>e))&&a.push(i)})),a=a.sort(((t,e)=>t-e)),z()(a,((t,e)=>{r[e]={},r[e+.5]={}})),z()(i,(t=>{const i=t.getX()+t.width/2,n=Math.floor(t.getY()/e),h=Math.floor((t.getY()+t.height)/e);h>s&&(s=h);const g=B()(a,(t=>Math.abs(i-t)<=e));z()(_()(n,h+1),(t=>{r[g][t]=!0})),o[t.getX()]=g}));const h=J()(n,(t=>{if(t.getSourcePort()&&t.getTargetPort()){const e=t.getSourcePort().getNode(),i=t.getTargetPort().getNode(),n=o[e.getX()],s=o[i.getX()];return n>s?{link:t,sourceIndex:n,sourceY:e.getY()+e.height/2,source:e,targetIndex:s,targetY:i.getY()+e.height/2,target:i}:{link:t,sourceIndex:s,sourceY:i.getY()+i.height/2,source:i,targetIndex:n,targetY:e.getY()+e.height/2,target:e}}})),g=Q()(h,(t=>Math.abs(t.targetIndex-t.sourceIndex)));this.options.includeLinks&&z()(g,(i=>{const n=t.getLink(i.link.getID());if(Math.abs(i.sourceIndex-i.targetIndex)>1){const t=_()(i.sourceIndex-1,i.targetIndex),o=Math.floor(i.sourceY/e),h=Math.floor(i.targetY/e);let g=1,l=o;for(;l>=0&&!q()(t,(t=>!(r[t][l]||r[t+.5][l]||r[t-.5][l])));l--,g++);let c=0,d=o;for(;d<=s&&!q()(t,(t=>!(r[t][d]||r[t+.5][d]||r[t-.5][d])));d++,c++);const u=c+(d-h)<g+(h-l)?d+1:l-1,p=[n.getFirstPoint()];p.push(new S.PointModel({link:n,position:new X.Point((a[t[0]]+a[t[0]+1])/2,(u+.5)*e)})),z()(t,(t=>{p.push(new S.PointModel({link:n,position:new X.Point(a[t],(u+.5)*e)})),p.push(new S.PointModel({link:n,position:new X.Point((a[t]+a[t-1])/2,(u+.5)*e)})),r[t][u]=!0,r[t][u+1]=!0,r[t+.5][u]=!0,r[t+.5][u+1]=!0})),n.setPoints(p.concat(n.getLastPoint()))}else{n.setPoints([n.getFirstPoint(),n.getLastPoint()]);const t=(i.sourceIndex+i.targetIndex)/2;r[t]||(r[t]={});const s=Math.floor((i.sourceY+i.targetY)/2/e);r[t][s]=!0,r[t][s+1]=!0}}))}}return e})()));
//# sourceMappingURL=index.umd.js.map