@@ -1073,6 +1073,26 @@ export default class Gantt {
1073
1073
return [ min_start , max_start , max_end ] ;
1074
1074
}
1075
1075
1076
+ sort_bars ( ) {
1077
+ const changed_bars = [ ] ;
1078
+ if ( ! this . bars ) {
1079
+ return changed_bars ;
1080
+ }
1081
+ this . bars = this . bars . sort ( ( b0 , b1 ) => {
1082
+ return b0 . $bar . getY ( ) - b1 . $bar . getY ( ) ;
1083
+ } ) ;
1084
+
1085
+ this . tasks = this . bars . map ( ( b , i ) => {
1086
+ const task = b . task ;
1087
+ if ( task . _index !== i ) {
1088
+ changed_bars . push ( b ) ;
1089
+ }
1090
+ task . _index = i ;
1091
+ return task ;
1092
+ } ) ;
1093
+ return changed_bars ;
1094
+ }
1095
+
1076
1096
bind_bar_events ( ) {
1077
1097
let is_dragging = false ;
1078
1098
let x_on_start = 0 ;
@@ -1081,8 +1101,13 @@ export default class Gantt {
1081
1101
let is_resizing_left = false ;
1082
1102
let is_resizing_right = false ;
1083
1103
let parent_bar_id = null ;
1084
- let bars = [ ] ; // instanceof Bar
1085
- this . bar_being_dragged = null ;
1104
+ let bars = [ ] ; // instanceof Bars, the dragged bar and its children
1105
+ const min_y = this . options . header_height ;
1106
+ const max_y =
1107
+ this . options . header_height +
1108
+ this . tasks . length *
1109
+ ( this . options . bar_height + this . options . padding ) ;
1110
+ this . bar_being_dragged = null ; // instanceof dragged bar
1086
1111
1087
1112
const action_in_progress = ( ) =>
1088
1113
is_dragging || is_resizing_left || is_resizing_right ;
@@ -1091,11 +1116,13 @@ export default class Gantt {
1091
1116
if ( e . target . classList . contains ( 'grid-row' ) ) this . unselect_all ( ) ;
1092
1117
} ;
1093
1118
1094
- let pos = 0 ;
1119
+ let x_pos = 0 ;
1120
+ let y_pos = 0 ;
1095
1121
$ . on ( this . $svg , 'mousemove' , '.bar-wrapper, .handle' , ( e ) => {
1096
1122
if (
1097
1123
this . bar_being_dragged === false &&
1098
- Math . abs ( ( e . offsetX || e . layerX ) - pos ) > 10
1124
+ ( Math . abs ( ( e . offsetX || e . layerX ) - x_pos ) > 10 ||
1125
+ Math . abs ( ( e . offsetY || e . layerY ) - y_pos ) > 10 )
1099
1126
)
1100
1127
this . bar_being_dragged = true ;
1101
1128
} ) ;
@@ -1130,14 +1157,17 @@ export default class Gantt {
1130
1157
bars = ids . map ( ( id ) => this . get_bar ( id ) ) ;
1131
1158
1132
1159
this . bar_being_dragged = false ;
1133
- pos = x_on_start ;
1160
+ x_pos = x_on_start ;
1161
+ y_pos = y_on_start ;
1134
1162
1135
1163
bars . forEach ( ( bar ) => {
1136
1164
const $bar = bar . $bar ;
1137
1165
$bar . ox = $bar . getX ( ) ;
1138
1166
$bar . oy = $bar . getY ( ) ;
1139
1167
$bar . owidth = $bar . getWidth ( ) ;
1140
1168
$bar . finaldx = 0 ;
1169
+ $bar . finaldy = 0 ;
1170
+ return bar ;
1141
1171
} ) ;
1142
1172
} ) ;
1143
1173
@@ -1281,9 +1311,14 @@ export default class Gantt {
1281
1311
$ . on ( this . $svg , 'mousemove' , ( e ) => {
1282
1312
if ( ! action_in_progress ( ) ) return ;
1283
1313
const dx = ( e . offsetX || e . layerX ) - x_on_start ;
1314
+ const dy = ( e . offsetY || e . layerY ) - y_on_start ;
1284
1315
1316
+ let bar_dragging = null
1285
1317
bars . forEach ( ( bar ) => {
1286
1318
const $bar = bar . $bar ;
1319
+ if ( parent_bar_id === bar . task . id ) {
1320
+ bar_dragging = bar ;
1321
+ }
1287
1322
$bar . finaldx = this . get_snap_position ( dx , $bar . ox ) ;
1288
1323
this . hide_popup ( ) ;
1289
1324
if ( is_resizing_left ) {
@@ -1308,9 +1343,34 @@ export default class Gantt {
1308
1343
! this . options . readonly &&
1309
1344
! this . options . readonly_dates
1310
1345
) {
1311
- bar . update_bar_position ( { x : $bar . ox + $bar . finaldx } ) ;
1346
+ if ( parent_bar_id === bar . task . id ) {
1347
+ bar . update_bar_position ( {
1348
+ x : $bar . ox + $bar . finaldx ,
1349
+ y : Math . min ( Math . max ( $bar . oy + dy , min_y ) , max_y )
1350
+ } ) ;
1351
+ } else {
1352
+ bar . update_bar_position ( { x : $bar . ox + $bar . finaldx } ) ;
1353
+ }
1312
1354
}
1313
1355
} ) ;
1356
+
1357
+ // update y pos
1358
+ if (
1359
+ is_dragging &&
1360
+ ! this . options . readonly &&
1361
+ ! this . options . readonly_dates &&
1362
+ Math . abs ( dy - bar_dragging . $bar . finaldy ) > bar_dragging . height
1363
+ ) {
1364
+ const changed_bars = this . sort_bars ( ) ;
1365
+ changed_bars . map ( ( bar ) => {
1366
+ const y = bar . compute_y ( ) ;
1367
+ if ( bar . task . id === parent_bar_id ) {
1368
+ bar . $bar . finaldy = y - bar . $bar . oy ;
1369
+ return ;
1370
+ }
1371
+ bar . update_bar_position ( { y : y } ) ;
1372
+ } ) ;
1373
+ }
1314
1374
} ) ;
1315
1375
1316
1376
document . addEventListener ( 'mouseup' , ( ) => {
@@ -1323,13 +1383,17 @@ export default class Gantt {
1323
1383
} ) ;
1324
1384
1325
1385
$ . on ( this . $svg , 'mouseup' , ( e ) => {
1386
+ const dy = e . offsetY - y_on_start ;
1326
1387
this . bar_being_dragged = null ;
1327
1388
bars . forEach ( ( bar ) => {
1328
1389
const $bar = bar . $bar ;
1329
- if ( ! $bar . finaldx ) return ;
1390
+ if ( ! $bar . finaldx && ! $bar . finaldy ) return ;
1330
1391
bar . date_changed ( ) ;
1331
1392
bar . compute_progress ( ) ;
1332
1393
bar . set_action_completed ( ) ;
1394
+ if ( dy !== $bar . finaldy ) {
1395
+ bar . update_bar_position ( { y : $bar . oy + $bar . finaldy } )
1396
+ }
1333
1397
} ) ;
1334
1398
} ) ;
1335
1399
0 commit comments