| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143 |
- $(function()
- {
- if(ganttPlans)
- {
- $('#ganttPlans .gantt-plan, #ganttContainer .gantt-row').remove();
- initWaterfallGanttBlock();
- }
- $('#ganttContainer').off('scroll').on('scroll', function(e) {
- $('#ganttPlans')[0].scrollTop = e.target.scrollTop;
- });
- });
- window.initWaterfallGanttBlock = function()
- {
- var ganttData = ganttPlans;
- if(!ganttData) return;
- var plans = [];
- var tasks = [];
- var plansMap = {};
- var startDatetime = Number.MAX_SAFE_INTEGER;
- var endDatetime = 0;
- var minTimeGap = Number.MAX_SAFE_INTEGER;
- var $gantt = $('#' + waterfallGanttID);
- var ONE_DAY = 24 * 3600 * 1000;
- var TIME_GAP_STEP = 7;
- var MIN_COL_WIDTH = 60;
- $.each(ganttData, function(index, item)
- {
- plansMap[item.id] = item;
- if(item.type == 'plan' && item.parent == '0')
- {
- item.startDatetime = createDatetime(item.start_date);
- item.endDatetime = createDatetime(item.deadline);
- startDatetime = Math.min(startDatetime, item.startDatetime);
- endDatetime = Math.max(endDatetime, item.endDatetime);
- minTimeGap = Math.min(minTimeGap, endDatetime - startDatetime);
- item.tasks = [];
- item.completeTasks = [];
- item.progress = Number.parseFloat(item.taskProgress.replace('%', ''), 10);
- plans.push(item);
- }
- else if(item.type === 'task')
- {
- item.progress = Number.parseFloat(item.taskProgress.replace('%', ''), 10);
- tasks.push(item);
- }
- });
- $.each(tasks, function(index, task)
- {
- var plan = plansMap[task.parent];
- if(typeof(plan) == 'undefined') return;
- while(plan.parent > 0)
- {
- plan = plansMap[plan.parent];
- if(typeof(plan) != 'object') return;
- }
- if(task.progress === 100) plan.completeTasks.push(task);
- plan.tasks.push(task);
- });
- var $plans = $gantt.find('.gantt-plans');
- var $ganttContainer = $gantt.find('.gantt-container');
- var $ganttCanvas = $gantt.find('.gantt-canvas');
- var themeColor = 'rgb(46, 127, 255)';
- var canvasHeight = plans.length * 50 + 10;
- var days = Math.ceil((endDatetime - startDatetime) / ONE_DAY);
- minTimeGap = Math.max(1, Math.ceil(minTimeGap / ONE_DAY));
- /* Update gantt plans and bars */
- $.each(plans, function(index, plan)
- {
- var $plan = $('<div class="gantt-plan"></div>');
- $plan.append('<div class="strong flex" title="' + plan.name + '"><div class="text-ellipsis">' + plan.name + '</div>' + (plan.milestonecode == '1' ? '<icon class="icon icon-flag icon-sm red center"></icon>' : '') + '</div>');
- $plans.append($plan);
- var $bar = $('<div class="gantt-bar"></div>');
- $('<div class="gantt-bar-progress bg-primary"></div>').css(
- {
- width: plan.progress + '%',
- background: themeColor,
- }).appendTo($bar);
- $bar.append('<div class="gantt-task-info text-muted small">' + progressLang + ' ' + plan.taskProgress + '</div>').attr('title', zui.formatDate(plan.startDatetime, 'yyyy-MM-dd') + '~' + zui.formatDate(plan.endDatetime, 'yyyy-MM-dd'));
- var $row = $('<div class="gantt-row" data-id="' + plan.id + '"></div>').append($bar);
- $ganttCanvas.append($row);
- });
- /* Layout gantt container */
- $ganttContainer.css('left', $plans.width() + 15);
- $ganttCanvas.css('height', canvasHeight);
- /* Layout gantt */
- var minWidth = $ganttContainer.width();
- var timeGap = minTimeGap < TIME_GAP_STEP ? minTimeGap : Math.floor(minTimeGap / TIME_GAP_STEP) * TIME_GAP_STEP;
- var colsCount = Math.ceil(days / timeGap);
- var canvasWidth = Math.max(minWidth, colsCount * MIN_COL_WIDTH);
- var colWidth = Math.floor(canvasWidth / colsCount);
- var pxPerMs = colWidth / (timeGap * ONE_DAY);
- $ganttCanvas.css('width', canvasWidth).find('.gantt-col').remove();
- for (var i = 0; i < colsCount; ++i)
- {
- var $col = $('<div class="gantt-col"></div>');
- $col.css(
- {
- left: i * colWidth,
- width: colWidth,
- height: canvasHeight
- });
- var colTime = startDatetime + i * timeGap * ONE_DAY;
- $col.append('<div class="gantt-col-time text-muted small">' + zui.formatDate(colTime, 'MM/dd') + '</div>');
- $ganttCanvas.append($col);
- }
- $.each(plans, function(index, plan)
- {
- var $planRow = $gantt.find('.gantt-row[data-id="' + plan.id + '"]');
- $planRow.find('.gantt-bar').css(
- {
- left: Math.floor((plan.startDatetime - startDatetime) * pxPerMs),
- width: Math.floor((plan.endDatetime - plan.startDatetime) * pxPerMs)
- });
- });
- $gantt.find('.gantt-today').css('left', (Date.now() - startDatetime) * pxPerMs);
- /**
- * Create date from string
- *
- * @param {String} dateStr like '2020-08-02'
- * @return {Number} Date timestramp
- */
- function createDatetime(dateStr)
- {
- dateStr = dateStr.split('-');
- var year = Number.parseInt(dateStr[0].length > 3 ? dateStr[0] : dateStr[2], 10);
- var month = Number.parseInt(dateStr[1], 10);
- var day = Number.parseInt(dateStr[2].length > 3 ? dateStr[0] : dateStr[2], 10);
- return new Date(year, month - 1, day).getTime();
- }
- }
|