You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
279 lines
7.4 KiB
279 lines
7.4 KiB
var overlayControl = gantt.ext.overlay; |
|
var today = new Date(); |
|
var return_first; |
|
var parts = []; |
|
|
|
var sCurvePayload = { |
|
period: 'week', |
|
project_id: proyekId, |
|
gantt_id: ganttId |
|
}; |
|
|
|
function callback(response) { |
|
return_first = response; |
|
} |
|
|
|
function getSCurveData(){ |
|
|
|
// Send a message to the parent window requesting the URL |
|
window.parent.postMessage({ action: 'getUrl' }, '*'); |
|
|
|
// Listen for messages from the parent window |
|
window.addEventListener('message', function(event) { |
|
if (event.data && event.data.action === 'sendUrl') { |
|
const parentUrl = event.data.url; |
|
|
|
// Remove the base URL and hash |
|
const path = parentUrl.replace("https://adw.ospro.id/#/dashboard-project/", ""); |
|
|
|
// Split the remaining path by "/" |
|
parts = path.split("/"); |
|
if (parts[2] && parts[2] == "1") { |
|
$.ajax({ |
|
headers: { |
|
"Content-Type": "application/json", |
|
"Authorization": `Bearer ${token}` |
|
}, |
|
url: `${base_url}project/calculate-s-curve`, |
|
type: "POST", |
|
data:JSON.stringify(sCurvePayload), |
|
success: function (data) { |
|
callback(data) |
|
} |
|
}); |
|
$.ajax({ |
|
headers: { |
|
"Content-Type": "application/json", |
|
"Authorization": `Bearer ${token}` |
|
}, |
|
url: `${base_url}project/s-curve-command`, |
|
type: "POST", |
|
data:JSON.stringify(sCurvePayload), |
|
}); |
|
} else { |
|
$.ajax({ |
|
headers: { |
|
"Content-Type": "application/json", |
|
"Authorization": `Bearer ${token}` |
|
}, |
|
url: `${base_url}project/get-s-curve`, |
|
type: "POST", |
|
data:JSON.stringify(sCurvePayload), |
|
success: function (data) { |
|
callback(data) |
|
} |
|
}); |
|
} |
|
} |
|
}); |
|
}; |
|
|
|
function toggleOverlay() { |
|
if(overlayControl.isOverlayVisible(lineOverlay)){ |
|
gantt.config.readonly = false; |
|
overlayControl.hideOverlay(lineOverlay); |
|
gantt.$root.classList.remove("overlay_visible"); |
|
}else{ |
|
gantt.config.readonly = true; |
|
overlayControl.showOverlay(lineOverlay); |
|
gantt.$root.classList.add("overlay_visible"); |
|
} |
|
} |
|
|
|
function getChartScaleRange(){ |
|
var tasksRange = gantt.getSubtaskDates(); |
|
var cells = []; |
|
var scale = gantt.getScale(); |
|
if(!tasksRange.start_date){ |
|
return scale.trace_x; |
|
} |
|
|
|
scale.trace_x.forEach(function(date){ |
|
// if(date >= tasksRange.start_date && date <= tasksRange.end_date){ |
|
// cells.push(date); |
|
// } |
|
cells.push(date); |
|
}); |
|
return cells; |
|
} |
|
|
|
function getProgressLine(){ |
|
// As long as the progress data length is same with chart scale range (period) then it's fine. |
|
getSCurveData(); |
|
var cumulativePlannedDurations = return_first.data[0].data.percentagePlan; |
|
var cumulativeRealDurations = return_first.data[0].data.percentageReal; |
|
var maxPlan = cumulativePlannedDurations[cumulativePlannedDurations.length - 1] |
|
var maxReal = cumulativeRealDurations[cumulativeRealDurations.length - 1] |
|
var dates = return_first.data[0].data.date; |
|
if (maxReal > 100 || maxPlan > 100) { |
|
var plannedDurations = cumulativePlannedDurations.map((item) => { |
|
return item/maxPlan*100; |
|
}) |
|
var realDurations = cumulativeRealDurations.map((item) => { |
|
return item/maxPlan*100; |
|
}) |
|
return {planned: plannedDurations, real: realDurations, dates: dates}; |
|
} |
|
|
|
return {planned: cumulativePlannedDurations, real: cumulativeRealDurations, dates: dates}; |
|
} |
|
|
|
function getScalePaddings(){ |
|
var scale = gantt.getScale(); |
|
var dataRange = gantt.getSubtaskDates(); |
|
let minDate = new Date(); |
|
let maxDate = new Date(); |
|
|
|
gantt.eachTask(function(task){ |
|
let plannedEarlier = task.planned_start < task.start_date; |
|
let plannedLater = task.planned_end > task.end_date; |
|
|
|
if (plannedEarlier) { |
|
minDate = new Date(Math.min(minDate.getTime(), task.planned_start.getTime())); |
|
} else { |
|
minDate = new Date(Math.min(minDate.getTime(), task.start_date.getTime())); |
|
} |
|
|
|
if (plannedLater) { |
|
maxDate = new Date(Math.max(maxDate.getTime(), task.planned_end.getTime())); |
|
} else { |
|
maxDate = new Date(Math.max(maxDate.getTime(), task.end_date.getTime())); |
|
} |
|
}) |
|
|
|
var padding = { |
|
left:0, |
|
right:0 |
|
}; |
|
|
|
if(dataRange.start_date){ |
|
var yScaleLabelsWidth = 48; |
|
// fine tune values in order to align chart with the scale range |
|
padding.left = gantt.posFromDate(minDate) - yScaleLabelsWidth; |
|
padding.right = scale.full_width - gantt.posFromDate(maxDate) - yScaleLabelsWidth; |
|
padding.top = gantt.config.row_height - 12; |
|
padding.bottom = gantt.config.row_height - 12; |
|
} |
|
return padding; |
|
} |
|
|
|
var myChart; |
|
var lineOverlay = overlayControl.addOverlay(function(container) { |
|
var values = getProgressLine(); |
|
var scaleLabels = []; |
|
|
|
// if(parts[2] && parts[2] == '1'){ |
|
// values.dates.forEach(function(date){ |
|
// var dateScale = new Date(date); |
|
// scaleLabels.push(dateToStr(dateScale)); |
|
// }) |
|
// } else { |
|
// var chartScale = getChartScaleRange(); |
|
|
|
// chartScale.forEach(function(date){ |
|
// scaleLabels.push(dateToStr(date)); |
|
// }); |
|
// } |
|
values.dates.forEach(function(date){ |
|
var dateScale = new Date(date); |
|
scaleLabels.push(dateToStr(dateScale)); |
|
}) |
|
var canvas = document.createElement("canvas"); |
|
container.appendChild(canvas); |
|
canvas.style.height = container.offsetHeight + "px"; |
|
canvas.style.width = container.offsetWidth + "px"; |
|
|
|
var ctx = canvas.getContext("2d"); |
|
if(myChart){ |
|
myChart.destroy(); |
|
} |
|
myChart = new Chart(ctx, { |
|
type: "line", |
|
data: { |
|
datasets: [ |
|
{ |
|
label: "Planned progress", |
|
backgroundColor: "#0000cc", |
|
borderColor: "#0000cc", |
|
data: values.planned, |
|
fill: false, |
|
cubicInterpolationMode: 'monotone' |
|
}, |
|
{ |
|
label: "Real progress", |
|
backgroundColor: "#006600", |
|
borderColor: "#006600", |
|
data: values.real, |
|
fill: false, |
|
cubicInterpolationMode: 'monotone' |
|
} |
|
] |
|
}, |
|
options: { |
|
responsive: true, |
|
maintainAspectRatio: false, |
|
layout: { |
|
padding: getScalePaddings() |
|
}, |
|
onResize: function(chart, newSize) { |
|
var dataRange = gantt.getSubtaskDates(); |
|
if(dataRange.start_date){ |
|
// align chart with the scale range |
|
chart.options.layout.padding = getScalePaddings(); |
|
} |
|
}, |
|
legend: { |
|
display: false |
|
}, |
|
tooltips: { |
|
mode: "index", |
|
intersect: false, |
|
callbacks: { |
|
label: function(tooltipItem, data) { |
|
var dataset = data.datasets[tooltipItem.datasetIndex]; |
|
return dataset.label + ": " + dataset.data[tooltipItem.index] + "%"; |
|
} |
|
} |
|
}, |
|
hover: { |
|
mode: "nearest", |
|
intersect: true |
|
}, |
|
scales: { |
|
xAxes: [{ |
|
labels: scaleLabels, |
|
gridLines:{ |
|
display: false |
|
}, |
|
ticks: { |
|
display: false |
|
} |
|
}, |
|
{ |
|
position:"top", |
|
labels: scaleLabels, |
|
gridLines:{ |
|
display: false |
|
}, |
|
ticks: { |
|
display: false |
|
} |
|
} |
|
], |
|
yAxes: [{ |
|
display: true, |
|
gridLines: { |
|
display:false |
|
}, |
|
ticks: { |
|
display: true, |
|
min: 0, |
|
stepSize: 10, |
|
} |
|
}, |
|
] |
|
} |
|
} |
|
}); |
|
return canvas; |
|
});
|
|
|