Fixed project-planner maths

This commit is contained in:
Ray 2023-12-23 22:00:22 +00:00
parent d36b98a20c
commit 01ea1b6d01
3 changed files with 153 additions and 202 deletions

View File

@ -122,31 +122,9 @@ gantt1.AddTask({
CollatedTaskID: 8
});
gantt1.InvalidateTasks();
console.log(gantt1.ExportTasks);
// console.log(gantt1.Tasks);
// var dataSet = [
// { key: "b", value: "B2", num: 2, f: 2.2, date: new Date(2001, 2, 2) },
// { key: "d", value: "D4", num: 4, f: 4.4, date: new Date(2001, 4, 4) },
// { key: "a", value: "A1", num: 1, f: 1.1, date: new Date(2001, 10, 1) },
// { key: "e", value: "E5", num: 5, f: 5.5, date: new Date(2001, 5, 5) },
// { key: "c", value: "C3", num: 3, f: 3.3, date: new Date(2001, 3, 3) }
// ];
// // let result = dataSet.index("key", "d");
// //dataSet = dataSet.orderBy("date");
// dataSet = dataSet.orderByDesc("date");
// console.log(result);
// console.log(dataSet);
gantt1.Invalidate();
console.log(gantt1.ExportTasks());
</script>

View File

@ -62,22 +62,6 @@ class RyzGantt {
};
}
get ExportTasks() {
const a = this;
let result = [];
a.#exportTasks(result, a.Tasks.copy());
for (var i=0; i<result.length; i++) {
result[i].Order = (i + 1);
delete result[i].Tasks;
}
return result;
}
AddTask(task) {
const a = this;
@ -113,6 +97,22 @@ class RyzGantt {
a.Tasks = [];
}
ExportTasks() {
const a = this;
let result = [];
a.#exportTasks(result, a.Tasks.copy());
for (var i=0; i<result.length; i++) {
result[i].Order = (i + 1);
delete result[i].Tasks;
}
return result;
}
FindTask(id) {
const a = this;
@ -171,97 +171,20 @@ class RyzGantt {
return 0;
}
InvalidateTasks() {
Invalidate() {
const a = this;
let isSuccess = false;
// a.#log(a.Tasks.copy());
if (!a.Recalc()) {
isSuccess = false;
}
a.Recalc();
// a.#log(a.Tasks.copy());
// return;
// a.#resetTasks();
// console.log("Original");
// console.log(a.Tasks.copy());
// // Get root nodes
// let nodes = a.Tasks.selectMany(
// { propName: "DependsOnTaskID", value: null },
// { propName: "CollatedTaskID", value: null }
// );
// nodes.orderBy("StartDelay");
// a.Tasks.removeRange(nodes);
// console.log("Root");
// console.log(a.Tasks.copy());
// console.log(nodes.copy());
// //
// for (let i=(nodes.length - 1); i>=0; i--) {
// // Find dependent tasks
// let foundNodes = a.Tasks.select("DependsOnTaskID", nodes[i].ID);
// foundNodes.forEach(e => {
// nodes.insert((i + 1), e);
// });
// a.Tasks.removeRange(foundNodes);
// // Add child tasks
// if (nodes[i].IsCollated == true) {
// foundNodes = a.Tasks.select("CollatedTaskID", nodes[i].ID);
// foundNodes.forEach(e => {
// nodes.insert((i + 1), e);
// });
// a.Tasks.removeRange(foundNodes);
// }
// }
// // console.log(a.Tasks.copy());
// // a.Tasks = a.#findTasksL0(a.Tasks);
// console.log("Final");
// console.log(a.Tasks.copy());
// console.log(nodes.copy());
return isSuccess;
}
// #popL0Tasks(array) {
// const a = this;
// let nodes = array.selectMany(
// { propName: "DependsOnTaskID", value: null },
// { propName: "CollatedTaskID", value: null }
// );
// nodes = nodes.orderBy("StartDelay");
// array.removeRange(nodes);
// return nodes;
// }
// #addTasks(sourceTasksArray, targetTasksArray, index) {
// const a = this;
// const nodes = sourceTasksArray.select("DependsOnTaskID", targetTasksArray[index].ID);
// for (let i=0; i<nodes.length; i++) {
// targetTasksArray.insert((index + 1), nodes[i]);
// }
// sourceTasksArray.removeRange(nodes);
// }
Recalc() {
const a = this;
let isSuccess = false;
a.Sort();
@ -277,42 +200,87 @@ class RyzGantt {
result[i].CalcWorkHours = null;
}
for (var i=0; i<result.length; i++) {
const nodeType = a.GetNodeType(result[i]);
// Maximum 128 rounds
for (var x=0; x<128; x++) {
let pendingCount = result.copy().countMany(
{ propName: "StartDate", value: null },
{ propName: "FinishDate", value: null }
);
switch (nodeType) {
case 1: // task no-parent/root
result[i].StartDate = Date.addDays(a.Project.StartDate, result[i].StartDelay);
result[i].FinishDate = Date.addDays(result[i].StartDate, result[i].Duration);
break;
case 2: // task no-parent/root, collated/group
break;
case 3: // task with parent
const node = result.first("ID", result[i].DependsOnTaskID);
if (node != null) {
if (node.FinishDate != null) {
result[i].StartDate = Date.addDays(node.FinishDate, result[i].StartDelay);
result[i].FinishDate = Date.addDays(result[i].StartDate, result[i].Duration);
}
}
break;
case 4: // task with parent, collated/group
break;
case 5: // sub-task
break;
case 6: // sub-task, collated/group
break;
default: // orphan
break;
// Done
if (pendingCount <= 0) {
isSuccess = true;
break;
}
a.#log("Round " + (x + 1));
for (var i=0; i<result.length; i++) {
const nodeType = a.GetNodeType(result[i]);
switch (nodeType) {
case 1: // task no-parent/root
result[i].StartDate = Date.addDays(a.Project.StartDate, result[i].StartDelay);
result[i].FinishDate = Date.addDays(result[i].StartDate, result[i].Duration);
break;
case 2: // task no-parent/root, collated/group
result[i].StartDate = Date.addDays(a.Project.StartDate, result[i].StartDelay);
// update finish date, if possible
result[i].FinishDate = a.#calcCollatedFinishDate(result, i);
break;
case 3: // task with parent
const node3 = result.first("ID", result[i].DependsOnTaskID);
if (node3 != null) {
if (node3.FinishDate != null) {
result[i].StartDate = Date.addDays(node3.FinishDate, result[i].StartDelay);
result[i].FinishDate = Date.addDays(result[i].StartDate, result[i].Duration);
}
}
break;
case 4: // task with parent, collated/group
const node4 = result.first("ID", result[i].DependsOnTaskID);
if (node4 != null) {
if (node4.FinishDate != null) {
result[i].StartDate = Date.addDays(node4.FinishDate, result[i].StartDelay);
// update finish date, if possible
result[i].FinishDate = a.#calcCollatedFinishDate(result, i);
}
}
break;
case 5: // sub-task
const node5 = result.first("ID", result[i].CollatedTaskID);
if (node5 != null) {
if (node5.StartDate != null) {
result[i].StartDate = Date.addDays(node5.StartDate, result[i].StartDelay);
result[i].FinishDate = Date.addDays(result[i].StartDate, result[i].Duration);
}
}
break;
case 6: // sub-task, collated/group
const node6 = result.first("ID", result[i].CollatedTaskID);
if (node6 != null) {
if (node6.StartDate != null) {
result[i].StartDate = Date.addDays(node6.StartDate, result[i].StartDelay);
// update finish date, if possible
result[i].FinishDate = a.#calcCollatedFinishDate(result, i);
}
}
break;
default: // orphan
break;
}
}
}
// a.#resetTasks(a.Tasks);
// a.#recalcTasks(a.Project.StartDate, a.Tasks);
return isSuccess;
}
Sort() {
@ -322,6 +290,28 @@ class RyzGantt {
}
#calcCollatedFinishDate(array, index) {
let node2 = array.select("CollatedTaskID", array[index].ID);
if (node2.length <= 0) {
// No children
return new Date(array[index].StartDate);
}
// Not ready, calculation pending
if (node2.any("FinishDate", null)) {
return null;
}
let node2FinishDate = new Date(array[index].StartDate);
node2.forEach(e => {
if (e.FinishDate > node2FinishDate) {
node2FinishDate = e.FinishDate;
}
});
return new Date(node2FinishDate);
}
#exportTasks(outputArray, array) {
const a = this;
@ -338,50 +328,6 @@ class RyzGantt {
console.log(message);
}
// #recalcTasks(startDate, array) {
// const a = this;
// for (let i=0; i<array.length; i++) {
// array[i].Order = null;
// array[i].StartDate = Date.addDays(startDate, array[i].StartDelay);
// array[i].FinishDate = null;
// // array[i].CalcWorkHours = null;
// if (array[i].IsCollated == true) {
// if (array[i].Tasks.length > 0) {
// a.#recalcTasks(array[i].StartDate, array[i].Tasks);
// }
// } else {
// array[i].FinishDate = Date.addDays(array[i].StartDate, array[i].Duration);
// if (array[i].Tasks.length > 0) {
// a.#recalcTasks(array[i].FinishDate, array[i].Tasks);
// }
// }
// // if (array[i].Tasks.length > 0) {
// // a.#recalcTasks(array[i].StartDate, array[i].Tasks);
// // }
// }
// }
// #resetTasks(array) {
// const a = this;
// for (let i=0; i<array.length; i++) {
// array[i].Order = null;
// array[i].StartDate = null;
// array[i].FinishDate = null;
// array[i].CalcWorkHours = null;
// if (array[i].Tasks.length > 0) {
// a.#resetTasks(array[i].Tasks);
// }
// }
// }
#searchForTaskID(array, id) {
const a = this;
@ -415,7 +361,4 @@ class RyzGantt {
}
}
}

View File

@ -10,10 +10,40 @@ Array.prototype.addRange = function (array) {
return this;
};
Array.prototype.any = function (propName, value) {
return (this.count(propName, value) > 0);
};
Array.prototype.copy = function () {
return JSON.parse(JSON.stringify(this));
};
Array.prototype.count = function (propName, value) {
let result = 0;
for (let i = 0; i < this.length; i++) {
if (typeof(this[i][propName]) == "undefined") {
continue;
}
if (this[i][propName] == value){
result++;
}
}
return result;
};
Array.prototype.countMany = function (...filters) {
let result = 0;
filters.forEach(e => {
result += this.count(e.propName, e.value);
});
return result;
};
Array.prototype.index = function (propName, value) {
for (let i = 0; i < this.length; i++) {
if (typeof(this[i][propName]) == "undefined") {