Skip to content

Commit

Permalink
enable dragging to change the task order
Browse files Browse the repository at this point in the history
  • Loading branch information
hiawui committed Jun 28, 2022
1 parent dc57669 commit 3688be1
Show file tree
Hide file tree
Showing 3 changed files with 130 additions and 48 deletions.
14 changes: 3 additions & 11 deletions src/arrow.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,22 +23,14 @@ export default class Arrow {
}

const start_y =
this.gantt.options.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;
this.from_task.$bar.getY() + this.gantt.options.bar_height;

const end_x = this.to_task.$bar.getX() - this.gantt.options.padding / 2;
const end_y =
this.gantt.options.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;
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;
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;
const curve_y = from_is_below_to ? -curve : curve;
Expand Down
15 changes: 13 additions & 2 deletions src/bar.js
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,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) {
// get all x values of parent task
Expand All @@ -239,9 +239,12 @@ export default class Bar {
if (width && width >= this.gantt.options.column_width) {
this.update_attr(bar, 'width', width);
}
if (y) {
this.update_attr(bar, 'y', y);
}
this.update_label_position();
this.update_handle_position();
this.update_progressbar_position();
this.update_handle_position();
this.update_arrow_position();
}

Expand Down Expand Up @@ -370,6 +373,7 @@ export default class Bar {
update_progressbar_position() {
if (this.invalid) return;
this.$bar_progress.setAttribute('x', this.$bar.getX());
this.$bar_progress.setAttribute('y', this.$bar.getY());
this.$bar_progress.setAttribute(
'width',
this.$bar.getWidth() * (this.task.progress / 100)
Expand All @@ -387,6 +391,7 @@ export default class Bar {
label.classList.remove('big');
label.setAttribute('x', bar.getX() + bar.getWidth() / 2);
}
label.setAttribute('y', bar.getY() + bar.getHeight() / 2);
}

update_handle_position() {
Expand All @@ -395,9 +400,15 @@ export default class Bar {
this.handle_group
.querySelector('.handle.left')
.setAttribute('x', bar.getX() + 1);
this.handle_group
.querySelector('.handle.left')
.setAttribute('y', bar.getY() + 1);
this.handle_group
.querySelector('.handle.right')
.setAttribute('x', bar.getEndX() - 9);
this.handle_group
.querySelector('.handle.right')
.setAttribute('y', bar.getY() + 1);
const handle = this.group.querySelector('.handle.progress');
handle &&
handle.setAttribute('points', this.get_progress_polygon_points());
Expand Down
149 changes: 114 additions & 35 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ export default class Gantt {
popup_trigger: 'click',
custom_popup_html: null,
language: 'en',
sortable: false,
};
this.options = Object.assign({}, default_options, options);
}
Expand Down Expand Up @@ -649,15 +650,40 @@ export default class Gantt {
);
}

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;
let y_on_start = 0;
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

function action_in_progress() {
return is_dragging || is_resizing_left || is_resizing_right;
Expand All @@ -684,16 +710,18 @@ export default class Gantt {
parent_bar_id,
...this.get_all_dependent_tasks(parent_bar_id),
];
bars = ids.map((id) => this.get_bar(id));

this.bar_being_dragged = parent_bar_id;

bars.forEach((bar) => {
bars = ids.map((id) => {
const bar = this.get_bar(id);
if (parent_bar_id === id) {
this.bar_being_dragged = bar;
}
const $bar = bar.$bar;
$bar.ox = $bar.getX();
$bar.oy = $bar.getY();
$bar.owidth = $bar.getWidth();
$bar.finaldx = 0;
$bar.finaldy = 0;
return bar;
});
});

Expand All @@ -702,53 +730,104 @@ export default class Gantt {
const dx = e.offsetX - x_on_start;
const dy = e.offsetY - y_on_start;

this.hide_popup();

// update the dragged bar
const bar_being_dragged = this.bar_being_dragged;
bar_being_dragged.$bar.finaldx = this.get_snap_position(dx);
if (is_resizing_left) {
bar_being_dragged.update_bar_position({
x:
bar_being_dragged.$bar.ox +
bar_being_dragged.$bar.finaldx,
width:
bar_being_dragged.$bar.owidth -
bar_being_dragged.$bar.finaldx,
});
} else if (is_resizing_right) {
bar_being_dragged.update_bar_position({
width:
bar_being_dragged.$bar.owidth +
bar_being_dragged.$bar.finaldx,
});
} else if (is_dragging) {
let y = bar_being_dragged.$bar.oy + dy;
if (y < min_y) {
y = min_y;
} else if (y > max_y) {
y = max_y;
}
bar_being_dragged.update_bar_position({
x:
bar_being_dragged.$bar.ox +
bar_being_dragged.$bar.finaldx,
y: this.options.sortable ? y : null,
});
}

// update children
bars.forEach((bar) => {
if (bar.task.id === parent_bar_id) {
return;
}
const $bar = bar.$bar;
$bar.finaldx = this.get_snap_position(dx);
this.hide_popup();
if (is_resizing_left) {
if (parent_bar_id === bar.task.id) {
bar.update_bar_position({
x: $bar.ox + $bar.finaldx,
width: $bar.owidth - $bar.finaldx,
});
} else {
bar.update_bar_position({
x: $bar.ox + $bar.finaldx,
});
}
} else if (is_resizing_right) {
if (parent_bar_id === bar.task.id) {
bar.update_bar_position({
width: $bar.owidth + $bar.finaldx,
});
}
bar.update_bar_position({
x: $bar.ox + $bar.finaldx,
});
} else if (is_dragging) {
bar.update_bar_position({ x: $bar.ox + $bar.finaldx });
bar.update_bar_position({
x: $bar.ox + $bar.finaldx,
});
}
});

// update y pos
if (
this.options.sortable &&
is_dragging &&
Math.abs(dy - bar_being_dragged.$bar.finaldy) >
bar_being_dragged.height
) {
this.sort_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', (e) => {
const dy = e.offsetY - y_on_start;
if (is_dragging || is_resizing_left || is_resizing_right) {
bars.forEach((bar) => bar.group.classList.remove('active'));
bars.forEach((bar) => {
bar.group.classList.remove('active');

const $bar = bar.$bar;
if ($bar.finaldx) {
bar.date_changed();
bar.set_action_completed();
}
});
const $bar = this.bar_being_dragged.$bar;
if (this.options.sortable && dy !== $bar.finaldy) {
this.bar_being_dragged.update_bar_position({
y: $bar.oy + $bar.finaldy,
});
}
}

this.bar_being_dragged = null;
is_dragging = false;
is_resizing_left = false;
is_resizing_right = false;
});

$.on(this.$svg, 'mouseup', (e) => {
this.bar_being_dragged = null;
bars.forEach((bar) => {
const $bar = bar.$bar;
if (!$bar.finaldx) return;
bar.date_changed();
bar.set_action_completed();
});
});

this.bind_bar_progress();
}

Expand Down

0 comments on commit 3688be1

Please sign in to comment.