treechartjs
Advanced tools
Comparing version 0.0.4 to 0.0.5
@@ -1,1 +0,1 @@ | ||
function e(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function t(e,t){for(var n=0;n<t.length;n++){var i=t[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(e,i.key,i)}}function n(e,n,i){return n&&t(e.prototype,n),i&&t(e,i),e}function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function o(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?r(Object(n),!0).forEach((function(t){i(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):r(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}var a=function(){function t(n){e(this,t);var i=n.scrollContainer,r=n.eventContainer,o=n.autoScrollTriggerDistance,a=n.autoScrollSpeed;this.scrollContainer=i,this.eventContainer=r,this.autoScrollSpeed=a,this.triggerDistance=o||0,this.targetNode=null,this.interval=0,this.directData={left:!1,right:!1,top:!1,bottom:!1},this.setEvent()}return n(t,[{key:"setEvent",value:function(){var e=this,t=this.eventContainer;this.mouseMoveHandler=function(t){var n=t.button,i=t.movementX,r=t.movementY;0===i&&0===r||!n&&e.targetNode&&(e.setDirectData(t),e.triggerScroll())},t.addEventListener("mousemove",this.mouseMoveHandler)}},{key:"setDirectData",value:function(e){var t=e.movementX,n=e.movementY,i=this.scrollContainer,r=this.targetNode,o=this.triggerDistance,a=this.directData,s=i.scrollLeft,l=i.scrollTop,c=i.scrollWidth,d=i.scrollHeight,h=i.clientWidth,u=i.clientHeight,v=i.getBoundingClientRect(),g=v.left,f=v.right,y=v.top,p=v.bottom,m=r.getBoundingClientRect(),C=m.left,k=m.right,E=m.top,L=m.bottom;C-g<o&&(a.left=!0),E-y<o&&(a.top=!0),f-k<o&&(a.right=!0),p-L<o&&(a.bottom=!0),(t>0||0===s)&&(a.left=!1),(n>0||0===l)&&(a.top=!1),(t<0||s+h>=c)&&(a.right=!1),(n<0||l+u>=d)&&(a.bottom=!1)}},{key:"triggerScroll",value:function(){var e=this.directData,t=this.scrollContainer,n=this.autoScrollSpeed,i=!1;for(var r in e)if(e[r]){i=!0;break}if(!i)return this.stop(!0);this.interval||(this.interval=setInterval((function(){var i=t.scrollLeft,r=t.scrollTop;e.left&&(i-=n),e.right&&(i+=n),e.top&&(r-=n),e.bottom&&(r+=n),t.scrollLeft=i,t.scrollTop=r}),20))}},{key:"start",value:function(e){this.targetNode=e}},{key:"stop",value:function(){var e=arguments.length>0&&void 0!==arguments[0]&&arguments[0];e||(this.targetNode=null),this.interval&&(clearInterval(this.interval),this.interval=0)}},{key:"destroy",value:function(){this.eventContainer.removeEventListener("mousemove",this.mouseMoveHandler),this.targetNode=this.scrollContainer=this.eventContainer=null,this.interval=0}}]),t}(),s=function(e){return/HTML/.test(Object.prototype.toString.call(e))&&1===e.nodeType},l=function(e){return/Number/.test(Object.prototype.toString.call(e))},c=function(){function t(n){e(this,t),this.mergeOption(n),this.createChartElement(),this.resize(),this.setEvent()}return n(t,[{key:"getKeyByElement",value:function(e){return s(e)&&e.classList.contains("tree-chart-node")?e.getAttribute("data-key"):null}},{key:"getNodeElement",value:function(e){return this.nodesContainer.querySelector(".tree-chart-item-".concat(e))}},{key:"getPreviousKey",value:function(e){try{var t=this.getNodeElement(e);return this.getKeyByElement(t.parentElement.previousElementSibling.querySelector(".tree-chart-node"))}catch(e){return null}}},{key:"getNextKey",value:function(e){try{var t=this.getNodeElement(e);return this.getKeyByElement(t.parentElement.nextElementSibling.querySelector(".tree-chart-node"))}catch(e){return null}}},{key:"getParentKey",value:function(e){try{var t=this.getNodeElement(e);return this.getKeyByElement(t.parentElement.parentElement.previousElementSibling)}catch(e){return null}}},{key:"getChildrenKeys",value:function(e){var t=this.getNodeElement(e).getAttribute("data-children");return t?t.split(","):[]}},{key:"existChildren",value:function(e){var t=this.getNodeElement(e);return!!t&&Boolean(t.getAttribute("data-children"))}},{key:"insertNode",value:function(e,t,n){var i=this.getNodeElement(e);if(!/next|previous/.test(n)||i!==this.rootNode){var r=null,o=null,a=null;if(/Object/.test(Object.prototype.toString.call(t)))r=this.getKeyField(t),o=this.createNode(t),(a=this.createNodeContainer()).appendChild(o),this.setNodeEvent(o);else{r=t,a=(o=this.getNodeElement(r)).parentElement;var s=this.getParentKey(r);this.removeChildrenKey(s,r),this.existChildren(s)||(this.removeChildrenContainer(s),this.allowFold&&this.removeFoldButton(s))}if("child"===n){if(this.existChildren(e))this.getChildrenContainer(e).appendChild(a),this.nodeIsFold(e)&&this.toggleFold(e);else{var l=this.createChildrenContainer();l.appendChild(a),i.parentElement.appendChild(l),this.createFoldButton(i)}this.addChildrenKey(e,r)}else{var c=this.getParentKey(e),d=this.getChildrenContainer(c),h=i.parentElement;"previous"===n&&d.insertBefore(a,h),"next"===n&&d.insertBefore(a,h.nextElementSibling),this.addChildrenKey(c,r)}this.reloadLink()}}},{key:"removeNode",value:function(e){var t=this.getNodeElement(e);if(t){if(t===this.rootNode)return console.warn("not allow remove root node");var n=this.getParentKey(e);this.removeChildrenKey(n,e);var i=t.parentElement;i.parentElement.removeChild(i),this.existChildren(n)||(this.removeChildrenContainer(n),this.allowFold&&this.removeFoldButton(n)),this.reloadLink()}}},{key:"nodeIsFold",value:function(e){return this.getFoldButton(e).classList.contains("is-fold")}},{key:"toggleFold",value:function(e){var t=this.getFoldButton(e);if(t){var n=this.getChildrenContainer(e);this.nodeIsFold(e)?(n.classList.remove("is-hidden"),t.classList.remove("is-fold")):(n.classList.add("is-hidden"),t.classList.add("is-fold")),this.reloadLink()}}},{key:"reRenderNode",value:function(e,t){var n=this,i=e.toString(),r=this.getKeyField(t),o=this.getNodeElement(i),a=this.getChildrenKeys(e);if(r!==i){var s=this.linkContainer,l=this.getParentKey(i);this.replaceChildrenKey(l,i,r);var c="line-".concat(l,"-").concat(i),d=s.querySelector(".".concat(c));d.classList.remove(c),d.classList.add("line-".concat(l,"-").concat(r)),a.forEach((function(e){var t="line-".concat(i,"-").concat(e),o=n.linkContainer.querySelector(".".concat(t));o.classList.remove(t),o.classList.add("line-".concat(r,"-").concat(e))})),this.replacePositionNodeKey(i,r)}var h=this.createNode(t);a.length&&h.setAttribute("data-children",a.join()),o.querySelector(".tree-chart-unfold")&&this.createFoldButton(h);var u=o.parentElement;u.insertBefore(h,o),u.removeChild(o)}},{key:"reloadLink",value:function(){this.createLink(),this.resize()}},{key:"reRender",value:function(e){var t=this.nodesContainer;t.innerHTML="";var n=this.createNodeContainer();t.appendChild(n),this.createNodes(e,n,!0),this.reloadLink()}},{key:"registerEvent",value:function(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:window;this.eventList||(this.eventList=[]);var i=t.bind(this);this.eventList.push({eventTarget:n,type:e,handler:i}),n.addEventListener(e,i)}},{key:"unregisterEvent",value:function(){this.eventList.forEach((function(e){return e.eventTarget.removeEventListener(e.type,e.handler)}))}},{key:"addChildrenKey",value:function(e,t){var n=this.getNodeElement(e),i=n.getAttribute("data-children")||"";n.setAttribute("data-children",i?"".concat(i,",").concat(t):t)}},{key:"removeChildrenKey",value:function(e,t){var n=this.getChildrenKeys(e);if(n.length){var i=n.indexOf(t);i>-1&&n.splice(i,1);var r=this.getNodeElement(e);n.length?r.setAttribute("data-children",n.join()):r.removeAttribute("data-children")}}},{key:"replaceChildrenKey",value:function(e,t,n){var i=this.getChildrenKeys(e);if(i.length){var r=i.indexOf(t);-1!==r&&(i.splice(r,1,n),this.getNodeElement(e).setAttribute("data-children",i.join()))}}},{key:"createChildrenContainer",value:function(e){var t=document.createElement("div");return t.classList.add("tree-chart-children-container"),e&&t.classList.add(e),t}},{key:"getChildrenContainer",value:function(e){return this.getNodeElement(e).nextElementSibling}},{key:"removeChildrenContainer",value:function(e){var t=this.getChildrenContainer(e);t.parentElement.removeChild(t)}},{key:"getKeyField",value:function(e){return e[this.option.keyField].toString()||null}}]),n(t,[{key:"mergeOption",value:function(e){var t=o({keyField:"id",isVertical:!0,distanceX:40,distanceY:40,allowFold:!1,foldNodeKeys:[],draggable:!1,dragScroll:!1,autoScrollTriggerDistance:50,autoScrollSpeed:6,line:{type:"bezier",smooth:50}},e),n=t.draggable,i=t.allowFold,r=t.dragScroll,a=t.isVertical,s=t.line,c=t.padding,d=t.distanceX,h=t.distanceY;d<40&&(t.distanceX=40),h<40&&(t.distanceY=40),this.draggable=n,this.allowFold=i,this.dragScroll=r,this.isVertical=a,this.lineConfig=s;var u=o({top:30,right:30,bottom:30,left:30},c);for(var v in u){var g=u[v];l(g)||(g=0),n&&g<30&&(g=30),u[v]=g}this.containerPadding=u,this.option=t,this.initHooks()}},{key:"initHooks",value:function(){var e=this,t=["contentRender"].concat(["nodeControl","preventDrag"],["dragStart","dragEnd","click","mouseEnter","mouseLeave"]);this.hooks={},t.forEach((function(t){var n=e.option[t];"function"==typeof n&&(e.hooks[t]=n)}))}},{key:"createChartElement",value:function(){var e=this.isVertical,t=this.option,n=t.container,i=t.data;n.classList.add("tree-chart"),e&&n.classList.add("is-vertical"),this.container=n,this.createNodes(i,this.createNodesContainer()),this.createLinkContainer(),this.createLink(),this.createGhostContainer()}},{key:"createNodesContainer",value:function(){var e=this.container,t=this.containerPadding,n=this.createNodeContainer();for(var i in n.classList.add("is-nodes-container"),t)if(/left|top|right|bottom/.test(i)){var r=t[i];n.style["padding".concat(i.replace(/^./,(function(e){return e.toUpperCase()})))]="".concat(r,"px")}e.appendChild(n),this.nodesContainer=n;var o=this.createNodeContainer();return n.append(o),o}},{key:"createNodeContainer",value:function(){var e=document.createElement("div");return e.classList.add("tree-chart-container"),e}},{key:"createNodes",value:function(e,t,n){var i=this,r=this.allowFold,o=this.rootNode,a=this.option,s=e.children,l=a.foldNodeKeys,c=Array.isArray(s)&&s.length>0,d=this.createNode(e);if(t.appendChild(d),o&&!n||(this.rootNode=d),c){var h=this.createChildrenContainer();if(t.appendChild(h),r){var u=this.createFoldButton(d);l.includes(this.getKeyField(e))&&(u.classList.add("is-fold"),h.classList.add("is-hidden"))}var v=[];s.forEach((function(e){v.push(i.getKeyField(e));var t=i.createNodeContainer();h.appendChild(t),i.createNodes(e,t)})),d.setAttribute("data-children",v.join())}}},{key:"createNode",value:function(e){var t=this.draggable,n=this.hooks,i=this.option,r=i.distanceX,a=i.distanceY,l=n.contentRender,c=n.nodeControl,d=document.createElement("div"),h=this.getKeyField(e);d.classList.add("tree-chart-node","tree-chart-item-".concat(h)),d.setAttribute("data-key",h),d.style.marginBottom="".concat(a,"px"),d.style.marginRight="".concat(r,"px");var u=document.createElement("div");if(u.classList.add("tree-render-container"),l){var v=l(e);"string"==typeof v?u.innerHTML=v.replace(/>\s+</g,"><"):s(v)?u.appendChild(v):u.innerText="Please check contentRender return type is string or element"}else u.innerText="option.contentRender is required";if(d.appendChild(u),this.setNodeEvent(d),t&&c){var g=o({draggable:!0,insertChild:!0,insertPrevious:!0,insertNext:!0},c(e));!g.draggable&&d.classList.add("not-allow-drag"),!g.insertChild&&d.classList.add("not-allow-insert-child"),!g.insertPrevious&&d.classList.add("not-allow-insert-previous"),!g.insertNext&&d.classList.add("not-allow-insert-next")}return d}},{key:"createGhostContainer",value:function(){var e=this.container,t=document.createElement("div");t.classList.add("tree-chart-ghost-container"),e.appendChild(t),this.ghostContainer=t}},{key:"createFoldButton",value:function(e){if(!e.querySelector(".tree-chart-unfold")){var t=document.createElement("div");return t.classList.add("tree-chart-unfold"),t.innerHTML="<div></div><div></div>",e.appendChild(t),t}}},{key:"getFoldButton",value:function(e){return this.getNodeElement(e).querySelector(".tree-chart-unfold")}},{key:"removeFoldButton",value:function(e){var t=this.getFoldButton(e);t&&t.parentElement.removeChild(t)}},{key:"createLinkContainer",value:function(){var e=this.container,t=document.createElementNS("http://www.w3.org/2000/svg","svg");t.classList.add("tree-chart-link-container"),e.appendChild(t),this.linkContainer=t}},{key:"createLink",value:function(){var e=this,t=this.container,n=this.nodesContainer,i=this.linkContainer,r=this.draggable,o=this.isVertical,a=t.getBoundingClientRect(),s=a.left,l=a.top,c=t.scrollLeft,d=t.scrollTop;i.innerHTML="",r&&this.initPositionData(),n.querySelectorAll(".tree-chart-node").forEach((function(t){var n=t.getAttribute("data-children"),i=t.getBoundingClientRect(),a=i.left,h=i.right,u=i.top,v=i.bottom,g=e.getKeyByElement(t),f=t.nextElementSibling;if(n&&!f.classList.contains("is-hidden")){var y={x:a-s+c+(o?t.offsetWidth/2:t.offsetWidth),y:u-l+d+(o?t.offsetHeight:t.offsetHeight/2),key:g};n.split(",").forEach((function(t){var n=e.getNodeElement(t),i=n.getBoundingClientRect(),r=i.left,a=i.top,h=n.offsetWidth,u=(n.offsetHeight,{x:r-s+c+(o?h/2:0),y:a-l+d+(o?0:n.offsetHeight/2),key:t});e.drawLine(y,u)}))}r&&e.addPositionData(g,{left:a-s+c,right:h-s+c,top:u-l+d,bottom:v-l+d})}))}},{key:"initPositionData",value:function(){this.positionData={left:{sortList:[]},right:{sortList:[]},top:{sortList:[]},bottom:{sortList:[]},node:{}}}},{key:"addPositionData",value:function(e,t){var n=this.positionData;for(var i in n.node[e]=t,t){var r=t[i],o=n[i];o[r]?o[r].push(e):o[r]=[e];var a=o.sortList;if(a.length)for(var s=0,l=a.length;s<l;s++){var c=a[s];if(r===c)break;if(r<c){a.splice(s,0,r);break}s===l-1&&a.push(r)}else a.push(r)}}},{key:"replacePositionNodeKey",value:function(e,t){var n=this.positionData;n.node[t]=n.node[e],delete n.node[e],["left","top","right","bottom"].forEach((function(i){var r=n[i];for(var o in r)if("sortList"!==o){var a=r[o],s=a.indexOf(e);if(s>-1){a.splice(s,1,t);break}}}))}},{key:"setEvent",value:function(){var e=this.allowFold,t=this.draggable,n=this.dragScroll;e&&this.setFoldEvent(),this.setClickHook(),t&&this.setDragEvent(),n&&this.setDragScroll()}},{key:"setFoldEvent",value:function(){var e=this;this.nodesContainer.addEventListener("click",(function(t){var n=t.target;n.classList.contains("tree-chart-unfold")&&e.toggleFold(e.getKeyByElement(n.parentElement))}))}},{key:"drawLine",value:function(e,t,n){var i=this.linkContainer,r=this.isVertical,o=this.allowFold,a=this.lineConfig,s=a.type,l=a.smooth,c="line-".concat(e.key,"-").concat(t.key),d=document.querySelector(".".concat(c));d||((d=document.createElementNS("http://www.w3.org/2000/svg","path")).classList.add(c,"line-from-".concat(e.key)),n&&d.classList.add("is-temp-line"),i.appendChild(d));var h="",u=e.x,v=e.y,g=t.x,f=t.y;o&&this.existChildren(e.key)&&(r?v+=5:u+=5);var y=(g-u)/2,p=(f-v)/2,m="".concat(u," ").concat(v),C="".concat(g," ").concat(f);if("straight"===s&&(h="M".concat(m," T ").concat(C)),"broken"===s){var k="",E="";r?(k="".concat(u," ").concat(v+p),E="".concat(g," ").concat(f-p)):(k="".concat(u+y," ").concat(v),E="".concat(g-y," ").concat(f)),h="M".concat(m," L").concat(k," L").concat(E," L").concat(C)}if("bezier"===s){var L=l/100,b="";b=r?"".concat(u," ").concat(v+(p-p*L)):"".concat(u+(y-y*L)," ").concat(v);var N="".concat(u+y," ").concat(v+p);h="M".concat(m," Q").concat(b," ").concat(N," T ").concat(C)}d.setAttribute("d",h)}},{key:"getCurrentEventNode",value:function(e){var t=this.nodesContainer;if(e.classList.contains("tree-chart-unfold"))return null;for(var n=e;t!==n;){if(n.classList.contains("tree-chart-node"))return n;n=n.parentElement}return null}},{key:"isDragging",value:function(){var e=this.draggable,t=this.dragData;if(!e)return!1;var n=t.ghostTranslateX,i=t.ghostTranslateY;return t.key&&(0!==n||0!==i)}},{key:"setClickHook",value:function(){var e=this,t=this.nodesContainer,n=this.hooks.click;if(n){var i=null;t.addEventListener("mousedown",(function(t){var n=t.button,r=t.target;0===n&&(i=e.getCurrentEventNode(r))})),t.addEventListener("mouseup",(function(t){var r=t.button,o=t.target;if(0===r){var a=e.getCurrentEventNode(o);a&&a===i&&!e.isDragging()&&n({key:e.getKeyByElement(a),element:a},t)}}))}}},{key:"setNodeEvent",value:function(e){var t=this,n=this.hooks,i=n.mouseEnter,r=n.mouseLeave,o={key:this.getKeyByElement(e),element:e},a=e.querySelector(".tree-render-container");i&&a.addEventListener("mouseenter",(function(e){t.isDragging()||i(o,e)})),r&&a.addEventListener("mouseleave",(function(e){t.isDragging()||r(o,e)}))}},{key:"createNodeParams",value:function(e){return{key:e,parentKey:this.getParentKey(e),previousKey:this.getPreviousKey(e),nextKey:this.getNextKey(e)}}},{key:"initDragData",value:function(){this.dragData={key:null,ghostElement:null,ghostTranslateX:0,ghostTranslateY:0,mouseDownOffsetX:0,mouseDownOffsetY:0}}},{key:"setDragEvent",value:function(){var e=this,t=this.ghostContainer,n=this.container,i=this.nodesContainer,r=this.hooks,o=this.option,s=o.autoScrollTriggerDistance,l=o.autoScrollSpeed,c=r.preventDrag,d=r.dragStart,h=r.dragEnd,u=!0;this.initDragData(),i.addEventListener("mousedown",(function(t){var i=t.button,r=t.clientX,o=t.clientY;if(0===i){var a=e.getCurrentEventNode(t.target),s=e.getKeyByElement(a);if(a&&a!==e.rootNode&&!(a.classList.contains("not-allow-drag")||c&&c({key:s,element:a},t))){var l=e.positionData.node[s],d=l.left,h=l.top,u=a.cloneNode(!0);u.style.margin="0px",Object.assign(e.dragData,{key:s,ghostElement:u,mouseDownOffsetX:r+n.scrollLeft-d,mouseDownOffsetY:o+n.scrollTop-h}),e.FollowScroll.start(u)}}})),i.addEventListener("mousemove",(function(r){var o=r.button,a=r.movementX,s=r.movementY,l=r.clientX,c=r.clientY,h=e.dragData,v=h.ghostElement,g=h.mouseDownOffsetX,f=h.mouseDownOffsetY,y=h.key;if(0===o&&y&&(0!==a||0!==s)){getSelection&&getSelection().removeAllRanges(),i.classList.add("cursor-move"),!t.contains(v)&&t.appendChild(v);var p=l+n.scrollLeft-g,m=c+n.scrollTop-f;v.style.transform="translate(".concat(p,"px, ").concat(m,"px)"),Object.assign(e.dragData,{ghostTranslateX:p,ghostTranslateY:m});var C=e.getGhostPosition();e.setDragEffect(C),d&&u&&(u=!1,d({key:y,element:e.getNodeElement(y)}))}})),this.registerEvent("mouseup",(function(){u=!0;var t=e.dragData,n=e.nodesContainer,i=e.ghostContainer,r="",o="",a=t.key;if(a){var s=n.querySelector(".collide-node");if(s&&(r=e.getKeyByElement(s),s.classList.contains("become-previous")&&(o="previous"),s.classList.contains("become-next")&&(o="next"),s.classList.contains("become-child")&&(o="child")),e.FollowScroll.stop(),n.classList.remove("cursor-move"),i.innerHTML="",e.removeDragEffect(),e.initDragData(),s){var l=e.createNodeParams(a);e.insertNode(r,a,o);var c=e.createNodeParams(a);h&&h({from:l,to:c,target:r,key:a,type:o})}}}));var v={top:n.scrollTop,left:n.scrollLeft};this.registerEvent("scroll",(function(){var t=e.dragData,i=t.key,r=t.ghostElement,o=t.ghostTranslateY,a=t.ghostTranslateX,s=v.left,l=v.top,c=n.scrollLeft,d=n.scrollTop;if(i&&r){var h=a+c-s,u=o+d-l;r.style.transform="translate(".concat(h,"px, ").concat(u,"px)"),Object.assign(e.dragData,{ghostTranslateX:h,ghostTranslateY:u}),e.setDragEffect(e.getGhostPosition())}v.left=c,v.top=d}),n),this.FollowScroll=new a({scrollContainer:n,autoScrollTriggerDistance:s,eventContainer:i,autoScrollSpeed:l})}},{key:"getGhostPosition",value:function(){var e=this.dragData,t=e.ghostTranslateX,n=e.ghostTranslateY,i=e.ghostElement;return{left:t,top:n,right:t+i.offsetWidth,bottom:n+i.offsetHeight}}},{key:"removeDragEffect",value:function(){var e=this.linkContainer,t=this.nodesContainer,n=e.querySelector(".is-temp-line");n&&e.removeChild(n);var i=t.querySelector(".collide-node");i&&i.classList.remove("collide-node","become-previous","become-next","become-child");var r=t.querySelector(".temp-children-container");r&&r.parentElement.removeChild(r);var o=t.querySelector(".show-not-allow");o&&o.classList.remove("show-not-allow")}},{key:"getCollideType",value:function(e,t){var n=this.rootNode,i=this.isVertical,r=this.dragData,o=this.positionData,a=r.key,s=o.node[e],l=s.top,c=s.bottom,d=s.left,h=s.right,u=t.left,v=t.right,g=t.top,f=t.bottom,y=this.getNodeElement(a),p=this.getNodeElement(e),m=e===this.getParentKey(a),C=e===this.getPreviousKey(a),k=e===this.getNextKey(a),E={child:!p.classList.contains("not-allow-insert-child")&&!m,next:!p.classList.contains("not-allow-insert-next")&&!C,previous:!p.classList.contains("not-allow-insert-previous")&&!k};if(p===n)return E.child?"child":"notAllow";if(y.parentElement.contains(p))return"notAllow";if(i){var L=.5*(h-d);if(v<=d+L&&E.previous)return"previous";if(u>=h-L&&E.next)return"next"}else{var b=.5*(c-l);if(f<=l+b&&E.previous)return"previous";if(g>=c-b&&E.next)return"next"}if(E.child)return"child";for(var N in E)if(E[N])return N;return"notAllow"}},{key:"getCollideLinePosition",value:function(e,t){var n=this.isVertical,i=this.positionData,r=this.option,o=r.distanceX,a=r.distanceY,s={},l=i.node[t],c=l.top,d=l.bottom,h=l.left,u=l.right;if(n){if("child"===e){if(s.from={x:(h+u)/2,y:d,key:t},this.existChildren(t)&&!this.nodeIsFold(t)){var v=this.getChildrenKeys(t).pop(),g=i.node[v],f=g.right,y=g.top;return s.to={x:f+20,y:y,key:"temp"},s}return s.to={x:(h+u)/2,y:d+a,key:"temp"},s}var p=this.getParentKey(t),m=i.node[p];return s.from={x:(m.left+m.right)/2,y:m.bottom,key:p},s.to={x:"previous"===e?h-20:u+20,y:c,key:"temp"},s}if("child"===e){if(s.from={x:u,y:(c+d)/2,key:t},this.existChildren(t)&&!this.nodeIsFold(t)){var C=this.getChildrenKeys(t).pop(),k=i.node[C],E=k.left,L=k.bottom;return s.to={x:E,y:L+20,key:"temp"},s}return s.to={x:u+o,y:(c+d)/2,key:"temp"},s}var b=this.getParentKey(t),N=i.node[b];return s.from={x:N.right,y:(N.top+N.bottom)/2,key:b},s.to={x:h,y:"previous"===e?c-20:d+20,key:"temp"},s}},{key:"createDragEffect",value:function(e,t){var n=this.positionData,i=this.getNodeElement(e),r=this.getCollideType(e,t);if("notAllow"===r)return i.classList.add("show-not-allow");i.classList.add("become-".concat(r),"collide-node");var o=this.getCollideLinePosition(r,e),a=o.from,s=o.to;if(this.drawLine(a,s,!0),"child"===r&&(!this.existChildren(e)||this.nodeIsFold(e))){var l=n.node[e],c=l.top,d=l.bottom,h=l.left,u=l.right,v=document.createElement("div");v.classList.add("tree-chart-node","temp-chart-content"),v.style.width="".concat(u-h,"px"),v.style.height="".concat(d-c,"px");var g=this.createChildrenContainer("temp-children-container"),f=this.createNodeContainer(!0);f.appendChild(v),g.appendChild(f),i.parentElement.appendChild(g)}}},{key:"getCollideNode",value:function(e){var t=e.left,n=e.right,i=e.top,r=e.bottom,o=this.dragData.key,a=this.positionData,s=a.left,c=a.right,d=a.top,h=a.bottom,u=a.node,v=function(e,t,n){var i=t.length;if(n){for(var r=0;r<i;r++)if(t[r]>=e)return t[r]}else for(var o=i-1;o>-1;o--)if(t[o]<=e)return t[o];return null},g=v(t,c.sortList,!0),f=v(i,h.sortList,!0),y=v(n,s.sortList),p=v(r,d.sortList),m=function(e,t,n){var i=[];return l(e)&&t.sortList.forEach((function(r){(n?r>=e:r<=e)&&(i=i.concat(t[r]))})),i},C=function(){for(var e=arguments.length,t=new Array(e),n=0;n<e;n++)t[n]=arguments[n];var i=t.length;if(i<2)return[];var r=[],o={};return t.reduce((function(e,t){return e.concat(t)}),[]).forEach((function(e){o[e]?(o[e]++,o[e]===i&&r.push(e)):o[e]=1})),r}(m(g,c,!0),m(f,h,!0),m(y,s),m(p,d)),k=C.indexOf(o);if(k>-1&&C.splice(k,1),!C.length)return null;if(1===C.length)return C[0];var E={nodeKey:"",nodeArea:0};return C.forEach((function(e){var o=function(e){var o=u[e],a=o.left,s=o.right,l=o.top,c=o.bottom;return(a<=t?s-t:n-a)*(l<=i?c-i:r-l)}(e);o>E.nodeArea&&Object.assign(E,{nodeKey:e,nodeArea:o})})),E.nodeKey}},{key:"setDragEffect",value:function(e){this.removeDragEffect();var t=this.getCollideNode(e);t&&this.createDragEffect(t,e)}},{key:"resize",value:function(){var e=this.nodesContainer,t=this.linkContainer,n=this.draggable,i=this.ghostContainer,r=this.rootNode,o=this.isVertical,a=e.style,s=t.style;a.height="auto",a.width="auto",a.minHeight="auto",a.minWidth="auto";var l=e.clientWidth,c=e.clientHeight;if(n){var d=r.getBoundingClientRect(),h=d.width,u=d.height;o?c+=u:l+=h}var v="".concat(l,"px"),g="".concat(c,"px");if(a[o?"minHeight":"minWidth"]="100%",a.width=s.width=v,a.height=s.height=g,n){var f=i.style;f.width=v,f.height=g}}},{key:"setDragScroll",value:function(){var e=this.container,t=this.nodesContainer,n=!0;t.addEventListener("mousedown",(function(e){0!==e.button||function(e){if(e.classList.contains("tree-chart-node"))return e;for(var n=e;t!==n;){if(n.classList.contains("tree-chart-node"))return n;n=n.parentElement}return null}(e.target)||(n=!1)})),t.addEventListener("mousemove",(function(t){t.preventDefault(),0!==t.button||n||(e.scrollLeft=e.scrollLeft-t.movementX,e.scrollTop=e.scrollTop-t.movementY)})),this.registerEvent("mouseup",(function(e){0===e.button&&(n=!0)}))}},{key:"destroy",value:function(){for(var e in this.FollowScroll.destroy(),this.unregisterEvent(),this.container.innerHTML="",this)this[e]=null}}]),t}();export default c; | ||
function e(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function t(e,t){for(var n=0;n<t.length;n++){var i=t[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(e,i.key,i)}}function n(e,n,i){return n&&t(e.prototype,n),i&&t(e,i),e}function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function o(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?r(Object(n),!0).forEach((function(t){i(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):r(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}var a=function(){function t(n){e(this,t);var i=n.scrollContainer,r=n.eventContainer,o=n.autoScrollTriggerDistance,a=n.autoScrollSpeed;this.scrollContainer=i,this.eventContainer=r,this.autoScrollSpeed=a,this.triggerDistance=o||0,this.targetNode=null,this.interval=0,this.directData={left:!1,right:!1,top:!1,bottom:!1},this.setEvent()}return n(t,[{key:"setEvent",value:function(){var e=this,t=this.eventContainer;this.mouseMoveHandler=function(t){var n=t.button,i=t.movementX,r=t.movementY;0===i&&0===r||!n&&e.targetNode&&(e.setDirectData(t),e.triggerScroll())},t.addEventListener("mousemove",this.mouseMoveHandler)}},{key:"setDirectData",value:function(e){var t=e.movementX,n=e.movementY,i=this.scrollContainer,r=this.targetNode,o=this.triggerDistance,a=this.directData,s=i.scrollLeft,l=i.scrollTop,c=i.scrollWidth,d=i.scrollHeight,h=i.clientWidth,u=i.clientHeight,v=i.getBoundingClientRect(),g=v.left,f=v.right,m=v.top,y=v.bottom,p=r.getBoundingClientRect(),C=p.left,k=p.right,E=p.top,L=p.bottom;C-g<o&&(a.left=!0),E-m<o&&(a.top=!0),f-k<o&&(a.right=!0),y-L<o&&(a.bottom=!0),(t>0||0===s)&&(a.left=!1),(n>0||0===l)&&(a.top=!1),(t<0||s+h>=c)&&(a.right=!1),(n<0||l+u>=d)&&(a.bottom=!1)}},{key:"triggerScroll",value:function(){var e=this.directData,t=this.scrollContainer,n=this.autoScrollSpeed,i=!1;for(var r in e)if(e[r]){i=!0;break}if(!i)return this.stop(!0);this.interval||(this.interval=setInterval((function(){var i=t.scrollLeft,r=t.scrollTop;e.left&&(i-=n),e.right&&(i+=n),e.top&&(r-=n),e.bottom&&(r+=n),t.scrollLeft=i,t.scrollTop=r}),20))}},{key:"start",value:function(e){this.targetNode=e}},{key:"stop",value:function(){var e=arguments.length>0&&void 0!==arguments[0]&&arguments[0];e||(this.targetNode=null),this.interval&&(clearInterval(this.interval),this.interval=0)}},{key:"destroy",value:function(){this.eventContainer.removeEventListener("mousemove",this.mouseMoveHandler),this.targetNode=this.scrollContainer=this.eventContainer=null,this.interval=0}}]),t}(),s=function(e){return/HTML/.test(Object.prototype.toString.call(e))&&1===e.nodeType},l=function(e){return/Number/.test(Object.prototype.toString.call(e))},c=function(e,t){var n=e.style;for(var i in t)n[i]=t[i]},d=function(){function t(n){e(this,t),this.initData(n),this.createChartElement(),this.resize(),this.setEvent()}return n(t,[{key:"getKeyByElement",value:function(e){return s(e)&&e.classList.contains("tree-chart-node")?e.getAttribute("data-key"):null}},{key:"getNodeElement",value:function(e){return this.elements.nodesContainer.querySelector(".tree-chart-item-".concat(e))}},{key:"getPreviousKey",value:function(e){try{var t=this.getNodeElement(e);return this.getKeyByElement(t.parentElement.previousElementSibling.querySelector(".tree-chart-node"))}catch(e){return null}}},{key:"getNextKey",value:function(e){try{var t=this.getNodeElement(e);return this.getKeyByElement(t.parentElement.nextElementSibling.querySelector(".tree-chart-node"))}catch(e){return null}}},{key:"getParentKey",value:function(e){try{var t=this.getNodeElement(e);return this.getKeyByElement(t.parentElement.parentElement.previousElementSibling)}catch(e){return null}}},{key:"getChildrenKeys",value:function(e){var t=this.getNodeElement(e).getAttribute("data-children");return t?t.split(","):[]}},{key:"existChildren",value:function(e){var t=this.getNodeElement(e);return!!t&&Boolean(t.getAttribute("data-children"))}},{key:"insertNode",value:function(e,t,n){var i=this.getNodeElement(e);if(!/next|previous/.test(n)||i!==this.elements.rootNode){var r=null,o=null,a=null;if(/Object/.test(Object.prototype.toString.call(t)))r=this.getKeyField(t),o=this.createNode(t),(a=this.createNodeContainer()).appendChild(o),this.setNodeEvent(o);else{r=t,a=(o=this.getNodeElement(r)).parentElement;var s=this.getParentKey(r);this.removeChildrenKey(s,r),this.existChildren(s)||(this.removeChildrenContainer(s),this.allowFold&&this.removeFoldButton(s))}if("child"===n){if(this.existChildren(e))this.getChildrenContainer(e).appendChild(a),this.nodeIsFold(e)&&this.toggleFold(e);else{var l=this.createChildrenContainer();l.appendChild(a),i.parentElement.appendChild(l),this.createFoldButton(i)}this.addChildrenKey(e,r)}else{var c=this.getParentKey(e),d=this.getChildrenContainer(c),h=i.parentElement;"previous"===n&&d.insertBefore(a,h),"next"===n&&d.insertBefore(a,h.nextElementSibling),this.addChildrenKey(c,r)}this.reloadLink()}}},{key:"removeNode",value:function(e){var t=this.getNodeElement(e);if(t){if(t===this.elements.rootNode)return console.warn("not allow remove root node");var n=this.getParentKey(e);this.removeChildrenKey(n,e);var i=t.parentElement;i.parentElement.removeChild(i),this.existChildren(n)||(this.removeChildrenContainer(n),this.allowFold&&this.removeFoldButton(n)),this.reloadLink()}}},{key:"nodeIsFold",value:function(e){return this.getFoldButton(e).classList.contains("is-fold")}},{key:"toggleFold",value:function(e){var t=this.getFoldButton(e);if(t){var n=this.getChildrenContainer(e);this.nodeIsFold(e)?(n.classList.remove("is-hidden"),t.classList.remove("is-fold")):(n.classList.add("is-hidden"),t.classList.add("is-fold")),this.reloadLink();var i=this.hooks.foldChange;"function"==typeof i&&i(e,this.nodeIsFold(e))}}},{key:"reRenderNode",value:function(e,t){var n=this,i=e.toString(),r=this.getKeyField(t),o=this.getNodeElement(i),a=this.getChildrenKeys(e);if(r!==i){var s=this.elements.linkContainer,l=this.getParentKey(i);this.replaceChildrenKey(l,i,r);var c="line-".concat(l,"-").concat(i),d=s.querySelector(".".concat(c));d.classList.remove(c),d.classList.add("line-".concat(l,"-").concat(r)),a.forEach((function(e){var t="line-".concat(i,"-").concat(e),o=n.linkContainer.querySelector(".".concat(t));o.classList.remove(t),o.classList.add("line-".concat(r,"-").concat(e))})),this.replacePositionNodeKey(i,r)}var h=this.createNode(t);a.length&&h.setAttribute("data-children",a.join()),o.querySelector(".tree-chart-unfold")&&this.createFoldButton(h);var u=o.parentElement;u.insertBefore(h,o),u.removeChild(o)}},{key:"reloadLink",value:function(){this.createLink(),this.resize()}},{key:"reRender",value:function(e){var t=this.elements.nodesContainer;this.elements.rootNode=null,t.innerHTML="";var n=this.createNodeContainer();t.appendChild(n),this.createNodes(e,n),this.reloadLink()}},{key:"registerEvent",value:function(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:window;this.eventList||(this.eventList=[]);var i=t.bind(this);this.eventList.push({eventTarget:n,type:e,handler:i}),n.addEventListener(e,i)}},{key:"unregisterEvent",value:function(){this.eventList.forEach((function(e){return e.eventTarget.removeEventListener(e.type,e.handler)}))}},{key:"addChildrenKey",value:function(e,t){var n=this.getNodeElement(e),i=n.getAttribute("data-children")||"";n.setAttribute("data-children",i?"".concat(i,",").concat(t):t)}},{key:"removeChildrenKey",value:function(e,t){var n=this.getChildrenKeys(e);if(n.length){var i=n.indexOf(t);i>-1&&n.splice(i,1);var r=this.getNodeElement(e);n.length?r.setAttribute("data-children",n.join()):r.removeAttribute("data-children")}}},{key:"replaceChildrenKey",value:function(e,t,n){var i=this.getChildrenKeys(e);if(i.length){var r=i.indexOf(t);-1!==r&&(i.splice(r,1,n),this.getNodeElement(e).setAttribute("data-children",i.join()))}}},{key:"createChildrenContainer",value:function(e){var t=document.createElement("div");return t.classList.add("tree-chart-children-container"),e&&t.classList.add(e),t}},{key:"getChildrenContainer",value:function(e){return this.getNodeElement(e).nextElementSibling}},{key:"removeChildrenContainer",value:function(e){var t=this.getChildrenContainer(e);t.parentElement.removeChild(t)}},{key:"getKeyField",value:function(e){return e[this.option.keyField].toString()||null}}]),n(t,[{key:"initData",value:function(e){var t=o({keyField:"id",isVertical:!0,distanceX:40,distanceY:40,allowFold:!1,foldNodeKeys:[],draggable:!1,dragScroll:!1,autoScrollTriggerDistance:50,autoScrollSpeed:6,line:{type:"bezier",smooth:50},hook:{}},e),n=t.draggable,i=t.allowFold,r=t.dragScroll,a=t.isVertical,s=t.line,c=t.padding,d=t.distanceX,h=t.distanceY;d<40&&(t.distanceX=40),h<40&&(t.distanceY=40),this.draggable=n,this.allowFold=i,this.dragScroll=r,this.isVertical=a,this.lineConfig=s;var u=o({top:30,right:30,bottom:30,left:30},c);for(var v in u){var g=u[v];l(g)||(g=0),n&&g<30&&(g=30),u[v]=g}this.containerPadding=u,this.option=t,this.elements={container:null,ghostContainer:null,nodesContainer:null,linkContainer:null,rootNode:null},this.initHook()}},{key:"initHook",value:function(){var e=this,t=this.option.hook;this.hooks={};["dragStart","dragEnd","click","mouseEnter","mouseLeave","foldChange"].forEach((function(n){var i=t[n];"function"==typeof i&&(e.hooks[n]=i)}))}},{key:"createChartElement",value:function(){var e=this.isVertical,t=this.option,n=t.container,i=t.data;n.classList.add("tree-chart"),e&&n.classList.add("is-vertical"),this.elements.container=n,this.createNodes(i,this.createNodesContainer()),this.createLinkContainer(),this.createLink(),this.createGhostContainer()}},{key:"createNodesContainer",value:function(){var e=this.containerPadding,t=this.createNodeContainer();for(var n in t.classList.add("is-nodes-container"),e)if(/left|top|right|bottom/.test(n)){var i=e[n];t.style["padding".concat(n.replace(/^./,(function(e){return e.toUpperCase()})))]="".concat(i,"px")}this.elements.container.appendChild(t),this.elements.nodesContainer=t;var r=this.createNodeContainer();return t.append(r),r}},{key:"createNodeContainer",value:function(){var e=document.createElement("div");return e.classList.add("tree-chart-container"),e}},{key:"createNodes",value:function(e,t){var n=this,i=this.allowFold,r=this.option,o=this.elements,a=e.children,s=r.foldNodeKeys,l=Array.isArray(a)&&a.length>0,c=this.createNode(e);if(t.appendChild(c),o.rootNode||(o.rootNode=c),l){var d=this.createChildrenContainer();if(t.appendChild(d),i){var h=this.createFoldButton(c);s.includes(this.getKeyField(e))&&(h.classList.add("is-fold"),d.classList.add("is-hidden"))}var u=[];a.forEach((function(e){u.push(n.getKeyField(e));var t=n.createNodeContainer();d.appendChild(t),n.createNodes(e,t)})),c.setAttribute("data-children",u.join())}}},{key:"createNode",value:function(e){var t=this.draggable,n=this.option,i=n.distanceX,r=n.distanceY,a=n.contentRender,l=n.nodeControl,d=document.createElement("div"),h=this.getKeyField(e);d.classList.add("tree-chart-node","tree-chart-item-".concat(h)),d.setAttribute("data-key",h),c(d,{marginBottom:"".concat(r,"px"),marginRight:"".concat(i,"px")});var u=document.createElement("div");if(u.classList.add("tree-render-container"),a){var v=a(e);"string"==typeof v?u.innerHTML=v.replace(/>\s+</g,"><"):s(v)?u.appendChild(v):u.innerText="Please check contentRender return type is string or element"}else u.innerText="option.contentRender is required";if(d.appendChild(u),this.setNodeEvent(d),t&&l){var g=o({draggable:!0,insertChild:!0,insertPrevious:!0,insertNext:!0},l(e));!g.draggable&&d.classList.add("not-allow-drag"),!g.insertChild&&d.classList.add("not-allow-insert-child"),!g.insertPrevious&&d.classList.add("not-allow-insert-previous"),!g.insertNext&&d.classList.add("not-allow-insert-next")}return d}},{key:"createGhostContainer",value:function(){var e=document.createElement("div");e.classList.add("tree-chart-ghost-container"),this.elements.container.appendChild(e),this.elements.ghostContainer=e}},{key:"createFoldButton",value:function(e){if(!e.querySelector(".tree-chart-unfold")){var t=document.createElement("div");return t.classList.add("tree-chart-unfold"),t.innerHTML="<div></div><div></div>",e.appendChild(t),t}}},{key:"getFoldButton",value:function(e){return this.getNodeElement(e).querySelector(".tree-chart-unfold")}},{key:"removeFoldButton",value:function(e){var t=this.getFoldButton(e);t&&t.parentElement.removeChild(t)}},{key:"createLinkContainer",value:function(){var e=document.createElementNS("http://www.w3.org/2000/svg","svg");e.classList.add("tree-chart-link-container"),this.elements.container.appendChild(e),this.elements.linkContainer=e}},{key:"createLink",value:function(){var e=this,t=this.draggable,n=this.isVertical,i=this.elements,r=i.container,o=i.nodesContainer,a=i.linkContainer,s=r.getBoundingClientRect(),l=s.left,c=s.top,d=r.scrollLeft,h=r.scrollTop;a.innerHTML="",t&&this.initPositionData(),o.querySelectorAll(".tree-chart-node").forEach((function(i){var r=i.getAttribute("data-children"),o=i.getBoundingClientRect(),a=o.left,s=o.right,u=o.top,v=o.bottom,g=e.getKeyByElement(i),f=i.nextElementSibling;if(r&&!f.classList.contains("is-hidden")){var m={x:a-l+d+(n?i.offsetWidth/2:i.offsetWidth),y:u-c+h+(n?i.offsetHeight:i.offsetHeight/2),key:g};r.split(",").forEach((function(t){var i=e.getNodeElement(t),r=i.getBoundingClientRect(),o=r.left,a=r.top,s=i.offsetWidth,u=(i.offsetHeight,{x:o-l+d+(n?s/2:0),y:a-c+h+(n?0:i.offsetHeight/2),key:t});e.drawLine(m,u)}))}t&&e.addPositionData(g,{left:a-l+d,right:s-l+d,top:u-c+h,bottom:v-c+h})}))}},{key:"initPositionData",value:function(){this.positionData={left:{sortList:[]},right:{sortList:[]},top:{sortList:[]},bottom:{sortList:[]},node:{}}}},{key:"addPositionData",value:function(e,t){var n=this.positionData;for(var i in n.node[e]=t,t){var r=t[i],o=n[i];o[r]?o[r].push(e):o[r]=[e];var a=o.sortList;if(a.length)for(var s=0,l=a.length;s<l;s++){var c=a[s];if(r===c)break;if(r<c){a.splice(s,0,r);break}s===l-1&&a.push(r)}else a.push(r)}}},{key:"replacePositionNodeKey",value:function(e,t){var n=this.positionData;n.node[t]=n.node[e],delete n.node[e],["left","top","right","bottom"].forEach((function(i){var r=n[i];for(var o in r)if("sortList"!==o){var a=r[o],s=a.indexOf(e);if(s>-1){a.splice(s,1,t);break}}}))}},{key:"setEvent",value:function(){var e=this.allowFold,t=this.draggable,n=this.dragScroll;e&&this.setFoldEvent(),this.setClickHook(),t&&this.setDragEvent(),n&&this.setDragScroll()}},{key:"setFoldEvent",value:function(){var e=this;this.elements.nodesContainer.addEventListener("click",(function(t){var n=t.target;n.classList.contains("tree-chart-unfold")&&e.toggleFold(e.getKeyByElement(n.parentElement))}))}},{key:"drawLine",value:function(e,t,n){var i=this.isVertical,r=this.allowFold,o=this.elements.linkContainer,a=this.lineConfig,s=a.type,l=a.smooth,c="line-".concat(e.key,"-").concat(t.key),d=document.querySelector(".".concat(c));d||((d=document.createElementNS("http://www.w3.org/2000/svg","path")).classList.add(c,"line-from-".concat(e.key)),n&&d.classList.add("is-temp-line"),o.appendChild(d));var h="",u=e.x,v=e.y,g=t.x,f=t.y;r&&this.existChildren(e.key)&&(i?v+=5:u+=5);var m=(g-u)/2,y=(f-v)/2,p="".concat(u," ").concat(v),C="".concat(g," ").concat(f);if("straight"===s&&(h="M".concat(p," T ").concat(C)),"broken"===s){var k="",E="";i?(k="".concat(u," ").concat(v+y),E="".concat(g," ").concat(f-y)):(k="".concat(u+m," ").concat(v),E="".concat(g-m," ").concat(f)),h="M".concat(p," L").concat(k," L").concat(E," L").concat(C)}if("bezier"===s){var L=l/100,b="";b=i?"".concat(u," ").concat(v+(y-y*L)):"".concat(u+(m-m*L)," ").concat(v);var N="".concat(u+m," ").concat(v+y);h="M".concat(p," Q").concat(b," ").concat(N," T ").concat(C)}d.setAttribute("d",h)}},{key:"getCurrentEventNode",value:function(e){var t=this.elements.nodesContainer;if(e.classList.contains("tree-chart-unfold"))return null;for(var n=e;t!==n;){if(n.classList.contains("tree-chart-node"))return n;n=n.parentElement}return null}},{key:"isDragging",value:function(){var e=this.draggable,t=this.dragData;if(!e)return!1;var n=t.ghostTranslateX,i=t.ghostTranslateY;return t.key&&(0!==n||0!==i)}},{key:"setClickHook",value:function(){var e=this,t=this.elements.nodesContainer,n=this.hooks.click;if(n){var i=null;t.addEventListener("mousedown",(function(t){var n=t.button,r=t.target;0===n&&(i=e.getCurrentEventNode(r))})),t.addEventListener("mouseup",(function(t){var r=t.button,o=t.target;if(0===r){var a=e.getCurrentEventNode(o);a&&a===i&&!e.isDragging()&&n({key:e.getKeyByElement(a),element:a},t)}}))}}},{key:"setNodeEvent",value:function(e){var t=this,n=this.hooks,i=n.mouseEnter,r=n.mouseLeave,o={key:this.getKeyByElement(e),element:e},a=e.querySelector(".tree-render-container");i&&a.addEventListener("mouseenter",(function(e){t.isDragging()||i(o,e)})),r&&a.addEventListener("mouseleave",(function(e){t.isDragging()||r(o,e)}))}},{key:"createNodeParams",value:function(e){return{key:e,parentKey:this.getParentKey(e),previousKey:this.getPreviousKey(e),nextKey:this.getNextKey(e)}}},{key:"initDragData",value:function(){this.dragData={key:null,ghostElement:null,ghostTranslateX:0,ghostTranslateY:0,mouseDownOffsetX:0,mouseDownOffsetY:0}}},{key:"setDragEvent",value:function(){var e=this,t=this.option,n=t.autoScrollTriggerDistance,i=t.autoScrollSpeed,r=t.preventDrag,o=this.elements,s=o.container,l=o.nodesContainer,c=o.ghostContainer,d=this.hooks,h=d.dragStart,u=d.dragEnd,v=!0;this.initDragData(),l.addEventListener("mousedown",(function(t){var n=t.button,i=t.clientX,o=t.clientY;if(0===n){var a=e.getCurrentEventNode(t.target),l=e.getKeyByElement(a);if(a&&a!==e.elements.rootNode&&!(a.classList.contains("not-allow-drag")||r&&r({key:l,element:a},t))){var c=e.positionData.node[l],d=c.left,h=c.top,u=a.cloneNode(!0);u.style.margin="0px",Object.assign(e.dragData,{key:l,ghostElement:u,mouseDownOffsetX:i+s.scrollLeft-d,mouseDownOffsetY:o+s.scrollTop-h}),e.FollowScroll.start(u)}}})),l.addEventListener("mousemove",(function(t){var n=t.button,i=t.movementX,r=t.movementY,o=t.clientX,a=t.clientY,l=t.currentTarget,d=e.dragData,u=d.ghostElement,g=d.mouseDownOffsetX,f=d.mouseDownOffsetY,m=d.key;if(0===n&&m&&(0!==i||0!==r)){getSelection&&getSelection().removeAllRanges(),l.classList.add("cursor-move"),!c.contains(u)&&c.appendChild(u);var y=o+s.scrollLeft-g,p=a+s.scrollTop-f;u.style.transform="translate(".concat(y,"px, ").concat(p,"px)"),Object.assign(e.dragData,{ghostTranslateX:y,ghostTranslateY:p});var C=e.getGhostPosition();e.setDragEffect(C),h&&v&&(v=!1,h({key:m,element:e.getNodeElement(m)}))}})),this.registerEvent("mouseup",(function(){v=!0;var t=e.dragData.key;if(t){var n="",i="",r=l.querySelector(".collide-node");if(r&&(n=e.getKeyByElement(r),r.classList.contains("become-previous")&&(i="previous"),r.classList.contains("become-next")&&(i="next"),r.classList.contains("become-child")&&(i="child")),e.FollowScroll.stop(),l.classList.remove("cursor-move"),c.innerHTML="",e.removeDragEffect(),e.initDragData(),r){var o=e.createNodeParams(t);e.insertNode(n,t,i);var a=e.createNodeParams(t);u&&u({from:o,to:a,target:n,key:t,type:i})}}}));var g={top:s.scrollTop,left:s.scrollLeft};this.registerEvent("scroll",(function(t){var n=t.target,i=e.dragData,r=i.key,o=i.ghostElement,a=i.ghostTranslateY,s=i.ghostTranslateX,l=g.left,c=g.top,d=n.scrollLeft,h=n.scrollTop;if(r&&o){var u=s+d-l,v=a+h-c;o.style.transform="translate(".concat(u,"px, ").concat(v,"px)"),Object.assign(e.dragData,{ghostTranslateX:u,ghostTranslateY:v}),e.setDragEffect(e.getGhostPosition())}g.left=d,g.top=h}),s),this.FollowScroll=new a({scrollContainer:s,autoScrollTriggerDistance:n,eventContainer:l,autoScrollSpeed:i})}},{key:"getGhostPosition",value:function(){var e=this.dragData,t=e.ghostTranslateX,n=e.ghostTranslateY,i=e.ghostElement;return{left:t,top:n,right:t+i.offsetWidth,bottom:n+i.offsetHeight}}},{key:"removeDragEffect",value:function(){var e=this.elements,t=e.nodesContainer,n=e.linkContainer,i=n.querySelector(".is-temp-line");i&&n.removeChild(i);var r=t.querySelector(".collide-node");r&&r.classList.remove("collide-node","become-previous","become-next","become-child");var o=t.querySelector(".temp-children-container");o&&o.parentElement.removeChild(o);var a=t.querySelector(".show-not-allow");a&&a.classList.remove("show-not-allow")}},{key:"getCollideType",value:function(e,t){var n=this.isVertical,i=this.dragData,r=this.positionData,o=this.elements.rootNode,a=i.key,s=r.node[e],l=s.top,c=s.bottom,d=s.left,h=s.right,u=t.left,v=t.right,g=t.top,f=t.bottom,m=this.getNodeElement(a),y=this.getNodeElement(e),p=e===this.getParentKey(a),C=e===this.getPreviousKey(a),k=e===this.getNextKey(a),E={child:!y.classList.contains("not-allow-insert-child")&&!p,next:!y.classList.contains("not-allow-insert-next")&&!C,previous:!y.classList.contains("not-allow-insert-previous")&&!k};if(y===o)return E.child?"child":"notAllow";if(m.parentElement.contains(y))return"notAllow";if(n){var L=.5*(h-d);if(v<=d+L&&E.previous)return"previous";if(u>=h-L&&E.next)return"next"}else{var b=.5*(c-l);if(f<=l+b&&E.previous)return"previous";if(g>=c-b&&E.next)return"next"}if(E.child)return"child";for(var N in E)if(E[N])return N;return"notAllow"}},{key:"getCollideLinePosition",value:function(e,t){var n=this.isVertical,i=this.positionData,r=this.option,o=r.distanceX,a=r.distanceY,s={},l=i.node[t],c=l.top,d=l.bottom,h=l.left,u=l.right;if(n){if("child"===e){if(s.from={x:(h+u)/2,y:d,key:t},this.existChildren(t)&&!this.nodeIsFold(t)){var v=this.getChildrenKeys(t).pop(),g=i.node[v],f=g.right,m=g.top;return s.to={x:f+20,y:m,key:"temp"},s}return s.to={x:(h+u)/2,y:d+a,key:"temp"},s}var y=this.getParentKey(t),p=i.node[y];return s.from={x:(p.left+p.right)/2,y:p.bottom,key:y},s.to={x:"previous"===e?h-20:u+20,y:c,key:"temp"},s}if("child"===e){if(s.from={x:u,y:(c+d)/2,key:t},this.existChildren(t)&&!this.nodeIsFold(t)){var C=this.getChildrenKeys(t).pop(),k=i.node[C],E=k.left,L=k.bottom;return s.to={x:E,y:L+20,key:"temp"},s}return s.to={x:u+o,y:(c+d)/2,key:"temp"},s}var b=this.getParentKey(t),N=i.node[b];return s.from={x:N.right,y:(N.top+N.bottom)/2,key:b},s.to={x:h,y:"previous"===e?c-20:d+20,key:"temp"},s}},{key:"createDragEffect",value:function(e,t){var n=this.positionData,i=this.getNodeElement(e),r=this.getCollideType(e,t);if("notAllow"===r)return i.classList.add("show-not-allow");i.classList.add("become-".concat(r),"collide-node");var o=this.getCollideLinePosition(r,e),a=o.from,s=o.to;if(this.drawLine(a,s,!0),"child"===r&&(!this.existChildren(e)||this.nodeIsFold(e))){var l=n.node[e],d=l.top,h=l.bottom,u=l.left,v=l.right,g=document.createElement("div");g.classList.add("tree-chart-node"),c(g,{width:"".concat(v-u,"px"),height:"".concat(h-d,"px")});var f=this.createChildrenContainer("temp-children-container"),m=this.createNodeContainer(!0);m.appendChild(g),f.appendChild(m);var y=i.parentElement;i.nextElementSibling?y.insertBefore(f,i.nextElementSibling):y.appendChild(f)}}},{key:"getCollideNode",value:function(e){var t=e.left,n=e.right,i=e.top,r=e.bottom,o=this.dragData.key,a=this.positionData,s=a.left,c=a.right,d=a.top,h=a.bottom,u=a.node,v=function(e,t,n){var i=t.length;if(n){for(var r=0;r<i;r++)if(t[r]>=e)return t[r]}else for(var o=i-1;o>-1;o--)if(t[o]<=e)return t[o];return null},g=v(t,c.sortList,!0),f=v(i,h.sortList,!0),m=v(n,s.sortList),y=v(r,d.sortList),p=function(e,t,n){var i=[];return l(e)&&t.sortList.forEach((function(r){(n?r>=e:r<=e)&&(i=i.concat(t[r]))})),i},C=function(){for(var e=arguments.length,t=new Array(e),n=0;n<e;n++)t[n]=arguments[n];var i=t.length;if(i<2)return[];var r=[],o={};return t.reduce((function(e,t){return e.concat(t)}),[]).forEach((function(e){o[e]?(o[e]++,o[e]===i&&r.push(e)):o[e]=1})),r}(p(g,c,!0),p(f,h,!0),p(m,s),p(y,d)),k=C.indexOf(o);if(k>-1&&C.splice(k,1),!C.length)return null;if(1===C.length)return C[0];var E={nodeKey:"",nodeArea:0};return C.forEach((function(e){var o=function(e){var o=u[e],a=o.left,s=o.right,l=o.top,c=o.bottom;return(a<=t?s-t:n-a)*(l<=i?c-i:r-l)}(e);o>E.nodeArea&&Object.assign(E,{nodeKey:e,nodeArea:o})})),E.nodeKey}},{key:"setDragEffect",value:function(e){this.removeDragEffect();var t=this.getCollideNode(e);t&&this.createDragEffect(t,e)}},{key:"resize",value:function(){var e=this.draggable,t=this.isVertical,n=this.elements,i=n.rootNode,r=n.nodesContainer,o=n.ghostContainer,a=n.linkContainer;c(r,{height:"auto",width:"auto",minHeight:"auto",minWidth:"auto"});var s=r.clientWidth,l=r.clientHeight;if(e){var d=i.getBoundingClientRect(),h=d.width,u=d.height;t?l+=u:s+=h}var v="".concat(s,"px"),g="".concat(l,"px");c(r,{height:g,width:v,minHeight:"100%",minWidth:"100%"}),c(a,{height:g,width:v}),e&&c(o,{height:g,width:v})}},{key:"setDragScroll",value:function(){var e=this.elements,t=e.nodesContainer,n=e.container,i=!0;t.addEventListener("mousedown",(function(e){0!==e.button||function(e){if(e.classList.contains("tree-chart-node"))return e;for(var n=e;t!==n;){if(n.classList.contains("tree-chart-node"))return n;n=n.parentElement}return null}(e.target)||(n.classList.add("drag-scroll-start"),i=!1)})),t.addEventListener("mousemove",(function(e){e.preventDefault(),0!==e.button||i||(n.scrollLeft=n.scrollLeft-e.movementX,n.scrollTop=n.scrollTop-e.movementY,!n.classList.contains("drag-scroll-move")&&n.classList.add("drag-scroll-move"))})),this.registerEvent("mouseup",(function(e){0===e.button&&(n.classList.remove("drag-scroll-start","drag-scroll-move"),i=!0)}))}},{key:"destroy",value:function(){for(var e in this.FollowScroll.destroy(),this.unregisterEvent(),this.elements.container.innerHTML="",this)this[e]=null}}]),t}();export default d; |
@@ -37,3 +37,3 @@ # treechartjs | ||
## 配置项 | ||
#### keyField | ||
### keyField | ||
Type: `String` | ||
@@ -44,3 +44,3 @@ Default: `'id'` | ||
#### data | ||
### data | ||
Type: `Array` | ||
@@ -59,3 +59,3 @@ Default: `undefined` | ||
``` | ||
其中`id`和`children`是必须的,`children`是一个`array`类型,`id`可以替换为`keyField`所定义的值,可以增加其他自定义属性提供给`contentRender`使用: | ||
其中`id`和`children`是必须的,`children`是一个`Array`类型,`id`可以替换为`keyField`所定义的值,可以增加其他自定义属性提供给`contentRender`使用: | ||
```javascript | ||
@@ -74,3 +74,3 @@ { | ||
#### container | ||
### container | ||
Type: `HTMLElement` | ||
@@ -81,3 +81,3 @@ Default: `undefined` | ||
#### contentRender | ||
### contentRender | ||
Type: `Function` | ||
@@ -109,3 +109,3 @@ Default: `undefined` | ||
#### isVertical | ||
### isVertical | ||
Type: `Boolean` | ||
@@ -118,15 +118,15 @@ Default: `true` | ||
#### distanceX | ||
### distanceX | ||
Type: `Number` | ||
Default: `40` | ||
两个节点间的水平间距,这个值不能小于40 | ||
两个节点间的水平间距,这个值不能小于`40` | ||
#### distanceY | ||
### distanceY | ||
Type: `Number` | ||
Default: `40` | ||
两个节点间的垂直间距,这个值不能小于40 | ||
两个节点间的垂直间距,这个值不能小于`40` | ||
#### allowFold | ||
### allowFold | ||
Type: `Boolean` | ||
@@ -137,3 +137,3 @@ Default: `false` | ||
#### foldNodeKeys | ||
### foldNodeKeys | ||
Type: `Array` | ||
@@ -144,3 +144,3 @@ Default: `[]` | ||
#### draggable | ||
### draggable | ||
Type: `Boolean` | ||
@@ -151,3 +151,3 @@ Default: `false` | ||
#### dragScroll | ||
### dragScroll | ||
Type: `Boolean` | ||
@@ -159,9 +159,9 @@ Default: `false` | ||
#### autoScrollTriggerDistance | ||
### autoScrollTriggerDistance | ||
Type: `Number` | ||
Default: `50` | ||
正在拖拽的节点如果靠近边界,并且还有剩余节点没有显示的情况下会触发自动滚动,默认情况下拖拽节点与边界的距离小于`50px`会触发滚动,通过设置`autoScrollTriggerDistance`来改变这个临界值,这个值必须大于`0` | ||
正在拖拽的节点如果靠近边界,并且还有剩余节点没有显示的情况下会触发自动滚动。默认情况下拖拽节点与边界的距离如果小于`50px`就会触发滚动,可以通过设置`autoScrollTriggerDistance`来改变这个临界值,这个值必须大于`0` | ||
#### line | ||
### line | ||
Type: `Object` | ||
@@ -184,9 +184,9 @@ Default: `{ type: 'bezier', smooth: 50 }` | ||
仅在`line.type === bezier`时候生效,取值在`0~100`之间,`line.smooth === 100`时候连接线将会变成直线 | ||
想要启用这个配置需要先设定`line.type === bezier`,`smooth`的取值在`0~100`之间,`line.smooth === 100`时候连接线将会变成直线 | ||
#### nodeControl | ||
### nodeControl | ||
Type: `Function` | ||
Default: `undefined` | ||
在`option.draggable === true`的情况下,通过`option.nodeControl`可以控制节点是否能被拖拽和插入子节点或相邻节点 | ||
想要启用这个配置需要先设定`option.draggable === true`,通过`option.nodeControl`可以控制节点是否能被拖拽和插入子节点或相邻节点 | ||
```javascript | ||
@@ -218,7 +218,7 @@ { | ||
#### preventDrag | ||
### preventDrag | ||
Type: `Function` | ||
Default: `undefined` | ||
在`option.draggable === true`的情况下,在节点被拖拽之前会触发`option.preventDrag`,如果返回值为`true`的话会阻止当前节点的拖拽。和`option.nodeControl`不同的是,`option.nodeControl`只会在初始化阶段执行,但是`option.preventDrag`会在每一次拖拽之前执行。 | ||
想要启用这个配置需要先设定`option.draggable === true`,在节点被拖拽之前会触发`option.preventDrag`,如果返回值为`true`的话会阻止当前节点的拖拽。和`option.nodeControl`不同的是,`option.nodeControl`只会在初始化阶段执行,但是`option.preventDrag`会在每一次拖拽之前执行。 | ||
@@ -233,3 +233,16 @@ 使`id === 1`的节点在拖拽前被阻止: | ||
``` | ||
#### dragStart | ||
### hook | ||
Type: `Object` | ||
Default: `{}` | ||
```javascript | ||
{ | ||
hook: { | ||
dragStart() {/* something */}, | ||
dragEnd() {/* something */} | ||
} | ||
} | ||
``` | ||
##### hook.dragStart | ||
Type: `Function` | ||
@@ -241,4 +254,6 @@ Default: `undefined` | ||
{ | ||
dragStart(params) { | ||
console.log(data) // { element, key } | ||
hook: { | ||
dragStart(params) { | ||
console.log(data) // { element, key } | ||
} | ||
} | ||
@@ -248,3 +263,3 @@ } | ||
#### dragEnd | ||
##### hook.dragEnd | ||
Type: `Function` | ||
@@ -256,4 +271,6 @@ Default: `undefined` | ||
{ | ||
dragEnd(params) { | ||
console.log(params) // { key, target, type, from, to } | ||
hook: { | ||
dragEnd(params) { | ||
console.log(params) // { key, target, type, from, to } | ||
} | ||
} | ||
@@ -270,3 +287,3 @@ } | ||
#### click | ||
##### hook.click | ||
Type: `Function` | ||
@@ -278,4 +295,6 @@ Default: `undefined` | ||
{ | ||
click(params, event) { | ||
console.log(params, event) // ({ element, key }, event) | ||
hook: { | ||
click(params, event) { | ||
console.log(params, event) // ({ element, key }, event) | ||
} | ||
} | ||
@@ -285,3 +304,3 @@ } | ||
#### mouseEnter | ||
##### hook.mouseEnter | ||
Type: `Function` | ||
@@ -293,4 +312,6 @@ Default: `undefined` | ||
{ | ||
mouseEnter(params, event) { | ||
console.log(params, event) // ({ element, key }, event) | ||
hook: { | ||
mouseEnter(params, event) { | ||
console.log(params, event) // ({ element, key }, event) | ||
} | ||
} | ||
@@ -300,3 +321,3 @@ } | ||
#### mouseLeave | ||
##### hook.mouseLeave | ||
Type: `Function` | ||
@@ -308,4 +329,6 @@ Default: `undefined` | ||
{ | ||
mouseLeave(params, event) { | ||
console.log(params, event) // ({ element, key }, event) | ||
hook: { | ||
mouseLeave(params, event) { | ||
console.log(params, event) // ({ element, key }, event) | ||
} | ||
} | ||
@@ -315,2 +338,17 @@ } | ||
##### hook.foldChange | ||
Type: `Function` | ||
Default: `undefined` | ||
节点折叠状态变化的时候会触发`option.foldChange` | ||
```javascript | ||
{ | ||
hook: { | ||
foldChange(nodeKey, isFold) { | ||
console.log(nodeKey, isFold) // ('2', true) | ||
} | ||
} | ||
} | ||
``` | ||
## API | ||
@@ -317,0 +355,0 @@ |
{ | ||
"name": "treechartjs", | ||
"version": "0.0.4", | ||
"version": "0.0.5", | ||
"description": "Generate tree chart based on structured data, and support node expansion/collapse, and edit nodes through API or drag-and-drop behavior", | ||
@@ -8,3 +8,4 @@ "main": "dist/index.js", | ||
"dev": "cross-env NODE_ENV=development rollup -c --watch", | ||
"build": "rollup -c" | ||
"build": "rollup -c", | ||
"publish": "npm run build&npm publish" | ||
}, | ||
@@ -11,0 +12,0 @@ "repository": { |
121
README.md
# treechartjs | ||
`treechartjs` can generate tree diagrams based on structured data, and supports node expansion/collapse. Nodes can be edited through API or drag-and-drop behavior. Its size is very small and has no dependencies. The size after construction is only 25KB. | ||
[[中文文档](https://github.com/grajs/treechartjs/blob/master/doc/README.zh.md)] | ||
@@ -38,3 +37,3 @@ ![image](https://i.loli.net/2020/10/23/t73zrISF9aBTXe1.gif) | ||
## Option | ||
#### keyField | ||
### keyField | ||
Type: `String` | ||
@@ -45,3 +44,3 @@ Default: `'id'` | ||
#### data | ||
### data | ||
Type: `Array` | ||
@@ -74,3 +73,3 @@ Default: `undefined` | ||
#### container | ||
### container | ||
Type: `HTMLElement` | ||
@@ -81,3 +80,3 @@ Default: `undefined` | ||
#### contentRender | ||
### contentRender | ||
Type: `Function` | ||
@@ -98,3 +97,3 @@ Default: `undefined` | ||
``` | ||
or | ||
or | ||
```javascript | ||
@@ -110,3 +109,3 @@ { | ||
#### isVertical | ||
### isVertical | ||
Type: `Boolean` | ||
@@ -119,15 +118,15 @@ Default: `true` | ||
#### distanceX | ||
### distanceX | ||
Type: `Number` | ||
Default: `40` | ||
The horizontal distance between two nodes, this value cannot be less than 40 | ||
The horizontal distance between two nodes, this value cannot be less than `40` | ||
#### distanceY | ||
### distanceY | ||
Type: `Number` | ||
Default: `40` | ||
The vertical distance between two nodes, this value cannot be less than 40 | ||
The vertical distance between two nodes, this value cannot be less than `40` | ||
#### allowFold | ||
### allowFold | ||
Type: `Boolean` | ||
@@ -138,3 +137,3 @@ Default: `false` | ||
#### foldNodeKeys | ||
### foldNodeKeys | ||
Type: `Array` | ||
@@ -145,3 +144,3 @@ Default: `[]` | ||
#### draggable | ||
### draggable | ||
Type: `Boolean` | ||
@@ -152,3 +151,3 @@ Default: `false` | ||
#### dragScroll | ||
### dragScroll | ||
Type: `Boolean` | ||
@@ -160,9 +159,9 @@ Default: `false` | ||
#### autoScrollTriggerDistance | ||
### autoScrollTriggerDistance | ||
Type: `Number` | ||
Default: `50` | ||
If the dragging node is close to the boundary and there are remaining nodes that are not displayed, automatic scrolling will be triggered. By default, the distance between the dragging node and the boundary will be triggered if the distance is less than `50px`. This can be changed by setting `autoScrollTriggerDistance` Critical value, this value must be greater than `0` | ||
If the dragging node is close to the boundary and there are remaining nodes that are not displayed, automatic scrolling will be triggered. By default, if the distance between the dragging node and the boundary is less than `50px`, scrolling will be triggered. This critical value can be changed by setting `autoScrollTriggerDistance`, this value must be greater than `0` | ||
#### line | ||
### line | ||
Type: `Object` | ||
@@ -185,9 +184,9 @@ Default: `{ type: 'bezier', smooth: 50 }` | ||
Only effective when `line.type === bezier`, the value is between `0~100`, the connecting line will become a straight line when `line.smooth === 100` | ||
To enable this configuration, you need to set `line.type === bezier`, the value of `smooth` is between `0~100`, and the connection line will become when `line.smooth === 100` straight line | ||
#### nodeControl | ||
### nodeControl | ||
Type: `Function` | ||
Default: `undefined` | ||
In the case of `option.draggable === true`, through `option.nodeControl` you can control whether the node can be dragged and inserted into child nodes or adjacent nodes | ||
To enable this configuration, you need to first set `option.draggable === true`, through `option.nodeControl` you can control whether the node can be dragged and inserted into child nodes or adjacent nodes | ||
```javascript | ||
@@ -206,3 +205,3 @@ { | ||
Make the node with ʻid === 1` unable to be dragged: | ||
Make the node with `id === 1` unable to be dragged: | ||
```javascript | ||
@@ -220,7 +219,7 @@ { | ||
#### preventDrag | ||
### preventDrag | ||
Type: `Function` | ||
Default: `undefined` | ||
In the case of `option.draggable === true`, `option.preventDrag` will be triggered before the node is dragged. If the return value is `true`, the drag of the current node will be prevented. Unlike `option.nodeControl`, `option.nodeControl` will only be executed during the initialization phase, but `option.preventDrag` will be executed before each drag. | ||
To enable this configuration, you need to set `option.draggable === true` first, and `option.preventDrag` will be triggered before the node is dragged. If the return value is `true`, the dragging of the current node will be prevented. Unlike `option.nodeControl`, `option.nodeControl` will only be executed during the initialization phase, but ʻoption.preventDrag` will be executed before each drag. | ||
@@ -235,3 +234,16 @@ Make the node with `id === 1` blocked before dragging: | ||
``` | ||
#### dragStart | ||
### hook | ||
Type: `Object` | ||
Default: `{}` | ||
```javascript | ||
{ | ||
hook: { | ||
dragStart() {/* something */}, | ||
dragEnd() {/* something */} | ||
} | ||
} | ||
``` | ||
##### hook.dragStart | ||
Type: `Function` | ||
@@ -243,4 +255,6 @@ Default: `undefined` | ||
{ | ||
dragStart(params) { | ||
console.log(data) // { element, key } | ||
hook: { | ||
dragStart(params) { | ||
console.log(data) // { element, key } | ||
} | ||
} | ||
@@ -250,3 +264,3 @@ } | ||
#### dragEnd | ||
##### hook.dragEnd | ||
Type: `Function` | ||
@@ -258,4 +272,6 @@ Default: `undefined` | ||
{ | ||
dragEnd(params) { | ||
console.log(params) // { key, target, type, from, to } | ||
hook: { | ||
dragEnd(params) { | ||
console.log(params) // { key, target, type, from, to } | ||
} | ||
} | ||
@@ -270,5 +286,5 @@ } | ||
`params.from` and `params.to`: represents the location information before and after the node moves | ||
`params.from` and `params.to` represents the location information before and after the node moves | ||
#### click | ||
##### hook.click | ||
Type: `Function` | ||
@@ -280,4 +296,6 @@ Default: `undefined` | ||
{ | ||
click(params, event) { | ||
console.log(params, event) // ({ element, key }, event) | ||
hook: { | ||
click(params, event) { | ||
console.log(params, event) // ({ element, key }, event) | ||
} | ||
} | ||
@@ -287,3 +305,3 @@ } | ||
#### mouseEnter | ||
##### hook.mouseEnter | ||
Type: `Function` | ||
@@ -295,4 +313,6 @@ Default: `undefined` | ||
{ | ||
mouseEnter(params, event) { | ||
console.log(params, event) // ({ element, key }, event) | ||
hook: { | ||
mouseEnter(params, event) { | ||
console.log(params, event) // ({ element, key }, event) | ||
} | ||
} | ||
@@ -302,3 +322,3 @@ } | ||
#### mouseLeave | ||
##### hook.mouseLeave | ||
Type: `Function` | ||
@@ -310,4 +330,6 @@ Default: `undefined` | ||
{ | ||
mouseLeave(params, event) { | ||
console.log(params, event) // ({ element, key }, event) | ||
hook: { | ||
mouseLeave(params, event) { | ||
console.log(params, event) // ({ element, key }, event) | ||
} | ||
} | ||
@@ -317,2 +339,17 @@ } | ||
##### hook.foldChange | ||
Type: `Function` | ||
Default: `undefined` | ||
`option.foldChange` will be triggered when the node folding state changes | ||
```javascript | ||
{ | ||
hook: { | ||
foldChange(nodeKey, isFold) { | ||
console.log(nodeKey, isFold) // ('2', true) | ||
} | ||
} | ||
} | ||
``` | ||
## API | ||
@@ -414,3 +451,3 @@ | ||
```javascript | ||
chart.removeNode('3') // The node with key 3 is deleted | ||
chart.removeNode('3') // key为3的节点被删除 | ||
``` | ||
@@ -447,3 +484,3 @@ | ||
} | ||
chart.reRenderNode('2', nodeData) // The node with key 2 is re-rendered | ||
chart.reRenderNode('2', nodeData) // key为2的节点被重新渲染 | ||
``` | ||
@@ -450,0 +487,0 @@ |
215
src/index.js
import './index.scss' | ||
import FollowScroll from './follow-scroll' | ||
import { isElement, isNumber, getArrayIntersection, applyStyle } from './utils' | ||
const isElement = data => /HTML/.test(Object.prototype.toString.call(data)) && data.nodeType === 1 | ||
const isNumber = data => /Number/.test(Object.prototype.toString.call(data)) | ||
const setNotAllowEffect = node => node.classList.add('show-not-allow') | ||
// 求数组的交集 | ||
const getArrayIntersection = (...arrays) => { | ||
const arrayCount = arrays.length | ||
if (arrayCount < 2) return [] | ||
const result = [] | ||
const countMap = {} | ||
arrays.reduce((a, b) => a.concat(b), []).forEach(item => { | ||
if (countMap[item]) { | ||
countMap[item]++ | ||
countMap[item] === arrayCount && result.push(item) | ||
} else { | ||
countMap[item] = 1 | ||
} | ||
}) | ||
return result | ||
} | ||
export default class TreeChart { | ||
@@ -32,3 +13,3 @@ /* ======== API ======== */ | ||
getNodeElement(key) { | ||
return this.nodesContainer.querySelector(`.tree-chart-item-${key}`) | ||
return this.elements.nodesContainer.querySelector(`.tree-chart-item-${key}`) | ||
} | ||
@@ -78,3 +59,3 @@ | ||
// 限制不能给根节点添加兄弟元素 | ||
if (/next|previous/.test(type) && targetNode === this.rootNode) return | ||
if (/next|previous/.test(type) && targetNode === this.elements.rootNode) return | ||
@@ -139,3 +120,3 @@ // 处理origin部分 | ||
// 不支持移除root节点 | ||
if (targetNode === this.rootNode) return console.warn('not allow remove root node') | ||
if (targetNode === this.elements.rootNode) return console.warn('not allow remove root node') | ||
// 修改父节点的data-children | ||
@@ -171,2 +152,7 @@ const parentNodeKey = this.getParentKey(targetKey) | ||
this.reloadLink() | ||
const { foldChange } = this.hooks | ||
if (typeof foldChange === 'function') { | ||
foldChange(targetKey, this.nodeIsFold(targetKey)) | ||
} | ||
} | ||
@@ -182,3 +168,3 @@ | ||
if (newNodeKey !== oldNodeKey) { | ||
const { linkContainer } = this | ||
const { linkContainer } = this.elements | ||
const parentNodeKey = this.getParentKey(oldNodeKey) | ||
@@ -217,8 +203,9 @@ // 替换父节点的children-key | ||
reRender(data) { | ||
const { nodesContainer } = this | ||
const { nodesContainer } = this.elements | ||
// 更新nodes | ||
this.elements.rootNode = null | ||
nodesContainer.innerHTML = '' | ||
const nodeContainer = this.createNodeContainer() | ||
nodesContainer.appendChild(nodeContainer) | ||
this.createNodes(data, nodeContainer, true) | ||
this.createNodes(data, nodeContainer) | ||
// 更新links | ||
@@ -291,3 +278,3 @@ this.reloadLink() | ||
constructor(option) { | ||
this.mergeOption(option) | ||
this.initData(option) | ||
this.createChartElement() | ||
@@ -298,3 +285,3 @@ this.resize() | ||
mergeOption(data) { | ||
initData(inputOption) { | ||
const option = { | ||
@@ -315,3 +302,4 @@ keyField: 'id', // 作为唯一ID的字段 | ||
}, | ||
...data | ||
hook: {}, | ||
...inputOption | ||
} | ||
@@ -351,11 +339,16 @@ const { | ||
this.option = option | ||
this.initHooks() | ||
this.elements = { | ||
container: null, | ||
ghostContainer: null, | ||
nodesContainer: null, | ||
linkContainer: null, | ||
rootNode: null | ||
} | ||
this.initHook() | ||
} | ||
initHooks() { | ||
const controlHooks = [ | ||
'nodeControl', | ||
'preventDrag' | ||
] | ||
const eventHooks = [ | ||
initHook() { | ||
const optionHook = this.option.hook | ||
this.hooks = {} | ||
const hookList = [ | ||
'dragStart', | ||
@@ -365,8 +358,7 @@ 'dragEnd', | ||
'mouseEnter', | ||
'mouseLeave' | ||
'mouseLeave', | ||
'foldChange' | ||
] | ||
const hookList = ['contentRender', ...controlHooks, ...eventHooks] | ||
this.hooks = {} | ||
hookList.forEach(name => { | ||
const handler = this.option[name] | ||
const handler = optionHook[name] | ||
if (typeof handler === 'function') this.hooks[name] = handler | ||
@@ -381,3 +373,3 @@ }) | ||
isVertical && container.classList.add('is-vertical') | ||
this.container = container | ||
this.elements.container = container | ||
this.createNodes(data, this.createNodesContainer()) | ||
@@ -390,3 +382,3 @@ this.createLinkContainer() | ||
createNodesContainer() { | ||
const { container, containerPadding } = this | ||
const { containerPadding } = this | ||
const nodesContainer = this.createNodeContainer() | ||
@@ -399,4 +391,4 @@ nodesContainer.classList.add('is-nodes-container') | ||
} | ||
container.appendChild(nodesContainer) | ||
this.nodesContainer = nodesContainer | ||
this.elements.container.appendChild(nodesContainer) | ||
this.elements.nodesContainer = nodesContainer | ||
const nodeContainer = this.createNodeContainer() | ||
@@ -414,4 +406,4 @@ nodesContainer.append(nodeContainer) | ||
// 数据数据结构生成节点 | ||
createNodes(data, parentNodeContainer, reRender) { | ||
const { allowFold, rootNode, option } = this | ||
createNodes(data, parentNodeContainer) { | ||
const { allowFold, option, elements } = this | ||
const { children } = data | ||
@@ -425,4 +417,3 @@ const { foldNodeKeys } = option | ||
// 初始化或重新渲染的时候 | ||
if (!rootNode || reRender) this.rootNode = node | ||
if (!elements.rootNode) elements.rootNode = node | ||
@@ -453,5 +444,4 @@ if (existChildren) { | ||
createNode(data) { | ||
const { draggable, hooks, option } = this | ||
const { distanceX, distanceY } = option | ||
const { contentRender, nodeControl } = hooks | ||
const { draggable, option } = this | ||
const { distanceX, distanceY, contentRender, nodeControl } = option | ||
@@ -462,4 +452,6 @@ const node = document.createElement('div') | ||
node.setAttribute('data-key', key) | ||
node.style.marginBottom = `${distanceY}px` | ||
node.style.marginRight = `${distanceX}px` | ||
applyStyle(node, { | ||
marginBottom: `${distanceY}px`, | ||
marginRight: `${distanceX}px` | ||
}) | ||
@@ -507,7 +499,6 @@ const renderContainer = document.createElement('div') | ||
createGhostContainer() { | ||
const { container } = this | ||
const ghostContainer = document.createElement('div') | ||
ghostContainer.classList.add('tree-chart-ghost-container') | ||
container.appendChild(ghostContainer) | ||
this.ghostContainer = ghostContainer | ||
this.elements.container.appendChild(ghostContainer) | ||
this.elements.ghostContainer = ghostContainer | ||
} | ||
@@ -536,7 +527,6 @@ | ||
createLinkContainer() { | ||
const { container } = this | ||
const linkContainer = document.createElementNS('http://www.w3.org/2000/svg', 'svg') | ||
linkContainer.classList.add('tree-chart-link-container') | ||
container.appendChild(linkContainer) | ||
this.linkContainer = linkContainer | ||
const svgElement = document.createElementNS('http://www.w3.org/2000/svg', 'svg') | ||
svgElement.classList.add('tree-chart-link-container') | ||
this.elements.container.appendChild(svgElement) | ||
this.elements.linkContainer = svgElement | ||
} | ||
@@ -546,3 +536,4 @@ | ||
createLink() { | ||
const { container, nodesContainer, linkContainer, draggable, isVertical } = this | ||
const { draggable, isVertical } = this | ||
const { container, nodesContainer, linkContainer } = this.elements | ||
const { left: containerLeft, top: containerTop } = container.getBoundingClientRect() | ||
@@ -660,3 +651,3 @@ const { scrollLeft, scrollTop } = container | ||
setFoldEvent() { | ||
this.nodesContainer.addEventListener('click', ({ target }) => { | ||
this.elements.nodesContainer.addEventListener('click', ({ target }) => { | ||
if (!target.classList.contains('tree-chart-unfold')) return | ||
@@ -669,4 +660,5 @@ this.toggleFold(this.getKeyByElement(target.parentElement)) | ||
drawLine(from, to, isTemp) { | ||
const { linkContainer, isVertical, allowFold, lineConfig } = this | ||
const { type: lineType, smooth } = lineConfig | ||
const { isVertical, allowFold } = this | ||
const { linkContainer } = this.elements | ||
const { type: lineType, smooth } = this.lineConfig | ||
@@ -722,3 +714,3 @@ const lineClassName = `line-${from.key}-${to.key}` | ||
getCurrentEventNode(eventTarget) { | ||
const { nodesContainer } = this | ||
const { nodesContainer } = this.elements | ||
// 忽略展开按钮 | ||
@@ -743,4 +735,4 @@ if (eventTarget.classList.contains('tree-chart-unfold')) return null | ||
setClickHook() { | ||
const { nodesContainer, hooks } = this | ||
const { click: clickHook } = hooks | ||
const { nodesContainer } = this.elements | ||
const { click: clickHook } = this.hooks | ||
if (!clickHook) return | ||
@@ -802,5 +794,5 @@ // 用mouseEvent来实现click主要是为了区别dragStart和click的行为 | ||
setDragEvent() { | ||
const { ghostContainer, container, nodesContainer, hooks, option } = this | ||
const { autoScrollTriggerDistance, autoScrollSpeed } = option | ||
const { preventDrag, dragStart, dragEnd } = hooks | ||
const { autoScrollTriggerDistance, autoScrollSpeed, preventDrag } = this.option | ||
const { container, nodesContainer, ghostContainer } = this.elements | ||
const { dragStart, dragEnd } = this.hooks | ||
// 是否触发dragStart事件 | ||
@@ -818,3 +810,3 @@ let emitDragStart = true | ||
// 根节点不允许拖动 | ||
if (!dragNode || dragNode === this.rootNode) return | ||
if (!dragNode || dragNode === this.elements.rootNode) return | ||
// 用户禁止拖动的节点 | ||
@@ -841,3 +833,3 @@ if (dragNode.classList.contains('not-allow-drag')) return | ||
nodesContainer.addEventListener('mousemove', e => { | ||
const { button, movementX, movementY, clientX, clientY } = e | ||
const { button, movementX, movementY, clientX, clientY, currentTarget } = e | ||
const { ghostElement, mouseDownOffsetX, mouseDownOffsetY, key } = this.dragData | ||
@@ -852,3 +844,3 @@ | ||
// 光标形状变为move | ||
nodesContainer.classList.add('cursor-move') | ||
currentTarget.classList.add('cursor-move') | ||
// 添加镜像元素和同步位置 | ||
@@ -874,8 +866,7 @@ !ghostContainer.contains(ghostElement) && ghostContainer.appendChild(ghostElement) | ||
emitDragStart = true | ||
const { dragData, nodesContainer, ghostContainer } = this | ||
const { key: dragKey } = this.dragData | ||
if (!dragKey) return | ||
let targetKey = '' | ||
let type = '' | ||
const dragKey = dragData.key | ||
if (!dragKey) return | ||
@@ -911,6 +902,6 @@ const targetNode = nodesContainer.querySelector('.collide-node') | ||
} | ||
this.registerEvent('scroll', () => { | ||
this.registerEvent('scroll', ({ target }) => { | ||
const { key, ghostElement, ghostTranslateY: oldTranslateY, ghostTranslateX: oldTranslateX } = this.dragData | ||
const { left: oldScrollLeft, top: oldScrollTop } = oldScroll | ||
const { scrollLeft: currentScrollLeft, scrollTop: currentScrollTop } = container | ||
const { scrollLeft: currentScrollLeft, scrollTop: currentScrollTop } = target | ||
@@ -947,3 +938,3 @@ if (key && ghostElement) { | ||
removeDragEffect() { | ||
const { linkContainer, nodesContainer } = this | ||
const { nodesContainer, linkContainer } = this.elements | ||
const tempLink = linkContainer.querySelector('.is-temp-line') | ||
@@ -960,3 +951,4 @@ tempLink && linkContainer.removeChild(tempLink) | ||
getCollideType(collideNodeKey, ghostPosition) { | ||
const { rootNode, isVertical, dragData, positionData } = this | ||
const { isVertical, dragData, positionData } = this | ||
const { rootNode } = this.elements | ||
const { key: dragNodeKey } = dragData | ||
@@ -1109,3 +1101,3 @@ | ||
const collideType = this.getCollideType(collideNodeKey, ghostPosition) | ||
if (collideType === 'notAllow') return setNotAllowEffect(collideNode) | ||
if (collideType === 'notAllow') return collideNode.classList.add('show-not-allow') | ||
collideNode.classList.add(`become-${collideType}`, 'collide-node') | ||
@@ -1118,5 +1110,7 @@ const { from, to } = this.getCollideLinePosition(collideType, collideNodeKey) | ||
const chartContent = document.createElement('div') | ||
chartContent.classList.add('tree-chart-node', 'temp-chart-content') | ||
chartContent.style.width = `${collideNodeRight - collideNodeLeft}px` | ||
chartContent.style.height = `${collideNodeBottom - collideNodeTop}px` | ||
chartContent.classList.add('tree-chart-node') | ||
applyStyle(chartContent, { | ||
width: `${collideNodeRight - collideNodeLeft}px`, | ||
height: `${collideNodeBottom - collideNodeTop}px` | ||
}) | ||
const childrenContainer = this.createChildrenContainer('temp-children-container') | ||
@@ -1126,3 +1120,8 @@ const chartContainer = this.createNodeContainer(true) | ||
childrenContainer.appendChild(chartContainer) | ||
collideNode.parentElement.appendChild(childrenContainer) | ||
const collideNodeParent = collideNode.parentElement | ||
if (collideNode.nextElementSibling) { | ||
collideNodeParent.insertBefore(childrenContainer, collideNode.nextElementSibling) | ||
} else { | ||
collideNodeParent.appendChild(childrenContainer) | ||
} | ||
} | ||
@@ -1209,11 +1208,12 @@ } | ||
resize() { | ||
const { nodesContainer, linkContainer, draggable, ghostContainer, rootNode, isVertical } = this | ||
const { style: nodesContainerStyle } = nodesContainer | ||
const { style: linkContainerStyle } = linkContainer | ||
const { draggable, isVertical } = this | ||
const { rootNode, nodesContainer, ghostContainer, linkContainer } = this.elements | ||
// 需要先清除旧的尺寸 | ||
nodesContainerStyle.height = 'auto' | ||
nodesContainerStyle.width = 'auto' | ||
nodesContainerStyle.minHeight = 'auto' | ||
nodesContainerStyle.minWidth = 'auto' | ||
applyStyle(nodesContainer, { | ||
height: 'auto', | ||
width: 'auto', | ||
minHeight: 'auto', | ||
minWidth: 'auto' | ||
}) | ||
@@ -1237,14 +1237,20 @@ const { clientWidth: nodeContainerWidth, clientHeight: nodeContainerHeight } = nodesContainer | ||
nodesContainerStyle[isVertical ? 'minHeight' : 'minWidth'] = '100%' | ||
nodesContainerStyle.width = linkContainerStyle.width = newWidth | ||
nodesContainerStyle.height = linkContainerStyle.height = newHeight | ||
if (draggable) { | ||
const { style: ghostContainerStyle } = ghostContainer | ||
ghostContainerStyle.width = newWidth | ||
ghostContainerStyle.height = newHeight | ||
} | ||
applyStyle(nodesContainer, { | ||
height: newHeight, | ||
width: newWidth, | ||
minHeight: '100%', | ||
minWidth: '100%' | ||
}) | ||
applyStyle(linkContainer, { | ||
height: newHeight, | ||
width: newWidth | ||
}) | ||
draggable && applyStyle(ghostContainer, { | ||
height: newHeight, | ||
width: newWidth | ||
}) | ||
} | ||
setDragScroll() { | ||
const { container, nodesContainer } = this | ||
const { nodesContainer, container } = this.elements | ||
let lock = true | ||
@@ -1264,2 +1270,3 @@ | ||
if (e.button !== 0 || getEventNode(e.target)) return | ||
container.classList.add('drag-scroll-start') | ||
lock = false | ||
@@ -1272,5 +1279,7 @@ }) | ||
container.scrollTop = container.scrollTop - e.movementY | ||
!container.classList.contains('drag-scroll-move') && container.classList.add('drag-scroll-move') | ||
}) | ||
this.registerEvent('mouseup', e => { | ||
if (e.button !== 0) return | ||
container.classList.remove('drag-scroll-start', 'drag-scroll-move') | ||
lock = true | ||
@@ -1283,3 +1292,3 @@ }) | ||
this.unregisterEvent() | ||
this.container.innerHTML = '' | ||
this.elements.container.innerHTML = '' | ||
for (const key in this) { | ||
@@ -1286,0 +1295,0 @@ this[key] = null |
@@ -48,3 +48,3 @@ import TreeChart from '../src/index' | ||
container: document.querySelector('#demo'), | ||
// isVertical: false, | ||
isVertical: false, | ||
distanceX: 80, | ||
@@ -68,17 +68,5 @@ distanceY: 80, | ||
}, | ||
dragStart() { | ||
console.log('dragstart') | ||
preventDrag(data) { | ||
return data.key === '14' | ||
}, | ||
dragEnd(data) { | ||
console.log('dragend', data) | ||
}, | ||
click() { | ||
console.log('click') | ||
}, | ||
// mouseEnter(data) { | ||
// console.log('enter', data) | ||
// }, | ||
// mouseLeave(data) { | ||
// console.log('leave', data) | ||
// }, | ||
contentRender(data) { | ||
@@ -93,5 +81,25 @@ const container = document.createElement('div') | ||
return container | ||
}, | ||
hook: { | ||
dragStart() { | ||
console.log('dragstart') | ||
}, | ||
dragEnd() { | ||
console.log('dragend') | ||
}, | ||
click() { | ||
console.log('click') | ||
}, | ||
mouseEnter() { | ||
console.log('enter') | ||
}, | ||
mouseLeave() { | ||
console.log('leave') | ||
}, | ||
foldChange(nodeKey, isFold) { | ||
console.log(key, isFold) | ||
} | ||
} | ||
}) | ||
console.log(chart) | ||
document.querySelector('.re-render').addEventListener('click', () => { | ||
@@ -98,0 +106,0 @@ chart.reRender(data) |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
394987
20
1735
486