2023-05-16 10:50:42 +08:00

380 lines
14 KiB
PHP

<?php include $app->getModuleRoot() . 'common/view/gantt.html.php';?>
<style>
#mainContent:before {background: #fff;}
#ganttView .gantt_layout_cell {min-width: 560px!important;}
.gantt-fullscreen #header,
.gantt-fullscreen #mainMenu,
.gantt-fullscreen #footer {display: none!important;}
.gantt-fullscreen #mainContent {position: fixed; top: 0; right: 0; bottom: 0; left: 0}
.gantt_task_content{display: none;}
</style>
<div id='mainContent' class='main-content load-indicator' data-loading='<?php echo $lang->review->exporting;?>'>
<div id='ganttContainer'>
<div class='gantt' id='ganttView'></div>
</div>
</div>
<script>
var scriptLoadedMap = {};
var loadingPrefixText = '<?php echo $lang->review->exporting;?>';
function getRemoteScript(url, sucessCallback, errorCallback)
{
if(scriptLoadedMap[url]) return sucessCallback && sucessCallback();
$.getScript(url, function()
{
scriptLoadedMap[url] = true;
if(sucessCallback) sucessCallback();
}).fail(function()
{
if(errorCallback) errorCallback('Cannot load "' + url + '".');
});
}
function updateProgress(progress)
{
var progressText = loadingPrefixText;
if(progress < 1) progressText += Math.floor(progress * 100) + '%';
$('#mainContent').attr('data-loading', progressText);
}
function drawGanttToCanvas(exportType, sucessCallback, errorCallback)
{
updateProgress(0);
exportType = exportType || 'image';
var $ganttView = $('#ganttView');
var oldHeight = $ganttView.css('height');
var $ganttContainer = $('#ganttContainer');
var $ganttDataArea = $ganttView.find('.gantt_data_area');
var $ganttDridData = $ganttView.find('.gantt_grid_data');
var ganttHeight = $ganttView.find('.gantt_task_bg').outerHeight() + $ganttView.find('.gantt_grid_scale').outerHeight() + 1;
var ganttWidth = $ganttDataArea.outerWidth() + $ganttDridData.outerWidth();
$ganttContainer.css(
{
height: ganttHeight + $('#ganttHeader').outerHeight() + 80,
width: ganttWidth + 93
});
$ganttView.css('height', ganttHeight);
gantt.render();
updateProgress(0.1);
getRemoteScript('<?php echo $jsRoot . 'html2canvas/min.js';?>', function()
{
updateProgress(0.2);
var afterFinish = function(canvas)
{
$ganttContainer.css(
{
width: '',
height: ''
});
$ganttView.css('height', oldHeight);
if(canvas) canvas.remove();
};
var delayTime = Math.max(1000, Math.floor(10 * (ganttHeight * ganttWidth) / 100000));
var progressTimer;
if(delayTime > 1500)
{
var startProgress = 0.2;
var deltaProgress = 0.5 / Math.floor(delayTime/1000);
progressTimer = setInterval(function()
{
startProgress += deltaProgress;
updateProgress(Math.min(0.7, startProgress));
}, 1000);
}
setTimeout(function()
{
if(progressTimer) clearInterval(progressTimer);
updateProgress(0.7);
html2canvas($ganttContainer[0], {logging: false}).then(function(canvas)
{
var isExportPDF = exportType === 'pdf';
updateProgress(isExportPDF ? 0.8 : 0.9);
canvas.onerror = function()
{
afterFinish(canvas);
if(errorCallback) errorCallback('Cannot convert image to blob.');
};
if(isExportPDF)
{
var width = canvas.width;
var height = canvas.height;
getRemoteScript('<?php echo $jsRoot . 'pdfjs/min.js';?>', function()
{
updateProgress(0.8);
var pdf = new jsPDF(
{
format: [width, height],
unit: 'px',
orientation: width > height ? 'l' : 'p'
});
pdf.addImage(canvas, 0, 0, pdf.internal.pageSize.getWidth(), pdf.internal.pageSize.getHeight());
pdf.save('gantt-export-<?php echo $review->project;?>.pdf');
if(sucessCallback) sucessCallback(pdf);
afterFinish();
}, function(error)
{
afterFinish(canvas);
if(errorCallback) errorCallback(error);
});
}
else
{
canvas.toBlob(function(blob)
{
updateProgress(0.95);
var imageUrl = URL.createObjectURL(blob);
if(navigator.msSaveBlob)
{
navigator.msSaveOrOpenBlob(blob, 'gantt.png');
}
else
{
$('#ganttDownload').attr({href: imageUrl})[0].click();
}
if(sucessCallback) sucessCallback(imageUrl);
afterFinish(canvas);
});
}
}).catch(function(error)
{
afterFinish();
if(errorCallback) errorCallback('Cannot draw graphic to canvas.');
});
}, delayTime);
}, errorCallback);
}
function exportGantt(exportType)
{
var $mainContent = $('#mainContent');
$mainContent.addClass('loading').css('height', Math.max(200, Math.floor($(window).height() - $('#footer').outerHeight() - $('#header').outerHeight() - $('#mainMenu').outerHeight() - 38)));
$('#ganttExportDate').text(new Date().format('yyyy-MM-dd hh:mm:ss'));
var afterFinish = function(url)
{
setTimeout(function()
{
$mainContent.css('height', '').removeClass('loading');
}, 300);
updateProgress(1);
};
drawGanttToCanvas(exportType, afterFinish, function(errorText)
{
afterFinish();
$.zui.messager.danger('<?php echo $lang->execution->gantt->exportFail;?>' + (errorText || ''));
});
}
function getByIdForGantt(list, id)
{
for (var i = 0; i < list.length; i++)
{
if (list[i].key == id) return list[i].label || "";
}
return "";
}
function zoomTasks(node)
{
switch(node.value)
{
case "day":
gantt.config.min_column_width = 70;
gantt.config.scales = [{unit: 'day', step: 1, format: '%m-%d'}];
gantt.config.scale_height = 35;
break;
case "week":
gantt.config.min_column_width = 70;
gantt.config.scales = [{unit: 'week', step: 1, format: "<?php echo $lang->execution->gantt->zooming['week'];?> #%W"}, {unit:"day", step:1, date:"%D"}]
gantt.config.scale_height = 60;
break;
case "month":
gantt.config.min_column_width = 70;
gantt.config.scale_height = 60;
gantt.config.scales = [{unit: 'month', step: 1, format: '%M'}, {unit:"week", step:1, date:"<?php echo $lang->execution->gantt->zooming['week'];?> #%W"}];
break;
}
gantt.render();
}
function updateCriticalPath()
{
gantt.config.highlight_critical_path = !gantt.config.highlight_critical_path;
if(gantt.config.highlight_critical_path)
{
$('#criticalPath').html(<?php echo json_encode($lang->execution->gantt->hideCriticalPath);?>);
gantt.config.highlight_critical_path = true;
}
else
{
$('#criticalPath').html(<?php echo json_encode($lang->execution->gantt->showCriticalPath);?>);
gantt.config.highlight_critical_path = false;
}
gantt.render();
}
function exitHandler()
{
if (!document.fullscreenElement && !document.webkitIsFullScreen && !document.mozFullScreen && !document.msFullscreenElement) {
location.reload();
}
}
$(function()
{
document.addEventListener('fullscreenchange', exitHandler);
var layout = '';
// Set gantt view height
var resizeGanttView = function()
{
if(gantt.getState().fullscreen) return false;
$('#ganttView').css('height', Math.max(200, Math.floor($(window).height() - $('#footer').outerHeight() - $('#header').outerHeight() - $('#mainMenu').outerHeight() - 100)));
};
var ganttData = $.parseJSON(<?php echo json_encode(json_encode($plans));?>);
if(!ganttData.data) ganttData.data = [];
gantt.config.readonly = true;
gantt.config.row_height = 25;
gantt.config.min_column_width = 40;
gantt.config.details_on_create = false;
gantt.config.scales = [{unit: 'day', step: 1, format: '%m-%d'}];
gantt.config.duration_unit = "day";
gantt.config.columns = [
{name: 'text', width: '*', tree: true, resize: true, width:200},
{name: 'start_date', align: 'center', resize: true, width: 80},
{name: 'deadline', align: 'center', resize: true, width: 80},
{name: 'duration', align: 'center', resize: true, width: 60},
{name: 'percent', align: 'center', resize: true, width:70, template: function(plan)
{
if(plan.percent) return Math.round(plan.percent) + '%';
}
},
{name: 'taskProgress', align: 'center', resize: true, width: 60},
{name: 'realStarted', align: 'center', resize: true, width: 80},
{name: 'realFinished', align: 'center', width: 80}
];
layout = gantt.config.layout;
gantt.config.layout = {
css: "gantt_container",
cols: [
{
rows:[
{view: "grid", scrollX: "gridScroll", scrollable: true, scrollY: "scrollVer"},
{view: "scrollbar", id: "gridScroll", group:"horizontal"}
]
}
]
};
gantt.locale.labels.column_text = "<?php echo $lang->programplan->name;?>";
gantt.locale.labels.column_percent = "<?php echo $lang->programplan->percentAB;?>";
gantt.locale.labels.column_taskProgress = "<?php echo $lang->programplan->taskProgress;?>";
gantt.locale.labels.column_start_date = "<?php echo $lang->programplan->begin;?>";
gantt.locale.labels.column_deadline = "<?php echo $lang->programplan->end;?>";
gantt.locale.labels.column_realStarted = "<?php echo $lang->programplan->realBegan;?>";
gantt.locale.labels.column_realFinished = "<?php echo $lang->programplan->realEnd;?>";
gantt.locale.labels.column_duration = "<?php echo $lang->programplan->duration;?>";
var date2Str = gantt.date.date_to_str(gantt.config.task_date);
var today = new Date();
var todayTips = "<?php echo $lang->programplan->today;?>";
gantt.addMarker({
start_date: today,
css: "today",
text: todayTips,
title: todayTips + ": " + date2Str(today)
});
gantt.templates.scale_cell_class = function(date)
{
if(date.getDay() == 0 || date.getDay() == 6) return 'weekend';
};
gantt.templates.timeline_cell_class = function(item, date)
{
if(date.getDay() == 0 || date.getDay() == 6) return 'weekend';
};
gantt.attachEvent('onTemplatesReady', function()
{
$('#fullScreenBtn').click(function()
{
gantt.config.layout = layout;
gantt.init('ganttView');
gantt.expand();
});
});
var isGanttExpand = false;
var delayTimer = null;
var handleFullscreen = function()
{
if(isGanttExpand)
{
$('body').addClass('gantt-fullscreen');
$('#ganttView').css('height', $(window).height() - 40);
isGanttExpand = false;
}
else
{
$('body').removeClass('gantt-fullscreen');
resizeGanttView();
}
delayTimer = null;
};
var delayHandleFullscreen = function()
{
if(delayTimer) clearTimeout(delayTimer);
delayTimer = setTimeout(handleFullscreen, 50);
};
gantt.attachEvent('onBeforeExpand', function()
{
$('body').addClass('gantt-fullscreen');
isGanttExpand = true;
return true;
});
if(document.addEventListener)
{
document.addEventListener('webkitfullscreenchange', delayHandleFullscreen, false);
document.addEventListener('mozfullscreenchange', delayHandleFullscreen, false);
document.addEventListener('fullscreenchange', delayHandleFullscreen, false);
document.addEventListener('MSFullscreenChange', delayHandleFullscreen, false);
}
resizeGanttView();
$(window).resize(resizeGanttView);
gantt.templates.grid_folder = function(item) {
return "";
};
gantt.templates.grid_file = function(item) {
return "";
};
gantt.init('ganttView');
gantt.parse(ganttData);
gantt.showDate(new Date());
// Show task in modal on click task
var taskModalTrigger = new $.zui.ModalTrigger({type: 'iframe', width: '80%'});
gantt.attachEvent('onTaskClick', function(id, e)
{
if($(e.srcElement).hasClass('gantt_close') || $(e.srcElement).hasClass('gantt_open')) return false;
if(typeof id === 'string') id = parseInt(id);
if(!isNaN(id) && id > 0)
{
//taskModalTrigger.show({url: createLink('task', 'view', 'taskID=' + id, 'html', true)});
}
});
// Make folder can open or close by click
$('#ganttView').on('click', '.gantt_close,.gantt_open', function()
{
var $task = $(this).closest('.gantt_row_task');
var task = gantt.getTask($task.attr('task_id'));
if(task) gantt[task.$open ? 'close' : 'open'](task.id);
});
});
</script>