From c8ca787652905eb89325e63a91c541eddd211f6b Mon Sep 17 00:00:00 2001 From: hiawui Date: Tue, 28 Jun 2022 23:00:11 +0800 Subject: [PATCH 1/3] enable dragging to change the task order --- src/arrow.js | 23 +++++----------- src/bar.js | 15 ++++++++-- src/index.js | 78 +++++++++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 90 insertions(+), 26 deletions(-) diff --git a/src/arrow.js b/src/arrow.js index da6925c60..030603536 100644 --- a/src/arrow.js +++ b/src/arrow.js @@ -23,25 +23,16 @@ export default class Arrow { } start_x -= 10; - let start_y = - this.gantt.config.header_height + - this.gantt.options.bar_height + - (this.gantt.options.padding + this.gantt.options.bar_height) * - this.from_task.task._index + - this.gantt.options.padding / 2; + const start_y = + this.from_task.$bar.getY() + this.gantt.options.bar_height; - let end_x = this.to_task.$bar.getX() - 13; - let end_y = - this.gantt.config.header_height + - this.gantt.options.bar_height / 2 + - (this.gantt.options.padding + this.gantt.options.bar_height) * - this.to_task.task._index + - this.gantt.options.padding / 2; + const end_x = this.to_task.$bar.getX() - 13; + const end_y = + this.to_task.$bar.getY() + this.gantt.options.bar_height / 2; const from_is_below_to = - this.from_task.task._index > this.to_task.task._index; - - let curve = this.gantt.options.arrow_curve; + this.from_task.$bar.getY() > this.to_task.$bar.getY(); + const curve = this.gantt.options.arrow_curve; const clockwise = from_is_below_to ? 1 : 0; let curve_y = from_is_below_to ? -curve : curve; diff --git a/src/bar.js b/src/bar.js index 2ff5c45f6..b3468c339 100644 --- a/src/bar.js +++ b/src/bar.js @@ -395,7 +395,7 @@ export default class Bar { }); } - update_bar_position({ x = null, width = null }) { + update_bar_position({ x = null, width = null, y = null }) { const bar = this.$bar; if (x) { @@ -414,7 +414,9 @@ export default class Bar { this.update_attr(bar, 'width', width); this.$date_highlight.style.width = width + 'px'; } - + if (y) { + this.update_attr(bar, 'y', y); + } this.update_label_position(); this.update_handle_position(); this.date_changed(); @@ -648,7 +650,7 @@ export default class Bar { update_progressbar_position() { if (this.invalid || this.gantt.options.readonly) return; this.$bar_progress.setAttribute('x', this.$bar.getX()); - + this.$bar_progress.setAttribute('y', this.$bar.getY()); this.$bar_progress.setAttribute( 'width', this.calculate_progress_width(), @@ -690,6 +692,7 @@ export default class Bar { ); } } + label.setAttribute('y', bar.getY() + bar.getHeight() / 2); } update_handle_position() { @@ -698,9 +701,15 @@ export default class Bar { this.handle_group .querySelector('.handle.left') .setAttribute('x', bar.getX()); + this.handle_group + .querySelector('.handle.left') + .setAttribute('y', bar.getY() + this.height / 4); this.handle_group .querySelector('.handle.right') .setAttribute('x', bar.getEndX()); + this.handle_group + .querySelector('.handle.right') + .setAttribute('y', bar.getY() + this.height / 4); const handle = this.group.querySelector('.handle.progress'); handle && handle.setAttribute('cx', this.$bar_progress.getEndX()); } diff --git a/src/index.js b/src/index.js index 93524b63f..d84fb3c0d 100644 --- a/src/index.js +++ b/src/index.js @@ -1073,6 +1073,26 @@ export default class Gantt { return [min_start, max_start, max_end]; } + sort_bars() { + const changed_bars = []; + if (!this.bars) { + return changed_bars; + } + this.bars = this.bars.sort((b0, b1) => { + return b0.$bar.getY() - b1.$bar.getY(); + }); + + this.tasks = this.bars.map((b, i) => { + const task = b.task; + if (task._index !== i) { + changed_bars.push(b); + } + task._index = i; + return task; + }); + return changed_bars; + } + bind_bar_events() { let is_dragging = false; let x_on_start = 0; @@ -1081,8 +1101,13 @@ export default class Gantt { let is_resizing_left = false; let is_resizing_right = false; let parent_bar_id = null; - let bars = []; // instanceof Bar - this.bar_being_dragged = null; + let bars = []; // instanceof Bars, the dragged bar and its children + const min_y = this.options.header_height; + const max_y = + this.options.header_height + + this.tasks.length * + (this.options.bar_height + this.options.padding); + this.bar_being_dragged = null; // instanceof dragged bar const action_in_progress = () => is_dragging || is_resizing_left || is_resizing_right; @@ -1091,11 +1116,13 @@ export default class Gantt { if (e.target.classList.contains('grid-row')) this.unselect_all(); }; - let pos = 0; + let x_pos = 0; + let y_pos = 0; $.on(this.$svg, 'mousemove', '.bar-wrapper, .handle', (e) => { if ( this.bar_being_dragged === false && - Math.abs((e.offsetX || e.layerX) - pos) > 10 + (Math.abs((e.offsetX || e.layerX) - x_pos) > 10 || + Math.abs((e.offsetY || e.layerY) - y_pos) > 10) ) this.bar_being_dragged = true; }); @@ -1130,7 +1157,8 @@ export default class Gantt { bars = ids.map((id) => this.get_bar(id)); this.bar_being_dragged = false; - pos = x_on_start; + x_pos = x_on_start; + y_pos = y_on_start; bars.forEach((bar) => { const $bar = bar.$bar; @@ -1138,6 +1166,8 @@ export default class Gantt { $bar.oy = $bar.getY(); $bar.owidth = $bar.getWidth(); $bar.finaldx = 0; + $bar.finaldy = 0; + return bar; }); }); @@ -1281,9 +1311,14 @@ export default class Gantt { $.on(this.$svg, 'mousemove', (e) => { if (!action_in_progress()) return; const dx = (e.offsetX || e.layerX) - x_on_start; + const dy = (e.offsetY || e.layerY) - y_on_start; + let bar_dragging = null bars.forEach((bar) => { const $bar = bar.$bar; + if (parent_bar_id === bar.task.id) { + bar_dragging = bar; + } $bar.finaldx = this.get_snap_position(dx, $bar.ox); this.hide_popup(); if (is_resizing_left) { @@ -1308,9 +1343,34 @@ export default class Gantt { !this.options.readonly && !this.options.readonly_dates ) { - bar.update_bar_position({ x: $bar.ox + $bar.finaldx }); + if (parent_bar_id === bar.task.id) { + bar.update_bar_position({ + x: $bar.ox + $bar.finaldx, + y: Math.min(Math.max($bar.oy + dy, min_y), max_y) + }); + } else { + bar.update_bar_position({ x: $bar.ox + $bar.finaldx }); + } } }); + + // update y pos + if ( + is_dragging && + !this.options.readonly && + !this.options.readonly_dates && + Math.abs(dy - bar_dragging.$bar.finaldy) > bar_dragging.height + ) { + const changed_bars = this.sort_bars(); + changed_bars.map((bar) => { + const y = bar.compute_y(); + if (bar.task.id === parent_bar_id) { + bar.$bar.finaldy = y - bar.$bar.oy; + return; + } + bar.update_bar_position({ y: y }); + }); + } }); document.addEventListener('mouseup', () => { @@ -1323,13 +1383,17 @@ export default class Gantt { }); $.on(this.$svg, 'mouseup', (e) => { + const dy = e.offsetY - y_on_start; this.bar_being_dragged = null; bars.forEach((bar) => { const $bar = bar.$bar; - if (!$bar.finaldx) return; + if (!$bar.finaldx && !$bar.finaldy) return; bar.date_changed(); bar.compute_progress(); bar.set_action_completed(); + if (dy !== $bar.finaldy) { + bar.update_bar_position({ y: $bar.oy + $bar.finaldy }) + } }); }); From c4c528af4120df46b740003fa6bf9e62580bdb0d Mon Sep 17 00:00:00 2001 From: hiawui Date: Thu, 9 Jan 2025 22:09:11 +0800 Subject: [PATCH 2/3] fix: mousemove & mouseup --- src/arrow.js | 2 +- src/index.js | 31 ++++++++++++++++--------------- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/src/arrow.js b/src/arrow.js index 030603536..ece4af712 100644 --- a/src/arrow.js +++ b/src/arrow.js @@ -71,7 +71,7 @@ export default class Arrow { this.path = ` M ${start_x} ${start_y} V ${offset} - a ${curve} ${curve} 0 0 ${clockwise} ${curve} ${curve} + a ${curve} ${curve} 0 0 ${clockwise} ${curve} ${curve_y} L ${end_x} ${end_y} m -5 -5 l 5 5 diff --git a/src/index.js b/src/index.js index d84fb3c0d..dadae9339 100644 --- a/src/index.js +++ b/src/index.js @@ -1102,9 +1102,9 @@ export default class Gantt { let is_resizing_right = false; let parent_bar_id = null; let bars = []; // instanceof Bars, the dragged bar and its children - const min_y = this.options.header_height; + const min_y = this.config.header_height; const max_y = - this.options.header_height + + this.config.header_height + this.tasks.length * (this.options.bar_height + this.options.padding); this.bar_being_dragged = null; // instanceof dragged bar @@ -1122,7 +1122,7 @@ export default class Gantt { if ( this.bar_being_dragged === false && (Math.abs((e.offsetX || e.layerX) - x_pos) > 10 || - Math.abs((e.offsetY || e.layerY) - y_pos) > 10) + Math.abs((e.offsetY || e.layerY) - y_pos) > 10) ) this.bar_being_dragged = true; }); @@ -1313,11 +1313,11 @@ export default class Gantt { const dx = (e.offsetX || e.layerX) - x_on_start; const dy = (e.offsetY || e.layerY) - y_on_start; - let bar_dragging = null + let bar_dragging = null; bars.forEach((bar) => { const $bar = bar.$bar; if (parent_bar_id === bar.task.id) { - bar_dragging = bar; + bar_dragging = bar; } $bar.finaldx = this.get_snap_position(dx, $bar.ox); this.hide_popup(); @@ -1346,7 +1346,7 @@ export default class Gantt { if (parent_bar_id === bar.task.id) { bar.update_bar_position({ x: $bar.ox + $bar.finaldx, - y: Math.min(Math.max($bar.oy + dy, min_y), max_y) + y: Math.min(Math.max($bar.oy + dy, min_y), max_y), }); } else { bar.update_bar_position({ x: $bar.ox + $bar.finaldx }); @@ -1363,12 +1363,12 @@ export default class Gantt { ) { const changed_bars = this.sort_bars(); changed_bars.map((bar) => { - const y = bar.compute_y(); + bar.compute_y(); if (bar.task.id === parent_bar_id) { - bar.$bar.finaldy = y - bar.$bar.oy; + bar.$bar.finaldy = bar.y - bar.$bar.oy; return; } - bar.update_bar_position({ y: y }); + bar.update_bar_position({ y: bar.y }); }); } }); @@ -1383,17 +1383,18 @@ export default class Gantt { }); $.on(this.$svg, 'mouseup', (e) => { - const dy = e.offsetY - y_on_start; + const dy = (e.offsetY || e.layerY) - y_on_start; this.bar_being_dragged = null; bars.forEach((bar) => { const $bar = bar.$bar; - if (!$bar.finaldx && !$bar.finaldy) return; - bar.date_changed(); - bar.compute_progress(); - bar.set_action_completed(); + if (!$bar.finaldx) { + bar.date_changed(); + bar.compute_progress(); + } if (dy !== $bar.finaldy) { - bar.update_bar_position({ y: $bar.oy + $bar.finaldy }) + bar.update_bar_position({ y: $bar.oy + $bar.finaldy }); } + bar.set_action_completed(); }); }); From 60354d9fb49d36a8612733b5c49e4ba8cf0b535b Mon Sep 17 00:00:00 2001 From: hiawui Date: Fri, 10 Jan 2025 09:57:21 +0800 Subject: [PATCH 3/3] fix: mouseup --- src/index.js | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/index.js b/src/index.js index dadae9339..8bf68294c 100644 --- a/src/index.js +++ b/src/index.js @@ -1101,13 +1101,13 @@ export default class Gantt { let is_resizing_left = false; let is_resizing_right = false; let parent_bar_id = null; - let bars = []; // instanceof Bars, the dragged bar and its children + let bars = []; // instanceof Bar + this.bar_being_dragged = null; const min_y = this.config.header_height; const max_y = this.config.header_height + this.tasks.length * (this.options.bar_height + this.options.padding); - this.bar_being_dragged = null; // instanceof dragged bar const action_in_progress = () => is_dragging || is_resizing_left || is_resizing_right; @@ -1359,7 +1359,7 @@ export default class Gantt { is_dragging && !this.options.readonly && !this.options.readonly_dates && - Math.abs(dy - bar_dragging.$bar.finaldy) > bar_dragging.height + Math.abs(dy - bar_dragging.$bar.finaldy) >= bar_dragging.height ) { const changed_bars = this.sort_bars(); changed_bars.map((bar) => { @@ -1382,8 +1382,7 @@ export default class Gantt { ?.classList?.remove?.('visible'); }); - $.on(this.$svg, 'mouseup', (e) => { - const dy = (e.offsetY || e.layerY) - y_on_start; + $.on(this.$svg, 'mouseup', () => { this.bar_being_dragged = null; bars.forEach((bar) => { const $bar = bar.$bar; @@ -1391,8 +1390,8 @@ export default class Gantt { bar.date_changed(); bar.compute_progress(); } - if (dy !== $bar.finaldy) { - bar.update_bar_position({ y: $bar.oy + $bar.finaldy }); + if (parent_bar_id === bar.task.id) { + bar.update_bar_position({ y: bar.y }); } bar.set_action_completed(); });