@tisoap/react-flow-smart-edge
Advanced tools
Comparing version 0.3.0 to 0.4.0
@@ -83,10 +83,10 @@ 'use strict'; | ||
* Since the top most point can have X/Y values different than zero, | ||
* and each cell in a grid represents a 10x10 pixel area in the grid, | ||
* there's need to be a conversion between a point in a graph to a point | ||
* in the grid. | ||
* and each cell in a grid represents a 10x10 pixel area in the grid (or a | ||
* gridRatio area), there's need to be a conversion between a point in a graph | ||
* to a point in the grid. | ||
* | ||
* We do this conversion by dividing a graph point X/Y values by 10, and | ||
* "shifting" their values up or down, depending on the values of the top most | ||
* point in the graph. The top most point in the graph will have the smallest | ||
* values for X and Y. | ||
* We do this conversion by dividing a graph point X/Y values by the grid ratio, | ||
* and "shifting" their values up or down, depending on the values of the top | ||
* most point in the graph. The top most point in the graph will have the | ||
* smallest values for X and Y. | ||
* | ||
@@ -213,4 +213,4 @@ * We avoid setting nodes in the border of the grid (x=0 or y=0), so there's | ||
height = graph.height; // Create a grid representation of the graph box, where each cell is | ||
// equivalent to 10x10 pixels on the graph. We'll use this simplified grid | ||
// to do pathfinding. | ||
// equivalent to 10x10 pixels (or the grid ratio) on the graph. We'll use | ||
// this simplified grid to do pathfinding. | ||
@@ -260,2 +260,12 @@ var mapColumns = roundUp(width, gridRatio) / gridRatio + 1; | ||
*/ | ||
var drawStraightLinePath = function drawStraightLinePath(source, target, path) { | ||
var svgPathString = "M " + source.x + ", " + source.y + " "; | ||
path.forEach(function (point) { | ||
var x = point[0], | ||
y = point[1]; | ||
svgPathString += "L " + x + ", " + y + " "; | ||
}); | ||
svgPathString += "L " + target.x + ", " + target.y + " "; | ||
return svgPathString; | ||
}; | ||
/** | ||
@@ -296,8 +306,13 @@ * Draws a SVG path from a list of points, using rounded lines. | ||
var generatePath = function generatePath(grid, start, end) { | ||
var finder = new pathfinding.AStarFinder({ | ||
diagonalMovement: pathfinding.DiagonalMovement.Always, | ||
allowDiagonal: true, | ||
dontCrossCorners: true | ||
}); | ||
var withDiagonalMovement = { | ||
allowDiagonal: true, | ||
dontCrossCorners: true, | ||
diagonalMovement: pathfinding.DiagonalMovement.Always | ||
}; | ||
var withStraightMovement = { | ||
allowDiagonal: false | ||
}; | ||
var generatePath = function generatePath(grid, start, end, lessCorners) { | ||
var finderOptions = lessCorners ? withStraightMovement : withDiagonalMovement; | ||
var finder = new pathfinding.AStarFinder(finderOptions); | ||
var fullPath = []; | ||
@@ -439,3 +454,5 @@ var smoothedPath = []; | ||
nodePadding: 10, | ||
gridRatio: 10 | ||
gridRatio: 10, | ||
lineType: 'curve', | ||
lessCorners: false | ||
}; | ||
@@ -452,7 +469,16 @@ var SmartEdgeContext = /*#__PURE__*/React.createContext(defaultOptions); | ||
_options$gridRatio = options.gridRatio, | ||
gridRatio = _options$gridRatio === void 0 ? 10 : _options$gridRatio; // Guarantee that all values are positive integers | ||
gridRatio = _options$gridRatio === void 0 ? 10 : _options$gridRatio, | ||
_options$lineType = options.lineType, | ||
lineType = _options$lineType === void 0 ? 'curve' : _options$lineType, | ||
_options$lessCorners = options.lessCorners, | ||
lessCorners = _options$lessCorners === void 0 ? false : _options$lessCorners; // Guarantee that all values are positive integers | ||
gridRatio = toInteger(gridRatio, 2); | ||
nodePadding = toInteger(nodePadding, 2); | ||
debounceTime = toInteger(debounceTime); | ||
debounceTime = toInteger(debounceTime); // Guarantee correct line type | ||
if (lineType !== 'curve' && lineType !== 'straight') { | ||
lineType = 'curve'; | ||
} | ||
warning(debounceTime >= 30, 'A small debounce time on SmartEdge can cause performance issues on large graphs.') ; | ||
@@ -464,3 +490,5 @@ warning(gridRatio >= 10, 'A small grid ratio on SmartEdge can cause performance issues on large graphs.') ; | ||
nodePadding: nodePadding, | ||
gridRatio: gridRatio | ||
gridRatio: gridRatio, | ||
lineType: lineType, | ||
lessCorners: lessCorners | ||
} | ||
@@ -476,3 +504,3 @@ }, children); | ||
if (context.debounceTime === undefined || context.gridRatio === undefined || context.nodePadding === undefined) { | ||
if (context.debounceTime === undefined || context.gridRatio === undefined || context.nodePadding === undefined || context.lineType === undefined) { | ||
throw new Error('Missing options on SmartEdgeProvider'); | ||
@@ -504,3 +532,5 @@ } | ||
gridRatio = _useSmartEdge.gridRatio, | ||
nodePadding = _useSmartEdge.nodePadding; | ||
nodePadding = _useSmartEdge.nodePadding, | ||
lineType = _useSmartEdge.lineType, | ||
lessCorners = _useSmartEdge.lessCorners; | ||
@@ -532,3 +562,3 @@ var roundCoordinatesTo = gridRatio; // We use the node's information to generate bounding boxes for them | ||
var _generatePath = generatePath(grid, start, end), | ||
var _generatePath = generatePath(grid, start, end, lessCorners), | ||
fullPath = _generatePath.fullPath, | ||
@@ -545,3 +575,7 @@ smoothedPath = _generatePath.smoothedPath; | ||
if (smoothedPath.length <= 2) { | ||
return React__default.createElement(reactFlowRenderer.BezierEdge, Object.assign({}, props)); | ||
if (lineType === 'curve') { | ||
return React__default.createElement(reactFlowRenderer.BezierEdge, Object.assign({}, props)); | ||
} | ||
return React__default.createElement(reactFlowRenderer.StraightEdge, Object.assign({}, props)); | ||
} // Here we convert the grid path to a sequence of graph coordinates. | ||
@@ -560,3 +594,3 @@ | ||
var svgPathString = drawSmoothLinePath(source, target, graphPath); // The Label, if any, should be placed in the middle of the path | ||
var svgPathString = lineType === 'curve' ? drawSmoothLinePath(source, target, graphPath) : drawStraightLinePath(source, target, graphPath); // The Label, if any, should be placed in the middle of the path | ||
@@ -563,0 +597,0 @@ var _fullPath$Math$floor = fullPath[Math.floor(fullPath.length / 2)], |
@@ -1,2 +0,2 @@ | ||
"use strict";function e(e){return e&&"object"==typeof e&&"default"in e?e.default:e}Object.defineProperty(exports,"__esModule",{value:!0});var t=require("react"),r=e(t),n=e(require("react-use/lib/useDebounce")),o=require("react-flow-renderer"),i=require("pathfinding");function a(){return(a=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var r=arguments[t];for(var n in r)Object.prototype.hasOwnProperty.call(r,n)&&(e[n]=r[n])}return e}).apply(this,arguments)}require("tiny-warning");var d=function(e,t){switch(t){case"top":return{x:e.x,y:e.y-1};case"bottom":return{x:e.x,y:e.y+1};case"left":return{x:e.x-1,y:e.y};case"right":return{x:e.x+1,y:e.y}}},u=function(e,t,r){for(var n=e.getNodeAt(t.x,t.y);!n.walkable;){e.setWalkableAt(n.x,n.y,!0);var o=d(n,r);n=e.getNodeAt(o.x,o.y)}},l=function(e,t,r,n){var o=e.x/n,i=e.y/n,a=t/n,d=r/n;if(a<1)for(;1!==a;)a++,o++;else if(a>1)for(;1!==a;)a--,o--;if(d<1)for(;1!==d;)d++,i++;else if(d>1)for(;1!==d;)d--,i--;return{x:o,y:i}},s=function(e,t,r,n){var o=e.x*n,i=e.y*n,a=t,d=r;if(a<n)for(;a!==n;)a+=n,o-=n;else if(a>n)for(;a!==n;)a-=n,o+=n;if(d<n)for(;d!==n;)d+=n,i-=n;else if(d>n)for(;d!==n;)d-=n,i+=n;return{x:o,y:i}},c=function(e,t){return void 0===t&&(t=10),Math.round(e/t)*t},y=function(e,t){return void 0===t&&(t=10),Math.floor(e/t)*t},x=function(e,t){return void 0===t&&(t=10),Math.ceil(e/t)*t},f=function(e,t){void 0===t&&(t=0);var r=Math.max(Math.round(e),t);return(r=Number.isInteger(r)?r:t)>=t?r:t},g={debounceTime:200,nodePadding:10,gridRatio:10},v=t.createContext(g),h=function(e){var t=e.children,n=e.options,o=void 0===n?g:n,i=o.debounceTime,a=void 0===i?200:i,d=o.nodePadding,u=void 0===d?10:d,l=o.gridRatio,s=void 0===l?10:l;return s=f(s,2),u=f(u,2),a=f(a),r.createElement(v.Provider,{value:{debounceTime:a,nodePadding:u,gridRatio:s}},t)},m=function(){var e=t.useContext(v);if(void 0===e)throw new Error("useSmartEdge must be used within a SmartEdgeProvider");if(void 0===e.debounceTime||void 0===e.gridRatio||void 0===e.nodePadding)throw new Error("Missing options on SmartEdgeProvider");return e},b=t.memo((function(e){var t=e.sourceX,n=e.sourceY,a=e.sourcePosition,f=e.targetX,g=e.targetY,v=e.targetPosition,h=e.arrowHeadType,b=e.markerEndId,p=e.style,E=e.storeNodes,M=e.label,w=e.labelStyle,P=e.labelShowBg,S=e.labelBgStyle,N=e.labelBgPadding,R=e.labelBgBorderRadius,A=m(),_=A.gridRatio,T=function(e,t,r){void 0===t&&(t=2),void 0===r&&(r=2);var n=Number.MIN_SAFE_INTEGER,o=Number.MIN_SAFE_INTEGER,i=Number.MAX_SAFE_INTEGER,a=Number.MAX_SAFE_INTEGER,d=e.map((function(e){var d,u,l=null==e?void 0:e.__rf,s=Math.max((null==l?void 0:l.width)||0,1),c=Math.max((null==l?void 0:l.height)||0,1),f=(null==l||null==(d=l.position)?void 0:d.x)||0,g=(null==l||null==(u=l.position)?void 0:u.y)||0,v={x:f-t,y:g-t},h={x:f-t,y:g+c+t},m={x:f+s+t,y:g-t},b={x:f+s+t,y:g+c+t};return r>0&&(v.x=y(v.x,r),v.y=y(v.y,r),h.x=y(h.x,r),h.y=x(h.y,r),m.x=x(m.x,r),m.y=y(m.y,r),b.x=x(b.x,r),b.y=x(b.y,r)),v.y<a&&(a=v.y),v.x<i&&(i=v.x),b.y>o&&(o=b.y),b.x>n&&(n=b.x),{id:e.id,width:s,height:c,topLeft:v,bottomLeft:h,topRight:m,bottomRight:b}})),u=2*t;n=x(n+u,r),o=x(o+u,r),i=y(i-u,r),a=y(a-u,r);var l={x:i,y:a},s={x:i,y:o},c={x:n,y:a};return{nodes:d,graph:{topLeft:l,bottomLeft:s,topRight:c,bottomRight:{x:n,y:o},width:Math.abs(l.x-c.x),height:Math.abs(l.y-s.y),xMax:n,yMax:o,xMin:i,yMin:a}}}(E,A.nodePadding,_),B=T.graph,j={x:t,y:n,position:a},O={x:f,y:g,position:v},I=function(e,t,r,n,o){void 0===o&&(o=2);var a=e.xMin,s=e.yMin,y=e.height,f=x(e.width,o)/o+1,g=x(y,o)/o+1,v=new i.Grid(f,g);t.forEach((function(e){for(var t=l(e.topLeft,a,s,o),r=l(e.bottomRight,a,s,o),n=t.x;n<r.x;n++)for(var i=t.y;i<r.y;i++)v.setWalkableAt(n,i,!1)}));var h=l({x:c(r.x,o),y:c(r.y,o)},a,s,o),m=l({x:c(n.x,o),y:c(n.y,o)},a,s,o),b=v.getNodeAt(h.x,h.y);u(v,b,r.position);var p=v.getNodeAt(m.x,m.y);u(v,p,n.position);var E=d(b,r.position),M=d(p,n.position);return{grid:v,start:E,end:M}}(B,T.nodes,j,O,_),k=function(e,t,r){var n=new i.AStarFinder({diagonalMovement:i.DiagonalMovement.Always,allowDiagonal:!0,dontCrossCorners:!0}),o=[],a=[];try{o=n.findPath(t.x,t.y,r.x,r.y,e),a=i.Util.smoothenPath(e,o)}catch(e){}return{fullPath:o,smoothedPath:a}}(I.grid,I.start,I.end),F=k.fullPath,q=k.smoothedPath;if(q.length<=2)return r.createElement(o.BezierEdge,Object.assign({},e));var C=function(e,t,r){return function(e){for(var t=e[0],r=e[0],n="M"+r[0]+","+r[1]+"M",o=0;o<e.length;o++){var i=e[o],a=[(t[0]-(d=i[0]))/2+d,(t[1]-(u=i[1]))/2+u];n+=" "+a[0]+","+a[1],n+="Q"+i[0]+","+i[1],t=i}var d,u,l=e[e.length-1];return n+" "+l[0]+","+l[1]}([[e.x,e.y]].concat(r,[[t.x,t.y]]))}(j,O,q.map((function(e){var t=s({x:e[0],y:e[1]},B.xMin,B.yMin,_);return[t.x,t.y]}))),G=F[Math.floor(F.length/2)],L=s({x:G[0],y:G[1]},B.xMin,B.yMin,_),X=M?r.createElement(o.EdgeText,{x:L.x,y:L.y,label:M,labelStyle:w,labelShowBg:P,labelBgStyle:S,labelBgPadding:N,labelBgBorderRadius:R}):null,D=o.getMarkerEnd(h,b);return r.createElement(r.Fragment,null,r.createElement("path",{style:p,className:"react-flow__edge-path",d:C,markerEnd:D}),X)})),p=t.memo((function(e){var i=o.useStoreState((function(e){return e.nodes})),d=m().debounceTime,u=t.useState(a({storeNodes:i},e)),l=u[0],s=u[1];return n((function(){s(a({storeNodes:i},e))}),d,[e,i]),r.createElement(b,Object.assign({},l))})),E=t.memo((function(e){var t=o.useStoreState((function(e){return e.nodes}));return r.createElement(b,Object.assign({storeNodes:t},e))})),M=t.memo((function(e){var n=t.useContext(v);return n?r.createElement(0===n.debounceTime?E:p,Object.assign({},e)):r.createElement(h,null,r.createElement(p,Object.assign({},e)),";")}));exports.SmartEdge=M,exports.SmartEdgeProvider=h,exports.default=M; | ||
"use strict";function e(e){return e&&"object"==typeof e&&"default"in e?e.default:e}Object.defineProperty(exports,"__esModule",{value:!0});var t=require("react"),r=e(t),n=e(require("react-use/lib/useDebounce")),o=require("react-flow-renderer"),i=require("pathfinding");function a(){return(a=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var r=arguments[t];for(var n in r)Object.prototype.hasOwnProperty.call(r,n)&&(e[n]=r[n])}return e}).apply(this,arguments)}require("tiny-warning");var u=function(e,t){switch(t){case"top":return{x:e.x,y:e.y-1};case"bottom":return{x:e.x,y:e.y+1};case"left":return{x:e.x-1,y:e.y};case"right":return{x:e.x+1,y:e.y}}},d=function(e,t,r){for(var n=e.getNodeAt(t.x,t.y);!n.walkable;){e.setWalkableAt(n.x,n.y,!0);var o=u(n,r);n=e.getNodeAt(o.x,o.y)}},l=function(e,t,r,n){var o=e.x/n,i=e.y/n,a=t/n,u=r/n;if(a<1)for(;1!==a;)a++,o++;else if(a>1)for(;1!==a;)a--,o--;if(u<1)for(;1!==u;)u++,i++;else if(u>1)for(;1!==u;)u--,i--;return{x:o,y:i}},s=function(e,t,r,n){var o=e.x*n,i=e.y*n,a=t,u=r;if(a<n)for(;a!==n;)a+=n,o-=n;else if(a>n)for(;a!==n;)a-=n,o+=n;if(u<n)for(;u!==n;)u+=n,i-=n;else if(u>n)for(;u!==n;)u-=n,i+=n;return{x:o,y:i}},c=function(e,t){return void 0===t&&(t=10),Math.round(e/t)*t},y=function(e,t){return void 0===t&&(t=10),Math.floor(e/t)*t},f=function(e,t){return void 0===t&&(t=10),Math.ceil(e/t)*t},x=function(e,t){void 0===t&&(t=0);var r=Math.max(Math.round(e),t);return(r=Number.isInteger(r)?r:t)>=t?r:t},g={allowDiagonal:!0,dontCrossCorners:!0,diagonalMovement:i.DiagonalMovement.Always},v={allowDiagonal:!1},h={debounceTime:200,nodePadding:10,gridRatio:10,lineType:"curve",lessCorners:!1},m=t.createContext(h),b=function(e){var t=e.children,n=e.options,o=void 0===n?h:n,i=o.debounceTime,a=void 0===i?200:i,u=o.nodePadding,d=void 0===u?10:u,l=o.gridRatio,s=void 0===l?10:l,c=o.lineType,y=void 0===c?"curve":c,f=o.lessCorners,g=void 0!==f&&f;return s=x(s,2),d=x(d,2),a=x(a),"curve"!==y&&"straight"!==y&&(y="curve"),r.createElement(m.Provider,{value:{debounceTime:a,nodePadding:d,gridRatio:s,lineType:y,lessCorners:g}},t)},p=function(){var e=t.useContext(m);if(void 0===e)throw new Error("useSmartEdge must be used within a SmartEdgeProvider");if(void 0===e.debounceTime||void 0===e.gridRatio||void 0===e.nodePadding||void 0===e.lineType)throw new Error("Missing options on SmartEdgeProvider");return e},E=t.memo((function(e){var t=e.sourceX,n=e.sourceY,a=e.sourcePosition,x=e.targetX,h=e.targetY,m=e.targetPosition,b=e.arrowHeadType,E=e.markerEndId,M=e.style,w=e.storeNodes,S=e.label,P=e.labelStyle,N=e.labelShowBg,T=e.labelBgStyle,R=e.labelBgPadding,A=e.labelBgBorderRadius,_=p(),B=_.gridRatio,j=_.lineType,C=_.lessCorners,O=function(e,t,r){void 0===t&&(t=2),void 0===r&&(r=2);var n=Number.MIN_SAFE_INTEGER,o=Number.MIN_SAFE_INTEGER,i=Number.MAX_SAFE_INTEGER,a=Number.MAX_SAFE_INTEGER,u=e.map((function(e){var u,d,l=null==e?void 0:e.__rf,s=Math.max((null==l?void 0:l.width)||0,1),c=Math.max((null==l?void 0:l.height)||0,1),x=(null==l||null==(u=l.position)?void 0:u.x)||0,g=(null==l||null==(d=l.position)?void 0:d.y)||0,v={x:x-t,y:g-t},h={x:x-t,y:g+c+t},m={x:x+s+t,y:g-t},b={x:x+s+t,y:g+c+t};return r>0&&(v.x=y(v.x,r),v.y=y(v.y,r),h.x=y(h.x,r),h.y=f(h.y,r),m.x=f(m.x,r),m.y=y(m.y,r),b.x=f(b.x,r),b.y=f(b.y,r)),v.y<a&&(a=v.y),v.x<i&&(i=v.x),b.y>o&&(o=b.y),b.x>n&&(n=b.x),{id:e.id,width:s,height:c,topLeft:v,bottomLeft:h,topRight:m,bottomRight:b}})),d=2*t;n=f(n+d,r),o=f(o+d,r),i=y(i-d,r),a=y(a-d,r);var l={x:i,y:a},s={x:i,y:o},c={x:n,y:a};return{nodes:u,graph:{topLeft:l,bottomLeft:s,topRight:c,bottomRight:{x:n,y:o},width:Math.abs(l.x-c.x),height:Math.abs(l.y-s.y),xMax:n,yMax:o,xMin:i,yMin:a}}}(w,_.nodePadding,B),I=O.graph,L={x:t,y:n,position:a},k={x:x,y:h,position:m},F=function(e,t,r,n,o){void 0===o&&(o=2);var a=e.xMin,s=e.yMin,y=e.height,x=f(e.width,o)/o+1,g=f(y,o)/o+1,v=new i.Grid(x,g);t.forEach((function(e){for(var t=l(e.topLeft,a,s,o),r=l(e.bottomRight,a,s,o),n=t.x;n<r.x;n++)for(var i=t.y;i<r.y;i++)v.setWalkableAt(n,i,!1)}));var h=l({x:c(r.x,o),y:c(r.y,o)},a,s,o),m=l({x:c(n.x,o),y:c(n.y,o)},a,s,o),b=v.getNodeAt(h.x,h.y);d(v,b,r.position);var p=v.getNodeAt(m.x,m.y);d(v,p,n.position);var E=u(b,r.position),M=u(p,n.position);return{grid:v,start:E,end:M}}(I,O.nodes,L,k,B),q=function(e,t,r,n){var o=new i.AStarFinder(n?v:g),a=[],u=[];try{a=o.findPath(t.x,t.y,r.x,r.y,e),u=i.Util.smoothenPath(e,a)}catch(e){}return{fullPath:a,smoothedPath:u}}(F.grid,F.start,F.end,C),G=q.fullPath,D=q.smoothedPath;if(D.length<=2)return r.createElement("curve"===j?o.BezierEdge:o.StraightEdge,Object.assign({},e));var X=D.map((function(e){var t=s({x:e[0],y:e[1]},I.xMin,I.yMin,B);return[t.x,t.y]})),W="curve"===j?function(e,t,r){return function(e){for(var t=e[0],r=e[0],n="M"+r[0]+","+r[1]+"M",o=0;o<e.length;o++){var i=e[o],a=[(t[0]-(u=i[0]))/2+u,(t[1]-(d=i[1]))/2+d];n+=" "+a[0]+","+a[1],n+="Q"+i[0]+","+i[1],t=i}var u,d,l=e[e.length-1];return n+" "+l[0]+","+l[1]}([[e.x,e.y]].concat(r,[[t.x,t.y]]))}(L,k,X):function(e,t,r){var n="M "+e.x+", "+e.y+" ";return r.forEach((function(e){n+="L "+e[0]+", "+e[1]+" "})),n+="L "+t.x+", "+t.y+" "}(L,k,X),Y=G[Math.floor(G.length/2)],z=s({x:Y[0],y:Y[1]},I.xMin,I.yMin,B),H=S?r.createElement(o.EdgeText,{x:z.x,y:z.y,label:S,labelStyle:P,labelShowBg:N,labelBgStyle:T,labelBgPadding:R,labelBgBorderRadius:A}):null,Q=o.getMarkerEnd(b,E);return r.createElement(r.Fragment,null,r.createElement("path",{style:M,className:"react-flow__edge-path",d:W,markerEnd:Q}),H)})),M=t.memo((function(e){var i=o.useStoreState((function(e){return e.nodes})),u=p().debounceTime,d=t.useState(a({storeNodes:i},e)),l=d[0],s=d[1];return n((function(){s(a({storeNodes:i},e))}),u,[e,i]),r.createElement(E,Object.assign({},l))})),w=t.memo((function(e){var t=o.useStoreState((function(e){return e.nodes}));return r.createElement(E,Object.assign({storeNodes:t},e))})),S=t.memo((function(e){var n=t.useContext(m);return n?r.createElement(0===n.debounceTime?w:M,Object.assign({},e)):r.createElement(b,null,r.createElement(M,Object.assign({},e)),";")}));exports.SmartEdge=S,exports.SmartEdgeProvider=b,exports.default=S; | ||
//# sourceMappingURL=react-flow-smart-edge.cjs.production.min.js.map |
import React, { createContext, useContext, memo, useState } from 'react'; | ||
import useDebounce from 'react-use/lib/useDebounce'; | ||
import { useStoreState, BezierEdge, EdgeText, getMarkerEnd } from 'react-flow-renderer'; | ||
import { Grid, AStarFinder, DiagonalMovement, Util } from 'pathfinding'; | ||
import { useStoreState, BezierEdge, StraightEdge, EdgeText, getMarkerEnd } from 'react-flow-renderer'; | ||
import { Grid, AStarFinder, Util, DiagonalMovement } from 'pathfinding'; | ||
import warning from 'tiny-warning'; | ||
@@ -76,10 +76,10 @@ | ||
* Since the top most point can have X/Y values different than zero, | ||
* and each cell in a grid represents a 10x10 pixel area in the grid, | ||
* there's need to be a conversion between a point in a graph to a point | ||
* in the grid. | ||
* and each cell in a grid represents a 10x10 pixel area in the grid (or a | ||
* gridRatio area), there's need to be a conversion between a point in a graph | ||
* to a point in the grid. | ||
* | ||
* We do this conversion by dividing a graph point X/Y values by 10, and | ||
* "shifting" their values up or down, depending on the values of the top most | ||
* point in the graph. The top most point in the graph will have the smallest | ||
* values for X and Y. | ||
* We do this conversion by dividing a graph point X/Y values by the grid ratio, | ||
* and "shifting" their values up or down, depending on the values of the top | ||
* most point in the graph. The top most point in the graph will have the | ||
* smallest values for X and Y. | ||
* | ||
@@ -206,4 +206,4 @@ * We avoid setting nodes in the border of the grid (x=0 or y=0), so there's | ||
height = graph.height; // Create a grid representation of the graph box, where each cell is | ||
// equivalent to 10x10 pixels on the graph. We'll use this simplified grid | ||
// to do pathfinding. | ||
// equivalent to 10x10 pixels (or the grid ratio) on the graph. We'll use | ||
// this simplified grid to do pathfinding. | ||
@@ -253,2 +253,12 @@ var mapColumns = roundUp(width, gridRatio) / gridRatio + 1; | ||
*/ | ||
var drawStraightLinePath = function drawStraightLinePath(source, target, path) { | ||
var svgPathString = "M " + source.x + ", " + source.y + " "; | ||
path.forEach(function (point) { | ||
var x = point[0], | ||
y = point[1]; | ||
svgPathString += "L " + x + ", " + y + " "; | ||
}); | ||
svgPathString += "L " + target.x + ", " + target.y + " "; | ||
return svgPathString; | ||
}; | ||
/** | ||
@@ -289,8 +299,13 @@ * Draws a SVG path from a list of points, using rounded lines. | ||
var generatePath = function generatePath(grid, start, end) { | ||
var finder = new AStarFinder({ | ||
diagonalMovement: DiagonalMovement.Always, | ||
allowDiagonal: true, | ||
dontCrossCorners: true | ||
}); | ||
var withDiagonalMovement = { | ||
allowDiagonal: true, | ||
dontCrossCorners: true, | ||
diagonalMovement: DiagonalMovement.Always | ||
}; | ||
var withStraightMovement = { | ||
allowDiagonal: false | ||
}; | ||
var generatePath = function generatePath(grid, start, end, lessCorners) { | ||
var finderOptions = lessCorners ? withStraightMovement : withDiagonalMovement; | ||
var finder = new AStarFinder(finderOptions); | ||
var fullPath = []; | ||
@@ -432,3 +447,5 @@ var smoothedPath = []; | ||
nodePadding: 10, | ||
gridRatio: 10 | ||
gridRatio: 10, | ||
lineType: 'curve', | ||
lessCorners: false | ||
}; | ||
@@ -445,7 +462,16 @@ var SmartEdgeContext = /*#__PURE__*/createContext(defaultOptions); | ||
_options$gridRatio = options.gridRatio, | ||
gridRatio = _options$gridRatio === void 0 ? 10 : _options$gridRatio; // Guarantee that all values are positive integers | ||
gridRatio = _options$gridRatio === void 0 ? 10 : _options$gridRatio, | ||
_options$lineType = options.lineType, | ||
lineType = _options$lineType === void 0 ? 'curve' : _options$lineType, | ||
_options$lessCorners = options.lessCorners, | ||
lessCorners = _options$lessCorners === void 0 ? false : _options$lessCorners; // Guarantee that all values are positive integers | ||
gridRatio = toInteger(gridRatio, 2); | ||
nodePadding = toInteger(nodePadding, 2); | ||
debounceTime = toInteger(debounceTime); | ||
debounceTime = toInteger(debounceTime); // Guarantee correct line type | ||
if (lineType !== 'curve' && lineType !== 'straight') { | ||
lineType = 'curve'; | ||
} | ||
process.env.NODE_ENV !== "production" ? warning(debounceTime >= 30, 'A small debounce time on SmartEdge can cause performance issues on large graphs.') : void 0; | ||
@@ -457,3 +483,5 @@ process.env.NODE_ENV !== "production" ? warning(gridRatio >= 10, 'A small grid ratio on SmartEdge can cause performance issues on large graphs.') : void 0; | ||
nodePadding: nodePadding, | ||
gridRatio: gridRatio | ||
gridRatio: gridRatio, | ||
lineType: lineType, | ||
lessCorners: lessCorners | ||
} | ||
@@ -469,3 +497,3 @@ }, children); | ||
if (context.debounceTime === undefined || context.gridRatio === undefined || context.nodePadding === undefined) { | ||
if (context.debounceTime === undefined || context.gridRatio === undefined || context.nodePadding === undefined || context.lineType === undefined) { | ||
throw new Error('Missing options on SmartEdgeProvider'); | ||
@@ -497,3 +525,5 @@ } | ||
gridRatio = _useSmartEdge.gridRatio, | ||
nodePadding = _useSmartEdge.nodePadding; | ||
nodePadding = _useSmartEdge.nodePadding, | ||
lineType = _useSmartEdge.lineType, | ||
lessCorners = _useSmartEdge.lessCorners; | ||
@@ -525,3 +555,3 @@ var roundCoordinatesTo = gridRatio; // We use the node's information to generate bounding boxes for them | ||
var _generatePath = generatePath(grid, start, end), | ||
var _generatePath = generatePath(grid, start, end, lessCorners), | ||
fullPath = _generatePath.fullPath, | ||
@@ -538,3 +568,7 @@ smoothedPath = _generatePath.smoothedPath; | ||
if (smoothedPath.length <= 2) { | ||
return React.createElement(BezierEdge, Object.assign({}, props)); | ||
if (lineType === 'curve') { | ||
return React.createElement(BezierEdge, Object.assign({}, props)); | ||
} | ||
return React.createElement(StraightEdge, Object.assign({}, props)); | ||
} // Here we convert the grid path to a sequence of graph coordinates. | ||
@@ -553,3 +587,3 @@ | ||
var svgPathString = drawSmoothLinePath(source, target, graphPath); // The Label, if any, should be placed in the middle of the path | ||
var svgPathString = lineType === 'curve' ? drawSmoothLinePath(source, target, graphPath) : drawStraightLinePath(source, target, graphPath); // The Label, if any, should be placed in the middle of the path | ||
@@ -556,0 +590,0 @@ var _fullPath$Math$floor = fullPath[Math.floor(fullPath.length / 2)], |
@@ -7,2 +7,4 @@ import React from 'react'; | ||
gridRatio?: number; | ||
lineType?: 'curve' | 'straight'; | ||
lessCorners?: boolean; | ||
}; | ||
@@ -9,0 +11,0 @@ export declare const SmartEdgeContext: React.Context<SmartEdgeOptions | undefined>; |
@@ -11,5 +11,5 @@ import type { Grid } from 'pathfinding'; | ||
} | ||
export declare const generatePath: (grid: Grid, start: XYPosition, end: XYPosition) => { | ||
export declare const generatePath: (grid: Grid, start: XYPosition, end: XYPosition, lessCorners: boolean) => { | ||
fullPath: number[][]; | ||
smoothedPath: number[][]; | ||
}; |
@@ -10,10 +10,10 @@ import type { XYPosition } from 'react-flow-renderer'; | ||
* Since the top most point can have X/Y values different than zero, | ||
* and each cell in a grid represents a 10x10 pixel area in the grid, | ||
* there's need to be a conversion between a point in a graph to a point | ||
* in the grid. | ||
* and each cell in a grid represents a 10x10 pixel area in the grid (or a | ||
* gridRatio area), there's need to be a conversion between a point in a graph | ||
* to a point in the grid. | ||
* | ||
* We do this conversion by dividing a graph point X/Y values by 10, and | ||
* "shifting" their values up or down, depending on the values of the top most | ||
* point in the graph. The top most point in the graph will have the smallest | ||
* values for X and Y. | ||
* We do this conversion by dividing a graph point X/Y values by the grid ratio, | ||
* and "shifting" their values up or down, depending on the values of the top | ||
* most point in the graph. The top most point in the graph will have the | ||
* smallest values for X and Y. | ||
* | ||
@@ -20,0 +20,0 @@ * We avoid setting nodes in the border of the grid (x=0 or y=0), so there's |
{ | ||
"name": "@tisoap/react-flow-smart-edge", | ||
"version": "0.3.0", | ||
"version": "0.4.0", | ||
"keywords": [ | ||
@@ -58,10 +58,12 @@ "react", | ||
"@babel/core": "7.16.0", | ||
"@storybook/addon-essentials": "6.3.12", | ||
"@storybook/addon-essentials": "6.4.9", | ||
"@storybook/addon-info": "5.3.21", | ||
"@storybook/addon-links": "6.3.12", | ||
"@storybook/addons": "6.3.12", | ||
"@storybook/components": "6.3.12", | ||
"@storybook/core-events": "6.3.12", | ||
"@storybook/react": "6.3.12", | ||
"@storybook/theming": "6.3.12", | ||
"@storybook/addon-links": "6.4.9", | ||
"@storybook/addons": "6.4.9", | ||
"@storybook/builder-webpack5": "6.4.9", | ||
"@storybook/components": "6.4.9", | ||
"@storybook/core-events": "6.4.9", | ||
"@storybook/manager-webpack5": "6.4.9", | ||
"@storybook/react": "6.4.9", | ||
"@storybook/theming": "6.4.9", | ||
"@types/pathfinding": "0.0.5", | ||
@@ -68,0 +70,0 @@ "@types/react": "17.0.34", |
@@ -65,3 +65,3 @@ # React Flow Smart Edge | ||
// Configure by how many milliseconds the Edge render should be | ||
//debounced. Default 200, 0 to disable. | ||
// debounced. Default 200, 0 to disable. | ||
debounceTime: 200, | ||
@@ -78,2 +78,11 @@ | ||
gridRatio: 10, | ||
// The type of line that is draw. Available options are: | ||
// 'curve' - Curved lines with BezierEdge fallback (default) | ||
// 'straight' - Straight lines with StraightEdge fallback | ||
lineType: 'curve', | ||
// Boolean value to control if the path finding algorithm should | ||
// use less diagonal movement, default to false. | ||
lessCorners: false, | ||
}; | ||
@@ -80,0 +89,0 @@ ``` |
@@ -27,4 +27,4 @@ import { Grid } from 'pathfinding'; | ||
// Create a grid representation of the graph box, where each cell is | ||
// equivalent to 10x10 pixels on the graph. We'll use this simplified grid | ||
// to do pathfinding. | ||
// equivalent to 10x10 pixels (or the grid ratio) on the graph. We'll use | ||
// this simplified grid to do pathfinding. | ||
const mapColumns = roundUp(width, gridRatio) / gridRatio + 1; | ||
@@ -31,0 +31,0 @@ const mapRows = roundUp(height, gridRatio) / gridRatio + 1; |
@@ -15,13 +15,24 @@ import { AStarFinder, Util, DiagonalMovement } from 'pathfinding'; | ||
const withDiagonalMovement = { | ||
allowDiagonal: true, | ||
dontCrossCorners: true, | ||
diagonalMovement: DiagonalMovement.Always, | ||
}; | ||
const withStraightMovement = { | ||
allowDiagonal: false, | ||
}; | ||
export const generatePath = ( | ||
grid: Grid, | ||
start: XYPosition, | ||
end: XYPosition | ||
end: XYPosition, | ||
lessCorners: boolean | ||
) => { | ||
const finder = new AStarFinder({ | ||
diagonalMovement: DiagonalMovement.Always, | ||
allowDiagonal: true, | ||
dontCrossCorners: true, | ||
}); | ||
const finderOptions = lessCorners | ||
? withStraightMovement | ||
: withDiagonalMovement; | ||
const finder = new AStarFinder(finderOptions); | ||
let fullPath: number[][] = []; | ||
@@ -28,0 +39,0 @@ let smoothedPath: number[][] = []; |
@@ -11,10 +11,10 @@ import type { XYPosition } from 'react-flow-renderer'; | ||
* Since the top most point can have X/Y values different than zero, | ||
* and each cell in a grid represents a 10x10 pixel area in the grid, | ||
* there's need to be a conversion between a point in a graph to a point | ||
* in the grid. | ||
* and each cell in a grid represents a 10x10 pixel area in the grid (or a | ||
* gridRatio area), there's need to be a conversion between a point in a graph | ||
* to a point in the grid. | ||
* | ||
* We do this conversion by dividing a graph point X/Y values by 10, and | ||
* "shifting" their values up or down, depending on the values of the top most | ||
* point in the graph. The top most point in the graph will have the smallest | ||
* values for X and Y. | ||
* We do this conversion by dividing a graph point X/Y values by the grid ratio, | ||
* and "shifting" their values up or down, depending on the values of the top | ||
* most point in the graph. The top most point in the graph will have the | ||
* smallest values for X and Y. | ||
* | ||
@@ -21,0 +21,0 @@ * We avoid setting nodes in the border of the grid (x=0 or y=0), so there's |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
194446
2002
131
38