在源任务 DHTMLX 甘特图的结束日期内拖动任务
Dragging tasks within the end date of source task DHTMLX Gantt
我用我的数据库定制了一个 DHTMLX 甘特图。
对于数据,我只选择 id、文本、start_date、持续时间和 end_date。
对于 links 我选择 id、souce、target 和 type,所有类型都是 0。
我已经完成了拖动任务和他们的依赖任务,手动移动任务。与主任务同步移动后代(link:https://docs.dhtmlx.com/gantt/desktop__dragging_dependent_tasks.html#movingtasksmanually)
我已将此代码添加到我的 gantt.aspx 中:
gantt.eachSuccessor = function (callback, root) {
if (!this.isTaskExists(root))
return;
// remember tasks we've already iterated in order to avoid infinite loops
var traversedTasks = arguments[2] || {};
if (traversedTasks[root])
return;
traversedTasks[root] = true;
var rootTask = this.getTask(root);
var links = rootTask.$source;
if (links) {
for (var i = 0; i < links.length; i++) {
var link = this.getLink(links[i]);
if (this.isTaskExists(link.target) && !traversedTasks[link.target]) {
callback.call(this, this.getTask(link.target));
// iterate the whole branch, not only first-level dependencies
this.eachSuccessor(callback, link.target, traversedTasks);
}
}
}
};
gantt.attachEvent("onTaskDrag", function (id, mode, task, original) {
var modes = gantt.config.drag_mode;
if (mode == modes.move) {
var diff = task.start_date - original.start_date;
gantt.eachSuccessor(function (child) {
child.start_date = new Date(+child.start_date + diff);
child.end_date = new Date(+child.end_date + diff);
gantt.refreshTask(child.id, true);
}, id);
}
return true;
});
gantt.attachEvent("onAfterTaskDrag", function (id, mode, e) {
var modes = gantt.config.drag_mode;
if (mode == modes.move) {
gantt.eachSuccessor(function (child) {
child.start_date = gantt.roundDate(child.start_date);
child.end_date = gantt.calculateEndDate(child.start_date, child.duration);
gantt.updateTask(child.id);
}, id);
}
});```
Now i have to add the constrain that a child(target) task can’t move before the end date of father(source). I have to add a Left limit for all tasks, but i have no idea how to do, because i haven’t “parent” on my data details.
在 onTaskDrag
事件处理程序中,您拥有正在拖动的任务的 task
对象。对于相关任务,有 child
变量,尽管这些任务不一定是拖动任务的子任务。因此,您可以从 task
对象中获取您正在拖动的任务的结束日期。
在 onAfterTaskDrag
事件处理程序中,您没有 task
对象,但是您可以使用 gantt.getTask(id)
方法获取它:
gantt.attachEvent("onAfterTaskDrag", function (id, mode, e) {
var task = gantt.getTask(id);
var modes = gantt.config.drag_mode;
if (mode == modes.move) {
gantt.eachSuccessor(function (child) {
child.start_date = gantt.roundDate(child.start_date);
child.end_date = gantt.calculateEndDate(child.start_date, child.duration);
gantt.updateTask(child.id);
}, id);
}
});
https://docs.dhtmlx.com/gantt/api__gantt_gettask.html
您还可以使用 auto-scheduling 功能:
https://docs.dhtmlx.com/gantt/desktop__auto_scheduling.html
我用我的数据库定制了一个 DHTMLX 甘特图。 对于数据,我只选择 id、文本、start_date、持续时间和 end_date。 对于 links 我选择 id、souce、target 和 type,所有类型都是 0。
我已经完成了拖动任务和他们的依赖任务,手动移动任务。与主任务同步移动后代(link:https://docs.dhtmlx.com/gantt/desktop__dragging_dependent_tasks.html#movingtasksmanually)
我已将此代码添加到我的 gantt.aspx 中:
gantt.eachSuccessor = function (callback, root) {
if (!this.isTaskExists(root))
return;
// remember tasks we've already iterated in order to avoid infinite loops
var traversedTasks = arguments[2] || {};
if (traversedTasks[root])
return;
traversedTasks[root] = true;
var rootTask = this.getTask(root);
var links = rootTask.$source;
if (links) {
for (var i = 0; i < links.length; i++) {
var link = this.getLink(links[i]);
if (this.isTaskExists(link.target) && !traversedTasks[link.target]) {
callback.call(this, this.getTask(link.target));
// iterate the whole branch, not only first-level dependencies
this.eachSuccessor(callback, link.target, traversedTasks);
}
}
}
};
gantt.attachEvent("onTaskDrag", function (id, mode, task, original) {
var modes = gantt.config.drag_mode;
if (mode == modes.move) {
var diff = task.start_date - original.start_date;
gantt.eachSuccessor(function (child) {
child.start_date = new Date(+child.start_date + diff);
child.end_date = new Date(+child.end_date + diff);
gantt.refreshTask(child.id, true);
}, id);
}
return true;
});
gantt.attachEvent("onAfterTaskDrag", function (id, mode, e) {
var modes = gantt.config.drag_mode;
if (mode == modes.move) {
gantt.eachSuccessor(function (child) {
child.start_date = gantt.roundDate(child.start_date);
child.end_date = gantt.calculateEndDate(child.start_date, child.duration);
gantt.updateTask(child.id);
}, id);
}
});```
Now i have to add the constrain that a child(target) task can’t move before the end date of father(source). I have to add a Left limit for all tasks, but i have no idea how to do, because i haven’t “parent” on my data details.
在 onTaskDrag
事件处理程序中,您拥有正在拖动的任务的 task
对象。对于相关任务,有 child
变量,尽管这些任务不一定是拖动任务的子任务。因此,您可以从 task
对象中获取您正在拖动的任务的结束日期。
在 onAfterTaskDrag
事件处理程序中,您没有 task
对象,但是您可以使用 gantt.getTask(id)
方法获取它:
gantt.attachEvent("onAfterTaskDrag", function (id, mode, e) {
var task = gantt.getTask(id);
var modes = gantt.config.drag_mode;
if (mode == modes.move) {
gantt.eachSuccessor(function (child) {
child.start_date = gantt.roundDate(child.start_date);
child.end_date = gantt.calculateEndDate(child.start_date, child.duration);
gantt.updateTask(child.id);
}, id);
}
});
https://docs.dhtmlx.com/gantt/api__gantt_gettask.html
您还可以使用 auto-scheduling 功能: https://docs.dhtmlx.com/gantt/desktop__auto_scheduling.html