UNPKG

jetsum_dhtmlx_gantt

Version:

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

429 lines (370 loc) 11.4 kB
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Drag timeline</title> <script src="../../codebase/dhtmlxgantt.js?v=7.1.9"></script> <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"> <link rel="stylesheet" href="../common/controls_styles.css?v=7.1.9"> <link rel="stylesheet" href="../../codebase/dhtmlxgantt.css?v=7.1.9"> <script src="../common/resource_construction_materials.js?v=7.1.9"></script> <style> html, body { padding: 0px; margin: 0px; height: 100%; } #gantt_here { width:100%; height: calc(100vh - 52px); } .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{ width: 28px; height: 28px; line-height: 29px; display: inline-block; color: #FFF; margin: 3px; } .resource_marker.workday_ok div { border-radius: 15px; background: #51c185; } .resource_marker.workday_over div{ border-radius: 3px; background: #ff8686; } .folder_row { font-weight: bold; } .gantt_task_cell.week_end { background-color: #e8e8e87d; } .gantt_task_row.gantt_selected .gantt_task_cell.week_end { background-color: #e8e8e87d !important; } .group_row, .group_row.odd, .gantt_task_row.group_row{ background-color: rgba(232, 232, 232, 0.6); } .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; } .filters_wrapper { font: 600 14px Roboto; } .filters_wrapper span { font-weight: bold; padding-right: 5px; color: rgba(0,0,0,0.7); } .filters_wrapper label { padding-right: 3px; } .gantt_control{ width: 100%; } </style> </head> <body> <div class="gantt_control"> <div class="filters_wrapper" id="filters_wrapper"> <span>Drag timeline:</span> <label class="checked_label">Enable <input type="checkbox" id="enableTimelineDnd" checked><i class="material-icons icon_color">check_box</i></label> <label class="checked_label">Require control key to drag <input type="checkbox" id="ctrlDragTimeline"><i class="material-icons">check_box_outline_blank</i></label> </div> </div> <div id="gantt_here"></div> <script> gantt.plugins({ drag_timeline: true }); gantt.message({ text:"Use mouse drag and drop to scroll the timeline", expire: 15000 }) var gantt_control = document.querySelector(".gantt_control"); gantt_control.addEventListener("change", function(e) { updIcon(e.target); var enabled = enableTimelineDnd.checked; var requireCtrlKey = ctrlDragTimeline.checked; if(!enabled){ gantt.config.drag_timeline = null; }else{ if(requireCtrlKey){ gantt.config.drag_timeline = { ignore: "", useKey: "ctrlKey" }; }else { gantt.config.drag_timeline = { ignore:".gantt_task_line, .gantt_task_link", useKey: false }; } } }); gantt.config.drag_timeline = { ignore:".gantt_task_line, .gantt_task_link", useKey: false }; function updIcon(el) { el.parentElement.classList.toggle("checked_label"); var iconEl = el.parentElement.querySelector("i"), checked = "check_box", unchecked = "check_box_outline_blank", className = "icon_color"; iconEl.textContent = iconEl.textContent==checked?unchecked:checked; iconEl.classList.toggle(className); } gantt.config.date_format = "%Y-%m-%d %H:%i:%s"; gantt.templates.grid_row_class = function(start, end, task){ var css = []; if(gantt.hasChild(task.id)){ css.push("folder_row"); } if(task.$virtual){ css.push("group_row") } return css.join(" "); }; gantt.templates.task_row_class = function(start, end, task){ return ""; }; gantt.templates.timeline_cell_class = function (task, date) { if (!gantt.isWorkTime({date: date, task: task})) return "week_end"; return ""; }; gantt.templates.resource_cell_class = function(start_date, end_date, resource, tasks){ var css = []; css.push("resource_marker"); if (tasks.length <= 1) { css.push("workday_ok"); } else { css.push("workday_over"); } return css.join(" "); }; gantt.templates.resource_cell_value = function(start_date, end_date, resource, tasks){ var result = 0; tasks.forEach(function(item) { var assignments = gantt.getResourceAssignments(resource.id, item.id); assignments.forEach(function(assignment){ var task = gantt.getTask(assignment.task_id); if(resource.type == "work"){ result += assignment.value * 1; }else{ result += assignment.value / (task.duration || 1); } }); }); if(result % 1){ result = Math.round(result * 10)/10; } return "<div>" + result + "</div>"; }; var resourceTemplates = { grid_row_class: function(start, end, resource){ var css = []; if(gantt.$resourcesStore.hasChild(resource.id)){ css.push("folder_row"); css.push("group_row"); } return css.join(" "); }, task_row_class: function(start, end, resource){ var css = []; if(gantt.$resourcesStore.hasChild(resource.id)){ css.push("group_row"); } return css.join(" "); } }; gantt.locale.labels.section_resources = "Resources"; gantt.config.lightbox.sections = [ {name: "description", height: 38, map_to: "text", type: "textarea", focus: true}, {name: "resources", type: "resources", map_to: "resources", options: gantt.serverList("people")}, {name: "time", type: "duration", map_to: "auto"} ]; var resourceConfig = { scale_height: 30, scales: [ {unit: "day", step: 1, date: "%d %M"} ], columns: [ { name: "name", label: "Name", tree:true, width:250, template: function (resource) { return resource.text; }, resize: true }, { name: "allocated", label: "Allocated", align:"left", width:100, template: function (resource) { var assignments = gantt.getResourceAssignments(resource.id); var result = 0; assignments.forEach(function(assignment){ var task = gantt.getTask(assignment.task_id); if(resource.type == "work"){ result += task.duration * assignment.value; }else{ result += assignment.value * 1; } }); if(resource.type == "work"){ result = "<b>" +result + "</b> hours"; }else{ result = "<b>" +result + "</b> " + resource.unit; } return result; }, resize: true } ] }; gantt.config.scales = [ {unit: "month", step: 1, format: "%F, %Y"}, {unit: "day", step: 1, format: "%d %M"} ]; gantt.config.auto_scheduling = true; gantt.config.auto_scheduling_strict = true; gantt.config.work_time = true; gantt.config.columns = [ {name: "text", tree: true, width: 320, resize: true}, {name: "start_date", align: "center", width: 80, resize: true}, {name: "resources", align: "center", width: 80, label: "Resources", resize: true, template: function (task) { if (task.type == gantt.config.types.project) { return ""; } var result = ""; var store = gantt.getDatastore("resource"); var assignments = task[gantt.config.resource_property]; if (!assignments || !assignments.length) { return ""; } if(assignments.length == 1){ return store.getItem(assignments[0].resource_id).text.split(",")[0]; } assignments.forEach(function(assignment) { var resource = store.getItem(assignment.resource_id); if (!resource) return; result += "<div class='owner-label' title='" + resource.text + "'>" + resource.text.substr(0, 1) + "</div>"; }); return result; } }, {name: "duration", width: 60, align: "center", resize: true}, {name: "add", width: 44} ]; gantt.config.resource_store = "resource"; gantt.config.resource_property = "resources"; gantt.config.order_branch = true; gantt.config.open_tree_initially = true; gantt.config.scale_height = 50; gantt.config.layout = { css: "gantt_container", rows: [ { gravity: 2, cols: [ {view: "grid", group:"grids", scrollY: "scrollVer"}, {resizer: true, width: 1}, {view: "timeline", scrollX: "scrollHor", scrollY: "scrollVer"}, {view: "scrollbar", id: "scrollVer", group:"vertical"} ] }, { resizer: true, width: 1, next: "resources"}, { height: 35, cols: [ { html:"", group:"grids"}, { resizer: true, width: 1}, { html:""} ] }, { gravity:1, id: "resources", config: resourceConfig, templates: resourceTemplates, cols: [ { view: "resourceGrid", group:"grids", scrollY: "resourceVScroll" }, { resizer: true, width: 1}, { view: "resourceTimeline", scrollX: "scrollHor", scrollY: "resourceVScroll"}, { view: "scrollbar", id: "resourceVScroll", group:"vertical"} ] }, {view: "scrollbar", id: "scrollHor"} ] }; gantt.$resourcesStore = gantt.createDatastore({ name: gantt.config.resource_store, type: "treeDatastore", initItem: function (item) { item.parent = item.parent || gantt.config.root_id; item[gantt.config.resource_property] = item.parent; item.open = true; return item; } }); gantt.$resourcesStore.attachEvent("onFilterItem", function(id, item) { return gantt.getResourceAssignments(id).length > 0; }); gantt.init("gantt_here"); gantt.$resourcesStore.attachEvent("onParse", function(){ var people = []; gantt.$resourcesStore.eachItem(function(res){ if(!gantt.$resourcesStore.hasChild(res.id)){ var copy = gantt.copy(res); copy.key = res.id; copy.label = res.text; people.push(copy); } }); gantt.updateCollection("people", people); }); gantt.attachEvent("onParse", function(){ gantt.render(); }); gantt.$resourcesStore.parse([ {id: 1, text: "Anna, Architect", unit:"hours/day", default_value:8, type:"work"}, {id: 2, text: "Finn, Construction worker", unit:"hours/day", default_value:8, type:"work"}, {id: 3, text: "Jake, Construction worker", unit:"hours/day", default_value:8, type:"work"}, {id: 4, text: "Floe, Plasterer", unit:"hours/day", default_value:8, type:"work"}, {id: 5, text: "Tom, Plumber", unit:"hours/day", default_value:8, type:"work"}, {id: 6, text: "Mike, Electrician", unit:"hours/day", default_value:8, type:"work"}, {id: 7, text: "Joe, Handyman", unit:"hours/day", default_value:8, type:"work"}, {id: 8, text: "Concrete", unit:"m3", default_value:1}, {id: 9, text: "Blocks", unit:"m3", default_value:1}, {id: 10, text: "Air conditioners", unit:"units", default_value:1}, {id: 11, text: "Radiators", unit:"units", default_value:1}, {id: 12, text: "Pipes", unit:"meters", default_value:5}, {id: 13, text: "Wires", unit:"meters", default_value:10}, {id: 14, text: "Paint", unit:"cans%", default_value:1} ]); gantt.parse(taskData); </script> </body> </html>