@@ -87,6 +87,7 @@ export default class Gantt {
8787 popup_trigger : 'click' ,
8888 custom_popup_html : null ,
8989 language : 'en' ,
90+ sortable : false ,
9091 } ;
9192 this . options = Object . assign ( { } , default_options , options ) ;
9293 }
@@ -649,15 +650,40 @@ export default class Gantt {
649650 ) ;
650651 }
651652
653+ sort_bars ( ) {
654+ const changed_bars = [ ] ;
655+ if ( ! this . bars ) {
656+ return changed_bars ;
657+ }
658+ this . bars = this . bars . sort ( ( b0 , b1 ) => {
659+ return b0 . $bar . getY ( ) - b1 . $bar . getY ( ) ;
660+ } ) ;
661+
662+ this . tasks = this . bars . map ( ( b , i ) => {
663+ const task = b . task ;
664+ if ( task . _index !== i ) {
665+ changed_bars . push ( b ) ;
666+ }
667+ task . _index = i ;
668+ return task ;
669+ } ) ;
670+ return changed_bars ;
671+ }
672+
652673 bind_bar_events ( ) {
653674 let is_dragging = false ;
654675 let x_on_start = 0 ;
655676 let y_on_start = 0 ;
656677 let is_resizing_left = false ;
657678 let is_resizing_right = false ;
658679 let parent_bar_id = null ;
659- let bars = [ ] ; // instanceof Bar
660- this . bar_being_dragged = null ;
680+ let bars = [ ] ; // instanceof Bars, the dragged bar and its children
681+ const min_y = this . options . header_height ;
682+ const max_y =
683+ this . options . header_height +
684+ this . tasks . length *
685+ ( this . options . bar_height + this . options . padding ) ;
686+ this . bar_being_dragged = null ; // instanceof dragged bar
661687
662688 function action_in_progress ( ) {
663689 return is_dragging || is_resizing_left || is_resizing_right ;
@@ -684,16 +710,18 @@ export default class Gantt {
684710 parent_bar_id ,
685711 ...this . get_all_dependent_tasks ( parent_bar_id ) ,
686712 ] ;
687- bars = ids . map ( ( id ) => this . get_bar ( id ) ) ;
688-
689- this . bar_being_dragged = parent_bar_id ;
690-
691- bars . forEach ( ( bar ) => {
713+ bars = ids . map ( ( id ) => {
714+ const bar = this . get_bar ( id ) ;
715+ if ( parent_bar_id === id ) {
716+ this . bar_being_dragged = bar ;
717+ }
692718 const $bar = bar . $bar ;
693719 $bar . ox = $bar . getX ( ) ;
694720 $bar . oy = $bar . getY ( ) ;
695721 $bar . owidth = $bar . getWidth ( ) ;
696722 $bar . finaldx = 0 ;
723+ $bar . finaldy = 0 ;
724+ return bar ;
697725 } ) ;
698726 } ) ;
699727
@@ -702,53 +730,104 @@ export default class Gantt {
702730 const dx = e . offsetX - x_on_start ;
703731 const dy = e . offsetY - y_on_start ;
704732
733+ this . hide_popup ( ) ;
734+
735+ // update the dragged bar
736+ const bar_being_dragged = this . bar_being_dragged ;
737+ bar_being_dragged . $bar . finaldx = this . get_snap_position ( dx ) ;
738+ if ( is_resizing_left ) {
739+ bar_being_dragged . update_bar_position ( {
740+ x :
741+ bar_being_dragged . $bar . ox +
742+ bar_being_dragged . $bar . finaldx ,
743+ width :
744+ bar_being_dragged . $bar . owidth -
745+ bar_being_dragged . $bar . finaldx ,
746+ } ) ;
747+ } else if ( is_resizing_right ) {
748+ bar_being_dragged . update_bar_position ( {
749+ width :
750+ bar_being_dragged . $bar . owidth +
751+ bar_being_dragged . $bar . finaldx ,
752+ } ) ;
753+ } else if ( is_dragging ) {
754+ let y = bar_being_dragged . $bar . oy + dy ;
755+ if ( y < min_y ) {
756+ y = min_y ;
757+ } else if ( y > max_y ) {
758+ y = max_y ;
759+ }
760+ bar_being_dragged . update_bar_position ( {
761+ x :
762+ bar_being_dragged . $bar . ox +
763+ bar_being_dragged . $bar . finaldx ,
764+ y : this . options . sortable ? y : null ,
765+ } ) ;
766+ }
767+
768+ // update children
705769 bars . forEach ( ( bar ) => {
770+ if ( bar . task . id === parent_bar_id ) {
771+ return ;
772+ }
706773 const $bar = bar . $bar ;
707774 $bar . finaldx = this . get_snap_position ( dx ) ;
708775 this . hide_popup ( ) ;
709776 if ( is_resizing_left ) {
710- if ( parent_bar_id === bar . task . id ) {
711- bar . update_bar_position ( {
712- x : $bar . ox + $bar . finaldx ,
713- width : $bar . owidth - $bar . finaldx ,
714- } ) ;
715- } else {
716- bar . update_bar_position ( {
717- x : $bar . ox + $bar . finaldx ,
718- } ) ;
719- }
720- } else if ( is_resizing_right ) {
721- if ( parent_bar_id === bar . task . id ) {
722- bar . update_bar_position ( {
723- width : $bar . owidth + $bar . finaldx ,
724- } ) ;
725- }
777+ bar . update_bar_position ( {
778+ x : $bar . ox + $bar . finaldx ,
779+ } ) ;
726780 } else if ( is_dragging ) {
727- bar . update_bar_position ( { x : $bar . ox + $bar . finaldx } ) ;
781+ bar . update_bar_position ( {
782+ x : $bar . ox + $bar . finaldx ,
783+ } ) ;
728784 }
729785 } ) ;
786+
787+ // update y pos
788+ if (
789+ this . options . sortable &&
790+ is_dragging &&
791+ Math . abs ( dy - bar_being_dragged . $bar . finaldy ) >
792+ bar_being_dragged . height
793+ ) {
794+ this . sort_bars ( ) . map ( ( bar ) => {
795+ const y = bar . compute_y ( ) ;
796+ if ( bar . task . id === parent_bar_id ) {
797+ bar . $bar . finaldy = y - bar . $bar . oy ;
798+ return ;
799+ }
800+ bar . update_bar_position ( { y : y } ) ;
801+ } ) ;
802+ }
730803 } ) ;
731804
732805 document . addEventListener ( 'mouseup' , ( e ) => {
806+ const dy = e . offsetY - y_on_start ;
733807 if ( is_dragging || is_resizing_left || is_resizing_right ) {
734- bars . forEach ( ( bar ) => bar . group . classList . remove ( 'active' ) ) ;
808+ bars . forEach ( ( bar ) => {
809+ bar . group . classList . remove ( 'active' ) ;
810+
811+ const $bar = bar . $bar ;
812+ if ( $bar . finaldx ) {
813+ bar . date_changed ( ) ;
814+ bar . set_action_completed ( ) ;
815+ }
816+ } ) ;
817+ const $bar = this . bar_being_dragged . $bar ;
818+ if ( this . options . sortable && dy !== $bar . finaldy ) {
819+ this . bar_being_dragged . update_bar_position ( {
820+ y : $bar . oy + $bar . finaldy ,
821+ } ) ;
822+ }
735823 }
736824
825+ this . bar_being_dragged = null ;
737826 is_dragging = false ;
738827 is_resizing_left = false ;
739828 is_resizing_right = false ;
740829 } ) ;
741830
742- $ . on ( this . $svg , 'mouseup' , ( e ) => {
743- this . bar_being_dragged = null ;
744- bars . forEach ( ( bar ) => {
745- const $bar = bar . $bar ;
746- if ( ! $bar . finaldx ) return ;
747- bar . date_changed ( ) ;
748- bar . set_action_completed ( ) ;
749- } ) ;
750- } ) ;
751-
752831 this . bind_bar_progress ( ) ;
753832 }
754833
0 commit comments