UNPKG

jetsum_dhtmlx_gantt

Version:

An open source JavaScript Gantt chart that helps you illustrate a project schedule in a nice-looking chart.

871 lines (812 loc) 19.1 kB
<!DOCTYPE html> <head> <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <title>Assign resource values to specific days</title> <script src="../../codebase/dhtmlxgantt.js?v=7.1.9"></script> <link rel="stylesheet" href="../../codebase/dhtmlxgantt.css?v=7.1.9"> <script src="../common/resource_project_assignments.js?v=7.1.9"></script> <style> html, body { padding: 0px; margin: 0px; height: 100%; } #gantt_here { width:100%; height:100%; } .gantt_grid_scale .gantt_grid_head_cell, .gantt_task .gantt_task_scale .gantt_scale_cell { font-weight: bold; font-size: 14px; color: rgba(0, 0, 0, 0.7); } .resource_marker{ text-align: center; } .resource_marker div{ color: black; background: none; } .resource_marker.resource_cell div{ font-weight: bold; background-color: #d6d6d6; } .resource_marker.task_cell div { cursor: pointer; } .resource_marker.workday_ok div { } .resource_marker.workday_over div{ color: red; } .owner-label{ width: 20px; height: 20px; line-height: 20px; font-size: 12px; display: inline-block; border: 1px solid #cccccc; border-radius: 25px; background: #e6e6e6; color: #6f6f6f; margin: 0 3px; font-weight: bold; } </style> </head> <body> <div id="gantt_here"></div> <script> gantt.message({ text:[ "Click any cell of the <b>Interior office</b> item down in the resource panel in order to set resource values for specific days" ].join("<br><br>"), expire: -1 }); gantt.config.resource_render_empty_cells = true; gantt.config.columns = [ {name: "text", tree: true, width: 200, resize: true}, {name: "start_date", align: "center", width: 80, resize: true}, {name: "owner", align: "center", width: 75, label: "Owner", template: function (task) { if (task.type == gantt.config.types.project) { return ""; } var store = gantt.getDatastore("resource"); var assignments = gantt.getTaskAssignments(task.id); var uniqueResources = {}; var resourceCount = 0; assignments.forEach(function(a){ if(!uniqueResources[a.resource_id]){ uniqueResources[a.resource_id] = a.resource_id; resourceCount++; } }); if(!resourceCount){ return "Unassigned"; }else if(resourceCount === 1){ return store.getItem(assignments[0].resource_id).text; }else{ var result = ""; for(var i in uniqueResources){ var owner = store.getItem(uniqueResources[i]); if (!owner) continue; result += "<div class='owner-label' title='" + owner.text + "'>" + owner.text.substr(0, 1) + "</div>"; } return result; } return result; }, resize: true }, {name: "duration", width: 60, align: "center"}, {name: "add", width: 44} ]; function getResourceAssignments(resourceId) { var assignments; var store = gantt.getDatastore(gantt.config.resource_store); var resource = store.getItem(resourceId); if(resource.$role === "task"){ assignments = gantt.getResourceAssignments(resource.$resource_id, resource.$task_id); }else{ assignments = gantt.getResourceAssignments(resourceId); if(store.eachItem){ store.eachItem(function(childResource){ if(childResource.$role !== "task"){ assignments = assignments.concat(gantt.getResourceAssignments(childResource.id)); } }, resourceId); } } return assignments; } var resourceConfig = { columns: [ { name: "name", label: "Name", tree:true, template: function (resource) { return resource.text; } }, { name: "workload", label: "Workload", template: function (resource) { var totalDuration = 0; if (resource.$role === "task"){ gantt.getResourceAssignments(resource.$resource_id, resource.$task_id).forEach(function(a){ totalDuration += a.value * a.duration; }); }else{ getResourceAssignments(resource.id).forEach(function (assignment) { totalDuration += Number(assignment.value) * assignment.duration; }); } return (totalDuration || 0) + "h"; } } ] }; gantt.templates.resource_cell_class = function(start_date, end_date, resource, tasks, assignments){ var css = []; css.push("resource_marker"); if(resource.$role === "task"){ css.push("task_cell"); }else{ css.push("resource_cell"); } var sum = assignments.reduce(function(total, assignment){ return total + Number(assignment.value); }, 0); if (sum <= 8) { css.push("workday_ok"); } else { css.push("workday_over"); } return css.join(" "); }; gantt.templates.resource_cell_value = function(start_date, end_date, resource, tasks, assignments){ if(resource.$role === "task"){ if(start_date < resource.end_date && end_date > resource.start_date){ for(var i = 0; i < assignments.length; i++){ var a = assignments[i]; return "<div contenteditable data-assignment-cell data-assignment-id='"+a.id+"'"+ " data-row-id='"+resource.id+"'"+ " data-task='"+resource.$task_id+"'"+ " data-start-date='"+gantt.templates.format_date(start_date)+"'"+ " data-end-date='"+gantt.templates.format_date(end_date)+"'>" + a.value + "</div>" } return "<div contenteditable data-assignment-cell data-empty "+ " data-row-id='"+resource.id+"'"+ " data-resource-id='"+resource.$resource_id+"'"+ " data-task='"+resource.$task_id+"'"+ " data-start-date='"+gantt.templates.format_date(start_date)+"'"+ "' data-end-date='"+gantt.templates.format_date(end_date)+"'>-</div>"; } }else{ var sum = assignments.reduce(function(total, assignment){ return total + Number(assignment.value); }, 0); if(sum % 1){ sum = Math.round(sum * 10)/10; } if(sum){ return "<div>" + sum + "</div>"; } return ""; } }; gantt.attachEvent("onGanttReady", function(){ gantt.event(gantt.$container, "keypress", function(e){ var target = e.target.closest(".resourceTimeline_cell [data-assignment-cell]"); if(target){ if (e.keyCode === 13 || e.keyCode === 27) { target.blur(); } } }); gantt.event(gantt.$container, "focusout", function(e){ var target = e.target.closest(".resourceTimeline_cell [data-assignment-cell]"); if(target){ var strValue = (target.innerText || "").trim(); if(strValue == "-"){ strValue = "0"; } var value = Number(strValue); var rowId = target.getAttribute("data-row-id"); var assignmentId = target.getAttribute("data-assignment-id"); var taskId = target.getAttribute("data-task"); var resourceId = target.getAttribute("data-resource-id"); var startDate = gantt.templates.parse_date(target.getAttribute("data-start-date")); var endDate = gantt.templates.parse_date(target.getAttribute("data-end-date")); var assignmentStore = gantt.getDatastore(gantt.config.resource_assignment_store); if(isNaN(value)){ gantt.getDatastore(gantt.config.resource_store).refresh(rowId); }else{ var task = gantt.getTask(taskId); if(assignmentId){ var assignment = assignmentStore.getItem(assignmentId); if(value === assignment.value){ return; } if(assignment.start_date.valueOf() === startDate.valueOf() && assignment.end_date.valueOf() === endDate.valueOf()){ assignment.value = value; if(!value){ assignmentStore.removeItem(assignment.id); }else{ assignmentStore.updateItem(assignment.id); } } else { var prevChunk = null; if(assignment.end_date.valueOf() > endDate.valueOf()){ var nextChunk = gantt.copy(assignment); nextChunk.id = gantt.uid(); nextChunk.start_date = endDate; nextChunk.duration = gantt.calculateDuration({ start_date: nextChunk.start_date, end_date: nextChunk.end_date, task: task }); nextChunk.delay = gantt.calculateDuration({ start_date: task.start_date, end_date: nextChunk.start_date, task: task }); nextChunk.mode = assignment.mode || "default"; if(nextChunk.duration !== 0){ assignmentStore.addItem(nextChunk); } } if(assignment.start_date.valueOf() < startDate.valueOf()){ assignment.end_date = startDate; assignment.duration = gantt.calculateDuration({ start_date: assignment.start_date, end_date: assignment.end_date, task: task }); assignment.mode = "fixedDuration"; if(assignment.duration === 0){ assignmentStore.removeItem(assignment.id); }else{ assignmentStore.updateItem(assignment.id); } }else{ assignmentStore.removeItem(assignment.id); } if(value){ assignmentStore.addItem({ task_id: assignment.task_id, resource_id: assignment.resource_id, value: value, start_date: startDate, end_date: endDate, duration: gantt.calculateDuration({ start_date: startDate, end_date: endDate, task: task }), delay: gantt.calculateDuration({ start_date: task.start_date, end_date: startDate, task: task }), mode: "fixedDuration" }); } } gantt.updateTaskAssignments(task.id); gantt.updateTask(task.id); }else if(value){ var assignment = { task_id: taskId, resource_id: resourceId, value: value, start_date: startDate, end_date: endDate, duration: gantt.calculateDuration({ start_date: startDate, end_date: endDate, task: task }), delay: gantt.calculateDuration({ start_date: task.start_date, end_date: startDate, task: task }), mode: "fixedDuration" }; assignmentStore.addItem(assignment); gantt.updateTaskAssignments(task.id); gantt.updateTask(task.id); } } } }); }) gantt.locale.labels.section_resources = "Owners"; gantt.config.lightbox.sections = [ { name: "description", height: 38, map_to: "text", type: "textarea", focus: true }, { name: "resources", type: "resources", map_to: "owner", options: gantt.serverList("people"), default_value: 8}, { name: "time", type: "duration", map_to: "auto" } ]; gantt.config.resource_store = "resource"; gantt.config.resource_property = "owner"; gantt.config.order_branch = true; gantt.config.open_tree_initially = true; gantt.config.layout = { css: "gantt_container", rows: [ { cols: [ {view: "grid", group:"grids", scrollY: "scrollVer"}, {resizer: true, width: 1}, {view: "timeline", scrollX: "scrollHor", scrollY: "scrollVer"}, {view: "scrollbar", id: "scrollVer", group:"vertical"} ], gravity:2 }, {resizer: true, width: 1}, { config: resourceConfig, cols: [ {view: "resourceGrid", group:"grids", width: 435, scrollY: "resourceVScroll" }, {resizer: true, width: 1}, {view: "resourceTimeline", scrollX: "scrollHor", scrollY: "resourceVScroll"}, {view: "scrollbar", id: "resourceVScroll", group:"vertical"} ], gravity:1 }, {view: "scrollbar", id: "scrollHor"} ] }; var resourcesStore = gantt.createDatastore({ name: gantt.config.resource_store, type: "treeDatastore", fetchTasks: true, initItem: function (item) { item.parent = item.parent || gantt.config.root_id; item[gantt.config.resource_property] = item.parent; item.open = true; return item; } }); resourcesStore.attachEvent("onParse", function() { var people = []; resourcesStore.eachItem(function(res) { if (res.$level === 1) { var copy = gantt.copy(res); copy.key = res.id; copy.label = res.text; copy.unit = "hours/day"; people.push(copy); } }); gantt.updateCollection("people", people); }); gantt.init("gantt_here"); resourcesStore.parse([ {id: 1, text: "QA", parent:null}, {id: 2, text: "Development", parent:null}, {id: 3, text: "Sales", parent:null}, {id: 4, text: "Other", parent:null}, {id: 5, text: "Unassigned", parent:4}, {id: 6, text: "John", parent:1, unit: "hours/day" }, {id: 7, text: "Mike", parent:2, unit: "hours/day" }, {id: 8, text: "Anna", parent:2, unit: "hours/day" }, {id: 9, text: "Bill", parent:3, unit: "hours/day" }, {id: 10, text: "Floe", parent:3, unit: "hours/day" } ]); gantt.createDataProcessor(function(entity, action, data, id){ console.log(JSON.stringify({ entity, action, data, id }, null, 2)); }); gantt.parse({ data: [ { id: 1, text: "Office itinerancy", type: "project", start_date: "02-04-2019 00:00", duration: 17, progress: 0.4, parent: 0 }, { id: 2, text: "Office facing", type: "project", start_date: "02-04-2019 00:00", duration: 8, progress: 0.6, parent: "1" }, { id: 3, text: "Furniture installation", type: "project", start_date: "11-04-2019 00:00", duration: 8, parent: "1", progress: 0.6, owner: [] }, { id: 4, text: "The employee relocation", type: "project", start_date: "13-04-2019 00:00", duration: 5, parent: "1", progress: 0.5, owner: [], priority: 3 }, { id: 5, text: "Interior office", type: "task", start_date: "03-04-2019 00:00", duration: 7, parent: "2", progress: 0.6, owner: [ { resource_id: "6", value: 3, start_date: "03-04-2019 00:00", end_date: "05-04-2019 00:00", }], priority: 1 }, { id: 6, text: "Air conditioners check", type: "task", start_date: "03-04-2019 00:00", duration: 7, parent: "2", progress: 0.6, owner: [ { resource_id: "6", value: 4, delay: 2 }], priority: 2 }, { id: 7, text: "Workplaces preparation", type: "task", start_date: "12-04-2019 00:00", duration: 8, parent: "3", progress: 0.6, owner: [ { resource_id: "10", value: 2 }] }, { id: 8, text: "Preparing workplaces", type: "task", start_date: "14-04-2019 00:00", duration: 5, parent: "4", progress: 0.5, owner: [ { resource_id: "10", value: 4 }, { resource_id: "9", value: 5 }], priority: 1 }, { id: 9, text: "Workplaces importation", type: "task", start_date: "21-04-2019 00:00", duration: 4, parent: "4", progress: 0.5, owner: [ { resource_id: "7", value: 3 }] }, { id: 10, text: "Workplaces exportation", type: "task", start_date: "27-04-2019 00:00", duration: 3, parent: "4", progress: 0.5, owner: [ { resource_id: "8", value: 5 }], priority: 2 }, { id: 11, text: "Product launch", type: "project", progress: 0.6, start_date: "02-04-2019 00:00", duration: 13, owner: [ { resource_id: "5", value: 4 }], parent: 0 }, { id: 12, text: "Perform Initial testing", type: "task", start_date: "03-04-2019 00:00", duration: 5, parent: "11", progress: 1, owner: [ { resource_id: "7", value: 6 }] }, { id: 13, text: "Development", type: "project", start_date: "03-04-2019 00:00", duration: 11, parent: "11", progress: 0.5, owner: [ { resource_id: "5", value: 2 }] }, { id: 14, text: "Analysis", type: "task", start_date: "03-04-2019 00:00", duration: 6, parent: "11", owner: [ ], progress: 0.8 }, { id: 15, text: "Design", type: "project", start_date: "03-04-2019 00:00", duration: 5, parent: "11", progress: 0.2, owner: [ { resource_id: "5", value: 5 }] }, { id: 16, text: "Documentation creation", type: "task", start_date: "03-04-2019 00:00", duration: 7, parent: "11", progress: 0, owner: [ { resource_id: "7", value: 2 }], priority: 1 }, { id: 17, text: "Develop System", type: "task", start_date: "03-04-2019 00:00", duration: 2, parent: "13", progress: 1, owner: [ { resource_id: "8", value: 1 }], priority: 2 }, { id: 25, text: "Beta Release", type: "milestone", start_date: "06-04-2019 00:00", parent: "13", progress: 0, owner: [ { resource_id: "5", value: 1 }], duration: 0 }, { id: 18, text: "Integrate System", type: "task", start_date: "10-04-2019 00:00", duration: 2, parent: "13", progress: 0.8, owner: [ { resource_id: "6", value: 2 }], priority: 3 }, { id: 19, text: "Test", type: "task", start_date: "13-04-2019 00:00", duration: 4, parent: "13", progress: 0.2, owner: [ { resource_id: "6", value: 3 }] }, { id: 20, text: "Marketing", type: "task", start_date: "13-04-2019 00:00", duration: 4, parent: "13", progress: 0, owner: [ { resource_id: "8", value: 4 }], priority: 1 }, { id: 21, text: "Design database", type: "task", start_date: "03-04-2019 00:00", duration: 4, parent: "15", progress: 0.5, owner: [ { resource_id: "6", value: 5 }] }, { id: 22, text: "Software design", type: "task", start_date: "03-04-2019 00:00", duration: 4, parent: "15", progress: 0.1, owner: [ { resource_id: "8", value: 3 }], priority: 1 }, { id: 23, text: "Interface setup", type: "task", start_date: "03-04-2019 00:00", duration: 5, parent: "15", progress: 0, owner: [ { resource_id: "8", value: 5 }], priority: 1 }, { id: 24, text: "Release v1.0", type: "milestone", start_date: "20-04-2019 00:00", parent: "11", progress: 0, owner: [ { resource_id: "5", value: 3 }], duration: 0 } ], links: [ { id: "2", source: "2", target: "3", type: "0" }, { id: "3", source: "3", target: "4", type: "0" }, { id: "7", source: "8", target: "9", type: "0" }, { id: "8", source: "9", target: "10", type: "0" }, { id: "16", source: "17", target: "25", type: "0" }, { id: "17", source: "18", target: "19", type: "0" }, { id: "18", source: "19", target: "20", type: "0" }, { id: "22", source: "13", target: "24", type: "0" }, { id: "23", source: "25", target: "18", type: "0" } ] }); </script> </body>