parent
2a8264b675
commit
fc4f172e15
|
@ -0,0 +1,101 @@
|
|||
Canvas = {};
|
||||
|
||||
|
||||
Canvas.create = function (el) {
|
||||
el.innerHTML = "<canvas></canvas>";
|
||||
|
||||
const canvas = el.getElementsByTagName("canvas")[0];
|
||||
const width = (el.innerWidth || el.clientWidth);
|
||||
const height = (el.innerHeight || el.clientHeight);
|
||||
|
||||
canvas.style.width = width + "px";
|
||||
canvas.style.height = height + "px";
|
||||
|
||||
const ctx = canvas.getContext("2d");
|
||||
ctx.canvas.width = width;
|
||||
ctx.canvas.height = height;
|
||||
|
||||
return ctx;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
class RyzCanvas {
|
||||
constructor(el) {
|
||||
const a = this;
|
||||
|
||||
a.Container = el;
|
||||
a.CTX = Canvas.create(el);
|
||||
a.Padding = {
|
||||
Top: 0,
|
||||
Right: 0,
|
||||
Bottom: 0,
|
||||
Left: 0
|
||||
};
|
||||
|
||||
a.Clear();
|
||||
}
|
||||
|
||||
|
||||
get Width() {
|
||||
return this.CTX.canvas.width;
|
||||
}
|
||||
|
||||
get Height() {
|
||||
return this.CTX.canvas.height;
|
||||
}
|
||||
|
||||
get Rectangle() {
|
||||
return {
|
||||
X: this.Padding.Left,
|
||||
Y: this.Padding.Top,
|
||||
W: (this.Width - (this.Padding.Left + this.Padding.Right)),
|
||||
H: (this.Height - (this.Padding.Top + this.Padding.Bottom))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Clear() {
|
||||
const a = this;
|
||||
|
||||
a.CTX.clearRect(0, 0, a.CTX.canvas.width, a.CTX.canvas.height);
|
||||
}
|
||||
|
||||
DrawRectangle(rectangle, penColour, penWidth) {
|
||||
const a = this;
|
||||
|
||||
// Adjust for pen discrepancy
|
||||
rectangle.X += 0.5;
|
||||
rectangle.Y += 0.5;
|
||||
rectangle.W -= penWidth;
|
||||
rectangle.H -= penWidth;
|
||||
|
||||
a.CTX.beginPath();
|
||||
a.CTX.strokeStyle = penColour;
|
||||
a.CTX.lineWidth = penWidth;
|
||||
a.CTX.rect(rectangle.X, rectangle.Y, rectangle.W, rectangle.H);
|
||||
|
||||
//a.ctx.fillStyle = 'yellow';
|
||||
//a.ctx.fill();
|
||||
a.CTX.stroke();
|
||||
|
||||
return rectangle;
|
||||
}
|
||||
|
||||
MeasureText(font, value) {
|
||||
const a = this;
|
||||
|
||||
a.CTX.font = font;
|
||||
const size = a.CTX.measureText(value);
|
||||
|
||||
return {
|
||||
X: a.half(size.width),
|
||||
Y: a.half(size.fontBoundingBoxAscent),
|
||||
W: size.width,
|
||||
H: size.fontBoundingBoxAscent
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -22,6 +22,10 @@ Date.addYears = function (date, years) {
|
|||
return result;
|
||||
};
|
||||
|
||||
Date.diffDays = function (date1, date2) {
|
||||
return (date2.getTime() - date1.getTime()) / (1000 * 3600 * 24);
|
||||
};
|
||||
|
||||
Date.today = function () {
|
||||
let result = new Date();
|
||||
|
||||
|
|
|
@ -13,4 +13,8 @@ Math.average = function (values) {
|
|||
});
|
||||
|
||||
return Math.round(result / values.length);
|
||||
};
|
||||
|
||||
Math.half = function (value) {
|
||||
return (value / 2);
|
||||
};
|
|
@ -0,0 +1,96 @@
|
|||
class Rectangle {
|
||||
constructor(x, y, w, h) {
|
||||
this.X = x;
|
||||
this.Y = y;
|
||||
this.W = w;
|
||||
this.H = h;
|
||||
}
|
||||
|
||||
static containsPoint(rectangle, point) {
|
||||
const x2 = (rectangle.X + rectangle.W);
|
||||
const y2 = (rectangle.Y + rectangle.H);
|
||||
|
||||
return ((point.X >= rectangle.X) && (point.X <= x2) && (point.Y >= rectangle.Y) && (point.Y <= y2));
|
||||
}
|
||||
|
||||
static combine(rect1, rect2) {
|
||||
const x2 = Math.max((rect1.X + rect1.W), (rect2.X + rect2.W));
|
||||
const y2 = Math.max((rect1.Y + rect1.H), (rect2.Y + rect2.H));
|
||||
|
||||
const rect = {
|
||||
X: Math.min(rect1.X, rect2.X),
|
||||
Y: Math.min(rect1.Y, rect2.Y),
|
||||
W: 0,
|
||||
H: 0
|
||||
};
|
||||
|
||||
rect.W = x2 - rect.X;
|
||||
rect.H = y2 - rect.Y;
|
||||
|
||||
return rect;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
// Rectangle.containsPoint = function (rectangle, point) {
|
||||
// const x2 = (rectangle.X + rectangle.W);
|
||||
// const y2 = (rectangle.Y + rectangle.H);
|
||||
|
||||
// return ((point.X >= rectangle.X) && (point.X <= x2) && (point.Y >= rectangle.Y) && (point.Y <= y2));
|
||||
// };
|
||||
|
||||
// Rectangle.combine = function(rect1, rect2) {
|
||||
// const x2 = Math.max((rect1.X + rect1.W), (rect2.X + rect2.W));
|
||||
// const y2 = Math.max((rect1.Y + rect1.H), (rect2.Y + rect2.H));
|
||||
|
||||
// const rect = {
|
||||
// X: Math.min(rect1.X, rect2.X),
|
||||
// Y: Math.min(rect1.Y, rect2.Y),
|
||||
// W: 0,
|
||||
// H: 0
|
||||
// };
|
||||
|
||||
// rect.W = x2 - rect.X;
|
||||
// rect.H = y2 - rect.Y;
|
||||
|
||||
// return rect;
|
||||
// };
|
||||
|
||||
|
||||
|
||||
|
||||
// class RyzRectangle {
|
||||
// constructor(x, y, w, h) {
|
||||
// const a = this;
|
||||
|
||||
// a.X = x;
|
||||
// a.Y = y;
|
||||
// a.W = w;
|
||||
// a.H = h;
|
||||
// }
|
||||
|
||||
|
||||
// ContainsPoint(point) {
|
||||
// const a = this;
|
||||
|
||||
// return Rectangle.containsPoint(a.ToModel, point);
|
||||
// }
|
||||
|
||||
// ToModel() {
|
||||
// const a = this;
|
||||
|
||||
// return {
|
||||
// X: a.X,
|
||||
// Y: a.Y,
|
||||
// W: a.W,
|
||||
// H: a.H
|
||||
// };
|
||||
// }
|
||||
|
||||
// ToString() {
|
||||
// const a = this;
|
||||
|
||||
// return "x = " + a.X + ", y = " + a.Y + ", w = " + a.W + ", h = " + a.H;
|
||||
// }
|
||||
|
||||
// }
|
|
@ -7,8 +7,8 @@ Array.prototype.countMany=function(...a){let b=0;a.forEach(c=>{b+=this.count(c.p
|
|||
Array.prototype.joinIfNotNullOrWhitespace=function(a){let b="";for(let c=0;c<this.length;c++)String.isNullOrWhitespace(this[c])||(String.isNullOrWhitespace(b)||(b+=a),b+=this[c]);return b};Array.prototype.first=function(a,b){for(let c=0;c<this.length;c++)if("undefined"!=typeof this[c][a]&&this[c][a]==b)return this[c];return null};Array.prototype.forEachTree=function(a,b){for(let c=0;c<this.length&&!1!==b(this[c])&&(0>=this[c][a].length||!1!==this[c][a].forEachTree(a,b));c++);};
|
||||
Array.prototype.indexes=function(a,b){let c=[];for(let d=0;d<this.length;d++)"undefined"!=typeof this[d][a]&&this[d][a]==b&&c.push(d);return c};Array.prototype.orderBy=function(a){this.sort(function(b,c){return b[a]<c[a]?-1:b[a]>c[a]?1:0});return this};Array.prototype.orderByDesc=function(a){this.sort(function(b,c){return b[a]<c[a]?1:b[a]>c[a]?-1:0});return this};
|
||||
Array.prototype.remove=function(a){let b=[];for(let c=0;c<this.length;c++)this[c]==a&&b.push(c);for(a=b.length-1;0<=a;a--)this.removeAt(b[a]);return this};Array.prototype.removeAt=function(a){if(0>a||a>=this.length)return this;this.splice(a,1);return this};Array.prototype.removeRange=function(a){for(let b=0;b<a.length;b++)this.remove(a[b]);return this};Array.prototype.select=function(a,b){let c=[];for(let d=0;d<this.length;d++)"undefined"!=typeof this[d][a]&&this[d][a]==b&&c.push(this[d]);return c};
|
||||
Array.prototype.selectMany=function(...a){let b=this;a.forEach(c=>{b=b.select(c.propName,c.value)});return b};Array.prototype.toList=function(a){let b=[];this.forEach(c=>{b.push(c[a])});return b};Array.prototype.sortTree=function(a,b){this.orderBy(b);for(let c=0;c<this.length;c++)0>=this[c][a].length||this[c][a].orderBy(b)};Boolean.isFalse=function(a){return String.isNullOrUndefined(a)?!0:a.toString().containsCI("false","f","y","0","x")};Boolean.isTrue=function(a){return String.isNullOrUndefined(a)?!1:a.toString().containsCI("true","t","n","1","o")};Boolean.ifTrue=function(a,b,c){return Boolean.isTrue(a)?b:c};Date.addDays=function(a,b){a=new Date(a);a.addDays(b);return a};Date.addMonths=function(a,b){a=new Date(a);a.addMonths(b);return a};Date.addYears=function(a,b){a=new Date(a);a.addYears(b);return a};Date.today=function(){let a=new Date;a.setHours(0);a.setMinutes(0);a.setSeconds(0);a.setMilliseconds(0);return a};Date.prototype.addDays=function(a){this.setDate(this.getDate()+parseInt(a))};Date.prototype.addMonths=function(a){this.setMonth(this.getMonth()+parseInt(a))};
|
||||
Date.prototype.addYears=function(a){this.setFullYear(this.getFullYear()+parseInt(a))};
|
||||
Array.prototype.selectMany=function(...a){let b=this;a.forEach(c=>{b=b.select(c.propName,c.value)});return b};Array.prototype.toList=function(a){let b=[];this.forEach(c=>{b.push(c[a])});return b};Array.prototype.sortTree=function(a,b){this.orderBy(b);for(let c=0;c<this.length;c++)0>=this[c][a].length||this[c][a].orderBy(b)};Boolean.isFalse=function(a){return String.isNullOrUndefined(a)?!0:a.toString().containsCI("false","f","y","0","x")};Boolean.isTrue=function(a){return String.isNullOrUndefined(a)?!1:a.toString().containsCI("true","t","n","1","o")};Boolean.ifTrue=function(a,b,c){return Boolean.isTrue(a)?b:c};Date.addDays=function(a,b){a=new Date(a);a.addDays(b);return a};Date.addMonths=function(a,b){a=new Date(a);a.addMonths(b);return a};Date.addYears=function(a,b){a=new Date(a);a.addYears(b);return a};Date.diffDays=function(a,b){return(b.getTime()-a.getTime())/864E5};Date.today=function(){let a=new Date;a.setHours(0);a.setMinutes(0);a.setSeconds(0);a.setMilliseconds(0);return a};Date.prototype.addDays=function(a){this.setDate(this.getDate()+parseInt(a))};
|
||||
Date.prototype.addMonths=function(a){this.setMonth(this.getMonth()+parseInt(a))};Date.prototype.addYears=function(a){this.setFullYear(this.getFullYear()+parseInt(a))};
|
||||
Date.prototype.toCString=function(a){a=a.replace("fffffff",this.getMilliseconds().toString().padStart(7,"0"));a=a.replace("ffffff",this.getMilliseconds().toString().padStart(6,"0"));a=a.replace("fffff",this.getMilliseconds().toString().padStart(5,"0"));a=a.replace("yyyy",this.getFullYear().toString().padStart(4,"0"));a=a.replace("MMMM","{1}");a=a.replace("dddd","{2}");a=a.replace("ffff",this.getMilliseconds().toString().padStart(4,"0"));a=a.replace("yyy",this.getFullYear().toString().padStart(3,"0"));
|
||||
a=a.replace("MMM","{3}");a=a.replace("ddd","{4}");a=a.replace("fff",this.getMilliseconds().toString().padStart(3,"0"));a=a.replace("zzz","");a=a.replace("yy",this.getFullYear().toString().slice(-2));a=a.replace("MM",(this.getMonth()+1).toString().padStart(2,"0"));a=a.replace("dd",this.getDate().toString().padStart(2,"0"));a=a.replace("HH",this.getHours().toString().padStart(2,"0"));a=a.replace("hh",(12<this.getHours()?this.getHours()-12:this.getHours()).toString().padStart(2,"0"));a=a.replace("mm",
|
||||
this.getMinutes().toString().padStart(2,"0"));a=a.replace("ss",this.getSeconds().toString().padStart(2,"0"));a=a.replace("ff",this.getMilliseconds().toString().padStart(2,"0"));a=a.replace("tt","{5}");a=a.replace("zz","");a=a.replace("y",this.getFullYear().toString());a=a.replace("M",(this.getMonth()+1).toString());a=a.replace("d",this.getDate().toString());a=a.replace("H",this.getHours().toString());a=a.replace("h",(12<this.getHours()?this.getHours()-12:this.getHours()).toString());a=a.replace("m",
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
<meta name="keyword" content="" />
|
||||
|
||||
<script src="ryzjsext.min.js"></script>
|
||||
<script src="javascript-extensions/ryz-js-ext-canvas.js"></script>
|
||||
<script src="javascript-extensions/ryz-js-ext-rectangle.js"></script>
|
||||
|
||||
<script src="ryzproj.js"></script>
|
||||
<link href="ryzproj.css" rel="stylesheet" />
|
||||
|
@ -21,13 +23,21 @@ body {
|
|||
font-size: 10pt;
|
||||
}
|
||||
|
||||
.row {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.column {
|
||||
flex: 50%;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<script>
|
||||
|
||||
var gantt1 = new RyzGantt({ Name: "New Project 1" });
|
||||
var project1 = new RyzProject({ Name: "New Project 1" });
|
||||
|
||||
gantt1.AddTask({
|
||||
project1.AddTask({
|
||||
ID: 1,
|
||||
Name: "Task A",
|
||||
StartDelay: 0,
|
||||
|
@ -37,7 +47,7 @@ gantt1.AddTask({
|
|||
CollatedTaskID: null
|
||||
});
|
||||
|
||||
gantt1.AddTask({
|
||||
project1.AddTask({
|
||||
ID: 2,
|
||||
Name: "Task B",
|
||||
StartDelay: 1,
|
||||
|
@ -47,7 +57,7 @@ gantt1.AddTask({
|
|||
CollatedTaskID: null
|
||||
});
|
||||
|
||||
gantt1.AddTask({
|
||||
project1.AddTask({
|
||||
ID: 5,
|
||||
Name: "Task B1",
|
||||
StartDelay: 4,
|
||||
|
@ -57,7 +67,7 @@ gantt1.AddTask({
|
|||
CollatedTaskID: null
|
||||
});
|
||||
|
||||
gantt1.AddTask({
|
||||
project1.AddTask({
|
||||
ID: 6,
|
||||
Name: "Task B11",
|
||||
StartDelay: 0,
|
||||
|
@ -67,7 +77,7 @@ gantt1.AddTask({
|
|||
CollatedTaskID: 5
|
||||
});
|
||||
|
||||
gantt1.AddTask({
|
||||
project1.AddTask({
|
||||
ID: 7,
|
||||
Name: "Task B12",
|
||||
StartDelay: 0,
|
||||
|
@ -78,7 +88,7 @@ gantt1.AddTask({
|
|||
Progress: 50
|
||||
});
|
||||
|
||||
gantt1.AddTask({
|
||||
project1.AddTask({
|
||||
ID: 8,
|
||||
Name: "Task E",
|
||||
StartDelay: 3,
|
||||
|
@ -88,7 +98,7 @@ gantt1.AddTask({
|
|||
CollatedTaskID: null
|
||||
});
|
||||
|
||||
gantt1.AddTask({
|
||||
project1.AddTask({
|
||||
ID: 9,
|
||||
Name: "Task E1",
|
||||
StartDelay: 3,
|
||||
|
@ -98,7 +108,7 @@ gantt1.AddTask({
|
|||
CollatedTaskID: 8
|
||||
});
|
||||
|
||||
gantt1.AddTask({
|
||||
project1.AddTask({
|
||||
ID: 3,
|
||||
Name: "Task C",
|
||||
StartDelay: 5,
|
||||
|
@ -108,7 +118,7 @@ gantt1.AddTask({
|
|||
CollatedTaskID: null
|
||||
});
|
||||
|
||||
gantt1.AddTask({
|
||||
project1.AddTask({
|
||||
ID: 4,
|
||||
Name: "Task D",
|
||||
StartDelay: 1,
|
||||
|
@ -118,16 +128,22 @@ gantt1.AddTask({
|
|||
CollatedTaskID: null
|
||||
});
|
||||
|
||||
gantt1.Invalidate();
|
||||
project1.Invalidate();
|
||||
|
||||
// console.log(gantt1.ExportTasks());
|
||||
|
||||
Document.ready(async function() {
|
||||
const taskGrid1 = document.getElementById("projectTaskGrid1");
|
||||
const ganttChart1 = document.getElementById("projectGanttChart1");
|
||||
|
||||
taskGrid1.innerHTML = gantt1.RenderTaskGrid();
|
||||
|
||||
console.log(new Date(gantt1.StartDate).toLocaleDateString() + " - " + new Date(gantt1.FinishDate).toLocaleDateString());
|
||||
console.log(new Date(project1.StartDate).toLocaleDateString() + " - " + new Date(project1.FinishDate).toLocaleDateString());
|
||||
|
||||
console.log(project1.Duration);
|
||||
|
||||
taskGrid1.innerHTML = project1.RenderTaskGrid();
|
||||
|
||||
project1.RenderGanttChart(ganttChart1);
|
||||
|
||||
});
|
||||
|
||||
|
@ -136,29 +152,38 @@ Document.ready(async function() {
|
|||
</head>
|
||||
<body>
|
||||
|
||||
<div>
|
||||
<table class="ryz-project">
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th></th>
|
||||
<th>Task Name</th>
|
||||
<th>Duration</th>
|
||||
<th>Start</th>
|
||||
<th>Finish</th>
|
||||
<th>Predecessor</th>
|
||||
<th>Resource Names</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="projectTaskGrid1">
|
||||
<tr>
|
||||
<td></td>
|
||||
<td colspan="8" class="c">Loading...</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="column">
|
||||
|
||||
<table class="ryz-project">
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th></th>
|
||||
<th>Task Name</th>
|
||||
<th>Duration</th>
|
||||
<th>Start</th>
|
||||
<th>Finish</th>
|
||||
<th>Predecessor</th>
|
||||
<th>Resource Names</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="projectTaskGrid1">
|
||||
<tr>
|
||||
<td></td>
|
||||
<td colspan="8" class="c">Loading...</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
<div class="column">
|
||||
|
||||
<div id="projectGanttChart1" style="width:100%; height: 100%;"></div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</body>
|
||||
|
|
|
@ -46,7 +46,10 @@
|
|||
border-style: solid;
|
||||
border-width: 0px 0px 1px 0px;
|
||||
margin: 0px;
|
||||
overflow: hidden;
|
||||
padding: 5px 5px 5px 5px;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.ryz-project tbody tr td:first-child {
|
||||
border-right-width: 1px;
|
||||
|
|
136
ryzproj.js
136
ryzproj.js
|
@ -1,4 +1,16 @@
|
|||
class RyzGantt {
|
||||
class RyzGanttChart extends RyzCanvas {
|
||||
constructor(el) {
|
||||
super(el);
|
||||
|
||||
this.Padding.Left = 3;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
class RyzProject {
|
||||
constructor(options) {
|
||||
const a = this;
|
||||
const _options = Object.assign(a.#newProject, options);
|
||||
|
@ -61,6 +73,12 @@ class RyzGantt {
|
|||
return result;
|
||||
}
|
||||
|
||||
get Duration() {
|
||||
const a = this;
|
||||
|
||||
return Date.diffDays(a.StartDate, a.FinishDate);
|
||||
}
|
||||
|
||||
|
||||
get #newProject() {
|
||||
return {
|
||||
|
@ -92,6 +110,7 @@ class RyzGantt {
|
|||
Progress: 0,
|
||||
Resources: [],
|
||||
Level: 0,
|
||||
PredecessorTaskNo: null,
|
||||
Tasks: []
|
||||
};
|
||||
}
|
||||
|
@ -270,7 +289,7 @@ class RyzGantt {
|
|||
result[i].Progress = 0;
|
||||
|
||||
// update finish date, if possible
|
||||
a.#updateCollatedTask(result, i);
|
||||
a.#recalculateCollatedTask(result, i);
|
||||
|
||||
break;
|
||||
case 3: // task with parent
|
||||
|
@ -291,7 +310,7 @@ class RyzGantt {
|
|||
result[i].Progress = 0;
|
||||
|
||||
// update finish date, if possible
|
||||
a.#updateCollatedTask(result, i);
|
||||
a.#recalculateCollatedTask(result, i);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -316,7 +335,7 @@ class RyzGantt {
|
|||
result[i].Level = (node6.Level + 1);
|
||||
|
||||
// update finish date, if possible
|
||||
a.#updateCollatedTask(result, i);
|
||||
a.#recalculateCollatedTask(result, i);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -328,29 +347,10 @@ class RyzGantt {
|
|||
}
|
||||
|
||||
// Calculate work-hours
|
||||
for (var i=0; i<result.length; i++) {
|
||||
if (result[i].StartDate == null) {
|
||||
continue;
|
||||
}
|
||||
a.#recalculateWorkHours(result);
|
||||
|
||||
if (result[i].FinishDate == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (result[i].Duration <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let workHours = 0;
|
||||
let date = new Date(result[i].StartDate);
|
||||
for (let i=0; i<result[i].Duration; i++) {
|
||||
const d = date.getDay();
|
||||
|
||||
workHours += a.Project.WorkHours[d];
|
||||
}
|
||||
|
||||
result[i].CalcWorkHours = workHours;
|
||||
}
|
||||
// Calculate predecessor
|
||||
a.#recalculatePredecessorTaskNo(result);
|
||||
|
||||
return isSuccess;
|
||||
}
|
||||
|
@ -367,14 +367,6 @@ class RyzGantt {
|
|||
|
||||
const result = a.ExportTasks();
|
||||
result.forEach(e => {
|
||||
let predecessorNo = "";
|
||||
if (e.PredecessorTaskID != null) {
|
||||
const predecessor = a.FindTask(e.PredecessorTaskID);
|
||||
if (predecessor != null) {
|
||||
predecessorNo = predecessor.Order;
|
||||
}
|
||||
}
|
||||
|
||||
if (e.IsCollated == true) {
|
||||
htmlContent += "<tr class='b'>";
|
||||
} else {
|
||||
|
@ -394,7 +386,7 @@ class RyzGantt {
|
|||
htmlContent += "<td>" + e.Duration + " day" + (parseInt(e.Duration) == 1 ? "" : "s") + "</td>";
|
||||
htmlContent += "<td class='c'>" + new Date(e.StartDate).toLocaleDateString() + "</td>";
|
||||
htmlContent += "<td class='c'>" + new Date(e.FinishDate).toLocaleDateString() + "</td>";
|
||||
htmlContent += "<td class='c'>" + predecessorNo + "</td>";
|
||||
htmlContent += "<td class='c'>" + (e.PredecessorTaskNo ?? "") + "</td>";
|
||||
htmlContent += "<td></td>";
|
||||
htmlContent += "<td></td>";
|
||||
htmlContent += "</tr>";
|
||||
|
@ -403,7 +395,71 @@ class RyzGantt {
|
|||
return htmlContent;
|
||||
}
|
||||
|
||||
#updateCollatedTask(array, index) {
|
||||
RenderGanttChart(el) {
|
||||
const a = this;
|
||||
|
||||
const ganttCanvas = new RyzGanttChart(el);
|
||||
|
||||
|
||||
ganttCanvas.DrawRectangle(ganttCanvas.Rectangle, "#B8B8B8", 1);
|
||||
|
||||
ganttCanvas.DrawRectangle({ X: 50, Y: 50, W: 100, H: 100 }, "#B8B8B8", 3);
|
||||
|
||||
// console.log(ganttCanvas.Width);
|
||||
|
||||
|
||||
}
|
||||
|
||||
#log(message) {
|
||||
console.log(message);
|
||||
}
|
||||
|
||||
#recalculateWorkHours(array) {
|
||||
const a = this;
|
||||
|
||||
for (var i=0; i<array.length; i++) {
|
||||
if (array[i].StartDate == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (array[i].FinishDate == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (array[i].Duration <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let workHours = 0;
|
||||
let date = new Date(array[i].StartDate);
|
||||
for (let i=0; i<array[i].Duration; i++) {
|
||||
const d = date.getDay();
|
||||
|
||||
workHours += a.Project.WorkHours[d];
|
||||
}
|
||||
|
||||
array[i].CalcWorkHours = workHours;
|
||||
}
|
||||
}
|
||||
|
||||
#recalculatePredecessorTaskNo(array) {
|
||||
const a = this;
|
||||
|
||||
for (var i=0; i<array.length; i++) {
|
||||
if (array[i].PredecessorTaskID == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const predecessor = a.FindTask(array[i].PredecessorTaskID);
|
||||
if (predecessor == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
array[i].PredecessorTaskNo = predecessor.Order;
|
||||
}
|
||||
}
|
||||
|
||||
#recalculateCollatedTask(array, index) {
|
||||
let node2 = array.select("CollatedTaskID", array[index].ID);
|
||||
if (node2.length <= 0) {
|
||||
// No children
|
||||
|
@ -426,8 +482,8 @@ class RyzGantt {
|
|||
array[index].FinishDate = new Date(node2FinishDate);
|
||||
}
|
||||
|
||||
#log(message) {
|
||||
console.log(message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
Loading…
Reference in New Issue