Browse Source

first commit

pull/1/head
Ibnu hamdani 3 years ago
commit
b33489323f
  1. 282
      samples/dhtmlx-gantt/Gantt-Useful-Info.html
  2. 246
      samples/dhtmlx-gantt/backend/data-dynamic.json
  3. 230
      samples/dhtmlx-gantt/backend/data.json
  4. 6
      samples/dhtmlx-gantt/backend/index.js
  5. 16
      samples/dhtmlx-gantt/backend/item_initializer.js
  6. 16
      samples/dhtmlx-gantt/backend/package.json
  7. 92
      samples/dhtmlx-gantt/backend/router.js
  8. 12
      samples/dhtmlx-gantt/backend/router_dynamic_loading.js
  9. 41
      samples/dhtmlx-gantt/backend/server.js
  10. 65
      samples/dhtmlx-gantt/backend/storage.js
  11. 29
      samples/dhtmlx-gantt/backend/storage_tree.js
  12. 1
      samples/dhtmlx-gantt/codebase/dhtmlxgantt.css
  13. 2590
      samples/dhtmlx-gantt/codebase/dhtmlxgantt.d.ts
  14. 38
      samples/dhtmlx-gantt/codebase/dhtmlxgantt.js
  15. 1
      samples/dhtmlx-gantt/codebase/dhtmlxgantt.js.map
  16. 1
      samples/dhtmlx-gantt/codebase/skins/dhtmlxgantt_broadway.css
  17. 1
      samples/dhtmlx-gantt/codebase/skins/dhtmlxgantt_contrast_black.css
  18. 1
      samples/dhtmlx-gantt/codebase/skins/dhtmlxgantt_contrast_white.css
  19. 1
      samples/dhtmlx-gantt/codebase/skins/dhtmlxgantt_material.css
  20. 1
      samples/dhtmlx-gantt/codebase/skins/dhtmlxgantt_meadow.css
  21. 1
      samples/dhtmlx-gantt/codebase/skins/dhtmlxgantt_skyblue.css
  22. 1
      samples/dhtmlx-gantt/codebase/skins/dhtmlxgantt_terrace.css
  23. 1979
      samples/dhtmlx-gantt/codebase/sources/dhtmlxgantt.css
  24. 43380
      samples/dhtmlx-gantt/codebase/sources/dhtmlxgantt.js
  25. 2088
      samples/dhtmlx-gantt/codebase/sources/skins/dhtmlxgantt_broadway.css
  26. 2043
      samples/dhtmlx-gantt/codebase/sources/skins/dhtmlxgantt_contrast_black.css
  27. 2056
      samples/dhtmlx-gantt/codebase/sources/skins/dhtmlxgantt_contrast_white.css
  28. 2406
      samples/dhtmlx-gantt/codebase/sources/skins/dhtmlxgantt_material.css
  29. 1988
      samples/dhtmlx-gantt/codebase/sources/skins/dhtmlxgantt_meadow.css
  30. 1968
      samples/dhtmlx-gantt/codebase/sources/skins/dhtmlxgantt_skyblue.css
  31. 1979
      samples/dhtmlx-gantt/codebase/sources/skins/dhtmlxgantt_terrace.css
  32. 737
      samples/dhtmlx-gantt/index.html
  33. 339
      samples/dhtmlx-gantt/license.txt
  34. 31
      samples/dhtmlx-gantt/package.json
  35. 52
      samples/dhtmlx-gantt/readme.txt
  36. 33
      samples/dhtmlx-gantt/samples/01_initialization/01_basic_init.html
  37. 22
      samples/dhtmlx-gantt/samples/01_initialization/02_load_json.html
  38. 23
      samples/dhtmlx-gantt/samples/01_initialization/03_load_xml.html
  39. 44
      samples/dhtmlx-gantt/samples/01_initialization/04_save_rest.html
  40. 29
      samples/dhtmlx-gantt/samples/01_initialization/06_touch_forced.html
  41. 27
      samples/dhtmlx-gantt/samples/01_initialization/07_jquery.html
  42. 30
      samples/dhtmlx-gantt/samples/01_initialization/08_explicit_time_range.html
  43. 24
      samples/dhtmlx-gantt/samples/01_initialization/09_backward_compatibility.html
  44. 16
      samples/dhtmlx-gantt/samples/01_initialization/10_fixed_size.html
  45. 50
      samples/dhtmlx-gantt/samples/01_initialization/11_clickable_links.html
  46. 28
      samples/dhtmlx-gantt/samples/01_initialization/12_localization.html
  47. 82
      samples/dhtmlx-gantt/samples/01_initialization/13_project_duration.html
  48. 42
      samples/dhtmlx-gantt/samples/01_initialization/14_reinitializtion.html
  49. 24
      samples/dhtmlx-gantt/samples/01_initialization/15_connector_json_enddate.html
  50. 275
      samples/dhtmlx-gantt/samples/01_initialization/17_bootstrap.html
  51. 29
      samples/dhtmlx-gantt/samples/01_initialization/18_backward_planning.html
  52. 90
      samples/dhtmlx-gantt/samples/01_initialization/19_tasks_without_dates.html
  53. 73
      samples/dhtmlx-gantt/samples/01_initialization/20_tasks_outside_timescale.html
  54. 111
      samples/dhtmlx-gantt/samples/01_initialization/21_rollup_tasks.html
  55. 300
      samples/dhtmlx-gantt/samples/01_initialization/index.html
  56. 30
      samples/dhtmlx-gantt/samples/02_extensions/01_quickinfo.html
  57. 33
      samples/dhtmlx-gantt/samples/02_extensions/02_tooltip.html
  58. 59
      samples/dhtmlx-gantt/samples/02_extensions/05_today_line.html
  59. 227
      samples/dhtmlx-gantt/samples/02_extensions/09_multiselection.html
  60. 77
      samples/dhtmlx-gantt/samples/02_extensions/11_full_screen.html
  61. 70
      samples/dhtmlx-gantt/samples/02_extensions/13_smart_rendering.html
  62. 103
      samples/dhtmlx-gantt/samples/02_extensions/14_undo.html
  63. 105
      samples/dhtmlx-gantt/samples/02_extensions/16_keyboard_navigation.html
  64. 110
      samples/dhtmlx-gantt/samples/02_extensions/17_keyboard_navigation_cell.html
  65. 154
      samples/dhtmlx-gantt/samples/02_extensions/18_linked_tasks.html
  66. 359
      samples/dhtmlx-gantt/samples/02_extensions/21_overlay.html
  67. 392
      samples/dhtmlx-gantt/samples/02_extensions/22_tooltip_api.html
  68. 107
      samples/dhtmlx-gantt/samples/02_extensions/23_click_drag_splittask.html
  69. 71
      samples/dhtmlx-gantt/samples/02_extensions/24_click_drag.html
  70. 128
      samples/dhtmlx-gantt/samples/02_extensions/25_click_drag_select_by_drag.html
  71. 48
      samples/dhtmlx-gantt/samples/02_extensions/26_full_screen_with_additional_elements.html
  72. 429
      samples/dhtmlx-gantt/samples/02_extensions/27_drag_timeline.html
  73. 112
      samples/dhtmlx-gantt/samples/02_extensions/28_row_resize.html
  74. 399
      samples/dhtmlx-gantt/samples/02_extensions/28_tasks_grouping_relation_properties.html
  75. 369
      samples/dhtmlx-gantt/samples/02_extensions/data.js
  76. 369
      samples/dhtmlx-gantt/samples/02_extensions/data.json
  77. 300
      samples/dhtmlx-gantt/samples/02_extensions/index.html
  78. 55
      samples/dhtmlx-gantt/samples/03_scales/01_multiple_scales.html
  79. 33
      samples/dhtmlx-gantt/samples/03_scales/02_month_days.html
  80. 42
      samples/dhtmlx-gantt/samples/03_scales/03_full_year.html
  81. 33
      samples/dhtmlx-gantt/samples/03_scales/04_days.html
  82. 127
      samples/dhtmlx-gantt/samples/03_scales/05_dynamic_scales.html
  83. 48
      samples/dhtmlx-gantt/samples/03_scales/06_custom_scales.html
  84. 65
      samples/dhtmlx-gantt/samples/03_scales/07_minutes_scale.html
  85. 52
      samples/dhtmlx-gantt/samples/03_scales/08_scale_autoconfig.html
  86. 68
      samples/dhtmlx-gantt/samples/03_scales/10_working_hours.html
  87. 67
      samples/dhtmlx-gantt/samples/03_scales/11_select_column.html
  88. 53
      samples/dhtmlx-gantt/samples/03_scales/12_year_quarters.html
  89. 230
      samples/dhtmlx-gantt/samples/03_scales/13_zoom_to_fit.html
  90. 81
      samples/dhtmlx-gantt/samples/03_scales/14_scale_zoom_by_wheelmouse.html
  91. 234
      samples/dhtmlx-gantt/samples/03_scales/index.html
  92. 34
      samples/dhtmlx-gantt/samples/04_customization/01_outer_content.html
  93. 66
      samples/dhtmlx-gantt/samples/04_customization/02_custom_tree.html
  94. 79
      samples/dhtmlx-gantt/samples/04_customization/03_link_styles.html
  95. 84
      samples/dhtmlx-gantt/samples/04_customization/04_task_styles.html
  96. 39
      samples/dhtmlx-gantt/samples/04_customization/05_tree_template.html
  97. 43
      samples/dhtmlx-gantt/samples/04_customization/06_highlight_weekend.html
  98. 37
      samples/dhtmlx-gantt/samples/04_customization/07_progress_text.html
  99. 69
      samples/dhtmlx-gantt/samples/04_customization/08_templates.html
  100. 92
      samples/dhtmlx-gantt/samples/04_customization/09_html_content.html
  101. Some files were not shown because too many files have changed in this diff Show More

282
samples/dhtmlx-gantt/Gantt-Useful-Info.html

File diff suppressed because one or more lines are too long

246
samples/dhtmlx-gantt/backend/data-dynamic.json

@ -0,0 +1,246 @@
{
"data": [
{
"id": 1,
"start_date": "2018-04-01 00:00:00",
"duration": 5,
"text": "Project #1",
"progress": 0.8,
"parent": 0,
"open": 0
},
{
"id": 2,
"start_date": "2018-04-06 00:00:00",
"duration": 4,
"text": "Task #1",
"progress": 0.5,
"parent": 1,
"open": 0
},
{
"id": 5,
"start_date": "2018-04-05 00:00:00",
"duration": 5,
"text": "Task #1.1",
"progress": 0.34,
"parent": 2,
"open": 0
},
{
"id": 6,
"start_date": "2018-04-11 00:00:00",
"duration": 4,
"text": "Task #1.2",
"progress": 0.491477,
"parent": 2,
"open": 0
},
{
"id": 3,
"start_date": "2018-04-03 00:00:00",
"duration": 6,
"text": "Task #2",
"progress": 0.7,
"parent": 1,
"open": 0
},
{
"id": 7,
"start_date": "2018-04-07 00:00:00",
"duration": 5,
"text": "Task #2.1",
"progress": 0.2,
"parent": 3,
"open": 0
},
{
"id": 8,
"start_date": "2018-04-06 00:00:00",
"duration": 4,
"text": "Task #2.2",
"progress": 0.9,
"parent": 3,
"open": 0
},
{
"id": 4,
"start_date": "2018-04-07 00:00:00",
"duration": 2,
"text": "Task #3",
"progress": 0,
"parent": 1,
"open": 0
},
{
"id": 9,
"start_date": "2018-04-06 00:00:00",
"duration": 5,
"text": "Task #3.1",
"progress": 1,
"parent": 4,
"open": 0
},
{
"id": 10,
"start_date": "2018-04-06 00:00:00",
"duration": 3,
"text": "Task #3.2",
"progress": 0,
"parent": 4,
"open": 0
},
{
"id": 11,
"start_date": "2018-04-06 00:00:00",
"duration": 4,
"text": "Task #3.3",
"progress": 0.33,
"parent": 4,
"open": 0
},
{
"id": 12,
"start_date": "2018-04-02 00:00:00",
"duration": 8,
"text": "Project #2",
"progress": 0,
"parent": 0,
"open": 0
},
{
"id": 13,
"start_date": "2018-04-02 00:00:00",
"duration": 10,
"text": "Task #1",
"progress": 0.2,
"parent": 12,
"open": 0
},
{
"id": 14,
"start_date": "2018-04-04 00:00:00",
"duration": 4,
"text": "Task #2",
"progress": 0.9,
"parent": 12,
"open": 0
},
{
"id": 18,
"start_date": "2018-04-05 00:00:00",
"duration": 5,
"text": "Task #2.1",
"progress": 0.3,
"parent": 14,
"open": 0
},
{
"id": 19,
"start_date": "2018-04-05 00:00:00",
"duration": 6,
"text": "Task #2.2",
"progress": 0.453052,
"parent": 14,
"open": 0
},
{
"id": 20,
"start_date": "2018-04-05 00:00:00",
"duration": 4,
"text": "Task #2.3",
"progress": 0.512605,
"parent": 14,
"open": 0
},
{
"id": 21,
"start_date": "2018-04-05 00:00:00",
"duration": 6,
"text": "Task #2.4",
"progress": 0.7,
"parent": 14,
"open": 0
},
{
"id": 15,
"start_date": "2018-04-05 00:00:00",
"duration": 3,
"text": "Task #3",
"progress": 0.6,
"parent": 12,
"open": 0
},
{
"id": 16,
"start_date": "2018-04-01 00:00:00",
"duration": 3,
"text": "Task #4",
"progress": 0.214286,
"parent": 12,
"open": 0
},
{
"id": 22,
"start_date": "2018-04-05 00:00:00",
"duration": 7,
"text": "Task #4.1",
"progress": 1,
"parent": 16,
"open": 0
},
{
"id": 23,
"start_date": "2018-04-05 00:00:00",
"duration": 5,
"text": "Task #4.2",
"progress": 1,
"parent": 16,
"open": 0
},
{
"id": 24,
"start_date": "2018-04-05 00:00:00",
"duration": 5,
"text": "Task #4.3",
"progress": 0,
"parent": 16,
"open": 0
},
{
"id": 17,
"start_date": "2018-04-06 00:00:00",
"duration": 6,
"text": "Task #5",
"progress": 0.5,
"parent": 12,
"open": 0
}
],
"links": [
{
"id": 1,
"source": 1,
"target": 2,
"type": "0"
},
{
"id": 2,
"source": 1,
"target": 3,
"type": "0"
},
{
"id": 3,
"source": 1,
"target": 4,
"type": "0"
},
{
"id": 4,
"source": 2,
"target": 6,
"type": "0"
}
]
}

230
samples/dhtmlx-gantt/backend/data.json

@ -0,0 +1,230 @@
{
"data": [
{
"id": 1,
"text": "Project #1",
"start_date": "2018-04-01 00:00",
"duration": 11,
"progress": 0.6,
"open": true,
"users": [
"John",
"Mike",
"Anna"
],
"priority": "2",
"end_date": "2018-04-12 00:00",
"parent": 0,
"usage": [
{
"id": "1",
"value": "222"
}
]
},
{
"id": 2,
"text": "Task #1",
"start_date": "2018-04-03 00:00",
"duration": 5,
"parent": "1",
"progress": 1,
"open": true,
"users": [
"John",
"Mike"
],
"priority": "1",
"end_date": "2018-04-08 00:00"
},
{
"id": 3,
"text": "Task #2",
"start_date": "2018-04-02 00:00",
"duration": 7,
"parent": "1",
"progress": 0.5,
"open": true,
"users": [
"Anna"
],
"priority": "1",
"end_date": "2018-04-09 00:00"
},
{
"id": 7,
"text": "Task #2.1",
"start_date": "2018-04-03 00:00",
"duration": 2,
"parent": "3",
"progress": 1,
"open": true,
"users": [
"Mike",
"Anna"
],
"priority": "2",
"end_date": "2018-04-05 00:00",
"usage": [
{
"id": "3",
"value": "1"
}
]
},
{
"id": 8,
"text": "Task #2.2",
"start_date": "2018-04-06 00:00",
"duration": 3,
"parent": "3",
"progress": 0.8,
"open": true,
"users": [
"Anna"
],
"priority": "3",
"end_date": "2018-04-09 00:00"
},
{
"id": 9,
"text": "Task #2.3",
"start_date": "2018-04-10 00:00",
"duration": 4,
"parent": "3",
"progress": 0.2,
"open": true,
"users": [
"Mike",
"Anna"
],
"priority": "1",
"end_date": "2018-04-14 00:00",
"usage": [
{
"id": "2",
"value": "50"
},
{
"id": "1",
"value": "2"
}
]
},
{
"id": 10,
"text": "Task #2.4",
"start_date": "2018-04-10 00:00",
"duration": 4,
"parent": "3",
"progress": 0,
"open": true,
"users": [
"John",
"Mike"
],
"priority": "1",
"end_date": "2018-04-14 00:00"
},
{
"id": 4,
"text": "Task #3",
"start_date": "2018-04-02 00:00",
"duration": 6,
"parent": "1",
"progress": 0.8,
"open": true,
"users": [
"Mike",
"Anna"
],
"priority": "2",
"end_date": "2018-04-08 00:00"
},
{
"id": 5,
"text": "Task #4",
"start_date": "2018-04-02 00:00",
"duration": 5,
"parent": "1",
"progress": 0.2,
"open": true,
"users": [
"John"
],
"priority": "3",
"end_date": "2018-04-07 00:00"
},
{
"id": 11,
"text": "Task #4.1",
"start_date": "2018-04-03 00:00",
"duration": 4,
"parent": "5",
"progress": 0.5,
"open": true,
"users": [
"John",
"Anna"
],
"priority": "3",
"end_date": "2018-04-07 00:00"
},
{
"id": 12,
"text": "Task #4.2",
"start_date": "2018-04-03 00:00",
"duration": 4,
"parent": "5",
"progress": 0.1,
"open": true,
"users": [
"John"
],
"priority": "3",
"end_date": "2018-04-07 00:00"
},
{
"id": 13,
"text": "Task #4.3",
"start_date": "2018-04-03 00:00",
"duration": 5,
"parent": "5",
"progress": 0,
"open": true,
"users": [
"Anna"
],
"priority": "3",
"end_date": "2018-04-08 00:00"
},
{
"id": 6,
"text": "Task #5",
"start_date": "2018-04-02 00:00",
"duration": 7,
"parent": "1",
"progress": 0,
"open": true,
"users": [
"John"
],
"priority": "2",
"end_date": "2018-04-09 00:00"
}
],
"links": [
{
"id": "10",
"source": "11",
"target": "12",
"type": "1"
},
{
"id": "11",
"source": "11",
"target": "13",
"type": "1"
}
]
}

6
samples/dhtmlx-gantt/backend/index.js

@ -0,0 +1,6 @@
const backend = require("./server");
const host = process.env.HOST || "127.0.0.1";
const port = process.env.PORT || "9200";
backend(host, port);

16
samples/dhtmlx-gantt/backend/item_initializer.js

@ -0,0 +1,16 @@
module.exports = {
data: function(task) {
task.open = task.open * 1;
task.progress = task.progress * 1;
task.duration = task.duration * 1;
task.id = task.id * 1;
task.parent = task.parent * 1;
return task;
},
links: function(link){
link.id = link.id * 1;
link.source = link.source * 1;
link.source = link.source * 1;
return link;
}
};

16
samples/dhtmlx-gantt/backend/package.json

@ -0,0 +1,16 @@
{
"name": "dhtmlx-gantt-samples",
"version": "1.0.0",
"description": "Simple backend and REST api for dhtmlx gantt samples",
"main": "./index.js",
"scripts": {
"start": "node ./index.js"
},
"author": "DHTMLX",
"license": "DHTMLX Evaluation License",
"dependencies": {
"body-parser": "^1.18.3",
"express": "^4.16.4",
"striptags": "^3.1.1"
}
}

92
samples/dhtmlx-gantt/backend/router.js

@ -0,0 +1,92 @@
const actions = {
inserted: "inserted",
updated: "updated",
deleted: "deleted",
error: "error"
};
class Router {
constructor(root, storage) {
this.root = root;
this.storage = storage;
}
_tryProcess(code, req, res) {
try {
code.call(this, req, res);
} catch (e) {
res.send({action: actions.error, message: e.message});
}
}
getData(req, res) {
res.send(this.storage.all());
}
insertTask(req, res) {
this._tryProcess(function (req, res) {
var insertedTask = this.storage.insert("data", req.body);
res.send({action: actions.inserted, tid: insertedTask.id});
}, req, res);
}
updateTask(req, res) {
this._tryProcess(function (req, res) {
var sid = req.params.id;
this.storage.update(sid, "data", req.body);
res.send({action: actions.updated});
}, req, res)
}
deleteTask(req, res) {
this._tryProcess(function (req, res) {
var sid = req.params.id;
this.storage.delete(sid, "data");
res.send({action: actions.deleted});
}, req, res);
}
insertLink(req, res) {
this._tryProcess(function (req, res) {
var insertedLink = this.storage.insert("links", req.body);
res.send({action: actions.inserted, tid: insertedLink.id});
}, req, res);
}
updateLink(req, res) {
this._tryProcess(function (req, res) {
var sid = req.params.id;
this.storage.update(sid, "links", req.body);
res.send({action: actions.updated});
}, req, res);
}
deleteLink(req, res) {
this._tryProcess(function (req, res) {
var sid = req.params.id;
this.storage.delete(sid, "links");
res.send({action: actions.deleted});
}, req, res);
}
connect(app) {
this._connect(app, "");
this._connect(app, "/gantt/backend");
this._connect(app, "/backend");
}
_connect(app, prefix){
app.get(`${prefix}${this.root}`, this.getData.bind(this));
app.post(`${prefix}${this.root}/task`, this.insertTask.bind(this));
app.put(`${prefix}${this.root}/task/:id`, this.updateTask.bind(this));
app.delete(`${prefix}${this.root}/task/:id`, this.deleteTask.bind(this));
app.post(`${prefix}${this.root}/link`, this.insertLink.bind(this));
app.put(`${prefix}${this.root}/link/:id`, this.updateLink.bind(this));
app.delete(`${prefix}${this.root}/link/:id`, this.deleteLink.bind(this));
}
}
module.exports = Router;

12
samples/dhtmlx-gantt/backend/router_dynamic_loading.js

@ -0,0 +1,12 @@
var Router = require("./router");
class RouterDynamicLoading extends Router {
getData(req, res) {
this._tryProcess(function (req, res) {
var parentId = req.query.parent_id || 0;
res.send(this.storage.children(parentId));
}, req, res);
}
}
module.exports = RouterDynamicLoading;

41
samples/dhtmlx-gantt/backend/server.js

@ -0,0 +1,41 @@
var express = require("express");
var bodyParser = require("body-parser");
var path = require("path");
var Storage = require("./storage");
var StorageTree = require("./storage_tree");
var Router = require("./router");
var RouterDynamicLoading = require("./router_dynamic_loading");
var itemInitializer = require("./item_initializer");
module.exports = function (host = "127.0.0.1", port = "9200") {
var app = express();
var storage = new Storage(require("./data.json"), itemInitializer);
var dynamicStorage = new StorageTree(require("./data-dynamic.json"), itemInitializer);
var router = new Router("/data", storage);
var dynLoading = new RouterDynamicLoading("/data-dynamic", dynamicStorage);
app.use(bodyParser.json()); // for parsing application/json
app.use(bodyParser.urlencoded({ extended: true })); // for parsing application/x-www-form-urlencoded
app.use(function (req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
res.header("Access-Control-Allow-Methods", "*");
next();
});
router.connect(app);
dynLoading.connect(app);
app.use("/codebase", express.static(path.join(__dirname, "..", "codebase")));
app.use("/samples", express.static(path.join(__dirname, "..", "samples")));
app.use(/^\/$/, function (req, res) {//default url
res.redirect("/samples");
});
var server = app.listen(port, host, function () {
console.log("Server is running on port " + port + "...");
});
};

65
samples/dhtmlx-gantt/backend/storage.js

@ -0,0 +1,65 @@
const striptags = require("striptags");
class Storage {
constructor(data, initItem) {
this._data = data;
this._initItem = initItem;
}
all() {
return this._data;
}
get(id, table) {
return this._data[table].find(function(entry) {
return id === entry.id;
});
}
delete(id, table) {
this._data[table] = this._data[table].filter(function(entry) {
return id !== entry.id;
});
}
update(id, table, newData) {
return this._data[table].find(function(entry, index, arr) {
if (id == entry.id) {
var preparedItem = newData;
console.log(table)
if(this._initItem && this._initItem[table]){
preparedItem = this._initItem[table](preparedItem);
}
arr[index] = _addId(id, sanitizeObject(preparedItem));
return true;
}
}.bind(this));
}
insert(table, data) {
data.id = uid();
var preparedItem = data;
if(this._initItem && this._initItem[table]){
preparedItem = this._initItem[table](data);
}
this._data[table].push(sanitizeObject(preparedItem));
return data;
}
}
var seed = Date.now();
function uid(){
return seed++;
}
function sanitizeObject(data){
for(var i in data){
if(typeof data[i] === "string"){
data[i] = striptags(data[i]);
}else if(typeof data[i] === "object"){
sanitizeObject(data[i]);
}
}
return data;
}
function _addId(id, data) {
return Object.assign(data, {id: id});
}
module.exports = Storage;

29
samples/dhtmlx-gantt/backend/storage_tree.js

@ -0,0 +1,29 @@
var Storage = require("./storage");
class StorageTree extends Storage{
children(parentId = 0) {
var all = this._data.data;
var loaded = this._data.data.filter(function(entry) {
return parentId == entry.parent;
});
var search = {};
loaded.forEach(function(value){
search[value.id] = value;
});
all.forEach(function(task){
if(search[task.parent]) {
search[task.parent]["$has_child"] = true;
}
});
var links = this._data.links.filter(function(entry) {
return (search[entry.source] || search[entry.target]);
});
return {data: loaded, links: links};
}
}
module.exports = StorageTree;

1
samples/dhtmlx-gantt/codebase/dhtmlxgantt.css

File diff suppressed because one or more lines are too long

2590
samples/dhtmlx-gantt/codebase/dhtmlxgantt.d.ts vendored

File diff suppressed because it is too large Load Diff

38
samples/dhtmlx-gantt/codebase/dhtmlxgantt.js

File diff suppressed because one or more lines are too long

1
samples/dhtmlx-gantt/codebase/dhtmlxgantt.js.map

File diff suppressed because one or more lines are too long

1
samples/dhtmlx-gantt/codebase/skins/dhtmlxgantt_broadway.css

File diff suppressed because one or more lines are too long

1
samples/dhtmlx-gantt/codebase/skins/dhtmlxgantt_contrast_black.css

File diff suppressed because one or more lines are too long

1
samples/dhtmlx-gantt/codebase/skins/dhtmlxgantt_contrast_white.css

File diff suppressed because one or more lines are too long

1
samples/dhtmlx-gantt/codebase/skins/dhtmlxgantt_material.css

File diff suppressed because one or more lines are too long

1
samples/dhtmlx-gantt/codebase/skins/dhtmlxgantt_meadow.css

File diff suppressed because one or more lines are too long

1
samples/dhtmlx-gantt/codebase/skins/dhtmlxgantt_skyblue.css

File diff suppressed because one or more lines are too long

1
samples/dhtmlx-gantt/codebase/skins/dhtmlxgantt_terrace.css

File diff suppressed because one or more lines are too long

1979
samples/dhtmlx-gantt/codebase/sources/dhtmlxgantt.css

File diff suppressed because it is too large Load Diff

43380
samples/dhtmlx-gantt/codebase/sources/dhtmlxgantt.js

File diff suppressed because it is too large Load Diff

2088
samples/dhtmlx-gantt/codebase/sources/skins/dhtmlxgantt_broadway.css

File diff suppressed because it is too large Load Diff

2043
samples/dhtmlx-gantt/codebase/sources/skins/dhtmlxgantt_contrast_black.css

File diff suppressed because it is too large Load Diff

2056
samples/dhtmlx-gantt/codebase/sources/skins/dhtmlxgantt_contrast_white.css

File diff suppressed because it is too large Load Diff

2406
samples/dhtmlx-gantt/codebase/sources/skins/dhtmlxgantt_material.css

File diff suppressed because it is too large Load Diff

1988
samples/dhtmlx-gantt/codebase/sources/skins/dhtmlxgantt_meadow.css

File diff suppressed because it is too large Load Diff

1968
samples/dhtmlx-gantt/codebase/sources/skins/dhtmlxgantt_skyblue.css

File diff suppressed because it is too large Load Diff

1979
samples/dhtmlx-gantt/codebase/sources/skins/dhtmlxgantt_terrace.css

File diff suppressed because it is too large Load Diff

737
samples/dhtmlx-gantt/index.html

@ -0,0 +1,737 @@
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=9; IE=8; IE=7; IE=EDGE"/>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<title>Gantt Chart Editor Demo</title>
<link rel=stylesheet href="platform.css" type="text/css">
<link rel=stylesheet href="libs/jquery/dateField/jquery.dateField.css" type="text/css">
<link rel=stylesheet href="gantt.css" type="text/css">
<link rel=stylesheet href="ganttPrint.css" type="text/css" media="print">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<script src="libs/jquery/jquery.livequery.1.1.1.min.js"></script>
<script src="libs/jquery/jquery.timers.js"></script>
<script src="libs/utilities.js"></script>
<script src="libs/forms.js"></script>
<script src="libs/date.js"></script>
<script src="libs/dialogs.js"></script>
<script src="libs/layout.js"></script>
<script src="libs/i18nJs.js"></script>
<script src="libs/jquery/dateField/jquery.dateField.js"></script>
<script src="libs/jquery/JST/jquery.JST.js"></script>
<script type="text/javascript" src="libs/jquery/svg/jquery.svg.min.js"></script>
<script type="text/javascript" src="libs/jquery/svg/jquery.svgdom.1.8.js"></script>
<script src="ganttUtilities.js"></script>
<script src="ganttTask.js"></script>
<script src="ganttDrawerSVG.js"></script>
<script src="ganttGridEditor.js"></script>
<script src="ganttMaster.js"></script>
</head>
<body style="background-color: #fff;">
<div id="ndo" style="position:absolute;right:5px;top:5px;width:378px;padding:5px;background-color: #FFF5E6; border:1px solid #F9A22F; font-size:12px" class="noprint">
This Gantt editor is free thanks to <a href="http://twproject.com" target="_blank">Twproject</a> where it can be used on a complete and flexible project management solution.<br> Get your projects done! Give <a href="http://twproject.com" target="_blank">Twproject a try now</a>.
</div>
<div id="workSpace" style="padding:0px; overflow-y:auto; overflow-x:hidden;border:1px solid #e5e5e5;position:relative;margin:0 5px"></div>
<style>
.resEdit {
padding: 15px;
}
.resLine {
width: 95%;
padding: 3px;
margin: 5px;
border: 1px solid #d0d0d0;
}
body {
overflow: hidden;
}
.ganttButtonBar h1{
color: #000000;
font-weight: bold;
font-size: 28px;
margin-left: 10px;
}
</style>
<form id="gimmeBack" style="display:none;" action="../gimmeBack.jsp" method="post" target="_blank"><input type="hidden" name="prj" id="gimBaPrj"></form>
<script type="text/javascript">
var ge;
$(function() {
var canWrite=true; //this is the default for test purposes
// here starts gantt initialization
ge = new GanttMaster();
ge.set100OnClose=true;
ge.init($("#workSpace"));
loadI18n(); //overwrite with localized ones
//in order to force compute the best-fitting zoom level
delete ge.gantt.zoom;
var project=loadFromLocalStorage();
if (!project.canWrite)
$(".ganttButtonBar button.requireWrite").attr("disabled","true");
ge.loadProject(project);
ge.checkpoint(); //empty the undo stack
ge.editor.element.oneTime(100, "cl", function () {$(this).find("tr.emptyRow:first").click()});
});
function loadGanttFromServer(taskId, callback) {
//this is a simulation: load data from the local storage if you have already played with the demo or a textarea with starting demo data
loadFromLocalStorage();
//this is the real implementation
/*
//var taskId = $("#taskSelector").val();
var prof = new Profiler("loadServerSide");
prof.reset();
$.getJSON("ganttAjaxController.jsp", {CM:"LOADPROJECT",taskId:taskId}, function(response) {
//console.debug(response);
if (response.ok) {
prof.stop();
ge.loadProject(response.project);
ge.checkpoint(); //empty the undo stack
if (typeof(callback)=="function") {
callback(response);
}
} else {
jsonErrorHandling(response);
}
});
*/
}
function saveGanttOnServer() {
//this is a simulation: save data to the local storage or to the textarea
saveInLocalStorage();
/*
var prj = ge.saveProject();
delete prj.resources;
delete prj.roles;
var prof = new Profiler("saveServerSide");
prof.reset();
if (ge.deletedTaskIds.length>0) {
if (!confirm("TASK_THAT_WILL_BE_REMOVED\n"+ge.deletedTaskIds.length)) {
return;
}
}
$.ajax("ganttAjaxController.jsp", {
dataType:"json",
data: {CM:"SVPROJECT",prj:JSON.stringify(prj)},
type:"POST",
success: function(response) {
if (response.ok) {
prof.stop();
if (response.project) {
ge.loadProject(response.project); //must reload as "tmp_" ids are now the good ones
} else {
ge.reset();
}
} else {
var errMsg="Errors saving project\n";
if (response.message) {
errMsg=errMsg+response.message+"\n";
}
if (response.errorMessages.length) {
errMsg += response.errorMessages.join("\n");
}
alert(errMsg);
}
}
});
*/
}
function newProject(){
clearGantt();
}
//------------------------------------------- Create some demo data ------------------------------------------------------
function setRoles() {
ge.roles = [
{
id:"tmp_1",
name:"Project Manager"
},
{
id:"tmp_2",
name:"Worker"
},
{
id:"tmp_3",
name:"Stakeholder"
},
{
id:"tmp_4",
name:"Customer"
}
];
}
function setResource() {
var res = [];
for (var i = 1; i <= 10; i++) {
res.push({id:"tmp_" + i,name:"Resource " + i});
}
ge.resources = res;
}
function editResources(){
}
function clearGantt() {
ge.reset();
}
function loadI18n() {
GanttMaster.messages = {
"CANNOT_WRITE": "CANNOT_WRITE",
"CHANGE_OUT_OF_SCOPE":"NO_RIGHTS_FOR_UPDATE_PARENTS_OUT_OF_EDITOR_SCOPE",
"START_IS_MILESTONE":"START_IS_MILESTONE",
"END_IS_MILESTONE":"END_IS_MILESTONE",
"TASK_HAS_CONSTRAINTS":"TASK_HAS_CONSTRAINTS",
"GANTT_ERROR_DEPENDS_ON_OPEN_TASK":"GANTT_ERROR_DEPENDS_ON_OPEN_TASK",
"GANTT_ERROR_DESCENDANT_OF_CLOSED_TASK":"GANTT_ERROR_DESCENDANT_OF_CLOSED_TASK",
"TASK_HAS_EXTERNAL_DEPS":"TASK_HAS_EXTERNAL_DEPS",
"GANTT_ERROR_LOADING_DATA_TASK_REMOVED":"GANTT_ERROR_LOADING_DATA_TASK_REMOVED",
"ERROR_SETTING_DATES":"ERROR_SETTING_DATES",
"CIRCULAR_REFERENCE":"CIRCULAR_REFERENCE",
"CANNOT_DEPENDS_ON_ANCESTORS":"CANNOT_DEPENDS_ON_ANCESTORS",
"CANNOT_DEPENDS_ON_DESCENDANTS":"CANNOT_DEPENDS_ON_DESCENDANTS",
"INVALID_DATE_FORMAT":"INVALID_DATE_FORMAT",
"TASK_MOVE_INCONSISTENT_LEVEL":"TASK_MOVE_INCONSISTENT_LEVEL",
"GANTT_QUARTER_SHORT":"trim.",
"GANTT_SEMESTER_SHORT":"sem."
};
}
//------------------------------------------- Get project file as JSON (used for migrate project from gantt to Teamwork) ------------------------------------------------------
function getFile() {
$("#gimBaPrj").val(JSON.stringify(ge.saveProject()));
$("#gimmeBack").submit();
$("#gimBaPrj").val("");
/* var uriContent = "data:text/html;charset=utf-8," + encodeURIComponent(JSON.stringify(prj));
neww=window.open(uriContent,"dl");*/
}
function loadFromLocalStorage() {
var ret;
if (localStorage) {
if (localStorage.getObject("teamworkGantDemo")) {
ret = localStorage.getObject("teamworkGantDemo");
}
}
//if not found create a new example task
if (!ret || !ret.tasks || ret.tasks.length == 0){
ret= {"tasks": [
{"id": -1, "name": "Gantt editor", "progress": 0, "progressByWorklog": false, "relevance": 0, "type": "", "typeId": "", "description": "", "code": "", "level": 0, "status": "STATUS_ACTIVE", "depends": "", "canWrite": true, "start": 1396994400000, "duration": 20, "end": 1399586399999, "startIsMilestone": false, "endIsMilestone": false, "collapsed": false, "assigs": [], "hasChild": true},
{"id": -2, "name": "coding", "progress": 0, "progressByWorklog": false, "relevance": 0, "type": "", "typeId": "", "description": "", "code": "", "level": 1, "status": "STATUS_ACTIVE", "depends": "", "canWrite": true, "start": 1396994400000, "duration": 10, "end": 1398203999999, "startIsMilestone": false, "endIsMilestone": false, "collapsed": false, "assigs": [], "hasChild": true},
{"id": -3, "name": "gantt part", "progress": 0, "progressByWorklog": false, "relevance": 0, "type": "", "typeId": "", "description": "", "code": "", "level": 2, "status": "STATUS_ACTIVE", "depends": "", "canWrite": true, "start": 1396994400000, "duration": 2, "end": 1397167199999, "startIsMilestone": false, "endIsMilestone": false, "collapsed": false, "assigs": [], "hasChild": false},
{"id": -4, "name": "editor part", "progress": 0, "progressByWorklog": false, "relevance": 0, "type": "", "typeId": "", "description": "", "code": "", "level": 2, "status": "STATUS_SUSPENDED", "depends": "3", "canWrite": true, "start": 1397167200000, "duration": 4, "end": 1397685599999, "startIsMilestone": false, "endIsMilestone": false, "collapsed": false, "assigs": [], "hasChild": false},
{"id": -5, "name": "testing", "progress": 0, "progressByWorklog": false, "relevance": 0, "type": "", "typeId": "", "description": "", "code": "", "level": 1, "status": "STATUS_SUSPENDED", "depends": "2:5", "canWrite": true, "start": 1398981600000, "duration": 5, "end": 1399586399999, "startIsMilestone": false, "endIsMilestone": false, "collapsed": false, "assigs": [], "hasChild": true},
{"id": -6, "name": "test on safari", "progress": 0, "progressByWorklog": false, "relevance": 0, "type": "", "typeId": "", "description": "", "code": "", "level": 2, "status": "STATUS_SUSPENDED", "depends": "", "canWrite": true, "start": 1398981600000, "duration": 2, "end": 1399327199999, "startIsMilestone": false, "endIsMilestone": false, "collapsed": false, "assigs": [], "hasChild": false},
{"id": -7, "name": "test on ie", "progress": 0, "progressByWorklog": false, "relevance": 0, "type": "", "typeId": "", "description": "", "code": "", "level": 2, "status": "STATUS_SUSPENDED", "depends": "6", "canWrite": true, "start": 1399327200000, "duration": 3, "end": 1399586399999, "startIsMilestone": false, "endIsMilestone": false, "collapsed": false, "assigs": [], "hasChild": false},
{"id": -8, "name": "test on chrome", "progress": 0, "progressByWorklog": false, "relevance": 0, "type": "", "typeId": "", "description": "", "code": "", "level": 2, "status": "STATUS_SUSPENDED", "depends": "6", "canWrite": true, "start": 1399327200000, "duration": 2, "end": 1399499999999, "startIsMilestone": false, "endIsMilestone": false, "collapsed": false, "assigs": [], "hasChild": false}
], "selectedRow": 2, "deletedTaskIds": [],
"resources": [
{"id": "tmp_1", "name": "Resource 1"},
{"id": "tmp_2", "name": "Resource 2"},
{"id": "tmp_3", "name": "Resource 3"},
{"id": "tmp_4", "name": "Resource 4"}
],
"roles": [
{"id": "tmp_1", "name": "Project Manager"},
{"id": "tmp_2", "name": "Worker"},
{"id": "tmp_3", "name": "Stakeholder"},
{"id": "tmp_4", "name": "Customer"}
], "canWrite": true, "canDelete":true, "canWriteOnParent": true, "zoom": "w3"}
//actualize data
var offset=new Date().getTime()-ret.tasks[0].start;
for (var i=0;i<ret.tasks.length;i++) {
ret.tasks[i].start = ret.tasks[i].start + offset;
}
}
return ret;
}
function saveInLocalStorage() {
var prj = ge.saveProject();
if (localStorage) {
localStorage.setObject("teamworkGantDemo", prj);
}
}
//------------------------------------------- Open a black popup for managing resources. This is only an axample of implementation (usually resources come from server) ------------------------------------------------------
function editResources(){
//make resource editor
var resourceEditor = $.JST.createFromTemplate({}, "RESOURCE_EDITOR");
var resTbl=resourceEditor.find("#resourcesTable");
for (var i=0;i<ge.resources.length;i++){
var res=ge.resources[i];
resTbl.append($.JST.createFromTemplate(res, "RESOURCE_ROW"))
}
//bind add resource
resourceEditor.find("#addResource").click(function(){
resTbl.append($.JST.createFromTemplate({id:"new",name:"resource"}, "RESOURCE_ROW"))
});
//bind save event
resourceEditor.find("#resSaveButton").click(function(){
var newRes=[];
//find for deleted res
for (var i=0;i<ge.resources.length;i++){
var res=ge.resources[i];
var row = resourceEditor.find("[resId="+res.id+"]");
if (row.length>0){
//if still there save it
var name = row.find("input[name]").val();
if (name && name!="")
res.name=name;
newRes.push(res);
} else {
//remove assignments
for (var j=0;j<ge.tasks.length;j++){
var task=ge.tasks[j];
var newAss=[];
for (var k=0;k<task.assigs.length;k++){
var ass=task.assigs[k];
if (ass.resourceId!=res.id)
newAss.push(ass);
}
task.assigs=newAss;
}
}
}
//loop on new rows
var cnt=0
resourceEditor.find("[resId=new]").each(function(){
cnt++;
var row = $(this);
var name = row.find("input[name]").val();
if (name && name!="")
newRes.push (new Resource("tmp_"+new Date().getTime()+"_"+cnt,name));
});
ge.resources=newRes;
closeBlackPopup();
ge.redraw();
});
var ndo = createModalPopup(400, 500).append(resourceEditor);
}
</script>
<div id="gantEditorTemplates" style="display:none;">
<div class="__template__" type="GANTBUTTONS"><!--
<div class="ganttButtonBar noprint">
<div class="buttons">
<a href="https://gantt.twproject.com/"><img src="res/twGanttLogo.png" alt="Twproject" align="absmiddle" style="max-width: 136px; padding-right: 15px"></a>
<button onclick="$('#workSpace').trigger('undo.gantt');return false;" class="button textual icon requireCanWrite" title="undo"><span class="teamworkIcon">&#39;</span></button>
<button onclick="$('#workSpace').trigger('redo.gantt');return false;" class="button textual icon requireCanWrite" title="redo"><span class="teamworkIcon">&middot;</span></button>
<span class="ganttButtonSeparator requireCanWrite requireCanAdd"></span>
<button onclick="$('#workSpace').trigger('addAboveCurrentTask.gantt');return false;" class="button textual icon requireCanWrite requireCanAdd" title="insert above"><span class="teamworkIcon">l</span></button>
<button onclick="$('#workSpace').trigger('addBelowCurrentTask.gantt');return false;" class="button textual icon requireCanWrite requireCanAdd" title="insert below"><span class="teamworkIcon">X</span></button>
<span class="ganttButtonSeparator requireCanWrite requireCanInOutdent"></span>
<button onclick="$('#workSpace').trigger('outdentCurrentTask.gantt');return false;" class="button textual icon requireCanWrite requireCanInOutdent" title="un-indent task"><span class="teamworkIcon">.</span></button>
<button onclick="$('#workSpace').trigger('indentCurrentTask.gantt');return false;" class="button textual icon requireCanWrite requireCanInOutdent" title="indent task"><span class="teamworkIcon">:</span></button>
<span class="ganttButtonSeparator requireCanWrite requireCanMoveUpDown"></span>
<button onclick="$('#workSpace').trigger('moveUpCurrentTask.gantt');return false;" class="button textual icon requireCanWrite requireCanMoveUpDown" title="move up"><span class="teamworkIcon">k</span></button>
<button onclick="$('#workSpace').trigger('moveDownCurrentTask.gantt');return false;" class="button textual icon requireCanWrite requireCanMoveUpDown" title="move down"><span class="teamworkIcon">j</span></button>
<span class="ganttButtonSeparator requireCanDelete"></span>
<button onclick="$('#workSpace').trigger('deleteFocused.gantt');return false;" class="button textual icon delete requireCanWrite" title="Delete"><span class="teamworkIcon">&cent;</span></button>
<span class="ganttButtonSeparator"></span>
<button onclick="$('#workSpace').trigger('expandAll.gantt');return false;" class="button textual icon " title="EXPAND_ALL"><span class="teamworkIcon">6</span></button>
<button onclick="$('#workSpace').trigger('collapseAll.gantt'); return false;" class="button textual icon " title="COLLAPSE_ALL"><span class="teamworkIcon">5</span></button>
<span class="ganttButtonSeparator"></span>
<button onclick="$('#workSpace').trigger('zoomMinus.gantt'); return false;" class="button textual icon " title="zoom out"><span class="teamworkIcon">)</span></button>
<button onclick="$('#workSpace').trigger('zoomPlus.gantt');return false;" class="button textual icon " title="zoom in"><span class="teamworkIcon">(</span></button>
<span class="ganttButtonSeparator"></span>
<button onclick="print();return false;" class="button textual icon " title="Print"><span class="teamworkIcon">p</span></button>
<span class="ganttButtonSeparator"></span>
<button onclick="ge.gantt.showCriticalPath=!ge.gantt.showCriticalPath; ge.redraw();return false;" class="button textual icon requireCanSeeCriticalPath" title="CRITICAL_PATH"><span class="teamworkIcon">&pound;</span></button>
<span class="ganttButtonSeparator requireCanSeeCriticalPath"></span>
<button onclick="ge.splitter.resize(.1);return false;" class="button textual icon" ><span class="teamworkIcon">F</span></button>
<button onclick="ge.splitter.resize(50);return false;" class="button textual icon" ><span class="teamworkIcon">O</span></button>
<button onclick="ge.splitter.resize(100);return false;" class="button textual icon"><span class="teamworkIcon">R</span></button>
<span class="ganttButtonSeparator"></span>
<button onclick="$('#workSpace').trigger('fullScreen.gantt');return false;" class="button textual icon" title="FULLSCREEN" id="fullscrbtn"><span class="teamworkIcon">@</span></button>
<button onclick="ge.element.toggleClass('colorByStatus' );return false;" class="button textual icon"><span class="teamworkIcon">&sect;</span></button>
<button onclick="editResources();" class="button textual requireWrite" title="edit resources"><span class="teamworkIcon">M</span></button>
&nbsp; &nbsp; &nbsp; &nbsp;
<button onclick="saveGanttOnServer();" class="button first big requireWrite" title="Save">Save</button>
<button onclick='newProject();' class='button requireWrite newproject'><em>clear project</em></button>
<button class="button login" title="login/enroll" onclick="loginEnroll($(this));" style="display:none;">login/enroll</button>
<button class="button opt collab" title="Start with Twproject" onclick="collaborate($(this));" style="display:none;"><em>collaborate</em></button>
</div></div>
--></div>
<div class="__template__" type="TASKSEDITHEAD"><!--
<table class="gdfTable" cellspacing="0" cellpadding="0">
<thead>
<tr style="height:40px">
<th class="gdfColHeader" style="width:35px; border-right: none"></th>
<th class="gdfColHeader" style="width:25px;"></th>
<th class="gdfColHeader gdfResizable" style="width:100px;">code/short name</th>
<th class="gdfColHeader gdfResizable" style="width:300px;">name</th>
<th class="gdfColHeader" align="center" style="width:17px;" title="Start date is a milestone."><span class="teamworkIcon" style="font-size: 8px;">^</span></th>
<th class="gdfColHeader gdfResizable" style="width:80px;">start</th>
<th class="gdfColHeader" align="center" style="width:17px;" title="End date is a milestone."><span class="teamworkIcon" style="font-size: 8px;">^</span></th>
<th class="gdfColHeader gdfResizable" style="width:80px;">End</th>
<th class="gdfColHeader gdfResizable" style="width:50px;">dur.</th>
<th class="gdfColHeader gdfResizable" style="width:20px;">%</th>
<th class="gdfColHeader gdfResizable requireCanSeeDep" style="width:50px;">depe.</th>
<th class="gdfColHeader gdfResizable" style="width:1000px; text-align: left; padding-left: 10px;">assignees</th>
</tr>
</thead>
</table>
--></div>
<div class="__template__" type="TASKROW"><!--
<tr taskId="(#=obj.id#)" class="taskEditRow (#=obj.isParent()?'isParent':''#) (#=obj.collapsed?'collapsed':''#)" level="(#=level#)">
<th class="gdfCell edit" align="right" style="cursor:pointer;"><span class="taskRowIndex">(#=obj.getRow()+1#)</span> <span class="teamworkIcon" style="font-size:12px;" >e</span></th>
<td class="gdfCell noClip" align="center"><div class="taskStatus cvcColorSquare" status="(#=obj.status#)"></div></td>
<td class="gdfCell"><input type="text" name="code" value="(#=obj.code?obj.code:''#)" placeholder="code/short name"></td>
<td class="gdfCell indentCell" style="padding-left:(#=obj.level*10+18#)px;">
<div class="exp-controller" align="center"></div>
<input type="text" name="name" value="(#=obj.name#)" placeholder="name">
</td>
<td class="gdfCell" align="center"><input type="checkbox" name="startIsMilestone"></td>
<td class="gdfCell"><input type="text" name="start" value="" class="date"></td>
<td class="gdfCell" align="center"><input type="checkbox" name="endIsMilestone"></td>
<td class="gdfCell"><input type="text" name="end" value="" class="date"></td>
<td class="gdfCell"><input type="text" name="duration" autocomplete="off" value="(#=obj.duration#)"></td>
<td class="gdfCell"><input type="text" name="progress" class="validated" entrytype="PERCENTILE" autocomplete="off" value="(#=obj.progress?obj.progress:''#)" (#=obj.progressByWorklog?"readOnly":""#)></td>
<td class="gdfCell requireCanSeeDep"><input type="text" name="depends" autocomplete="off" value="(#=obj.depends#)" (#=obj.hasExternalDep?"readonly":""#)></td>
<td class="gdfCell taskAssigs">(#=obj.getAssigsString()#)</td>
</tr>
--></div>
<div class="__template__" type="TASKEMPTYROW"><!--
<tr class="taskEditRow emptyRow" >
<th class="gdfCell" align="right"></th>
<td class="gdfCell noClip" align="center"></td>
<td class="gdfCell"></td>
<td class="gdfCell"></td>
<td class="gdfCell"></td>
<td class="gdfCell"></td>
<td class="gdfCell"></td>
<td class="gdfCell"></td>
<td class="gdfCell"></td>
<td class="gdfCell"></td>
<td class="gdfCell requireCanSeeDep"></td>
<td class="gdfCell"></td>
</tr>
--></div>
<div class="__template__" type="TASKBAR"><!--
<div class="taskBox taskBoxDiv" taskId="(#=obj.id#)" >
<div class="layout (#=obj.hasExternalDep?'extDep':''#)">
<div class="taskStatus" status="(#=obj.status#)"></div>
<div class="taskProgress" style="width:(#=obj.progress>100?100:obj.progress#)%; background-color:(#=obj.progress>100?'red':'rgb(153,255,51);'#);"></div>
<div class="milestone (#=obj.startIsMilestone?'active':''#)" ></div>
<div class="taskLabel"></div>
<div class="milestone end (#=obj.endIsMilestone?'active':''#)" ></div>
</div>
</div>
--></div>
<div class="__template__" type="CHANGE_STATUS"><!--
<div class="taskStatusBox">
<div class="taskStatus cvcColorSquare" status="STATUS_ACTIVE" title="active"></div>
<div class="taskStatus cvcColorSquare" status="STATUS_DONE" title="completed"></div>
<div class="taskStatus cvcColorSquare" status="STATUS_FAILED" title="failed"></div>
<div class="taskStatus cvcColorSquare" status="STATUS_SUSPENDED" title="suspended"></div>
<div class="taskStatus cvcColorSquare" status="STATUS_UNDEFINED" title="undefined"></div>
</div>
--></div>
<div class="__template__" type="TASK_EDITOR"><!--
<div class="ganttTaskEditor">
<h2 class="taskData">Task editor</h2>
<table cellspacing="1" cellpadding="5" width="100%" class="taskData table" border="0">
<tr>
<td width="200" style="height: 80px" valign="top">
<label for="code">code/short name</label><br>
<input type="text" name="code" id="code" value="" size=15 class="formElements" autocomplete='off' maxlength=255 style='width:100%' oldvalue="1">
</td>
<td colspan="3" valign="top"><label for="name" class="required">name</label><br><input type="text" name="name" id="name"class="formElements" autocomplete='off' maxlength=255 style='width:100%' value="" required="true" oldvalue="1"></td>
</tr>
<tr class="dateRow">
<td nowrap="">
<div style="position:relative">
<label for="start">start</label>&nbsp;&nbsp;&nbsp;&nbsp;
<input type="checkbox" id="startIsMilestone" name="startIsMilestone" value="yes"> &nbsp;<label for="startIsMilestone">is milestone</label>&nbsp;
<br><input type="text" name="start" id="start" size="8" class="formElements dateField validated date" autocomplete="off" maxlength="255" value="" oldvalue="1" entrytype="DATE">
<span title="calendar" id="starts_inputDate" class="teamworkIcon openCalendar" onclick="$(this).dateField({inputField:$(this).prevAll(':input:first'),isSearchField:false});">m</span> </div>
</td>
<td nowrap="">
<label for="end">End</label>&nbsp;&nbsp;&nbsp;&nbsp;
<input type="checkbox" id="endIsMilestone" name="endIsMilestone" value="yes"> &nbsp;<label for="endIsMilestone">is milestone</label>&nbsp;
<br><input type="text" name="end" id="end" size="8" class="formElements dateField validated date" autocomplete="off" maxlength="255" value="" oldvalue="1" entrytype="DATE">
<span title="calendar" id="ends_inputDate" class="teamworkIcon openCalendar" onclick="$(this).dateField({inputField:$(this).prevAll(':input:first'),isSearchField:false});">m</span>
</td>
<td nowrap="" >
<label for="duration" class=" ">Days</label><br>
<input type="text" name="duration" id="duration" size="4" class="formElements validated durationdays" title="Duration is in working days." autocomplete="off" maxlength="255" value="" oldvalue="1" entrytype="DURATIONDAYS">&nbsp;
</td>
</tr>
<tr>
<td colspan="2">
<label for="status" class=" ">status</label><br>
<select id="status" name="status" class="taskStatus" status="(#=obj.status#)" onchange="$(this).attr('STATUS',$(this).val());">
<option value="STATUS_ACTIVE" class="taskStatus" status="STATUS_ACTIVE" >active</option>
<option value="STATUS_SUSPENDED" class="taskStatus" status="STATUS_SUSPENDED" >suspended</option>
<option value="STATUS_DONE" class="taskStatus" status="STATUS_DONE" >completed</option>
<option value="STATUS_FAILED" class="taskStatus" status="STATUS_FAILED" >failed</option>
<option value="STATUS_UNDEFINED" class="taskStatus" status="STATUS_UNDEFINED" >undefined</option>
</select>
</td>
<td valign="top" nowrap>
<label>progress</label><br>
<input type="text" name="progress" id="progress" size="7" class="formElements validated percentile" autocomplete="off" maxlength="255" value="" oldvalue="1" entrytype="PERCENTILE">
</td>
</tr>
</tr>
<tr>
<td colspan="4">
<label for="description">Description</label><br>
<textarea rows="3" cols="30" id="description" name="description" class="formElements" style="width:100%"></textarea>
</td>
</tr>
</table>
<h2>Assignments</h2>
<table cellspacing="1" cellpadding="0" width="100%" id="assigsTable">
<tr>
<th style="width:100px;">name</th>
<th style="width:70px;">Role</th>
<th style="width:30px;">est.wklg.</th>
<th style="width:30px;" id="addAssig"><span class="teamworkIcon" style="cursor: pointer">+</span></th>
</tr>
</table>
<div style="text-align: right; padding-top: 20px">
<span id="saveButton" class="button first" onClick="$(this).trigger('saveFullEditor.gantt');">Save</span>
</div>
</div>
--></div>
<div class="__template__" type="ASSIGNMENT_ROW"><!--
<tr taskId="(#=obj.task.id#)" assId="(#=obj.assig.id#)" class="assigEditRow" >
<td ><select name="resourceId" class="formElements" (#=obj.assig.id.indexOf("tmp_")==0?"":"disabled"#) ></select></td>
<td ><select type="select" name="roleId" class="formElements"></select></td>
<td ><input type="text" name="effort" value="(#=getMillisInHoursMinutes(obj.assig.effort)#)" size="5" class="formElements"></td>
<td align="center"><span class="teamworkIcon delAssig del" style="cursor: pointer">d</span></td>
</tr>
--></div>
<div class="__template__" type="RESOURCE_EDITOR"><!--
<div class="resourceEditor" style="padding: 5px;">
<h2>Project team</h2>
<table cellspacing="1" cellpadding="0" width="100%" id="resourcesTable">
<tr>
<th style="width:100px;">name</th>
<th style="width:30px;" id="addResource"><span class="teamworkIcon" style="cursor: pointer">+</span></th>
</tr>
</table>
<div style="text-align: right; padding-top: 20px"><button id="resSaveButton" class="button big">Save</button></div>
</div>
--></div>
<div class="__template__" type="RESOURCE_ROW"><!--
<tr resId="(#=obj.id#)" class="resRow" >
<td ><input type="text" name="name" value="(#=obj.name#)" style="width:100%;" class="formElements"></td>
<td align="center"><span class="teamworkIcon delRes del" style="cursor: pointer">d</span></td>
</tr>
--></div>
</div>
<script type="text/javascript">
$.JST.loadDecorator("RESOURCE_ROW", function(resTr, res){
resTr.find(".delRes").click(function(){$(this).closest("tr").remove()});
});
$.JST.loadDecorator("ASSIGNMENT_ROW", function(assigTr, taskAssig){
var resEl = assigTr.find("[name=resourceId]");
var opt = $("<option>");
resEl.append(opt);
for(var i=0; i< taskAssig.task.master.resources.length;i++){
var res = taskAssig.task.master.resources[i];
opt = $("<option>");
opt.val(res.id).html(res.name);
if(taskAssig.assig.resourceId == res.id)
opt.attr("selected", "true");
resEl.append(opt);
}
var roleEl = assigTr.find("[name=roleId]");
for(var i=0; i< taskAssig.task.master.roles.length;i++){
var role = taskAssig.task.master.roles[i];
var optr = $("<option>");
optr.val(role.id).html(role.name);
if(taskAssig.assig.roleId == role.id)
optr.attr("selected", "true");
roleEl.append(optr);
}
if(taskAssig.task.master.permissions.canWrite && taskAssig.task.canWrite){
assigTr.find(".delAssig").click(function(){
var tr = $(this).closest("[assId]").fadeOut(200, function(){$(this).remove()});
});
}
});
function loadI18n(){
GanttMaster.messages = {
"CANNOT_WRITE":"No permission to change the following task:",
"CHANGE_OUT_OF_SCOPE":"Project update not possible as you lack rights for updating a parent project.",
"START_IS_MILESTONE":"Start date is a milestone.",
"END_IS_MILESTONE":"End date is a milestone.",
"TASK_HAS_CONSTRAINTS":"Task has constraints.",
"GANTT_ERROR_DEPENDS_ON_OPEN_TASK":"Error: there is a dependency on an open task.",
"GANTT_ERROR_DESCENDANT_OF_CLOSED_TASK":"Error: due to a descendant of a closed task.",
"TASK_HAS_EXTERNAL_DEPS":"This task has external dependencies.",
"GANNT_ERROR_LOADING_DATA_TASK_REMOVED":"GANNT_ERROR_LOADING_DATA_TASK_REMOVED",
"CIRCULAR_REFERENCE":"Circular reference.",
"CANNOT_DEPENDS_ON_ANCESTORS":"Cannot depend on ancestors.",
"INVALID_DATE_FORMAT":"The data inserted are invalid for the field format.",
"GANTT_ERROR_LOADING_DATA_TASK_REMOVED":"An error has occurred while loading the data. A task has been trashed.",
"CANNOT_CLOSE_TASK_IF_OPEN_ISSUE":"Cannot close a task with open issues",
"TASK_MOVE_INCONSISTENT_LEVEL":"You cannot exchange tasks of different depth.",
"GANTT_QUARTER_SHORT":"Quarter",
"GANTT_SEMESTER_SHORT":"Sem",
"CANNOT_MOVE_TASK":"CANNOT_MOVE_TASK",
"PLEASE_SAVE_PROJECT":"PLEASE_SAVE_PROJECT"
};
}
function createNewResource(el) {
var row = el.closest("tr[taskid]");
var name = row.find("[name=resourceId_txt]").val();
var url = contextPath + "/applications/teamwork/resource/resourceNew.jsp?CM=ADD&name=" + encodeURI(name);
openBlackPopup(url, 700, 320, function (response) {
//fillare lo smart combo
if (response && response.resId && response.resName) {
//fillare lo smart combo e chiudere l'editor
row.find("[name=resourceId]").val(response.resId);
row.find("[name=resourceId_txt]").val(response.resName).focus().blur();
}
});
}
</script>
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-36251023-1']);
_gaq.push(['_setDomainName', 'jqueryscript.net']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
</body>
</html>

339
samples/dhtmlx-gantt/license.txt

@ -0,0 +1,339 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.

31
samples/dhtmlx-gantt/package.json

@ -0,0 +1,31 @@
{
"name": "dhtmlx-gantt",
"version": "7.1.8",
"description": "An open source JavaScript Gantt chart that helps you illustrate a project schedule in a nice-looking chart.",
"main": "codebase/dhtmlxgantt.js",
"types": "codebase/dhtmlxgantt.d.ts",
"repository": {
"type": "git",
"url": "git+https://github.com/DHTMLX/gantt.git"
},
"keywords": [
"gantt",
"chart",
"gantt chart",
"calendar",
"scheduler",
"dhtmlx",
"dhtmlxgantt",
"timeline",
"browser"
],
"author": "DHTMLX",
"license": "GPL-2.0",
"bugs": {
"url": "https://github.com/DHTMLX/gantt/issues"
},
"homepage": "https://github.com/DHTMLX/gantt#readme",
"scripts": {
"start": "cd backend && npm install && npm start"
}
}

52
samples/dhtmlx-gantt/readme.txt

@ -0,0 +1,52 @@
DHTMLX Gantt
============
Version 7.1.8, Standard Edition
License
------------
GPL-2.0 License, check license.txt for more details
How to start
------------
- check our how-to-start tutorials https://docs.dhtmlx.com/gantt/desktop__howtostart_guides.html
- explore code samples https://docs.dhtmlx.com/gantt/samples/
How to run samples
------------
All the samples except for a few that explicitly require a REST backend api can be opened as static files.
Running the backend:
- `npm install` or `yarn install`
- `npm start` or `yarn start`
- go to `http://localhost:9200`
or
- copy `codebase` and `samples` folders of the package to your Apache/nginx directory and open samples as static html pages. Demos that require RESTful backend will not work in that case.
Package structure
------------
- ./codebase - css and javascript files of the library
- ./samples - code samples
- ./backend - a simple node backend to run samples
Useful links
-------------
- Product information
https://dhtmlx.com/docs/products/dhtmlxGantt/
- Online documentation
https://docs.dhtmlx.com/gantt/
- Support forum
https://forum.dhtmlx.com/c/gantt

33
samples/dhtmlx-gantt/samples/01_initialization/01_basic_init.html

@ -0,0 +1,33 @@
<!DOCTYPE html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Basic initialization</title>
<script src="../../codebase/dhtmlxgantt.js?v=7.1.8"></script>
<link rel="stylesheet" href="../../codebase/dhtmlxgantt.css?v=7.1.8">
<style>
html, body {
height: 100%;
padding: 0px;
margin: 0px;
overflow: hidden;
}
</style>
</head>
<body>
<div id="gantt_here" style='width:100%; height:100%;'></div>
<script>
gantt.init("gantt_here");
gantt.parse({
data: [
{ id: 1, text: "Project #2", start_date: "01-04-2018", duration: 18, progress: 0.4, open: true },
{ id: 2, text: "Task #1", start_date: "02-04-2018", duration: 8, progress: 0.6, parent: 1 },
{ id: 3, text: "Task #2", start_date: "11-04-2018", duration: 8, progress: 0.6, parent: 1 }
],
links: [
{id: 1, source: 1, target: 2, type: "1"},
{id: 2, source: 2, target: 3, type: "0"}
]
});
</script>
</body>

22
samples/dhtmlx-gantt/samples/01_initialization/02_load_json.html

@ -0,0 +1,22 @@
<!DOCTYPE html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Load data from JSON file</title>
<script src="../../codebase/dhtmlxgantt.js?v=7.1.8"></script>
<link rel="stylesheet" href="../../codebase/dhtmlxgantt.css?v=7.1.8">
<style>
html, body {
padding: 0px;
margin: 0px;
height: 100%;
}
</style>
</head>
<body>
<div id="gantt_here" style='width:100%; height:100%;'></div>
<script>
gantt.config.date_format = "%Y-%m-%d %H:%i:%s";
gantt.init("gantt_here");
gantt.load("../common/data.json", "json");
</script>
</body>

23
samples/dhtmlx-gantt/samples/01_initialization/03_load_xml.html

@ -0,0 +1,23 @@
<!DOCTYPE html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Load data from XML file</title>
<script src="../../codebase/dhtmlxgantt.js?v=7.1.8"></script>
<link rel="stylesheet" href="../../codebase/dhtmlxgantt.css?v=7.1.8">
<style>
html, body {
padding: 0px;
margin: 0px;
height: 100%;
}
</style>
</head>
<body>
<div id="gantt_here" style='width:100%; height:100%;'></div>
<script>
gantt.config.date_grid = "%Y-%m-%d %H:%i";
gantt.config.date_format = "%Y-%m-%d %H:%i:%s";
gantt.init("gantt_here");
gantt.load("../common/data.xml", "xml");
</script>
</body>

44
samples/dhtmlx-gantt/samples/01_initialization/04_save_rest.html

@ -0,0 +1,44 @@
<!DOCTYPE html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Backend storage using REST API</title>
<script src="../../codebase/dhtmlxgantt.js?v=7.1.8"></script>
<link rel="stylesheet" href="../../codebase/dhtmlxgantt.css?v=7.1.8">
<style>
html, body {
height: 100%;
padding: 0px;
margin: 0px;
overflow: hidden;
}
</style>
</head>
<body>
<div id="gantt_here" style='width:100%; height:100%;'></div>
<script>
gantt.message({
text: "This example requires a RESTful API on the backend. <br>Check our <a target='_blank' href='https://docs.dhtmlx.com/gantt/desktop__server_side.html'>guides on backend integration here</a> ",
expire: -1
});
gantt.message({
text: "You can also find our step-by-step tutorials for different platforms <a target='_blank' href='https://docs.dhtmlx.com/gantt/desktop__howtostart_guides.html'>here </a> ",
expire: -1
});
gantt.attachEvent("onBeforeTaskAdd", function(id,task){
//do not allow incorrect dates
task.start_date = task.start_date || gantt.getTaskByIndex(0).start_date || new Date();
task.end_date = task.end_date || gantt.getTaskByIndex(0).end_date || new Date();
return true;
});
gantt.config.date_format = "%Y-%m-%d %H:%i:%s";
gantt.init("gantt_here");
gantt.load("/gantt/backend/data");
var dp = gantt.createDataProcessor({
url: "/gantt/backend/data",
mode: "REST"
});
</script>
</body>

29
samples/dhtmlx-gantt/samples/01_initialization/06_touch_forced.html

@ -0,0 +1,29 @@
<!doctype html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Forced touch mode</title>
<script src="../../codebase/dhtmlxgantt.js?v=7.1.8"></script>
<link rel="stylesheet" href="../../codebase/dhtmlxgantt.css?v=7.1.8">
<script src="../common/testdata.js?v=7.1.8"></script>
<style>
html, body {
height: 100%;
padding: 0px;
margin: 0px;
overflow: hidden;
}
</style>
</head>
<body>
<div id="gantt_here" style='width:100%; height:100%;'></div>
<script>
gantt.config.touch = "force";
gantt.init("gantt_here");
gantt.parse(demo_tasks);
</script>
</body>
</html>

27
samples/dhtmlx-gantt/samples/01_initialization/07_jquery.html

@ -0,0 +1,27 @@
<!DOCTYPE html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>jQuery integration</title>
<script src="https://code.jquery.com/jquery-1.7.1.min.js?v=7.1.8"></script>
<script src="../../codebase/dhtmlxgantt.js?v=7.1.8"></script>
<link rel="stylesheet" href="../../codebase/dhtmlxgantt.css?v=7.1.8">
<script src="../common/testdata.js?v=7.1.8"></script>
<style>
html, body {
height: 100%;
padding: 0px;
margin: 0px;
overflow: hidden;
}
</style>
</head>
<body>
<div class="mygantt" style='width:100%; height:100%;'></div>
<script>
$(".mygantt").dhx_gantt({
data: demo_tasks
});
</script>
</body>

30
samples/dhtmlx-gantt/samples/01_initialization/08_explicit_time_range.html

@ -0,0 +1,30 @@
<!DOCTYPE html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Define date range</title>
<script src="../../codebase/dhtmlxgantt.js?v=7.1.8"></script>
<link rel="stylesheet" href="../../codebase/skins/dhtmlxgantt_meadow.css?v=7.1.8">
<script src="../common/testdata.js?v=7.1.8"></script>
<style>
html, body {
height: 100%;
padding: 0px;
margin: 0px;
overflow: hidden;
}
</style>
</head>
<body>
<div id="gantt_here" style='width:100%; height:100%;'></div>
<script>
gantt.config.scales = [
{unit: "month", step: 1, format: "%M"},
{unit: "year", step: 1, format: "%Y"},
{unit: "day", format: "%d %M"}
];
gantt.config.scale_height = 3 * 28;
gantt.init("gantt_here", new Date(2018, 02, 10), new Date(2018, 03, 20));
gantt.parse(demo_tasks);
</script>
</body>

24
samples/dhtmlx-gantt/samples/01_initialization/09_backward_compatibility.html

@ -0,0 +1,24 @@
<!DOCTYPE html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Loading data in Gantt 1.6 format</title>
<script src="../../codebase/dhtmlxgantt.js?v=7.1.8"></script>
<link rel="stylesheet" href="../../codebase/dhtmlxgantt.css?v=7.1.8">
<script src="../common/testdata.js?v=7.1.8"></script>
<style>
html, body {
padding: 0px;
margin: 0px;
height: 100%;
}
</style>
</head>
<body>
<div id="gantt_here" style='width:100%; height:100%;'></div>
<script>
gantt.config.date_format = "%Y,%m,%d";
gantt.init("gantt_here");
gantt.load("../common/olddata.xml", "oldxml");
</script>
</body>

16
samples/dhtmlx-gantt/samples/01_initialization/10_fixed_size.html

@ -0,0 +1,16 @@
<!DOCTYPE html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Fixed size gantt</title>
<script src="../../codebase/dhtmlxgantt.js?v=7.1.8"></script>
<link rel="stylesheet" href="../../codebase/dhtmlxgantt.css?v=7.1.8">
<script src="../common/testdata.js?v=7.1.8"></script>
</head>
<body>
<div id="gantt_here" style='width:1020px; height:400px;'></div>
<script>
gantt.init("gantt_here");
gantt.parse(demo_tasks);
</script>
</body>

50
samples/dhtmlx-gantt/samples/01_initialization/11_clickable_links.html

@ -0,0 +1,50 @@
<!DOCTYPE html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Clickable links</title>
<script src="../../codebase/dhtmlxgantt.js?v=7.1.8"></script>
<link rel="stylesheet" href="../../codebase/dhtmlxgantt.css?v=7.1.8">
<script src="../common/testdata.js?v=7.1.8"></script>
<style>
html, body {
height: 100%;
padding: 0px;
margin: 0px;
overflow: hidden;
}
</style>
</head>
<body>
<div id="gantt_here" style='width:100%; height:100%;'></div>
<script>
gantt.init("gantt_here");
gantt.parse(demo_tasks);
gantt.attachEvent("onLinkClick", function (id) {
var link = this.getLink(id),
src = this.getTask(link.source),
trg = this.getTask(link.target),
types = this.config.links;
var first = "", second = "";
switch (link.type) {
case types.finish_to_start:
first = "finish";
second = "start";
break;
case types.start_to_start:
first = "start";
second = "start";
break;
case types.finish_to_finish:
first = "finish";
second = "finish";
break;
}
gantt.message("Must " + first + " <b>" + src.text + "</b> to " + second + " <b>" + trg.text + "</b>");
});
</script>
</body>

28
samples/dhtmlx-gantt/samples/01_initialization/12_localization.html

@ -0,0 +1,28 @@
<!DOCTYPE html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Localization</title>
<script src="../../codebase/dhtmlxgantt.js?v=7.1.8"></script>
<link rel="stylesheet" href="../../codebase/dhtmlxgantt.css?v=7.1.8">
<script src="../common/testdata.js?v=7.1.8"></script>
<style>
html, body {
height: 100%;
padding: 0px;
margin: 0px;
overflow: hidden;
}
</style>
</head>
<body>
<div id="gantt_here" style='width:100%; height:100%;'></div>
<script>
gantt.i18n.setLocale("fr");
gantt.init("gantt_here");
gantt.parse(demo_tasks);
</script>
</body>

82
samples/dhtmlx-gantt/samples/01_initialization/13_project_duration.html

@ -0,0 +1,82 @@
<!DOCTYPE html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Project duration</title>
<script src="../../codebase/dhtmlxgantt.js?v=7.1.8"></script>
<link rel="stylesheet" href="../../codebase/dhtmlxgantt.css?v=7.1.8">
<script src="../common/testdata.js?v=7.1.8"></script>
<style>
html, body {
height: 100%;
padding: 0px;
margin: 0px;
overflow: hidden;
}
.gantt_task_line.gantt_dependent_task {
background-color: #65c16f;
border: 1px solid #3c9445;
}
.gantt_task_line.gantt_dependent_task .gantt_task_progress {
background-color: #46ad51;
}
</style>
</head>
<body>
<div id="gantt_here" style='width:100%; height:100%;'></div>
<script>
gantt.config.lightbox.sections = [
{name: "description", height: 70, map_to: "text", type: "textarea", focus: true},
{name: "time", type: "duration", map_to: "auto"}
];
gantt.config.scale_height = 50;
gantt.config.scales = [
{unit: "month", format: "%F, %Y"},
{unit: "day", step: 1, format: "%j, %D"}
];
gantt.init("gantt_here");
gantt.parse({
data: [
{id: 11, text: "Project #1", start_date: "", duration: 0, progress: 0.6, open: true},
{id:12, text:"Task #1", start_date:"03-04-2018", duration:"5", parent:11, progress: 1, open: true},
{id:13, text:"Task #2", start_date:"", duration:"", parent:11, progress: 0.5, open: true},
{id:14, text:"Task #3", start_date:"02-04-2018", duration:"6", parent:11, progress: 0.8, open: true},
{id:15, text:"Task #4", start_date:"", duration:"", parent:11, progress: 0.2, open: true},
{id:16, text:"Task #5", start_date:"02-04-2018", duration:"7", parent:11, progress: 0, open: true},
{id:17, text:"Task #2.1", start_date:"03-04-2018", duration:"2", parent:13, progress: 1, open: true},
{id:18, text:"Task #2.2", start_date:"06-04-2018", duration:"3", parent:13, progress: 0.8, open: true},
{id:19, text:"Task #2.3", start_date:"10-04-2018", duration:"4", parent:13, progress: 0.2, open: true},
{id:20, text:"Task #2.4", start_date:"10-04-2018", duration:"4", parent:13, progress: 0, open: true},
{id:21, text:"Task #4.1", start_date:"03-04-2018", duration:"4", parent:15, progress: 0.5, open: true},
{id:22, text:"Task #4.2", start_date:"03-04-2018", duration:"4", parent:15, progress: 0.1, open: true},
{id:23, text:"Task #4.3", start_date:"03-04-2018", duration:"5", parent:15, progress: 0, open: true}
],
links:[
{id:"10",source:"11",target:"12",type:"1"},
{id:"11",source:"11",target:"13",type:"1"},
{id:"12",source:"11",target:"14",type:"1"},
{id:"13",source:"11",target:"15",type:"1"},
{id:"14",source:"11",target:"16",type:"1"},
{id:"15",source:"13",target:"17",type:"1"},
{id:"16",source:"17",target:"18",type:"0"},
{id:"17",source:"18",target:"19",type:"0"},
{id:"18",source:"19",target:"20",type:"0"},
{id:"19",source:"15",target:"21",type:"2"},
{id:"20",source:"15",target:"22",type:"2"},
{id:"21",source:"15",target:"23",type:"2"}
]
});
</script>
</body>

42
samples/dhtmlx-gantt/samples/01_initialization/14_reinitializtion.html

@ -0,0 +1,42 @@
<!DOCTYPE html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>ReInit in different container</title>
<script src="../../codebase/dhtmlxgantt.js?v=7.1.8"></script>
<link rel="stylesheet" href="../../codebase/dhtmlxgantt.css?v=7.1.8">
<link rel="stylesheet" href="../common/controls_styles.css?v=7.1.8">
<style>
html, body {
height: 100%;
padding: 0px;
margin: 0px;
overflow: hidden;
}
</style>
</head>
<body>
<div id="gantt_here" style='width:100%; height:40%;'></div>
<div class="gantt_control">
<input type="button" value="Init in the second html container" onclick="reinit()">
</div>
<div id="gantt_here2" style='width:100%; height:40%;'></div>
<script>
gantt.init("gantt_here");
gantt.parse({
data: [
{ id: 1, text: "Project #2", start_date: "01-04-2018", duration: 18, progress: 0.4, open: true },
{ id: 2, text: "Task #1", start_date: "02-04-2018", duration: 8, progress: 0.6, parent: 1 },
{ id: 3, text: "Task #2", start_date: "11-04-2018", duration: 8, progress: 0.6, parent: 1 }
],
links: [
{id: 1, source: 1, target: 2, type: "1"},
{id: 2, source: 2, target: 3, type: "0"}
]
});
function reinit() {
gantt.init("gantt_here2");
}
</script>
</body>

24
samples/dhtmlx-gantt/samples/01_initialization/15_connector_json_enddate.html

@ -0,0 +1,24 @@
<!DOCTYPE html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Loading tasks start/end dates</title>
<script src="../../codebase/dhtmlxgantt.js?v=7.1.8"></script>
<link rel="stylesheet" href="../../codebase/dhtmlxgantt.css?v=7.1.8">
<style>
html, body {
height: 100%;
padding: 0px;
margin: 0px;
overflow: hidden;
}
</style>
</head>
<body>
<div id="gantt_here" style='width:100%; height:100%;'></div>
<script>
gantt.config.date_format = "%Y-%m-%d %H:%i:%s";
gantt.init("gantt_here");
gantt.load("../common/data_start_end_dates.json");
</script>
</body>

275
samples/dhtmlx-gantt/samples/01_initialization/17_bootstrap.html

@ -0,0 +1,275 @@
<!DOCTYPE html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Bootstrap layout</title>
<script src="../../codebase/dhtmlxgantt.js?v=7.1.8"></script>
<link rel="stylesheet" href="../../codebase/dhtmlxgantt.css?v=7.1.8">
<script src="https://code.jquery.com/jquery-3.3.1.min.js?v=7.1.8" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css?v=7.1.8" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css?v=7.1.8" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js?v=7.1.8" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<style>
html, body {
height: 100%;
padding: 0px;
margin: 0px;
}
.weekend {
background: #f4f7f4 !important;
}
.gantt_selected .weekend {
background: #FFF3A1 !important;
}
.well {
text-align: right;
}
@media (max-width: 991px) {
.nav-stacked > li {
float: left;
}
}
.container-fluid .row {
margin-bottom: 10px;
}
.container-fluid .gantt_wrapper {
height: 700px;
width: 100%;
}
.gantt_container {
border-radius: 4px;
}
.gantt_grid_scale {
background-color: transparent;
}
.gantt_hor_scroll {
margin-bottom: 1px;
}
</style>
</head>
<body>
<div class="container-fluid">
<div class="row">
<div class="col-md-12">
<div class="navbar navbar-inverse">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse"
data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">Basic Gantt Chart</a>
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Project <span
class="caret"></span></a>
<ul class="dropdown-menu" role="menu">
<li><a href="#">Project information</a></li>
<li><a href="#">Custom fields</a></li>
<li><a href="#">Change working time</a></li>
<li class="divider"></li>
<li><a href="#">Export</a></li>
</ul>
</li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Task <span
class="caret"></span></a>
<ul class="dropdown-menu" role="menu">
<li><a href="#">Add task</a></li>
<li><a href="#">Add milestone</a></li>
<li class="divider"></li>
<li><a href="#">Summary</a></li>
</ul>
</li>
<li><a href="#">Team</a></li>
<li><a href="#">Format</a></li>
</ul>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-2 col-md-push-10">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Gantt info</h3>
</div>
<div class="panel-body">
<ul class="nav nav-pills nav-stacked" id="gantt_info">
</ul>
</div>
</div>
</div>
<div class="col-md-10 col-md-pull-2">
<div class="gantt_wrapper panel" id="gantt_here"></div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="well">
<div>
<a class="logo" title="DHTMLX - JavaScript Web App Framework &amp; UI Widgets"
href="https://dhtmlx.com/docs/products/dhtmlxGantt/">&copy; DHTMLX</a>
</div>
</div>
</div>
</div>
</div>
<script>
var demo_tasks = {
data:[
{id:1, text:"Office itinerancy", type:gantt.config.types.project, progress: 0.4, open: false},
{id:2, text:"Office facing", type:gantt.config.types.project, start_date:"02-04-2018", duration:"8", progress: 0.6, parent:"1", open: true},
{id:3, text:"Furniture installation", type:gantt.config.types.project, start_date:"11-04-2018", duration:"8", parent:"1", progress: 0.6, open: true},
{id:4, text:"The employee relocation", type:gantt.config.types.project, start_date:"13-04-2018", duration:"6", parent:"1", progress: 0.5, open: true},
{id:5, text:"Interior office", start_date:"02-04-2018", duration:"7", parent:"2", progress: 0.6, open: true},
{id:6, text:"Air conditioners check", start_date:"03-04-2018", duration:"7", parent:"2", progress: 0.6, open: true},
{id:7, text:"Workplaces preparation", start_date:"11-04-2018", duration:"8", parent:"3", progress: 0.6, open: true},
{id:8, text:"Preparing workplaces", start_date:"14-04-2018", duration:"5", parent:"4", progress: 0.5, open: true},
{id:9, text:"Workplaces importation", start_date:"14-04-2018", duration:"4", parent:"4", progress: 0.5, open: true},
{id:10, text:"Workplaces exportation", start_date:"14-04-2018", duration:"3", parent:"4", progress: 0.5, open: true},
{id:11, text:"Product launch", type:gantt.config.types.project, progress: 0.6, open: true},
{id:12, text:"Perform Initial testing", start_date:"03-04-2018", duration:"5", parent:"11", progress: 1, open: true},
{id:13, text:"Development", type:gantt.config.types.project, start_date:"02-04-2018", duration:"7", parent:"11", progress: 0.5, open: true},
{id:14, text:"Analysis", start_date:"02-04-2018", duration:"6", parent:"11", progress: 0.8, open: true},
{id:15, text:"Design", type:gantt.config.types.project, start_date:"02-04-2018", duration:"5", parent:"11", progress: 0.2, open: false},
{id:16, text:"Documentation creation", start_date:"02-04-2018", duration:"7", parent:"11", progress: 0, open: true},
{id:17, text:"Develop System", start_date:"03-04-2018", duration:"2", parent:"13", progress: 1, open: true},
{id:25, text:"Beta Release", start_date:"06-04-2018",type:gantt.config.types.milestone, parent:"13", progress: 0, open: true},
{id:18, text:"Integrate System", start_date:"08-04-2018", duration:"2", parent:"13", progress: 0.8, open: true},
{id:19, text:"Test", start_date:"10-04-2018", duration:"4", parent:"13", progress: 0.2, open: true},
{id:20, text:"Marketing", start_date:"10-04-2018", duration:"4", parent:"13", progress: 0, open: true},
{id:21, text:"Design database", start_date:"03-04-2018", duration:"4", parent:"15", progress: 0.5, open: true},
{id:22, text:"Software design", start_date:"03-04-2018", duration:"4", parent:"15", progress: 0.1, open: true},
{id:23, text:"Interface setup", start_date:"03-04-2018", duration:"5", parent:"15", progress: 0, open: true},
{id:24, text:"Release v1.0", start_date:"15-04-2018",type:gantt.config.types.milestone, parent:"11", progress: 0, open: true}
],
links: [
{id: "1", source: "1", target: "2", type: "1"},
{id: "2", source: "2", target: "3", type: "0"},
{id: "3", source: "3", target: "4", type: "0"},
{id: "4", source: "2", target: "5", type: "2"},
{id: "5", source: "2", target: "6", type: "2"},
{id: "6", source: "3", target: "7", type: "2"},
{id: "7", source: "4", target: "8", type: "2"},
{id: "8", source: "4", target: "9", type: "2"},
{id: "9", source: "4", target: "10", type: "2"},
{id: "10", source: "11", target: "12", type: "1"},
{id: "11", source: "11", target: "13", type: "1"},
{id: "12", source: "11", target: "14", type: "1"},
{id: "13", source: "11", target: "15", type: "1"},
{id: "14", source: "11", target: "16", type: "1"},
{id: "15", source: "13", target: "17", type: "1"},
{id: "16", source: "17", target: "25", type: "0"},
{id: "23", source: "25", target: "18", type: "0"},
{id: "17", source: "18", target: "19", type: "0"},
{id: "18", source: "19", target: "20", type: "0"},
{id: "19", source: "15", target: "21", type: "2"},
{id: "20", source: "15", target: "22", type: "2"},
{id: "21", source: "15", target: "23", type: "2"},
{id: "22", source: "13", target: "24", type: "0"}
]
};
var getListItemHTML = function (type, count, active) {
return '<li' + (active ? ' class="active"' : '') + '><a href="#">' + type + 's <span class="badge">' + count + '</span></a></li>';
};
var updateInfo = function () {
var state = gantt.getState(),
tasks = gantt.getTaskByTime(state.min_date, state.max_date),
types = gantt.config.types,
result = {},
html = "",
active = false;
// get available types
result[types.task] = 0;
result[types.project] = 0;
result[types.milestone] = 0;
// sort tasks by type
for (var i = 0, l = tasks.length; i < l; i++) {
if (tasks[i].type && result[tasks[i].type] != "undefined")
result[tasks[i].type] += 1;
else
result[types.task] += 1;
}
// render list items for each type
for (var j in result) {
if (j == types.task)
active = true;
else
active = false;
html += getListItemHTML(j, result[j], active);
}
document.getElementById("gantt_info").innerHTML = html;
};
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.templates.rightside_text = function (start, end, task) {
if (task.type == gantt.config.types.milestone) {
return task.text;
}
return "";
};
gantt.config.columns = [
{name: "text", label: "Task name", width: "*", tree: true},
{name: "start_date", label: "Start time", align: "center", width: 60},
{name: "duration", label: "Duration", align: "center", width: 60},
{name: "add", label: "", width: 44}
];
gantt.config.grid_width = 390;
gantt.config.date_grid = "%F %d";
gantt.config.scale_height = 60;
gantt.config.scales = [
{unit: "day", step: 1, format: "%d %M"},
{unit: "week", step: 1, format: "Week #%W"}
];
gantt.attachEvent("onAfterTaskAdd", function (id, item) {
updateInfo();
});
gantt.attachEvent("onAfterTaskDelete", function (id, item) {
updateInfo();
});
gantt.init("gantt_here");
gantt.parse(demo_tasks);
updateInfo();
</script>
</body>

29
samples/dhtmlx-gantt/samples/01_initialization/18_backward_planning.html

@ -0,0 +1,29 @@
<!DOCTYPE html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Backward planning</title>
<script src="../../codebase/dhtmlxgantt.js?v=7.1.8"></script>
<link rel="stylesheet" href="../../codebase/dhtmlxgantt.css?v=7.1.8">
<script src="../common/data_end_dates.js?v=7.1.8"></script>
<style>
html, body {
padding: 0px;
margin: 0px;
height: 100%;
}
</style>
</head>
<body>
<div id="gantt_here" style='width:100%; height:100%;'></div>
<script>
gantt.config.date_format = "%Y-%m-%d %H:%i:%s";
gantt.init("gantt_here");
gantt.message({
text: "Task schedules are calculated from an <b>end dates</b> and <b>durations</b>",
expire: -1
});
gantt.parse(taskData);
</script>
</body>

90
samples/dhtmlx-gantt/samples/01_initialization/19_tasks_without_dates.html

@ -0,0 +1,90 @@
<!DOCTYPE html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Show Unscheduled Tasks</title>
<script src="../../codebase/dhtmlxgantt.js?v=7.1.8"></script>
<link rel="stylesheet" href="../../codebase/dhtmlxgantt.css?v=7.1.8">
<script src="../common/testdata.js?v=7.1.8"></script>
<style>
html, body {
padding: 0px;
margin: 0px;
height: 100%;
}
</style>
</head>
<body>
<div id="gantt_here" style='width:100%; height:100%;'></div>
<script>
gantt.config.scale_height = 50;
gantt.config.scales = [
{unit: "month", step: 1, format: "%F, %Y"},
{unit: "day", step: 1, format: "%j, %D"}
];
gantt.templates.rightside_text = function (start, end, task) {
if (task.type == gantt.config.types.milestone) {
return task.text;
}
return "";
};
gantt.i18n.setLocale({
labels:{
time_enable_button: 'Schedule',
time_disable_button: 'Unschedule',
}
});
gantt.config.lightbox.sections = [
{name: "description", height: 70, map_to: "text", type: "textarea", focus: true},
{name: "time", map_to: "auto", button: true, type: "duration_optional"}
];
gantt.config.lightbox.milestone_sections = [
{name: "description", height: 70, map_to: "text", type: "textarea", focus: true},
{name: "time", map_to: "auto", button: true, single_date: true, type: "duration_optional"}
];
gantt.attachEvent("onLightboxSave", function (id, task, is_new) {
task.unscheduled = !task.start_date;
return true;
});
gantt.init("gantt_here");
gantt.parse({
"data": [
{"id": 11, "text": "Project #1", type: gantt.config.types.project, "progress": 0.6, "open": true},
{"id": 12, "text": "Task #1", "start_date": "03-04-2018", "duration": "5", "parent": "11", "progress": 1, "open": true},
{"id": 13, "text": "Unscheduled Project", "start_date": "03-04-2018", type: gantt.config.types.project, "parent": "11", "progress": 0.5, "open": true},
{"id": 14, "text": "Task #3", "start_date": "02-04-2018", "duration": "6", "parent": "11", "progress": 0.8, "open": true},
{"id": 15, "text": "Task #4", "start_date": "03-04-2018", type: gantt.config.types.project, "parent": "11", "progress": 0.2, "open": true},
{"id": 16, "text": "Final milestone", "start_date": "15-04-2018", type: gantt.config.types.milestone, "parent": "11", "progress": 0, "open": true},
{"id": 17, "text": "Task #2.1", unscheduled: true, "parent": "13", "progress": 1, "open": true},
{"id": 18, "text": "Task #2.2", unscheduled: true, "parent": "13", "progress": 0.8, "open": true},
{"id": 19, "text": "Task #2.3", unscheduled: true, "parent": "13", "progress": 0.2, "open": true},
{"id": 20, "text": "Task #2.4", unscheduled: true, "parent": "13", "progress": 0, "open": true},
{"id": 21, "text": "Task #4.1", unscheduled: true, "parent": "15", "progress": 0.5, "open": true},
{"id": 22, "text": "Task #4.2", unscheduled: true, "parent": "15", "progress": 0.1, "open": true},
{"id": 23, "text": "Mediate milestone", unscheduled: true, type: gantt.config.types.milestone, "parent": "15", "progress": 0, "open": true}
],
"links": [
{"id": "10", "source": "11", "target": "12", "type": "1"},
{"id": "11", "source": "11", "target": "13", "type": "1"},
{"id": "12", "source": "11", "target": "14", "type": "1"},
{"id": "13", "source": "11", "target": "15", "type": "1"},
{"id": "14", "source": "23", "target": "16", "type": "0"},
{"id": "15", "source": "13", "target": "17", "type": "1"},
{"id": "16", "source": "17", "target": "18", "type": "0"},
{"id": "17", "source": "18", "target": "19", "type": "0"},
{"id": "18", "source": "19", "target": "20", "type": "0"},
{"id": "19", "source": "15", "target": "21", "type": "2"},
{"id": "20", "source": "15", "target": "22", "type": "2"},
{"id": "21", "source": "15", "target": "23", "type": "0"}
]
});
</script>
</body>

73
samples/dhtmlx-gantt/samples/01_initialization/20_tasks_outside_timescale.html

@ -0,0 +1,73 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Tasks outside timescale</title>
<link rel="stylesheet" href="../../codebase/dhtmlxgantt.css?v=7.1.8">
<script src="../../codebase/dhtmlxgantt.js?v=7.1.8"></script>
<style>
html, body {
height: 100%;
padding: 0px;
margin: 0px;
}
</style>
</head>
<body>
<div id="gantt_here" style="width:100%; height:100%;"></div>
<script>
gantt.message({
text: "Timescale is limited to February 2020. <br> <b>Task #1</b> and <b>Task #3</b> are beyond this time period and are not displayed, but are listed in the grid.",
expire: -1
});
gantt.templates.date_grid = function(date, task) {
if (!date) {
return "";
}
return gantt.templates.grid_date_format(date);
};
gantt.config.scale_height = 60;
gantt.config.scale_height = 50;
gantt.config.scales = [
{unit: "month", step: 1, format: "%F, %Y"},
{unit: "day", step: 1, format: "%j, %D"}
];
gantt.config.show_tasks_outside_timescale = true;
gantt.config.start_date = new Date(2020, 1, 1);
gantt.config.end_date = new Date(2020, 2,1);
gantt.init("gantt_here");
gantt.parse({
data:[
{id:11, text:"Project #1", start_date:null, duration:0, type:"project", progress: 0.6, open: true},
{id:12, text:"Task #1", start_date:"03-01-2020", duration:5, parent:11, progress: 1, open: true},
{id:13, text:"Task #2", start_date:"03-02-2020", type:"project", parent:11, progress: 0.5, open: true},
{id:14, text:"Task #3", start_date:"02-03-2020", duration:6, parent:11, progress: 0.8, open: true},
{id:15, text:"Task #4", start_date:null, duration:0, type:"project", parent:11, progress: 0.2, open: true},
{id:17, text:"Task #2.1", start_date:"03-02-2020", duration:2, parent:13, progress: 1, open: true},
{id:18, text:"Task #2.2", start_date:"06-02-2020", duration:3, parent:13, progress: 0.8, open: true},
{id:19, text:"Task #2.3", start_date:"10-02-2020", duration:4, parent:13, progress: 0.2, open: true},
{id:20, text:"Task #2.4", start_date:"15-02-2020", duration:4, parent:13, progress: 0, open: true},
{id:21, text:"Task #4.1", start_date:"03-02-2020", duration:4, parent:15, progress: 0.5, open: true},
{id:22, text:"Task #4.2", start_date:"08-02-2020", duration:4, parent:15, progress: 0.1, open: true}
],
links:[
{id:1, source:17, target:18, type:"0"},
{id:2, source:18, target:19, type:"0"},
{id:3, source:19, target:20, type:"0"},
{id:4, source:21, target:22, type:"0"}
]
});
</script>
</body>
</html>

111
samples/dhtmlx-gantt/samples/01_initialization/21_rollup_tasks.html

@ -0,0 +1,111 @@
<!DOCTYPE html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Rollup tasks and milestones</title>
<script src="../../codebase/dhtmlxgantt.js?v=7.1.8"></script>
<link rel="stylesheet" href="../../codebase/dhtmlxgantt.css?v=7.1.8">
<script src="../common/testdata.js?v=7.1.8"></script>
<style>
html, body {
height: 100%;
padding: 0px;
margin: 0px;
overflow: hidden;
}
</style>
</head>
<body>
<div id="gantt_here" style='width:100%; height:100%;'></div>
<script>
gantt.message({
text:[
"Note that milestones are displayed on over Summary rows.",
"Double click any task to see available options."
].join("<br><br>"),
expire: -1
});
gantt.config.scale_height = 50;
gantt.config.scales = [
{unit: "month", step: 1, format: "%F, %Y"},
{unit: "day", step: 1, format: "%j, %D"}
];
gantt.templates.rightside_text = function (start, end, task) {
if (task.type == "milestone") {
return task.text;
}
return "";
};
gantt.locale.labels.section_rollup = "Rollup";
gantt.locale.labels.section_hide_bar = "Hide bar";
gantt.config.lightbox.sections = [
{name: "description", height: 70, map_to: "text", type: "textarea", focus: true},
{name: "rollup", type: "checkbox", map_to: "rollup"},
{name: "hide_bar", type: "checkbox", map_to: "hide_bar"},
{name: "type", type: "typeselect", map_to: "type"},
{name: "time", type: "duration", map_to: "auto"}
];
gantt.config.lightbox.milestone_sections = [
{name: "description", height: 70, map_to: "text", type: "textarea", focus: true},
{name: "rollup", type: "checkbox", map_to: "rollup"},
{name: "hide_bar", type: "checkbox", map_to: "hide_bar"},
{name: "type", type: "typeselect", map_to: "type"},
{name: "time", type: "duration", map_to: "auto"}
];
gantt.config.lightbox.project_sections = [
{name: "description", height: 70, map_to: "text", type: "textarea", focus: true},
{name: "hide_bar", type: "checkbox", map_to: "hide_bar"},
{name: "type", type: "typeselect", map_to: "type"},
{name: "time", type: "duration", map_to: "auto"}
];
gantt.init("gantt_here");
gantt.parse({
data:[
{id:11, text:"Project #1", type:"project", progress: 0.6, open: true},
{id:12, text:"Task #1", start_date:"03-04-2018", duration:"5", parent:"11", progress: 1, open: true},
{id:13, text:"Task #2", start_date:"03-04-2018", type:"project", parent:"11", progress: 0.5, open: true},
{id:14, text:"Task #3", start_date:"02-04-2018", duration:"6", parent:"11", progress: 0.8, open: true},
{id:15, text:"Task #4", type:"project", parent:"11", progress: 0.2, open: true},
{id:16, text:"Final milestone", start_date:"15-04-2018", type:"milestone", rollup: true, parent:"11", progress: 0, open: true},
{id:17, text:"Task #2.1", start_date:"03-04-2018", duration:"2", parent:"13", progress: 1, open: true},
{id:18, text:"Task #2.2", start_date:"06-04-2018", duration:"3", parent:"13", progress: 0.8, open: true},
{id:19, text:"Task #2.3", start_date:"10-04-2018", duration:"4", parent:"13", progress: 0.2, open: true},
{id:20, text:"Task #2.4", start_date:"10-04-2018", duration:"4", parent:"13", progress: 0, open: true},
{id:21, text:"Task #4.1", start_date:"03-04-2018", duration:"4", parent:"15", progress: 0.5, open: true},
{id:22, text:"Task #4.2", start_date:"03-04-2018", duration:"4", parent:"15", progress: 0.1, open: true},
{id:23, text:"Mediate milestone", start_date:"13-04-2018", type:"milestone", parent:"15", rollup: true, progress: 0, open: true}
],
links:[
{id:"10",source:"11",target:"12",type:"1"},
{id:"11",source:"11",target:"13",type:"1"},
{id:"12",source:"11",target:"14",type:"1"},
{id:"13",source:"11",target:"15",type:"1"},
{id:"14",source:"23",target:"16",type:"0"},
{id:"15",source:"13",target:"17",type:"1"},
{id:"16",source:"17",target:"18",type:"0"},
{id:"17",source:"18",target:"19",type:"0"},
{id:"18",source:"19",target:"20",type:"0"},
{id:"19",source:"15",target:"21",type:"2"},
{id:"20",source:"15",target:"22",type:"2"},
{id:"21",source:"15",target:"23",type:"0"}
]
});
</script>
</body>

300
samples/dhtmlx-gantt/samples/01_initialization/index.html

@ -0,0 +1,300 @@
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="../common/docs.css">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="initial-scale = 1.0" />
<title>Gantt : Samples</title></title>
</head>
<body>
<div class='abstop_header'>
<div class='content_area'>
&nbsp;
</div>
</div>
<div class="page_header">
<div class='page_inner_header'>
<a href='https://dhtmlx.com'><div class='top_webix_logo'></div></a>
Samples
</div>
</div>
<div class="page_space">
<div class="webixdoc_page webixdoc_start">
<div id="webixContent" class='webixdoc_content'>
<div class="webixdoc_content_inner">
<div class="webixdoc_breadcrumb nav_breadcrumb">
<a href="https://docs.dhtmlx.com/gantt/" class="webixdoc_back">Documentation</a>
<a href="../" class="webixdoc_back">Samples</a>
<a href="../" class="webixdoc_back">Initialization</a>
</div>
<table class='nav_table'>
<tr>
<td style='width:30px;'>
<a href='01_basic_init.html'>
<div class='nav_page_img'>&nbsp;</div>
</a>
</td>
<td>
<a href='01_basic_init.html'>Basic initialization</a>
</td>
</tr>
<tr>
<td style='width:30px;'>
<a href='02_load_json.html'>
<div class='nav_page_img'>&nbsp;</div>
</a>
</td>
<td>
<a href='02_load_json.html'>Load data from JSON file</a>
</td>
</tr>
<tr>
<td style='width:30px;'>
<a href='03_load_xml.html'>
<div class='nav_page_img'>&nbsp;</div>
</a>
</td>
<td>
<a href='03_load_xml.html'>Load data from XML file</a>
</td>
</tr>
<tr>
<td style='width:30px;'>
<a href='04_save_rest.html'>
<div class='nav_page_img'>&nbsp;</div>
</a>
</td>
<td>
<a href='04_save_rest.html'>Backend storage using REST API</a>
</td>
</tr>
<tr>
<td style='width:30px;'>
<a href='06_touch_forced.html'>
<div class='nav_page_img'>&nbsp;</div>
</a>
</td>
<td>
<a href='06_touch_forced.html'>Forced touch mode</a>
</td>
</tr>
<tr>
<td style='width:30px;'>
<a href='07_jquery.html'>
<div class='nav_page_img'>&nbsp;</div>
</a>
</td>
<td>
<a href='07_jquery.html'>jQuery integration</a>
</td>
</tr>
<tr>
<td style='width:30px;'>
<a href='08_explicit_time_range.html'>
<div class='nav_page_img'>&nbsp;</div>
</a>
</td>
<td>
<a href='08_explicit_time_range.html'>Define date range</a>
</td>
</tr>
<tr>
<td style='width:30px;'>
<a href='09_backward_compatibility.html'>
<div class='nav_page_img'>&nbsp;</div>
</a>
</td>
<td>
<a href='09_backward_compatibility.html'>Loading data in Gantt 1.6 format</a>
</td>
</tr>
<tr>
<td style='width:30px;'>
<a href='10_fixed_size.html'>
<div class='nav_page_img'>&nbsp;</div>
</a>
</td>
<td>
<a href='10_fixed_size.html'>Fixed size gantt</a>
</td>
</tr>
<tr>
<td style='width:30px;'>
<a href='11_clickable_links.html'>
<div class='nav_page_img'>&nbsp;</div>
</a>
</td>
<td>
<a href='11_clickable_links.html'>Clickable links</a>
</td>
</tr>
<tr>
<td style='width:30px;'>
<a href='12_localization.html'>
<div class='nav_page_img'>&nbsp;</div>
</a>
</td>
<td>
<a href='12_localization.html'>Localization</a>
</td>
</tr>
<tr>
<td style='width:30px;'>
<a href='13_project_duration.html'>
<div class='nav_page_img'>&nbsp;</div>
</a>
</td>
<td>
<a href='13_project_duration.html'>Project duration</a>
</td>
</tr>
<tr>
<td style='width:30px;'>
<a href='14_reinitializtion.html'>
<div class='nav_page_img'>&nbsp;</div>
</a>
</td>
<td>
<a href='14_reinitializtion.html'>ReInit in different container</a>
</td>
</tr>
<tr>
<td style='width:30px;'>
<a href='15_connector_json_enddate.html'>
<div class='nav_page_img'>&nbsp;</div>
</a>
</td>
<td>
<a href='15_connector_json_enddate.html'>Loading tasks start/end dates</a>
</td>
</tr>
<tr>
<td style='width:30px;'>
<a href='17_bootstrap.html'>
<div class='nav_page_img'>&nbsp;</div>
</a>
</td>
<td>
<a href='17_bootstrap.html'>Bootstrap layout</a>
</td>
</tr>
<tr>
<td style='width:30px;'>
<a href='18_backward_planning.html'>
<div class='nav_page_img'>&nbsp;</div>
</a>
</td>
<td>
<a href='18_backward_planning.html'>Backward planning</a>
</td>
</tr>
<tr>
<td style='width:30px;'>
<a href='19_tasks_without_dates.html'>
<div class='nav_page_img'>&nbsp;</div>
</a>
</td>
<td>
<a href='19_tasks_without_dates.html'>Show Unscheduled Tasks</a>
</td>
</tr>
<tr>
<td style='width:30px;'>
<a href='20_tasks_outside_timescale.html'>
<div class='nav_page_img'>&nbsp;</div>
</a>
</td>
<td>
<a href='20_tasks_outside_timescale.html'>Tasks outside timescale</a>
</td>
</tr>
<tr>
<td style='width:30px;'>
<a href='21_rollup_tasks.html'>
<div class='nav_page_img'>&nbsp;</div>
</a>
</td>
<td>
<a href='21_rollup_tasks.html'>Rollup tasks and milestones</a>
</td>
</tr>
</table>
</div>
</div>
</div>
</div>
<!--Side quick links -->
<div class="side_links">
<a class="reference_link" href="https://docs.dhtmlx.com/gantt/api__refs__gantt.html">
<span>API Reference</span>
</a>
<a class="sample_link" href="../">
<span>Code Samples</span>
</a>
<a class="forum_link" href="https://forum.dhtmlx.com/c/gantt">
<span>Developer Forum </span>
</a>
</div>
</div>
</div>
<div class="footer_linea">&nbsp;</div>
<div class="footer_lineb">
<div class='page_inner_header'>
<a href='https://dhtmlx.com'><div class='bottom_webix_block bottom_webix_logo' ></div></a>
<div class='copyright bottom_webix_block'>© 2021 XB Software Ltd.<br>
All rights reserved</div>
<div class='bottom_webix_also'>
<h4>Check also:</h4>
<li><a href='https://dhtmlx.com/docs/products/dhtmlxScheduler/' target='_blank'>DHTMLX Scheduler</a></li>
<li><a href='https://dhtmlx.com/docs/products/dhtmlxSpreadsheet/' target='_blank'>DHTMLX Spreadsheet</a></li>
<li><a href='https://dhtmlx.com/docs/products/dhtmlxSuite/' target='_blank'>Other DHTMLX components</a></li>
</div>
</div>
</div>
<script>
var msBrowser =
navigator.userAgent.indexOf("MSIE ") > 0 ||
navigator.userAgent.indexOf("Trident") > 0 ||
navigator.userAgent.indexOf("Edge") > 0
if (msBrowser){
var summaryElements = document.querySelectorAll(".list_samples");
for (var i = 0; i < summaryElements.length; i++) {
var navItem = summaryElements[i];
var link = navItem.querySelector("a");
var parent = navItem.parentNode;
parent.insertBefore(link, navItem);
navItem.style.display = 'none';
}
}
</script>
</body>
</html>

30
samples/dhtmlx-gantt/samples/02_extensions/01_quickinfo.html

@ -0,0 +1,30 @@
<!DOCTYPE html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>QuickInfo extension</title>
<script src="../../codebase/dhtmlxgantt.js?v=7.1.8"></script>
<link rel="stylesheet" href="../../codebase/dhtmlxgantt.css?v=7.1.8">
<script src="../common/testdata.js?v=7.1.8"></script>
<style>
html, body {
height: 100%;
padding: 0px;
margin: 0px;
overflow: hidden;
}
</style>
</head>
<body>
<div id="gantt_here" style='width:100%; height:100%;'></div>
<script>
gantt.plugins({
quick_info: true
});
gantt.init("gantt_here");
gantt.parse(demo_tasks);
</script>
</body>

33
samples/dhtmlx-gantt/samples/02_extensions/02_tooltip.html

@ -0,0 +1,33 @@
<!DOCTYPE html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Tooltip</title>
<script src="../../codebase/dhtmlxgantt.js?v=7.1.8"></script>
<link rel="stylesheet" href="../../codebase/dhtmlxgantt.css?v=7.1.8">
<script src="../common/testdata.js?v=7.1.8"></script>
<style>
html, body {
height: 100%;
padding: 0px;
margin: 0px;
overflow: hidden;
}
</style>
</head>
<body>
<div id="gantt_here" style='width:100%; height:100%;'></div>
<script>
gantt.plugins({
tooltip: true
});
gantt.attachEvent("onGanttReady", function(){
var tooltips = gantt.ext.tooltips;
tooltips.tooltip.setViewport(gantt.$task_data);
});
gantt.init("gantt_here");
gantt.parse(demo_tasks);
</script>
</body>

59
samples/dhtmlx-gantt/samples/02_extensions/05_today_line.html

@ -0,0 +1,59 @@
<!DOCTYPE html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Today and Status lines in Gantt</title>
<script src="../../codebase/dhtmlxgantt.js?v=7.1.8"></script>
<link rel="stylesheet" href="../../codebase/dhtmlxgantt.css?v=7.1.8">
<script src="../common/testdata.js?v=7.1.8"></script>
</head>
<body>
<style>
html, body {
padding: 0px;
margin: 0px;
height: 100%;
}
.status_line {
background-color: #0ca30a;
}
</style>
<div id="gantt_here" style='width:100%; height:100%;'></div>
<script>
gantt.plugins({
marker: true
});
var dateToStr = gantt.date.date_to_str(gantt.config.task_date);
var today = new Date(2018, 3, 5);
gantt.addMarker({
start_date: today,
css: "today",
text: "Today",
title: "Today: " + dateToStr(today)
});
var start = new Date(2018, 2, 28);
gantt.addMarker({
start_date: start,
css: "status_line",
text: "Start project",
title: "Start project: " + dateToStr(start)
});
gantt.config.scale_height = 50;
gantt.config.scales = [
{unit: "day", step: 1, format: "%j, %D"},
{unit: "month", step: 1, format: "%F, %Y"},
];
gantt.init("gantt_here");
gantt.parse(demo_tasks);
</script>
</body>

227
samples/dhtmlx-gantt/samples/02_extensions/09_multiselection.html

@ -0,0 +1,227 @@
<!DOCTYPE html>
<head>
<meta http-equiv='Content-type' content='text/html; charset=utf-8'>
<title>Multiselection and Indent/Outdent tasks</title>
<script src='../../codebase/dhtmlxgantt.js?v=7.1.8'></script>
<link rel='stylesheet' href='../../codebase/dhtmlxgantt.css?v=7.1.8'>
<link rel="stylesheet" href="../common/controls_styles.css?v=7.1.8">
<style>
html, body {
padding: 0px;
margin: 0px;
height: 100%;
overflow: hidden;
}
</style>
</head>
<body>
<div class="gantt_control">
<input class="action" name="undo" value="Undo" type="button">
<input class="action" name="redo" value="Redo" type="button">
<input class="action" name="indent" value="Indent" type="button">
<input class="action" name="outdent" value="Outdent" type="button">
<input class="action" name="del" value="Delete" type="button">
<input class="action" name="moveForward" value="Move Forward" type="button">
<input class="action" name="moveBackward" value="Move Backward" type="button">
</div>
<div id='gantt_here' style='height:calc(100vh - 52px);'></div>
<script>
gantt.plugins({
multiselect: true,
undo: true,
});
gantt.message({
text: "Hold <b>shift</b> or <b>ctrl</b> to select several items",
expire: -1
});
gantt.config.date_format = "%d-%m-%Y";
gantt.config.lightbox.sections = [
{name: "description", height: 70, map_to: "text", type: "textarea", focus: true},
{name: "time", type: "duration", map_to: "auto"}
];
gantt.config.scale_height = 50;
gantt.config.scales = [
{unit: "month", step: 1, format: "%F, %Y"},
{unit: "day", step: 1, format: "%j, %D"}
];
gantt.templates.task_class = gantt.templates.grid_row_class = gantt.templates.task_row_class = function (start, end, task) {
if (gantt.isSelectedTask(task.id))
return "gantt_selected";
};
gantt.init('gantt_here');
gantt.parse({
data: [
{id: 11, text: "Project #1", start_date: "28-03-2013", duration: "11"},
{id: 1, text: "Project #2", start_date: "01-04-2013", duration: "18"},
{id: 2, text: "Task #1", start_date: "02-04-2013", duration: "8"},
{id: 3, text: "Task #2", start_date: "11-04-2013", duration: "8"},
{id: 4, text: "Task #3", start_date: "13-04-2013", duration: "6"},
{id: 5, text: "Task #1.1", start_date: "02-04-2013", duration: "7"},
{id: 6, text: "Task #1.2", start_date: "03-04-2013", duration: "7"},
{id: 7, text: "Task #2.1", start_date: "11-04-2013", duration: "8"},
{id: 8, text: "Task #3.1", start_date: "14-04-2013", duration: "5"},
{id: 9, text: "Task #3.2", start_date: "14-04-2013", duration: "4"},
{id: 10, text: "Task #3.3", start_date: "14-04-2013", duration: "3"},
{id: 12, text: "Task #1", start_date: "03-04-2013", duration: "5"},
{id: 13, text: "Task #2", start_date: "02-04-2013", duration: "7"},
{id: 14, text: "Task #3", start_date: "02-04-2013", duration: "6"},
{id: 15, text: "Task #4", start_date: "02-04-2013", duration: "5"},
{id: 16, text: "Task #5", start_date: "02-04-2013", duration: "7"},
{id: 17, text: "Task #2.1", start_date: "03-04-2013", duration: "2"},
{id: 18, text: "Task #2.2", start_date: "06-04-2013", duration: "3"},
{id: 19, text: "Task #2.3", start_date: "10-04-2013", duration: "4"},
{id: 20, text: "Task #2.4", start_date: "10-04-2013", duration: "4"},
{id: 21, text: "Task #4.1", start_date: "03-04-2013", duration: "4"},
{id: 22, text: "Task #4.2", start_date: "03-04-2013", duration: "4"},
{id: 23, text: "Task #4.3", start_date: "03-04-2013", duration: "5"}
],
links: []
});
// indent-outdent implementation
(function () {
function shiftTask(task_id, direction) {
var task = gantt.getTask(task_id);
task.start_date = gantt.date.add(task.start_date, direction, "day");
task.end_date = gantt.calculateEndDate(task.start_date, task.duration);
gantt.updateTask(task.id);
}
var actions = {
undo: function(){
gantt.ext.undo.undo();
},
redo: function(){
gantt.ext.undo.redo();
},
indent: function indent(task_id) {
var prev_id = gantt.getPrevSibling(task_id);
while (gantt.isSelectedTask(prev_id)) {
var prev = gantt.getPrevSibling(prev_id);
if (!prev) break;
prev_id = prev;
}
if (prev_id) {
var new_parent = gantt.getTask(prev_id);
gantt.moveTask(task_id, gantt.getChildren(new_parent.id).length, new_parent.id);
new_parent.type = gantt.config.types.project;
new_parent.$open = true;
gantt.updateTask(task_id);
gantt.updateTask(new_parent.id);
return task_id;
}
return null;
},
outdent: function outdent(task_id, initialIndexes, initialSiblings) {
var cur_task = gantt.getTask(task_id);
var old_parent = cur_task.parent;
if (gantt.isTaskExists(old_parent) && old_parent != gantt.config.root_id) {
var index = gantt.getTaskIndex(old_parent) + 1;
var prevSibling = initialSiblings[task_id].first;
if(gantt.isSelectedTask(prevSibling)){
index += (initialIndexes[task_id] - initialIndexes[prevSibling]);
}
gantt.moveTask(task_id, index, gantt.getParent(cur_task.parent));
if (!gantt.hasChild(old_parent))
gantt.getTask(old_parent).type = gantt.config.types.task;
gantt.updateTask(task_id);
gantt.updateTask(old_parent);
return task_id;
}
return null;
},
del: function (task_id) {
if(gantt.isTaskExists(task_id)) gantt.deleteTask(task_id);
return task_id;
},
moveForward: function (task_id) {
shiftTask(task_id, 1);
},
moveBackward: function (task_id) {
shiftTask(task_id, -1);
}
};
var cascadeAction = {
indent: true,
outdent: true,
del: true
};
var singularAction = {
undo: true,
redo: true
};
gantt.performAction = function (actionName) {
var action = actions[actionName];
if (!action)
return;
if(singularAction[actionName]){
action();
return;
}
gantt.batchUpdate(function () {
// need to preserve order of items on indent/outdent,
// remember order before changing anything:
var indexes = {};
var siblings = {};
gantt.eachSelectedTask(function (task_id) {
gantt.ext.undo.saveState(task_id, "task");
indexes[task_id] = gantt.getTaskIndex(task_id);
siblings[task_id] = {
first: null
};
var currentId = task_id;
while(gantt.isTaskExists(gantt.getPrevSibling(currentId)) && gantt.isSelectedTask(gantt.getPrevSibling(currentId))){
currentId = gantt.getPrevSibling(currentId);
}
siblings[task_id].first = currentId;
});
var updated = {};
gantt.eachSelectedTask(function (task_id) {
if (cascadeAction[actionName]) {
if (!updated[gantt.getParent(task_id)]) {
var updated_id = action(task_id, indexes, siblings);
updated[updated_id] = true;
} else {
updated[task_id] = true;
}
} else {
action(task_id, indexes);
}
});
});
};
})();
var els = document.getElementsByClassName("action");
for (var i = 0; i < els.length; i++) {
els[i].onclick = function() {
gantt.performAction(this.name)
}
}
</script>
</body>

77
samples/dhtmlx-gantt/samples/02_extensions/11_full_screen.html

@ -0,0 +1,77 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Full Screen</title>
<script src="../../codebase/dhtmlxgantt.js?v=7.1.8"></script>
<script src="../common/testdata.js?v=7.1.8"></script>
<link rel="stylesheet" href="../../codebase/dhtmlxgantt.css?v=7.1.8"
>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css?v=7.1.8">
<style>
html, body {
height: 100%;
width: 100%;
padding: 0px;
margin: 0px;
}
.gantt-fullscreen {
position: absolute;
bottom: 20px;
right: 20px;
width: 30px;
height: 30px;
padding: 2px;
font-size: 32px;
background: transparent;
cursor: pointer;
opacity: 0.5;
text-align: center;
-webkit-transition: background-color 0.5s, opacity 0.5s;
transition: background-color 0.5s, opacity 0.5s;
}
.gantt-fullscreen:hover {
background: rgba(150, 150, 150, 0.5);
opacity: 1;
}
</style>
</head>
<body>
<div id="gantt_here" style='width:700px; height:600px;'></div>
<script>
gantt.plugins({
fullscreen: true
});
gantt.attachEvent("onTemplatesReady", function () {
var toggle = document.createElement("i");
toggle.className = "fa fa-expand gantt-fullscreen";
gantt.toggleIcon = toggle;
gantt.$container.appendChild(toggle);
toggle.onclick = function() {
gantt.ext.fullscreen.toggle();
};
});
gantt.attachEvent("onExpand", function () {
var icon = gantt.toggleIcon;
if (icon) {
icon.className = icon.className.replace("fa-expand", "fa-compress");
}
});
gantt.attachEvent("onCollapse", function () {
var icon = gantt.toggleIcon;
if (icon) {
icon.className = icon.className.replace("fa-compress", "fa-expand");
}
});
gantt.init("gantt_here");
gantt.parse(demo_tasks);
</script>
</body>

70
samples/dhtmlx-gantt/samples/02_extensions/13_smart_rendering.html

@ -0,0 +1,70 @@
<!DOCTYPE html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Working with 30000 tasks</title>
<script src="../../codebase/dhtmlxgantt.js?v=7.1.8"></script>
<link rel="stylesheet" href="../../codebase/dhtmlxgantt.css?v=7.1.8">
<script src="../common/data_large.js?v=7.1.8"></script>
<style>
html, body {
height: 100%;
padding: 0px;
margin: 0px;
overflow: hidden;
}
.gantt_task_cell.week_end {
background-color: #EFF5FD;
}
.gantt_task_row.gantt_selected .gantt_task_cell.week_end {
background-color: #F8EC9C;
}
</style>
</head>
<body>
<div id="gantt_here" style='width:100%; height:100%;'></div>
<script>
gantt.attachEvent("onLoadStart", function () {
gantt.message("Loading...");
});
gantt.attachEvent("onLoadEnd", function () {
gantt.message({
text: "Loaded " + gantt.getTaskCount() + " tasks, " + gantt.getLinkCount() + " links",
expire: 8 * 1000
});
});
gantt.config.min_column_width = 30;
gantt.config.scale_height = 60;
gantt.config.work_time = true;
gantt.config.scales = [
{unit: "day", step: 1, format: "%d"},
{unit: "month", step: 1, format: "%F, %Y"},
{unit: "year", step: 1, format: "%Y"}
];
gantt.config.row_height = 22;
gantt.config.static_background = true;
gantt.templates.timeline_cell_class = function (task, date) {
if (!gantt.isWorkTime(date))
return "week_end";
return "";
};
gantt.init("gantt_here");
gantt.parse(taskData);
</script>
</body>

103
samples/dhtmlx-gantt/samples/02_extensions/14_undo.html

@ -0,0 +1,103 @@
<!DOCTYPE html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Undo/Redo changes in Gantt</title>
<script src="../../codebase/dhtmlxgantt.js?v=7.1.8"></script>
<link rel="stylesheet" href="../../codebase/dhtmlxgantt.css?v=7.1.8">
<link rel="stylesheet" href="../common/controls_styles.css?v=7.1.8">
<style>
html, body {
height: 100%;
padding: 0px;
margin: 0px;
overflow: hidden;
}
.weekend {
background: #f4f7f4 !important;
}
</style>
</head>
<body>
<div class="gantt_control">
<input value="Undo" type="button" onclick='gantt.undo()' style='margin:0 15px;'>
<input value="Redo" type="button" onclick='gantt.redo()' style='margin:0 15px;'>
</div>
<div id="gantt_here" style='width:100%; height:calc(100vh - 52px);'></div>
<script>
gantt.plugins({
auto_scheduling: true,
undo: true
});
gantt.templates.scale_cell_class = function (date) {
if (!gantt.isWorkTime(date))
return "weekend";
};
gantt.templates.timeline_cell_class = function (item, date) {
if (!gantt.isWorkTime(date))
return "weekend";
};
gantt.config.work_time = true;
gantt.config.auto_scheduling = true;
gantt.config.auto_scheduling_strict = true;
gantt.config.date_format = "%d-%m-%Y";
gantt.config.start_date = new Date(2018, 3, 1);
gantt.config.end_date = new Date(2018, 5, 1);
gantt.attachEvent("onBeforeAutoSchedule", function () {
gantt.message("Recalculating project schedule...");
return true;
});
gantt.attachEvent("onAfterTaskAutoSchedule", function (task, new_date, constraint, predecessor) {
gantt.message({
text: "<b>" + task.text + "</b> has been rescheduled to " + gantt.templates.task_date(new_date) + " due to <b>" + predecessor.text + "</b> constraint",
expire: 4000
});
});
gantt.config.order_branch = true;
gantt.config.order_branch_free = true;
gantt.init("gantt_here");
gantt.parse({
data: [
{id: 11, text: "Project #1", type: gantt.config.types.project, progress: 0.6, open: true},
{id: 12, text: "Task #1", start_date: "02-04-2018", duration: "5", parent: "11", progress: 1, open: true},
{id: 13, text: "Task #2", start_date: "03-04-2018", type: gantt.config.types.project, parent: "11", progress: 0.5, open: true},
{id: 14, text: "Task #3", start_date: "02-04-2018", duration: "6", parent: "11", progress: 0.8, open: true},
{id: 15, text: "Task #4", type: gantt.config.types.project, parent: "11", progress: 0.2, open: true},
{id: 16, text: "Final milestone", start_date: "15-04-2018", type: gantt.config.types.milestone, parent: "11", progress: 0, open: true},
{id: 17, text: "Task #2.1", start_date: "03-04-2018", duration: "2", parent: "13", progress: 1, open: true},
{id: 18, text: "Task #2.2", start_date: "06-04-2018", duration: "3", parent: "13", progress: 0.8, open: true},
{id: 19, text: "Task #2.3", start_date: "10-04-2018", duration: "4", parent: "13", progress: 0.2, open: true},
{id: 20, text: "Task #2.4", start_date: "10-04-2018", duration: "4", parent: "13", progress: 0, open: true},
{id: 21, text: "Task #4.1", start_date: "02-04-2018", duration: "4", parent: "15", progress: 0.5, open: true},
{id: 22, text: "Task #4.2", start_date: "02-04-2018", duration: "4", parent: "15", progress: 0.1, open: true},
{id: 23, text: "Mediate milestone", start_date: "14-04-2018", type: gantt.config.types.milestone, parent: "15", progress: 0, open: true}
],
links: [
{id: "10", source: "11", target: "12", type: "1"},
{id: "11", source: "11", target: "13", type: "1"},
{id: "12", source: "11", target: "14", type: "1"},
{id: "13", source: "11", target: "15", type: "1"},
{id: "14", source: "23", target: "16", type: "0"},
{id: "15", source: "13", target: "17", type: "1"},
{id: "16", source: "17", target: "18", type: "0"},
{id: "17", source: "18", target: "19", type: "0"},
{id: "18", source: "19", target: "20", type: "0"},
{id: "21", source: "15", target: "23", type: "0"}
]
});
</script>
</body>

105
samples/dhtmlx-gantt/samples/02_extensions/16_keyboard_navigation.html

@ -0,0 +1,105 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Keyboard Navigation</title>
<script src="../../codebase/dhtmlxgantt.js?v=7.1.8"></script>
<link rel="stylesheet" href="../../codebase/dhtmlxgantt.css?v=7.1.8">
<style>
html, body{
padding:0;
margin: 0;
}
</style>
</head>
<body>
<div id="gantt_here" style='height:100vh;'></div>
<script>
gantt.plugins({
keyboard_navigation: true,
undo: true
});
gantt.message({
text: "<p>Keyboard shortcuts:</p>" +
"<b>Global</b>" +
"<ul>" +
"<li><b>Tab</b> - select gantt</li>" +
"<li><b>Alt + Up/Down/Left/Right</b> - scroll gantt</li>" +
"<li><b>Ctrl + Enter</b> - create new task</li>" +
"<li><b>Ctrl + Z</b> - undo</li>" +
"<li><b>Ctrl + R</b> - redo</li>" +
"</ul>" +
"<b>Header Cells</b>" +
"<ul>" +
"<li><b>Left/Right</b> - navigate over cells</li>" +
"<li><b>Home/End</b> - navigate to the first/last column</li>" +
"<li><b>Down</b> - navigate to task rows</li>" +
"<li><b>Space/Enter</b> - click header</li>" +
"</ul>" +
"<b>Task rows</b>" +
"<ul>" +
"<li><b>Up/Down</b> - navigate rows</li>" +
"<li><b>PageDown/PageUp</b> - navigate to the first/last task</li>" +
"<li><b>Space</b> - select task</li>" +
"<li><b>Ctrl + Enter</b> - create new task</li>" +
"<li><b>Delete</b> - delete selected task</li>" +
"<li><b>Enter</b> - open the lightbox</li>" +
"<li><b>Ctrl + Left/Right</b> - expand, collapse tree</li>" +
"</ul>",
expire: -1
});
gantt.config.sort = true;
gantt.config.duration_unit = "day";
gantt.config.row_height = 30;
gantt.config.min_column_width = 40;
gantt.init("gantt_here");
gantt.parse({
data: [
{id: 1, text: "Office itinerancy", open: true, type: "project"},
{id: 2, text: "Office facing", start_date: "21-07-2019", duration: "20", parent: "1"},
{id: 3, text: "Furniture installation", start_date: "21-07-2019", duration: "5", parent: "1"},
{id: 4, text: "The employee relocation", start_date: "28-07-2019", duration: "15", parent: "1"},
{id: 5, text: "Interior office", start_date: "28-07-2019", duration: "15", parent: "1"},
{id: 6, text: "Air conditioners installation", start_date: "18-08-2019", duration: "2", parent: "1"},
{id: 7, text: "Workplaces preparation", start_date: "20-08-2019", duration: "2", parent: "1"},
{id: 8, text: "Preparing workplaces for us", start_date: "21-07-2019", duration: "10", parent: "1"},
{id: 9, text: "Workplaces importation", start_date: "22-08-2019", duration: "1", parent: "1"},
{id: 10, text: "Analysis", open: true, type: "project"},
{id: 11, text: "Documentation creation", start_date: "25-08-2019", duration: "14", parent: "10"},
{id: 12, text: "Software design", start_date: "25-08-2019", duration: "10", parent: "10"},
{id: 13, text: "Interface setup", start_date: "12-09-2019", duration: "1", parent: "10"},
{id: 14, text: "Development", open: true, type: "project"},
{id: 15, text: "Develop System", start_date: "15-09-2019", duration: "5", parent: "14"},
{id: 16, text: "Integrate System", start_date: "15-09-2019", duration: "15", parent: "14"},
{id: 17, text: "Test", start_date: "06-10-2019", duration: "1", parent: "14"}
],
links: [
{id: "1", source: "3", target: "4", type: "0"},
{id: "2", source: "3", target: "5", type: "0"},
{id: "3", source: "2", target: "6", type: "0"},
{id: "4", source: "4", target: "6", type: "0"},
{id: "5", source: "5", target: "6", type: "0"},
{id: "6", source: "6", target: "7", type: "0"},
{id: "7", source: "7", target: "9", type: "0"},
{id: "8", source: "8", target: "9", type: "0"},
{id: "9", source: "9", target: "10", type: "0"},
{id: "10", source: "9", target: "11", type: "0"},
{id: "11", source: "9", target: "12", type: "0"},
{id: "12", source: "11", target: "13", type: "0"},
{id: "13", source: "12", target: "13", type: "0"},
{id: "14", source: "13", target: "14", type: "0"},
{id: "15", source: "13", target: "15", type: "0"},
{id: "16", source: "15", target: "17", type: "0"},
{id: "17", source: "16", target: "17", type: "0"}
]
});
</script>
</body>

110
samples/dhtmlx-gantt/samples/02_extensions/17_keyboard_navigation_cell.html

@ -0,0 +1,110 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Keyboard Navigation - navigate cells</title>
<script src="../../codebase/dhtmlxgantt.js?v=7.1.8"></script>
<link rel="stylesheet" href="../../codebase/dhtmlxgantt.css?v=7.1.8">
<style>
html, body{
padding:0;
margin: 0;
}
</style>
</head>
<body>
<div id="gantt_here" style='height:100vh;'></div>
<script>
gantt.plugins({
keyboard_navigation: true,
undo: true
});
gantt.message({
text: "<p>Keyboard shortcuts:</p>" +
"<b>Global</b>" +
"<ul>" +
"<li><b>Tab</b> - select gantt</li>" +
"<li><b>Alt + Up/Down/Left/Right</b> - scroll gantt</li>" +
"<li><b>Ctrl + Enter</b> - create new task</li>" +
"<li><b>Ctrl + Z</b> - undo</li>" +
"<li><b>Ctrl + R</b> - redo</li>" +
"</ul>" +
"<b>Header Cells</b>" +
"<ul>" +
"<li><b>Left/Right</b> - navigate over cells</li>" +
"<li><b>Home/End</b> - navigate to the first/last column</li>" +
"<li><b>Down</b> - navigate to task rows</li>" +
"<li><b>Space/Enter</b> - click header</li>" +
"</ul>" +
"<b>Task cells</b>" +
"<ul>" +
"<li><b>Up/Down/Left/Right</b> - navigate cells</li>" +
"<li><b>PageDown/PageUp</b> - navigate to the first/last cell in column</li>" +
"<li><b>Home/End</b> - navigate to the first/last cell in row</li>" +
"<li><b>Space</b> - select task</li>" +
"<li><b>Ctrl + Enter</b> - create new task</li>" +
"<li><b>Delete</b> - delete selected task</li>" +
"<li><b>Enter</b> - open the lightbox</li>" +
"<li><b>Ctrl + Left/Right</b> - expand, collapse tree</li>" +
"</ul>",
expire: -1
});
// gantt.config.show_errors = false;
gantt.config.sort = true;
gantt.config.duration_unit = "day";
gantt.config.row_height = 30;
gantt.config.min_column_width = 40;
gantt.config.keyboard_navigation_cells = true;
gantt.init("gantt_here");
gantt.parse({
data: [
{id: 1, text: "Office itinerancy", open: true, type: "project"},
{id: 2, text: "Office facing", start_date: "21-07-2019", duration: "20", parent: "1"},
{id: 3, text: "Furniture installation", start_date: "21-07-2019", duration: "5", parent: "1"},
{id: 4, text: "The employee relocation", start_date: "28-07-2019", duration: "15", parent: "1"},
{id: 5, text: "Interior office", start_date: "28-07-2019", duration: "15", parent: "1"},
{id: 6, text: "Air conditioners installation", start_date: "18-08-2019", duration: "2", parent: "1"},
{id: 7, text: "Workplaces preparation", start_date: "20-08-2019", duration: "2", parent: "1"},
{id: 8, text: "Preparing workplaces for us", start_date: "21-07-2019", duration: "10", parent: "1"},
{id: 9, text: "Workplaces importation", start_date: "22-08-2019", duration: "1", parent: "1"},
{id: 10, text: "Analysis", open: true, type: "project"},
{id: 11, text: "Documentation creation", start_date: "25-08-2019", duration: "14", parent: "10"},
{id: 12, text: "Software design", start_date: "25-08-2019", duration: "10", parent: "10"},
{id: 13, text: "Interface setup", start_date: "12-09-2019", duration: "1", parent: "10"},
{id: 14, text: "Development", open: true, type: "project"},
{id: 15, text: "Develop System", start_date: "15-09-2019", duration: "5", parent: "14"},
{id: 16, text: "Integrate System", start_date: "15-09-2019", duration: "15", parent: "14"},
{id: 17, text: "Test", start_date: "06-10-2019", duration: "1", parent: "14"}
],
links: [
{id: "1", source: "3", target: "4", type: "0"},
{id: "2", source: "3", target: "5", type: "0"},
{id: "3", source: "2", target: "6", type: "0"},
{id: "4", source: "4", target: "6", type: "0"},
{id: "5", source: "5", target: "6", type: "0"},
{id: "6", source: "6", target: "7", type: "0"},
{id: "7", source: "7", target: "9", type: "0"},
{id: "8", source: "8", target: "9", type: "0"},
{id: "9", source: "9", target: "10", type: "0"},
{id: "10", source: "9", target: "11", type: "0"},
{id: "11", source: "9", target: "12", type: "0"},
{id: "12", source: "11", target: "13", type: "0"},
{id: "13", source: "12", target: "13", type: "0"},
{id: "14", source: "13", target: "14", type: "0"},
{id: "15", source: "13", target: "15", type: "0"},
{id: "16", source: "15", target: "17", type: "0"},
{id: "17", source: "16", target: "17", type: "0"}
]
});
</script>
</body>

154
samples/dhtmlx-gantt/samples/02_extensions/18_linked_tasks.html

@ -0,0 +1,154 @@
<!DOCTYPE html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Auto Scheduling - Groups of connected tasks</title>
<script src="../../codebase/dhtmlxgantt.js?v=7.1.8"></script>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans|Roboto:regular,medium,thin,bold">
<link rel="stylesheet" href="../../codebase/skins/dhtmlxgantt_material.css?v=7.1.8">
<style>
html, body {
height: 100%;
padding: 0px;
margin: 0px;
overflow: hidden;
}
.weekend {
background: #f4f7f4 !important;
}
.task_groups {
background-color: orangered !important;
}
.task_groups .gantt_task_progress {
background-color: red;
opacity: 0.6;
}
.gantt_task_row.gantt_selected .weekend {
background-color: #C0E8FF !important;
}
</style>
</head>
<body>
<div id="gantt_here" style='width:100%; height:100%;'></div>
<script>
gantt.plugins({
auto_scheduling: true
});
gantt.templates.scale_cell_class = function (date) {
if (!gantt.isWorkTime(date)) {
return "weekend";
}
};
gantt.templates.timeline_cell_class = function (item, date) {
if (!gantt.isWorkTime({date: date, task: item})) {
return "weekend";
}
};
gantt.templates.rightside_text = function(start, end, task) {
if (task.type === gantt.config.types.milestone)
return task.text;
return ""
};
gantt.config.work_time = true;
gantt.config.min_column_width = 60;
gantt.config.auto_scheduling = true;
gantt.config.auto_scheduling_strict = true;
gantt.config.date_format = "%d-%m-%Y";
(function() {
var highlightTasks = [],
highlightSearch = {};
function reset(value) {
if (value) {
if (value.join() === highlightTasks.join()) {
return;
}
highlightTasks = value;
highlightSearch = {};
highlightTasks.forEach(function(id){
highlightSearch[id] = true;
});
gantt.render();
}
else if (highlightTasks.length) {
highlightTasks = [];
highlightSearch = {};
gantt.render();
}
}
gantt.templates.task_class = function(start, end, task) {
if (highlightSearch[task.id])
return "task_groups";
return "";
};
gantt.attachEvent("onTaskClick", function(id) {
var task = gantt.getTask(id);
var group = gantt.getConnectedGroup(id);
if(!group.tasks.length){
reset();
}else{
reset(group.tasks);
gantt.message({
text: "<strong>Selected task:</strong> " + task.text +
"<br><strong>Connected Group:</strong><br> " +
group.tasks.map(function(t) { return gantt.getTask(t).text}).join("<br>"),
expire: 5000
}
);
}
return true;
});
gantt.attachEvent("onEmptyClick", function() {
reset();
return true;
});
})();
gantt.message({text:"Click any task to highlight the connected group", expire:-1});
gantt.init("gantt_here");
gantt.parse({
data:[
{id:11,text:"Project #1",type:"project",progress:0.6,open:true,start_date:"02-04-2018",duration:14,parent:0},
{id:12,text:"Task #1",start_date:"02-04-2018",duration:5,parent:"11",progress:1,open:true},
{id:13,text:"Task #2",start_date:"03-04-2018",type:"project",parent:"11",progress:0.5,open:true,duration:13},
{id:17,text:"Task #2.1",start_date:"03-04-2018",duration:2,parent:"13",progress:1,open:true},
{id:18,text:"Task #2.2",start_date:"05-04-2018",duration:3,parent:"13",progress:0.8,open:true},
{id:19,text:"Task #2.3",start_date:"10-04-2018",duration:4,parent:"13",progress:0.2,open:true},
{id:20,text:"Task #2.4",start_date:"16-04-2018",duration:4,parent:"13",progress:0,open:true},
{id:14,text:"Task #3",start_date:"02-04-2018",duration:6,parent:"11",progress:0.8,open:true},
{id:15,text:"Task #4",type:"project",parent:"11",progress:0.2,open:true,start_date:"02-04-2018",duration:8},
{id:21,text:"Task #4.1",start_date:"02-04-2018",duration:4,parent:"15",progress:0.5,open:true},
{id:22,text:"Task #4.2",start_date:"06-04-2018",duration:4,parent:"15",progress:0.1,open:true},
{id:23,text:"Mediate milestone",start_date:"12-04-2018",type:"milestone",parent:"15",progress:0,open:true,duration:0}
],
links:[
{id:"15",source:"13",target:"17",type:"1"},
{id:"16",source:"17",target:"18",type:"0"},
{id:"17",source:"18",target:"19",type:"0"},
{id:"18",source:"19",target:"20",type:"0"},
{id:"21",source:"15",target:"23",type:"0"},
{id:"22",source:"21",target:"22",type:"0"},
{id:"23",source:"14",target:"15",type:"0"},
{id:"24",source:"22",target:"23",type:"0"},
{id:"25",source:"12",target:"19",type:"0"}
]
});
</script>
</body>

359
samples/dhtmlx-gantt/samples/02_extensions/21_overlay.html

@ -0,0 +1,359 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Gantt chart with overlay</title>
<script src="../../codebase/dhtmlxgantt.js?v=7.1.8"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.3/Chart.min.js?v=7.1.8"></script>
<link rel="stylesheet" href="../../codebase/dhtmlxgantt.css?v=7.1.8">
<link rel="stylesheet" href="../common/controls_styles.css?v=7.1.8">
<script src="./data.js?v=7.1.8"></script>
<style>
html, body {
padding: 0px;
margin: 0px;
height: 90%;
}
.gantt_marker{
background-color: rgba(255, 0, 0, 0.8);
}
.gantt_task_line, .gantt_task_link{
transition: opacity 200ms;
}
.overlay_visible .gantt_task_line,
.overlay_visible .gantt_task_link{
opacity: 0.6;
}
.gantt_marker.today{
background: #ffb121;
}
</style>
</head>
<body>
<div class="gantt_control" >
<input type='button' onclick="toggleOverlay()" value="Toggle Progress Line">
</div>
<div id="gantt_here" style="width:100%; height:calc(100vh - 52px);"></div>
<script>
gantt.plugins({
marker: true,
overlay: true
});
var overlayControl = gantt.ext.overlay;
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);
}
});
return cells;
}
function getProgressLine(){
var tasks = gantt.getTaskByTime();
var scale = gantt.getScale();
var step = scale.unit;
var timegrid = {};
var totalDuration = 0;
gantt.eachTask(function(task){
if(gantt.isSummaryTask(task)){
return;
}
if(!task.duration){
return;
}
var currDate = gantt.date[scale.unit + "_start"](new Date(task.start_date));
while (currDate < task.end_date) {
var date = currDate;
currDate = gantt.date.add(currDate, 1, step);
if (!gantt.isWorkTime({date: date, task: task, unit: step})) {
continue;
}
var timestamp = currDate.valueOf();
if (!timegrid[timestamp]){
timegrid[timestamp] = {
planned: 0,
real: 0
};
}
timegrid[timestamp].planned += 1;
if (date <= today){
timegrid[timestamp].real += 1 * (task.progress || 0);
}
totalDuration += 1;
}
});
var cumulativePlannedDurations = [];
var cumulativeRealDurations = [];
var cumulativePredictedDurations = []
var totalPlanned = 0;
var totalReal = 0;
var chartScale = getChartScaleRange();
var dailyRealProgress = -1;
var totalPredictedProgress = 0;
for(var i = 0; i < chartScale.length; i++){
start = new Date(chartScale[i]);
end = gantt.date.add(start, 1, step);
var cell = timegrid[start.valueOf()] || {planned:0, real:0};
totalPlanned = cell.planned + totalPlanned;
cumulativePlannedDurations.push(totalPlanned);
if(start <= today) {
totalReal = (cell.real||0) + totalReal;
cumulativeRealDurations.push(totalReal);
cumulativePredictedDurations.push(null);
} else{
if(dailyRealProgress < 0){
dailyRealProgress = totalReal / cumulativeRealDurations.length;
totalPredictedProgress = totalReal;
cumulativePredictedDurations.pop();
cumulativePredictedDurations.push(totalPredictedProgress);
}
totalPredictedProgress += dailyRealProgress;
cumulativePredictedDurations.push(totalPredictedProgress);
}
}
for(var i = 0; i < cumulativePlannedDurations.length; i++){
cumulativePlannedDurations[i] = Math.round(cumulativePlannedDurations[i] / totalPlanned * 100);
if(cumulativeRealDurations[i] !== undefined){
cumulativeRealDurations[i] = Math.round(cumulativeRealDurations[i] / totalPlanned * 100);
}
if(cumulativePredictedDurations[i] !== null){
cumulativePredictedDurations[i] = Math.round(cumulativePredictedDurations[i] / totalPlanned * 100);
}
}
return {planned: cumulativePlannedDurations, real: cumulativeRealDurations, predicted: cumulativePredictedDurations};
}
var dateToStr = gantt.date.date_to_str("%F %j, %Y");
var today = new Date(2019, 3, 14);
gantt.addMarker({
start_date: today,
css: "today",
text: "Today",
title: "Today: " + dateToStr(today)
});
var projectEnd = new Date(2019, 3, 19);
gantt.addMarker({
start_date: projectEnd,
text: "Project end",
title: "Project end: " + dateToStr(today)
});
gantt.config.open_tree_initially = true;
gantt.init("gantt_here");
function getScalePaddings(){
var scale = gantt.getScale();
var dataRange = gantt.getSubtaskDates();
var chartScale = getChartScaleRange();
var newWidth = scale.col_width;
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(dataRange.start_date) - yScaleLabelsWidth;
padding.right = scale.full_width - gantt.posFromDate(dataRange.end_date) - 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 scaleLabels = [];
var chartScale = getChartScaleRange();
chartScale.forEach(function(date){
scaleLabels.push(dateToStr(date));
});
var values = getProgressLine();
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: "#001eff",
borderColor: "#001eff",
data: values.planned,
fill: false,
cubicInterpolationMode: 'monotone'
},
{
label: "Real progress",
backgroundColor: "#ff5454",
borderColor: "#ff5454",
data: values.real,
fill: false,
cubicInterpolationMode: 'monotone'
}
,
{
label: "Real progress (predicted)",
backgroundColor: "#ff5454",
borderColor: "#ff5454",
data: values.predicted,
borderDash: [5, 10],
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,
max: 100,
stepSize: 10,
callback: function(current) {
if (current > 100) {return "";}
return current + "%";
}
}
},
{
display: true,
position: "right",
gridLines: {
display:false
},
ticks: {
display: true,
min: 0,
max: 100,
stepSize: 10,
callback: function(current) {
if (current > 100) {return "";}
return current + "%";
}
}}
]
}
}
});
return canvas;
});
gantt.parse(taskData);
</script>
</body>
</html>

392
samples/dhtmlx-gantt/samples/02_extensions/22_tooltip_api.html

@ -0,0 +1,392 @@
<!DOCTYPE html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Custom Tooltips</title>
<script src="../../codebase/dhtmlxgantt.js?v=7.1.8"></script>
<link rel="stylesheet" href="../../codebase/dhtmlxgantt.css?v=7.1.8">
<script src="../common/resource_project_assignments.js?v=7.1.8"></script>
<style>
html,
body {
height: 100%;
padding: 0px;
margin: 0px;
}
.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;
border-radius: 15px;
color: #FFF;
margin: 3px;
}
.resource_marker.workday_ok div {
background: #51c185;
}
.resource_marker.workday_over div {
background: #ff8686;
}
.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;
}
.gantt_tooltip {
font-size: 13px;
line-height: 16px;
}
</style>
</head>
<body>
<div id="gantt_here" style='width:100%; height:100vh;'></div>
<script>
function linkTypeToString(linkType) {
switch (linkType) {
case gantt.config.links.start_to_start:
return "Start to start";
case gantt.config.links.start_to_finish:
return "Start to finish";
case gantt.config.links.finish_to_start:
return "Finish to start";
case gantt.config.links.finish_to_finish:
return "Finish to finish";
default:
return ""
}
}
gantt.plugins({
tooltip: true
});
gantt.templates.tooltip_date_format = gantt.date.date_to_str("%F %j, %Y");
gantt.attachEvent("onGanttReady", function () {
var tooltips = gantt.ext.tooltips;
gantt.templates.tooltip_text = function (start, end, task) {
var store = gantt.getDatastore("resource");
var assignments = task[gantt.config.resource_property] || [];
var owners = [];
assignments.forEach(function (assignment) {
var owner = store.getItem(assignment.resource_id)
owners.push(owner.text);
});
return "<b>Task:</b> " + task.text + "<br/>" +
"<b>Owner:</b>" + owners.join(",") + "<br/>" +
"<b>Start date:</b> " +
gantt.templates.tooltip_date_format(start) +
"<br/><b>End date:</b> " + gantt.templates.tooltip_date_format(end);
};
tooltips.tooltipFor({
selector: ".gantt_task_link",
html: function (event, node) {
var linkId = node.getAttribute(gantt.config.link_attribute);
if (linkId) {
var link = gantt.getLink(linkId);
var from = gantt.getTask(link.source);
var to = gantt.getTask(link.target);
return [
"<b>Link:</b> " + linkTypeToString(link.type),
"<b>From: </b> " + from.text,
"<b>To: </b> " + to.text
].join("<br>");
}
}
});
tooltips.tooltipFor({
selector: ".gantt_row[resource_id]",
html: function (event, node) {
var resourceId = node.getAttribute("resource_id");
var store = gantt.getDatastore(gantt.config.resource_store);
var resource = store.getItem(resourceId);
var assignments = getResourceAssignments(resource, store)
var totalDuration = 0;
for (var i = 0; i < assignments.length; i++) {
var task = gantt.getTask(assignments[i].task_id);
totalDuration += task.duration * assignments[i].value;
}
return [
"<b>Resource:</b> " + resource.text,
"<b>Tasks assigned:</b> " + assignments.length,
"<b>Total load: </b>" + (totalDuration || 0) + "h"
].join("<br>");
}
});
tooltips.tooltipFor({
selector: ".gantt_scale_cell",
html: function (event, node) {
var relativePosition = gantt.utils.dom.getRelativeEventPosition(event, gantt.$task_scale);
return gantt.templates.tooltip_date_format(gantt.dateFromPos(relativePosition.x));
}
});
tooltips.tooltipFor({
selector: ".gantt_resource_marker",
html: function (event, node) {
var dataElement = node.querySelector("[data-recource-tasks]");
var ids = JSON.parse(dataElement.getAttribute("data-recource-tasks"));
var date = gantt.templates.parse_date(dataElement.getAttribute("data-cell-date"));
var resourceId = dataElement.getAttribute("data-resource-id");
var relativePosition = gantt.utils.dom.getRelativeEventPosition(event, gantt.$task_scale);
var store = gantt.getDatastore("resource");
var html = [
"<b>" + store.getItem(resourceId).text + "</b>" + ", " + gantt.templates.tooltip_date_format(date),
"",
ids.map(function (id, index) {
var task = gantt.getTask(id);
var assignenment = gantt.getResourceAssignments(resourceId, task.id);
var amount = "";
var taskIndex = (index + 1);
if (assignenment[0]) {
amount = " (" + assignenment[0].value + "h) ";
}
return "Task #" + taskIndex + ": " + amount + task.text;
}).join("<br>")
].join("<br>");
return html;
}
});
});
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 = task[gantt.config.resource_property] || [];
if (!assignments || !assignments.length) {
return "Unassigned";
}
if (assignments.length == 1) {
return store.getItem(assignments[0].resource_id).text;
}
var result = "";
assignments.forEach(function (assignment) {
var owner = store.getItem(assignment.resource_id);
if (!owner)
return;
result += "<div class='owner-label' title='" + owner.text + "'>" + owner.text.substr(0, 1) + "</div>";
});
return result;
}, resize: true
},
{ name: "duration", width: 60, align: "center" },
{ name: "add", width: 44 }
];
function getResourceAssignments(resource, store) {
var assignments = [];
if (store.hasChild(resource.id)) {
store.eachItem(function (res) {
assignments = assignments.concat(gantt.getResourceAssignments(res.id));
}, resource.id)
} else {
assignments = gantt.getResourceAssignments(resource.id)
}
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 store = gantt.getDatastore(gantt.config.resource_store);
var assignments = getResourceAssignments(resource, store)
var totalDuration = 0;
for (var i = 0; i < assignments.length; i++) {
var task = gantt.getTask(assignments[i].task_id);
totalDuration += task.duration * assignments[i].value;
}
return (totalDuration || 0) + "h";
}
}
]
};
function getTasksLoad(tasks, resourceId) {
var totalLoad = 0;
tasks.forEach(function (task) {
var assignments = gantt.getResourceAssignments(resourceId, task.id);
totalLoad += assignments[0].value;
});
return totalLoad;
}
gantt.templates.resource_cell_class = function (start_date, end_date, resource, tasks) {
var totalLoad = getTasksLoad(tasks, resource.id);
var css = [];
css.push("resource_marker");
if (totalLoad <= 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) {
var totalLoad = getTasksLoad(tasks, resource.id);
var tasksIds = "data-recource-tasks='" + JSON.stringify(tasks.map(function (task) {
return task.id
})) + "'";
var resourceId = "data-resource-id='" + resource.id + "'";
var dateAttr = "data-cell-date='" + gantt.templates.format_date(start_date) + "'";
return "<div " + tasksIds + " " + resourceId + " " + dateAttr + ">" + totalLoad + "</div>";
};
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",
initItem: function (item) {
item.parent = item.parent || gantt.config.root_id;
item[gantt.config.resource_property] = item.parent;
item.open = true;
return item;
}
});
gantt.attachEvent("onTaskCreated", function(task){
task[gantt.config.resource_property] = [];
return true;
});
gantt.init("gantt_here");
resourcesStore.attachEvent("onParse", function () {
var people = [];
resourcesStore.eachItem(function (res) {
if (!resourcesStore.hasChild(res.id)) {
var copy = gantt.copy(res);
copy.key = res.id;
copy.label = res.text;
people.push(copy);
}
});
gantt.updateCollection("people", people);
});
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.parse(taskData);
</script>
</body>

107
samples/dhtmlx-gantt/samples/02_extensions/23_click_drag_splittask.html

@ -0,0 +1,107 @@
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>Create split tasks by Drag and Drop</title>
<script src="../../codebase/dhtmlxgantt.js?v=7.1.8"></script>
<link rel="stylesheet" href="../../codebase/dhtmlxgantt.css?v=7.1.8">
</head>
<body>
<div id="gantt_here" style="width: 100%; height: 500px;"></div>
<script>
gantt.plugins({
click_drag: true
});
gantt.message({
text: "Click and drag to create a new split task or a new part to existing one.",
expire: -1
});
gantt.config.lightbox.sections = [
{name: "description", height: 38, map_to: "text", type: "textarea", focus: true},
{
name: "priority", height: 22, map_to: "priority", type: "select", options: [
{key: 1, label: "High"},
{key: 2, label: "Normal"},
{key: 3, label: "Low"}
]
},
{name: "time", type: "duration", map_to: "auto"}
];
gantt.config.open_split_tasks = true;
gantt.locale.labels.section_priority = "Priority";
gantt.config.multiselect = true;
gantt.config.click_drag = {
callback: onDragEnd,
singleRow: true
}
gantt.init("gantt_here");
gantt.parse({
data: [
{id: 11, text: "Project #1", type: "project", progress: 0, open: true, start_date: "02-04-2018 00:00", duration: 13, parent: 0},
{id: 12, text: "Task #1", start_date: "03-04-2018 00:00", duration: 5, parent: "11", progress: 0, open: true},
{id: 13, text: "Task #2", start_date: "03-04-2018 00:00", type: "project", render:"split", parent: "11", progress: 0.5, open: false, duration: 11},
{id: 17, text: "Stage #1", start_date: "03-04-2018 00:00", duration: 1, parent: "13", progress: 0, open: true},
{id: 18, text: "Stage #2", start_date: "05-04-2018 00:00", duration: 2, parent: "13", progress: 0, open: true},
{id: 19, text: "Stage #3", start_date: "08-04-2018 00:00", duration: 1, parent: "13", progress: 0, open: true},
{id: 20, text: "Stage #4", start_date: "10-04-2018 00:00", duration: 4, parent: "13", progress: 0, open: true},
{id: 14, text: "Task #3", start_date: "02-04-2018 00:00", duration: 6, parent: "11", progress: 0, open: true},
{id: 15, text: "Task #4", type: "project", render:"split", parent: "11", progress: 0, open: true, start_date: "03-04-2018 00:00", duration: 11},
{id: 21, text: "Stage #1", start_date: "03-04-2018 00:00", duration: 4, parent: "15", progress: 0, open: true},
{id: 22, text: "Stage #2", start_date: "08-04-2018 00:00", duration: 3, parent: "15", progress: 0, open: true},
{id: 23, text: "Mediate milestone", start_date: "14-04-2018 00:00", duration: 0, type: "milestone", parent: "15", progress: 0, open: true, duration: 0},
{id: 16, text: "Final milestone", start_date: "15-04-2018 00:00", duration: 0, type: "milestone", parent: "11", progress: 0, open: true, duration: 0}
],
links: [
{id: "1", source: "17", target: "18", type: "0"},
{id: "2", source: "18", target: "19", type: "0"},
{id: "3", source: "19", target: "20", type: "0"},
{id: "4", source: "21", target: "22", type: "0"},
{id: "5", source: "22", target: "23", type: "0"}
]
});
function onDragEnd(startPoint, endPoint, startDate, endDate, tasksBetweenDates, tasksInRow) {
if (tasksInRow.length === 1) {
var currentTask = tasksInRow[0];
if (currentTask.type === "project") {
currentTask.render = "split";
gantt.addTask({
text: "Subtask of " + currentTask.text,
start_date: gantt.roundDate(startDate),
end_date: gantt.roundDate(endDate)
}, currentTask.id);
} else {
var projectName = "new Project " + currentTask.text;
var newProject = gantt.addTask({
text: projectName,
render: "split",
type: "project",
}, currentTask.parent);
gantt.moveTask(newProject, gantt.getTaskIndex(currentTask.id), gantt.getParent(currentTask.id));
gantt.moveTask(currentTask.id, 0, newProject);
gantt.calculateTaskLevel(currentTask)
var newTask = gantt.addTask({
text: "Subtask of " + projectName,
start_date: gantt.roundDate(startDate),
end_date: gantt.roundDate(endDate)
}, newProject);
gantt.calculateTaskLevel(newTask);
}
} else if (tasksInRow.length === 0) {
gantt.createTask({
text: "New task",
start_date: gantt.roundDate(startDate),
end_date: gantt.roundDate(endDate)
});
}
}
</script>
</body>
</html>

71
samples/dhtmlx-gantt/samples/02_extensions/24_click_drag.html

@ -0,0 +1,71 @@
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>Create new tasks by Drag and Drop</title>
<script src="../../codebase/dhtmlxgantt.js?v=7.1.8"></script>
<link rel="stylesheet" href="../../codebase/dhtmlxgantt.css?v=7.1.8">
<style>
html, body {
height: 100%;
margin: 0;
}
</style>
</head>
<body>
<div id="gantt_here" style="width: 100%; height: 80%;"></div>
<script>
gantt.plugins({
click_drag: true
});
gantt.message({
text: "Click and drag to create a new task",
expire: -1
});
gantt.config.lightbox.sections = [
{ name: "description", height: 38, map_to: "text", type: "textarea", focus: true },
{ name: "priority", height: 22, map_to: "priority", type: "select", options: [
{key: 1, label: "High"},
{key: 2, label: "Normal"},
{key: 3, label: "Low"}
] },
{ name: "time", type: "duration", map_to: "auto" }
];
gantt.locale.labels.section_priority = "Priority";
gantt.config.click_drag = {
callback: onDragEnd,
singleRow: true
};
gantt.init("gantt_here");
gantt.parse({
data: [
{ id: 1, text: "Project #1", start_date: "01-04-2018", duration: 18, progress: 0.4, open: true },
{ id: 2, text: "Task #1", start_date: "02-04-2018", duration: 8, progress: 0.6, parent: 1 },
{ id: 3, text: "Task #2", start_date: "11-04-2018", duration: 8, progress: 0.6, parent: 1 }
],
links: [
{id: 1, source: 1, target: 2, type: "1"}
]
});
function onDragEnd(startPoint, endPoint, startDate, endDate, tasksBetweenDates, tasksInRow) {
if (tasksInRow.length === 1) {
var parent = tasksInRow[0];
gantt.createTask({
text:"Subtask of " + parent.text,
start_date: gantt.roundDate(startDate),
end_date: gantt.roundDate(endDate)
}, parent.id);
} else if (tasksInRow.length === 0) {
gantt.createTask({
text:"New task",
start_date: gantt.roundDate(startDate),
end_date: gantt.roundDate(endDate)
});
}
}
</script>
</body>
</html>

128
samples/dhtmlx-gantt/samples/02_extensions/25_click_drag_select_by_drag.html

@ -0,0 +1,128 @@
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>Select multiple tasks by Drag and Drop</title>
<script src="../../codebase/dhtmlxgantt.js?v=7.1.8"></script>
<link rel="stylesheet" href="../../codebase/dhtmlxgantt.css?v=7.1.8">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<link rel="stylesheet" href="../common/controls_styles.css?v=7.1.8">
<style>
html, body {
height: 100%;
padding: 0;
margin: 0;
}
</style>
</head>
<body>
<div class="gantt_control">
<input type="radio" id="mode1" class="gantt_radio" name="selectMode" value="1"/><label for="mode1"><i class="material-icons"></i>Select in dates</label>
<input type="radio" id="mode2" class="gantt_radio" name="selectMode" value="2"/><label for="mode2"><i class="material-icons"></i>Select in rows</label>
<input type="radio" id="mode3" class="gantt_radio" name="selectMode" value="3" checked /><label for="mode3"><i class="material-icons"></i>Select in bounds</label>
<button onClick="unselectTasks()">Unselect</button>
</div>
<div id="gantt_here" style="width: 100%; height:calc(100vh - 52px);"></div>
<script>
function unselectTasks() {
gantt.eachSelectedTask(function(item) {
gantt.unselectTask(item.id);
});
};
gantt.plugins({
multiselect: true,
click_drag: true
});
gantt.message({
text: "Click and drag to select multiple tasks",
expire: -1
});
gantt.config.lightbox.sections = [
{name: "description", height: 38, map_to: "text", type: "textarea", focus: true},
{
name: "priority", height: 22, map_to: "priority", type: "select", options: [
{key: 1, label: "High"},
{key: 2, label: "Normal"},
{key: 3, label: "Low"}
]
},
{name: "time", type: "duration", map_to: "auto"}
];
gantt.locale.labels.section_priority = "Priority";
gantt.config.multiselect = true;
gantt.config.click_drag = {
callback: onDragEnd
};
gantt.config.autoscroll = true;
gantt.config.autoscroll_speed = 50;
gantt.init("gantt_here");
gantt.parse({
data: [
{id: 11, text: "Project #1", start_date: "28-03-2013", duration: "11"},
{id: 1, text: "Project #2", start_date: "01-04-2013", duration: "18"},
{id: 2, text: "Task #1", start_date: "02-04-2013", duration: "8"},
{id: 3, text: "Task #2", start_date: "11-04-2013", duration: "8"},
{id: 4, text: "Task #3", start_date: "13-04-2013", duration: "6"},
{id: 5, text: "Task #1.1", start_date: "02-04-2013", duration: "7"},
{id: 6, text: "Task #1.2", start_date: "03-04-2013", duration: "7"},
{id: 7, text: "Task #2.1", start_date: "11-04-2013", duration: "8"},
{id: 8, text: "Task #3.1", start_date: "14-04-2013", duration: "5"},
{id: 9, text: "Task #3.2", start_date: "14-04-2013", duration: "4"},
{id: 10, text: "Task #3.3", start_date: "14-04-2013", duration: "3"},
{id: 12, text: "Task #1", start_date: "03-04-2013", duration: "5"},
{id: 13, text: "Task #2", start_date: "02-04-2013", duration: "7"},
{id: 14, text: "Task #3", start_date: "02-04-2013", duration: "6"},
{id: 15, text: "Task #4", start_date: "02-04-2013", duration: "5"},
{id: 16, text: "Task #5", start_date: "02-04-2013", duration: "7"},
{id: 17, text: "Task #2.1", start_date: "03-04-2013", duration: "2"},
{id: 18, text: "Task #2.2", start_date: "06-04-2013", duration: "3"},
{id: 19, text: "Task #2.3", start_date: "10-04-2013", duration: "4"},
{id: 20, text: "Task #2.4", start_date: "10-04-2013", duration: "4"},
{id: 21, text: "Task #4.1", start_date: "03-04-2013", duration: "4"},
{id: 22, text: "Task #4.2", start_date: "03-04-2013", duration: "4"},
{id: 23, text: "Task #4.3", start_date: "03-04-2013", duration: "5"}
],
links: [
{id: 1, source: 1, target: 2, type: "1"}
]
});
function onDragEnd(startPoint, endPoint, startDate, endDate, tasksBetweenDates, tasksInRows) {
var mode = document.querySelector("input[name=selectMode]:checked").value;
switch(mode) {
case "1":
unselectTasks();
tasksBetweenDates.forEach(function(item) {
gantt.selectTask(item.id);
});
break;
case "2":
unselectTasks();
tasksInRows.forEach(function(item) {
gantt.selectTask(item.id);
});
break;
case "3":
unselectTasks();
for (var i=0; i<tasksBetweenDates.length; i++) {
for (var j=0; j<tasksInRows.length; j++) {
if (tasksBetweenDates[i] === tasksInRows[j]) {
gantt.selectTask(tasksBetweenDates[i].id);
}
}
}
break;
return;
}
}
</script>
</body>
</html>

48
samples/dhtmlx-gantt/samples/02_extensions/26_full_screen_with_additional_elements.html

@ -0,0 +1,48 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Full Screen with additional elements</title>
<script src="../../codebase/dhtmlxgantt.js?v=7.1.8"></script>
<script src="../common/testdata.js?v=7.1.8"></script>
<link rel="stylesheet" href="../../codebase/dhtmlxgantt.css?v=7.1.8">
<link rel="stylesheet" href="../common/controls_styles.css?v=7.1.8">
<style>
html, body {
height: 100%;
width: 100%;
padding: 0px;
margin: 0px;
}
#myCover {
width:700px;
height:600px;
}
#toggleBtn {
max-height: 30px;
}
#gantt_here {
height: calc(100% - 52px);
}
</style>
</head>
<body>
<div id="myCover">
<div class="gantt_control">
<button id="toggle_fullscreen" onclick="gantt.ext.fullscreen.toggle();">toggle fullscreen</button>
</div>
<div id="gantt_here"></div>
</div>
<script>
gantt.plugins({
fullscreen: true
});
gantt.ext.fullscreen.getFullscreenElement = function() {
return document.getElementById("myCover");
}
gantt.init("gantt_here");
gantt.parse(demo_tasks);
</script>
</body>

429
samples/dhtmlx-gantt/samples/02_extensions/27_drag_timeline.html

@ -0,0 +1,429 @@
<!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.8"></script>
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<link rel="stylesheet" href="../common/controls_styles.css?v=7.1.8">
<link rel="stylesheet" href="../../codebase/dhtmlxgantt.css?v=7.1.8">
<script src="../common/resource_construction_materials.js?v=7.1.8"></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>

112
samples/dhtmlx-gantt/samples/02_extensions/28_row_resize.html

@ -0,0 +1,112 @@
<!DOCTYPE html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Resizable rows in grid</title>
<script src="../../codebase/dhtmlxgantt.js?v=7.1.8"></script>
<link rel="stylesheet" href="../../codebase/dhtmlxgantt.css?v=7.1.8">
<script src="../common/testdata.js?v=7.1.8"></script>
<style>
html, body {
height: 100%;
padding: 0px;
margin: 0px;
overflow: hidden;
}
.gantt_row_project{
font-weight: bold;
}
</style>
</head>
<body>
<div id="gantt_here" style='width:100%; height:100%;'></div>
<script>
gantt.message({
text:[
"You can increase the height of any row of the gantt by resizing it in the grid.",
"The height if an individual row can be set using the <b>row_height</b> and <b>bar_height</b> properties of the task object."
].join("<br><br>"),
expire: -1
});
gantt.config.resize_rows = true;
// return false to discard the resize
gantt.attachEvent("onBeforeRowResize", function (item) {
gantt.message("Start resizing <b>" + item.text + "</b>");
return true;
});
var message = null;
gantt.attachEvent("onRowResize", function (id, item, currentHeight) {
if (!message) {
message = gantt.message({
expire: -1,
text: "<b>" + item.text + "</b> is now <b id='height_placeholder'></b><b>px</b> height"
});
}
document.getElementById("height_placeholder").innerText = currentHeight;
});
// return false to discard the resize
gantt.attachEvent("onBeforeRowResizeEnd", function (id, item, newHeight) {
gantt.message.hide(message);
message = null;
gantt.message("<b>" + item.text + "</b> is now <b>" + newHeight + "px</b> height");
return true;
});
gantt.attachEvent("onAfterRowResize", function (id, item, oldHeight, newHeight) {
gantt.message.hide(message);
message = null;
gantt.message("<b>" + item.text + "</b> was <b>" + oldHeight + "px</b> height. <br><b>"
+ item.text + "</b> is now <b>" + newHeight + "px</b> height");
});
// keep height of bars when rows resized
function fixBarHeight(task){
task.bar_height = 30;
return true;
}
gantt.attachEvent("onTaskLoading", fixBarHeight);
gantt.attachEvent("onTaskCreated", fixBarHeight);
gantt.init("gantt_here");
gantt.parse({
data:[
{id:11, text:"Project #1", type:"project", progress: 0.6, open: true},
{id:12, text:"Task #1", start_date:"03-04-2018", duration:"5", parent:"11", progress: 1, open: true},
{id:13, text:"Task #2", start_date:"03-04-2018", type:"project", parent:"11", progress: 0.5, open: true},
{id:14, text:"Task #3", start_date:"02-04-2018", duration:"6", parent:"11", progress: 0.8, open: true},
{id:15, text:"Task #4", type:"project", parent:"11", progress: 0.2, open: true},
{id:16, text:"Final milestone", start_date:"15-04-2018", type:"milestone", parent:"11", progress: 0, open: true},
{id:17, text:"Task #2.1", start_date:"03-04-2018", duration:"2", parent:"13", progress: 1, open: true},
{id:18, text:"Task #2.2", start_date:"06-04-2018", duration:"3", parent:"13", progress: 0.8, open: true},
{id:19, text:"Task #2.3", start_date:"10-04-2018", duration:"4", parent:"13", progress: 0.2, open: true},
{id:20, text:"Task #2.4", start_date:"10-04-2018", duration:"4", parent:"13", progress: 0, open: true},
{id:21, text:"Task #4.1", start_date:"03-04-2018", duration:"4", parent:"15", progress: 0.5, open: true},
{id:22, text:"Task #4.2", start_date:"03-04-2018", duration:"4", parent:"15", progress: 0.1, open: true},
{id:23, text:"Mediate milestone", start_date:"13-04-2018", type:"milestone", parent:"15", progress: 0, open: true}
],
links:[
{id:"10",source:"11",target:"12",type:"1"},
{id:"11",source:"11",target:"13",type:"1"},
{id:"12",source:"11",target:"14",type:"1"},
{id:"13",source:"11",target:"15",type:"1"},
{id:"14",source:"23",target:"16",type:"0"},
{id:"15",source:"13",target:"17",type:"1"},
{id:"16",source:"17",target:"18",type:"0"},
{id:"17",source:"18",target:"19",type:"0"},
{id:"18",source:"19",target:"20",type:"0"},
{id:"19",source:"15",target:"21",type:"2"},
{id:"20",source:"15",target:"22",type:"2"},
{id:"21",source:"15",target:"23",type:"0"}
]
});
</script>
</body>

399
samples/dhtmlx-gantt/samples/02_extensions/28_tasks_grouping_relation_properties.html

@ -0,0 +1,399 @@
<!DOCTYPE html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Task grouping, different relation property types</title>
<script src="../../codebase/dhtmlxgantt.js?v=7.1.8"></script>
<link rel="stylesheet" href="../../codebase/dhtmlxgantt.css?v=7.1.8">
<link rel="stylesheet" href="../common/controls_styles.css?v=7.1.8">
<style>
html,
body {
padding: 0px;
margin: 0px;
height: 100%;
}
#gantt_here {
width: 100%;
height: 800px;
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;
}
.highlighted_resource,
.highlighted_resource.odd {
background-color: rgba(255, 251, 224, 0.6);
}
.resource-controls .gantt_layout_content {
padding: 7px;
overflow: hidden;
}
.resource-controls label {
margin: 0 10px;
vertical-align: bottom;
display: inline-block;
color: #3e3e3e;
padding: 2px;
transition: box-shadow 0.2s;
}
.resource-controls label:hover {
box-shadow: 0 2px rgba(84, 147, 255, 0.42);
}
.resource-controls label.active,
.resource-controls label.active:hover {
box-shadow: 0 2px #5493ffae;
color: #1f1f1f;
}
.resource-controls input {
vertical-align: top;
}
.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);
font-weight: bold;
}
.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 class="gantt_control">
<label title="Change the vertical task reorder in the grid">Reorder mode:</label>
<select class='reorder_mode' onchange=changeReorderMode(this.value)>
<option value="marker">Marker</option>
<option value="true">Classic</option>
</select>
<label>Group:</label>
<input type='button' id='default' onclick="showGroups()" value="Tree">
<input type='button' id='resources' onclick="showGroups('resources')" value="Group by Resources">
<input type='button' id='user' onclick="showGroups('owner')" value="Group by owner">
<input type='button' id='priority' onclick="showGroups('priority')" value="Group by priority">
</div>
<div id="gantt_here" style='width:100%; height:calc(100vh - 52px);'></div>
<script>
gantt.plugins({
grouping: true,
});
gantt.serverList("priority", [
{ key: 1, label: "High" },
{ key: 2, label: "Normal" },
{ key: 3, label: "Low" }
]);
gantt.serverList("owner", [
{ key: 1, label: "Ilona" },
{ key: 2, label: "John" },
{ key: 3, label: "Mike" },
{ key: 4, label: "Anna" },
{ key: 5, label: "Bill" },
{ key: 6, label: "Floe" }
]);
function byId(list, id) {
for (var i = 0; i < list.length; i++) {
if (list[i].key == id)
return list[i].label || "";
}
return "";
}
gantt.templates.grid_row_class = function (start, end, task) {
if (task.$virtual) {
return "group_row"
}
};
gantt.config.resource_store = "resource";
gantt.config.resource_property = "material";
gantt.locale.labels.section_owner = "Owner";
gantt.locale.labels.section_material = "Material";
gantt.config.lightbox.sections = [
{ name: "description", height: 38, map_to: "text", type: "textarea", focus: true },
{ name: "priority", type: "select", map_to: "priority", options: gantt.serverList("priority") },
{ name: "owner", type: "checkbox", map_to: "owner", options: gantt.serverList("owner") },
{ name: "material", type: "resources", map_to: "material", options: gantt.serverList("material"), default_value: 10 },
{ name: "time", type: "duration", map_to: "auto" }
];
gantt.config.scales = [
{ unit: "month", step: 1, format: "%F, %Y" },
{ unit: "day", step: 1, format: "%d %M" }
];
gantt.config.columns = [
{ name: "text", tree: true, width: 200, resize: true },
{ name: "start_date", align: "center", width: 80, resize: true },
{
name: "owners", width: 70, label: "Owner", align: "center", resize: true, template: function (task) {
var result = "";
var owners = task.owner
if (!owners)
return;
if (owners.length == 1) {
return byId(gantt.serverList('owner'), owners);
}
owners.forEach(function (element) {
var owner = byId(gantt.serverList('owner'), element);
result += "<div class='owner-label' title='" + owner + "'>" + owner.substr(0, 1) + "</div>";
});
return result
}
},
{
name: "material", align: "center", width: 60, label: "Material", template: function (task) {
if (task.type == gantt.config.types.project) {
return "";
}
var store = gantt.getDatastore("resource");
var assignments = task[gantt.config.resource_property];
if (!assignments || !assignments.length) {
return "Unassigned";
}
if (assignments.length == 1 && assignments[0].resource_id) {
return store.getItem(assignments[0].resource_id).text;
}
var result = "";
assignments.forEach(function (assignment) {
var owner = store.getItem(assignment.resource_id);
if (!owner)
return;
result += "<div class='owner-label' title='" + owner.text + "'>" + owner.text.substr(0, 1) + "</div>";
});
return result;
}, resize: true
},
{
name: "priority", label: "Priority", width: 50, align: "center", resize: true, template: function (task) {
return byId(gantt.serverList('priority'), task.priority);
}
},
{ name: "duration", width: 20, align: "center", resize: true },
{ name: "add", width: 44 }
];
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;
}
});
function changeReorderMode(value){
gantt.config.order_branch = value;
gantt.init("gantt_here");
}
gantt.config.order_branch = "marker";
gantt.config.order_branch_free = true;
gantt.config.open_tree_initially = true;
gantt.init("gantt_here");
function showGroups(type) {
if (type) {
gantt.$groupMode = true;
switch(type) {
case 'resources':
var groups = gantt.$resourcesStore.getItems().map(function (item) {
var group = gantt.copy(item);
group.group_id = group.id;
group.id = gantt.uid();
return group;
});
gantt.groupBy({
groups: groups,
relation_property: gantt.config.resource_property,
group_id: "group_id",
group_text: "text",
delimiter: ", ",
default_group_label: "No Material"
});
break;
case 'owner':
gantt.groupBy({
groups: gantt.serverList(type),
relation_property: type,
group_id: "key",
group_text: "label",
default_group_label: "Unassigned"
});
break;
case 'priority':
gantt.groupBy({
groups: gantt.serverList(type),
relation_property: type,
group_id: "key",
group_text: "label",
default_group_label: "Not Assigned"
});
break;
}
}
else {
gantt.$groupMode = true;
gantt.groupBy(false);
}
}
gantt.$resourcesStore.attachEvent("onParse", function () {
var material = [];
gantt.$resourcesStore.eachItem(function (res) {
if (!gantt.$resourcesStore.hasChild(res.id)) {
var copy = gantt.copy(res);
copy.key = res.id;
copy.label = res.text;
copy.unit = "hours";
material.push(copy);
}
});
gantt.updateCollection("material", material);
});
gantt.$resourcesStore.parse([
{ id: 1, text: "Wood", parent: null },
{ id: 2, text: "Iron", parent: null },
{ id: 3, text: "Plastic", parent: null },
{ id: 4, text: "Concrete", parent: null },
{ id: 5, text: "Glass", parent: null },
{ id: 6, text: "Rubber", parent: null },
{ id: 7, text: "Polymer", parent: null },
{ id: 8, text: "Plywood", parent: null },
{ id: 9, text: "Carton", parent: null },
{ id: 10, text: "Paper", parent: null }
]);
gantt.parse({
"data": [
{ "id": 1, "text": "Office itinerancy", "type": "project", "start_date": "02-04-2019 00:00", "duration": 17, "progress": 0.4, "material": [{ "resource_id": "5", "value": 3 }], "parent": 0 },
{ "id": 2, "text": "Office facing", "type": "project", "start_date": "02-04-2019 00:00", "duration": 8, "progress": 0.6, "material": [{ "resource_id": "5", "value": 4 }], "parent": "1" },
{ "id": 3, "text": "Furniture installation", "type": "project", "start_date": "11-04-2019 00:00", "duration": 8, "parent": "1", "progress": 0.6, "material": [{ "resource_id": "5", "value": 2 }] },
{ "id": 4, "text": "The employee relocation", "type": "project", "start_date": "13-04-2019 00:00", "duration": 5, "parent": "1", "progress": 0.5, "material": [{ "resource_id": "5", "value": 4 }], "priority": 3 },
{ "id": 5, "text": "Interior office", "type": "task", "start_date": "03-04-2019 00:00", "duration": 7, "parent": "2", "progress": 0.6, "material": [{ "resource_id": "6", "value": 5 }], "priority": 1, "owner": ["2", 2] },
{ "id": 6, "text": "Air conditioners check", "type": "task", "start_date": "03-04-2019 00:00", "duration": 7, "parent": "2", "progress": 0.6, "material": [{ "resource_id": "7", "value": 1 }], "priority": 2, "owner": ["2", "3"] },
{ "id": 7, "text": "Workplaces preparation", "type": "task", "start_date": "12-04-2019 00:00", "duration": 8, "parent": "3", "progress": 0.6, "material": [{ "resource_id": "10", "value": 2 }], "owner": ["6"] },
{ "id": 8, "text": "Preparing workplaces", "type": "task", "start_date": "14-04-2019 00:00", "duration": 5, "parent": "4", "progress": 0.5, "material": [{ "resource_id": "10", "value": 4 }, { "resource_id": "9", "value": 5 }, { "resource_id": "7", "value": 64 }], "priority": 1, "owner": ["6"] },
{ "id": 9, "text": "Workplaces importation", "type": "task", "start_date": "21-04-2019 00:00", "duration": 4, "parent": "4", "progress": 0.5, "material": [{ "resource_id": "7", "value": 3 }], "owner": ["5"] },
{ "id": 10, "text": "Workplaces exportation", "type": "task", "start_date": "27-04-2019 00:00", "duration": 3, "parent": "4", "progress": 0.5, "material": [{ "resource_id": "8", "value": 5 }], "priority": 2, "owner": ["5"] },
{ "id": 11, "text": "Product launch", "type": "project", "progress": 0.6, "start_date": "02-04-2019 00:00", "duration": 13, "material": [{ "resource_id": "5", "value": 4 }], "parent": 0, "owner": ["4"] },
{ "id": 12, "text": "Perform Initial testing", "type": "task", "start_date": "03-04-2019 00:00", "duration": 5, "parent": "11", "progress": 1, "material": [{ "resource_id": "7", "value": 6 }], "owner": ["4"] },
{ "id": 13, "text": "Development", "type": "project", "start_date": "03-04-2019 00:00", "duration": 11, "parent": "11", "progress": 0.5, "material": [{ "resource_id": "5", "value": 2 }], "owner": ["3"] },
{ "id": 14, "text": "Analysis", "type": "task", "start_date": "03-04-2019 00:00", "duration": 6, "parent": "11", "material": [], "progress": 0.8, "owner": ["2", "3"] },
{ "id": 15, "text": "Design", "type": "project", "start_date": "03-04-2019 00:00", "duration": 5, "parent": "11", "progress": 0.2, "material": [{ "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, "material": [{ "resource_id": "7", "value": 2 }], "priority": 1, "owner": ["1"] },
{ "id": 17, "text": "Develop System", "type": "task", "start_date": "03-04-2019 00:00", "duration": 2, "parent": "13", "progress": 1, "material": [{ "resource_id": "8", "value": 1 }], "priority": 2, "owner": ["1"] },
{ "id": 25, "text": "Beta Release", "type": "milestone", "start_date": "06-04-2019 00:00", "parent": "13", "progress": 0, "material": [{ "resource_id": "6", "value": 4 },{ "resource_id": "7", "value": 6 },{ "resource_id": "9", "value": 9 },{ "resource_id": "5", "value": 1 }], "duration": 0, "owner": ["4"] },
{ "id": 18, "text": "Integrate System", "type": "task", "start_date": "10-04-2019 00:00", "duration": 2, "parent": "13", "progress": 0.8, "material": [{ "resource_id": "6", "value": 2 }], "priority": 3, "owner": ["3"] },
{ "id": 19, "text": "Test", "type": "task", "start_date": "13-04-2019 00:00", "duration": 4, "parent": "13", "progress": 0.2, "material": [{ "resource_id": "6", "value": 3 }] },
{ "id": 20, "text": "Marketing", "type": "task", "start_date": "13-04-2019 00:00", "duration": 4, "parent": "13", "progress": 0, "material": [{ "resource_id": "8", "value": 4 }], "priority": 1, "owner": ["6", "1"] },
{ "id": 21, "text": "Design database", "type": "task", "start_date": "03-04-2019 00:00", "duration": 4, "parent": "15", "progress": 0.5, "material": [{ "resource_id": "6", "value": 5 }], "owner": ["1", "5"] },
{ "id": 22, "text": "Software design", "type": "task", "start_date": "03-04-2019 00:00", "duration": 4, "parent": "15", "progress": 0.1, "material": [{ "resource_id": "8", "value": 3 }], "priority": 1, "owner": ["4", "5"] },
{ "id": 23, "text": "Interface setup", "type": "task", "start_date": "03-04-2019 00:00", "duration": 5, "parent": "15", "progress": 0, "material": [{ "resource_id": "8", "value": 5 }], "priority": 1, "owner": ["6", "4"] },
{ "id": 24, "text": "Release v1.0", "type": "milestone", "start_date": "20-04-2019 00:00", "parent": "11", "progress": 0, "material": [{ "resource_id": "5", "value": 3 }], "duration": 0, "owner": ["4", "3"] }
],
"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>

369
samples/dhtmlx-gantt/samples/02_extensions/data.js

@ -0,0 +1,369 @@
var taskData = {
"data": [
{
"id": 1,
"text": "Office itinerancy",
"type": "project",
"order": "10",
"progress": 0.4,
"open": true,
"user":"0",
"start_date": "02-04-2019 00:00",
"duration": 17,
"end_date": "19-04-2019 00:00",
"parent": 0
},
{
"id": 2,
"text": "Office facing",
"type": "project",
"start_date": "02-04-2019 00:00",
"duration": 8,
"order": "10",
"progress": 0.6,
"user":"0",
"parent": "1",
"open": true,
"end_date": "10-04-2019 00:00"
},
{
"id": 5,
"text": "Interior office",
"start_date": "02-04-2019 00:00",
"duration": 7,
"order": "3",
"parent": "2",
"progress": 0.8,
"open": true,
"user":"1",
"end_date": "09-04-2019 00:00"
},
{
"id": 6,
"text": "Air conditioners check",
"start_date": "03-04-2019 00:00",
"duration": 7,
"order": "3",
"parent": "2",
"progress": 0.6,
"open": true,
"user":"2",
"end_date": "10-04-2019 00:00"
},
{
"id": 3,
"text": "Furniture installation",
"type": "project",
"start_date": "11-04-2019 00:00",
"duration": 8,
"order": "20",
"parent": "1",
"progress": 0.8,
"user":"0",
"open": true,
"end_date": "19-04-2019 00:00"
},
{
"id": 7,
"text": "Workplaces preparation",
"start_date": "11-04-2019 00:00",
"duration": 8,
"order": "3",
"parent": "3",
"progress": 0.6,
"user":"0",
"open": true,
"end_date": "19-04-2019 00:00"
},
{
"id": 4,
"text": "The employee relocation",
"type": "project",
"start_date": "14-04-2019 00:00",
"duration": 5,
"order": "30",
"parent": "1",
"progress": 0.5,
"user":"0",
"open": true,
"end_date": "19-04-2019 00:00"
},
{
"id": 8,
"text": "Preparing workplaces",
"start_date": "14-04-2019 00:00",
"duration": 5,
"order": "3",
"parent": "4",
"progress": 0.8,
"user":"2",
"open": true,
"end_date": "19-04-2019 00:00"
},
{
"id": 9,
"text": "Workplaces importation",
"start_date": "14-04-2019 00:00",
"duration": 4,
"order": "3",
"parent": "4",
"progress": 0.7,
"user":"0",
"open": true,
"end_date": "18-04-2019 00:00"
},
{
"id": 10,
"text": "Workplaces exportation",
"start_date": "14-04-2019 00:00",
"duration": 3,
"order": "3",
"parent": "4",
"progress": 0.75,
"user":"3",
"open": true,
"end_date": "17-04-2019 00:00"
},
{
"id": 11,
"text": "Product launch",
"type": "project",
"order": "5",
"progress": 0.6,
"open": true,
"user":"0",
"start_date": "02-04-2019 00:00",
"duration": 13,
"end_date": "15-04-2019 00:00",
"parent": 0
},
{
"id": 12,
"text": "Perform Initial testing",
"start_date": "03-04-2019 00:00",
"duration": 5,
"order": "3",
"parent": "11",
"progress": 1,
"user":"0",
"open": true,
"end_date": "08-04-2019 00:00"
},
{
"id": 13,
"text": "Development",
"type": "project",
"start_date": "03-04-2019 00:00",
"duration": 11,
"order": "3",
"parent": "11",
"progress": 0.5,
"user":"0",
"open": true,
"end_date": "14-04-2019 00:00"
},
{
"id": 17,
"text": "Develop System",
"start_date": "03-04-2019 00:00",
"duration": 2,
"order": "3",
"parent": "13",
"progress": 1,
"user":"3",
"open": true,
"end_date": "05-04-2019 00:00"
},
{
"id": 25,
"text": "Beta Release",
"start_date": "06-04-2019 00:00",
"order": "3",
"type": "milestone",
"parent": "13",
"progress": 0,
"open": true,
"user":"0",
"end_date": "06-04-2019 00:00",
"duration": 0
},
{
"id": 18,
"text": "Integrate System",
"start_date": "08-04-2019 00:00",
"duration": 2,
"order": "3",
"parent": "13",
"progress": 0.8,
"open": true,
"user":"1",
"end_date": "10-04-2019 00:00"
},
{
"id": 19,
"text": "Test",
"start_date": "10-04-2019 00:00",
"duration": 4,
"order": "3",
"parent": "13",
"progress": 0.82,
"open": true,
"user":"0",
"end_date": "14-04-2019 00:00"
},
{
"id": 20,
"text": "Marketing",
"start_date": "10-04-2019 00:00",
"duration": 4,
"order": "3",
"parent": "13",
"progress": 0.6,
"user":"3",
"open": true,
"end_date": "14-04-2019 00:00"
},
{
"id": 14,
"text": "Analysis",
"start_date": "02-04-2019 00:00",
"duration": 6,
"order": "3",
"parent": "11",
"progress": 0.8,
"user":"0",
"open": true,
"end_date": "08-04-2019 00:00"
},
{
"id": 15,
"text": "Design",
"type": "project",
"start_date": "03-04-2019 00:00",
"duration": 5,
"order": "3",
"parent": "11",
"progress": 0.2,
"user":"0",
"open": false,
"end_date": "08-04-2019 00:00"
},
{
"id": 21,
"text": "Design database",
"start_date": "03-04-2019 00:00",
"duration": 4,
"order": "3",
"parent": "15",
"progress": 0.5,
"user":"0",
"open": true,
"end_date": "07-04-2019 00:00"
},
{
"id": 22,
"text": "Software design",
"start_date": "03-04-2019 00:00",
"duration": 4,
"order": "3",
"parent": "15",
"progress": 0.1,
"user":"2",
"open": true,
"end_date": "07-04-2019 00:00"
},
{
"id": 23,
"text": "Interface setup",
"start_date": "03-04-2019 00:00",
"duration": 5,
"order": "3",
"parent": "15",
"progress": 0,
"user":"3",
"open": true,
"end_date": "08-04-2019 00:00"
},
{
"id": 16,
"text": "Documentation creation",
"start_date": "02-04-2019 00:00",
"duration": 7,
"order": "3",
"parent": "11",
"progress": 0,
"user":"2",
"open": true,
"end_date": "09-04-2019 00:00"
},
{
"id": 24,
"text": "Release v1.0",
"start_date": "15-04-2019 00:00",
"order": "3",
"type": "milestone",
"parent": "11",
"progress": 0,
"open": true,
"user":"0",
"end_date": "15-04-2019 00:00",
"duration": 0
}
],
"links": [
{
"id": "1",
"source": "1",
"target": "2",
"type": "1"
},
{
"id": "2",
"source": "2",
"target": "3",
"type": "0"
},
{
"id": "3",
"source": "3",
"target": "4",
"type": "0"
},
{
"id": "10",
"source": "11",
"target": "12",
"type": "1"
},
{
"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"
}
]
}

369
samples/dhtmlx-gantt/samples/02_extensions/data.json

@ -0,0 +1,369 @@
{
"data": [
{
"id": 1,
"text": "Office itinerancy",
"type": "project",
"order": "10",
"progress": 0.4,
"open": true,
"user":"0",
"start_date": "02-04-2019 00:00",
"duration": 17,
"end_date": "19-04-2019 00:00",
"parent": 0
},
{
"id": 2,
"text": "Office facing",
"type": "project",
"start_date": "02-04-2019 00:00",
"duration": 8,
"order": "10",
"progress": 0.6,
"user":"0",
"parent": "1",
"open": true,
"end_date": "10-04-2019 00:00"
},
{
"id": 5,
"text": "Interior office",
"start_date": "02-04-2019 00:00",
"duration": 7,
"order": "3",
"parent": "2",
"progress": 0.8,
"open": true,
"user":"1",
"end_date": "09-04-2019 00:00"
},
{
"id": 6,
"text": "Air conditioners check",
"start_date": "03-04-2019 00:00",
"duration": 7,
"order": "3",
"parent": "2",
"progress": 0.6,
"open": true,
"user":"2",
"end_date": "10-04-2019 00:00"
},
{
"id": 3,
"text": "Furniture installation",
"type": "project",
"start_date": "11-04-2019 00:00",
"duration": 8,
"order": "20",
"parent": "1",
"progress": 0.8,
"user":"0",
"open": true,
"end_date": "19-04-2019 00:00"
},
{
"id": 7,
"text": "Workplaces preparation",
"start_date": "11-04-2019 00:00",
"duration": 8,
"order": "3",
"parent": "3",
"progress": 0.6,
"user":"0",
"open": true,
"end_date": "19-04-2019 00:00"
},
{
"id": 4,
"text": "The employee relocation",
"type": "project",
"start_date": "14-04-2019 00:00",
"duration": 5,
"order": "30",
"parent": "1",
"progress": 0.5,
"user":"0",
"open": true,
"end_date": "19-04-2019 00:00"
},
{
"id": 8,
"text": "Preparing workplaces",
"start_date": "14-04-2019 00:00",
"duration": 5,
"order": "3",
"parent": "4",
"progress": 0.8,
"user":"2",
"open": true,
"end_date": "19-04-2019 00:00"
},
{
"id": 9,
"text": "Workplaces importation",
"start_date": "14-04-2019 00:00",
"duration": 4,
"order": "3",
"parent": "4",
"progress": 0.7,
"user":"0",
"open": true,
"end_date": "18-04-2019 00:00"
},
{
"id": 10,
"text": "Workplaces exportation",
"start_date": "14-04-2019 00:00",
"duration": 3,
"order": "3",
"parent": "4",
"progress": 0.75,
"user":"3",
"open": true,
"end_date": "17-04-2019 00:00"
},
{
"id": 11,
"text": "Product launch",
"type": "project",
"order": "5",
"progress": 0.6,
"open": true,
"user":"0",
"start_date": "02-04-2019 00:00",
"duration": 13,
"end_date": "15-04-2019 00:00",
"parent": 0
},
{
"id": 12,
"text": "Perform Initial testing",
"start_date": "03-04-2019 00:00",
"duration": 5,
"order": "3",
"parent": "11",
"progress": 1,
"user":"0",
"open": true,
"end_date": "08-04-2019 00:00"
},
{
"id": 13,
"text": "Development",
"type": "project",
"start_date": "03-04-2019 00:00",
"duration": 11,
"order": "3",
"parent": "11",
"progress": 0.5,
"user":"0",
"open": true,
"end_date": "14-04-2019 00:00"
},
{
"id": 17,
"text": "Develop System",
"start_date": "03-04-2019 00:00",
"duration": 2,
"order": "3",
"parent": "13",
"progress": 1,
"user":"3",
"open": true,
"end_date": "05-04-2019 00:00"
},
{
"id": 25,
"text": "Beta Release",
"start_date": "06-04-2019 00:00",
"order": "3",
"type": "milestone",
"parent": "13",
"progress": 0,
"open": true,
"user":"0",
"end_date": "06-04-2019 00:00",
"duration": 0
},
{
"id": 18,
"text": "Integrate System",
"start_date": "08-04-2019 00:00",
"duration": 2,
"order": "3",
"parent": "13",
"progress": 0.8,
"open": true,
"user":"1",
"end_date": "10-04-2019 00:00"
},
{
"id": 19,
"text": "Test",
"start_date": "10-04-2019 00:00",
"duration": 4,
"order": "3",
"parent": "13",
"progress": 0.82,
"open": true,
"user":"0",
"end_date": "14-04-2019 00:00"
},
{
"id": 20,
"text": "Marketing",
"start_date": "10-04-2019 00:00",
"duration": 4,
"order": "3",
"parent": "13",
"progress": 0.6,
"user":"3",
"open": true,
"end_date": "14-04-2019 00:00"
},
{
"id": 14,
"text": "Analysis",
"start_date": "02-04-2019 00:00",
"duration": 6,
"order": "3",
"parent": "11",
"progress": 0.8,
"user":"0",
"open": true,
"end_date": "08-04-2019 00:00"
},
{
"id": 15,
"text": "Design",
"type": "project",
"start_date": "03-04-2019 00:00",
"duration": 5,
"order": "3",
"parent": "11",
"progress": 0.2,
"user":"0",
"open": false,
"end_date": "08-04-2019 00:00"
},
{
"id": 21,
"text": "Design database",
"start_date": "03-04-2019 00:00",
"duration": 4,
"order": "3",
"parent": "15",
"progress": 0.5,
"user":"0",
"open": true,
"end_date": "07-04-2019 00:00"
},
{
"id": 22,
"text": "Software design",
"start_date": "03-04-2019 00:00",
"duration": 4,
"order": "3",
"parent": "15",
"progress": 0.1,
"user":"2",
"open": true,
"end_date": "07-04-2019 00:00"
},
{
"id": 23,
"text": "Interface setup",
"start_date": "03-04-2019 00:00",
"duration": 5,
"order": "3",
"parent": "15",
"progress": 0,
"user":"3",
"open": true,
"end_date": "08-04-2019 00:00"
},
{
"id": 16,
"text": "Documentation creation",
"start_date": "02-04-2019 00:00",
"duration": 7,
"order": "3",
"parent": "11",
"progress": 0,
"user":"2",
"open": true,
"end_date": "09-04-2019 00:00"
},
{
"id": 24,
"text": "Release v1.0",
"start_date": "15-04-2019 00:00",
"order": "3",
"type": "milestone",
"parent": "11",
"progress": 0,
"open": true,
"user":"0",
"end_date": "15-04-2019 00:00",
"duration": 0
}
],
"links": [
{
"id": "1",
"source": "1",
"target": "2",
"type": "1"
},
{
"id": "2",
"source": "2",
"target": "3",
"type": "0"
},
{
"id": "3",
"source": "3",
"target": "4",
"type": "0"
},
{
"id": "10",
"source": "11",
"target": "12",
"type": "1"
},
{
"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"
}
]
}

300
samples/dhtmlx-gantt/samples/02_extensions/index.html

@ -0,0 +1,300 @@
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="../common/docs.css">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="initial-scale = 1.0" />
<title>Gantt : Samples</title></title>
</head>
<body>
<div class='abstop_header'>
<div class='content_area'>
&nbsp;
</div>
</div>
<div class="page_header">
<div class='page_inner_header'>
<a href='https://dhtmlx.com'><div class='top_webix_logo'></div></a>
Samples
</div>
</div>
<div class="page_space">
<div class="webixdoc_page webixdoc_start">
<div id="webixContent" class='webixdoc_content'>
<div class="webixdoc_content_inner">
<div class="webixdoc_breadcrumb nav_breadcrumb">
<a href="https://docs.dhtmlx.com/gantt/" class="webixdoc_back">Documentation</a>
<a href="../" class="webixdoc_back">Samples</a>
<a href="../" class="webixdoc_back">Extensions</a>
</div>
<table class='nav_table'>
<tr>
<td style='width:30px;'>
<a href='01_quickinfo.html'>
<div class='nav_page_img'>&nbsp;</div>
</a>
</td>
<td>
<a href='01_quickinfo.html'>QuickInfo extension</a>
</td>
</tr>
<tr>
<td style='width:30px;'>
<a href='02_tooltip.html'>
<div class='nav_page_img'>&nbsp;</div>
</a>
</td>
<td>
<a href='02_tooltip.html'>Tooltip</a>
</td>
</tr>
<tr>
<td style='width:30px;'>
<a href='05_today_line.html'>
<div class='nav_page_img'>&nbsp;</div>
</a>
</td>
<td>
<a href='05_today_line.html'>Today and Status lines in Gantt</a>
</td>
</tr>
<tr>
<td style='width:30px;'>
<a href='09_multiselection.html'>
<div class='nav_page_img'>&nbsp;</div>
</a>
</td>
<td>
<a href='09_multiselection.html'>Multiselection and Indent/Outdent tasks</a>
</td>
</tr>
<tr>
<td style='width:30px;'>
<a href='11_full_screen.html'>
<div class='nav_page_img'>&nbsp;</div>
</a>
</td>
<td>
<a href='11_full_screen.html'>Full Screen</a>
</td>
</tr>
<tr>
<td style='width:30px;'>
<a href='13_smart_rendering.html'>
<div class='nav_page_img'>&nbsp;</div>
</a>
</td>
<td>
<a href='13_smart_rendering.html'>Working with 30000 tasks</a>
</td>
</tr>
<tr>
<td style='width:30px;'>
<a href='14_undo.html'>
<div class='nav_page_img'>&nbsp;</div>
</a>
</td>
<td>
<a href='14_undo.html'>Undo/Redo changes in Gantt</a>
</td>
</tr>
<tr>
<td style='width:30px;'>
<a href='16_keyboard_navigation.html'>
<div class='nav_page_img'>&nbsp;</div>
</a>
</td>
<td>
<a href='16_keyboard_navigation.html'>Keyboard Navigation</a>
</td>
</tr>
<tr>
<td style='width:30px;'>
<a href='17_keyboard_navigation_cell.html'>
<div class='nav_page_img'>&nbsp;</div>
</a>
</td>
<td>
<a href='17_keyboard_navigation_cell.html'>Keyboard Navigation - navigate cells</a>
</td>
</tr>
<tr>
<td style='width:30px;'>
<a href='18_linked_tasks.html'>
<div class='nav_page_img'>&nbsp;</div>
</a>
</td>
<td>
<a href='18_linked_tasks.html'>Auto Scheduling - Groups of connected tasks</a>
</td>
</tr>
<tr>
<td style='width:30px;'>
<a href='21_overlay.html'>
<div class='nav_page_img'>&nbsp;</div>
</a>
</td>
<td>
<a href='21_overlay.html'>Gantt chart with overlay</a>
</td>
</tr>
<tr>
<td style='width:30px;'>
<a href='22_tooltip_api.html'>
<div class='nav_page_img'>&nbsp;</div>
</a>
</td>
<td>
<a href='22_tooltip_api.html'>Custom Tooltips</a>
</td>
</tr>
<tr>
<td style='width:30px;'>
<a href='23_click_drag_splittask.html'>
<div class='nav_page_img'>&nbsp;</div>
</a>
</td>
<td>
<a href='23_click_drag_splittask.html'>Create split tasks by Drag and Drop</a>
</td>
</tr>
<tr>
<td style='width:30px;'>
<a href='24_click_drag.html'>
<div class='nav_page_img'>&nbsp;</div>
</a>
</td>
<td>
<a href='24_click_drag.html'>Create new tasks by Drag and Drop</a>
</td>
</tr>
<tr>
<td style='width:30px;'>
<a href='25_click_drag_select_by_drag.html'>
<div class='nav_page_img'>&nbsp;</div>
</a>
</td>
<td>
<a href='25_click_drag_select_by_drag.html'>Select multiple tasks by Drag and Drop</a>
</td>
</tr>
<tr>
<td style='width:30px;'>
<a href='26_full_screen_with_additional_elements.html'>
<div class='nav_page_img'>&nbsp;</div>
</a>
</td>
<td>
<a href='26_full_screen_with_additional_elements.html'>Full Screen with additional elements</a>
</td>
</tr>
<tr>
<td style='width:30px;'>
<a href='27_drag_timeline.html'>
<div class='nav_page_img'>&nbsp;</div>
</a>
</td>
<td>
<a href='27_drag_timeline.html'>Drag timeline</a>
</td>
</tr>
<tr>
<td style='width:30px;'>
<a href='28_row_resize.html'>
<div class='nav_page_img'>&nbsp;</div>
</a>
</td>
<td>
<a href='28_row_resize.html'>Resizable rows in grid</a>
</td>
</tr>
<tr>
<td style='width:30px;'>
<a href='28_tasks_grouping_relation_properties.html'>
<div class='nav_page_img'>&nbsp;</div>
</a>
</td>
<td>
<a href='28_tasks_grouping_relation_properties.html'>Task grouping, different relation property types</a>
</td>
</tr>
</table>
</div>
</div>
</div>
</div>
<!--Side quick links -->
<div class="side_links">
<a class="reference_link" href="https://docs.dhtmlx.com/gantt/api__refs__gantt.html">
<span>API Reference</span>
</a>
<a class="sample_link" href="../">
<span>Code Samples</span>
</a>
<a class="forum_link" href="https://forum.dhtmlx.com/c/gantt">
<span>Developer Forum </span>
</a>
</div>
</div>
</div>
<div class="footer_linea">&nbsp;</div>
<div class="footer_lineb">
<div class='page_inner_header'>
<a href='https://dhtmlx.com'><div class='bottom_webix_block bottom_webix_logo' ></div></a>
<div class='copyright bottom_webix_block'>© 2021 XB Software Ltd.<br>
All rights reserved</div>
<div class='bottom_webix_also'>
<h4>Check also:</h4>
<li><a href='https://dhtmlx.com/docs/products/dhtmlxScheduler/' target='_blank'>DHTMLX Scheduler</a></li>
<li><a href='https://dhtmlx.com/docs/products/dhtmlxSpreadsheet/' target='_blank'>DHTMLX Spreadsheet</a></li>
<li><a href='https://dhtmlx.com/docs/products/dhtmlxSuite/' target='_blank'>Other DHTMLX components</a></li>
</div>
</div>
</div>
<script>
var msBrowser =
navigator.userAgent.indexOf("MSIE ") > 0 ||
navigator.userAgent.indexOf("Trident") > 0 ||
navigator.userAgent.indexOf("Edge") > 0
if (msBrowser){
var summaryElements = document.querySelectorAll(".list_samples");
for (var i = 0; i < summaryElements.length; i++) {
var navItem = summaryElements[i];
var link = navItem.querySelector("a");
var parent = navItem.parentNode;
parent.insertBefore(link, navItem);
navItem.style.display = 'none';
}
}
</script>
</body>
</html>

55
samples/dhtmlx-gantt/samples/03_scales/01_multiple_scales.html

@ -0,0 +1,55 @@
<!DOCTYPE html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Multiple scales</title>
<script src="../../codebase/dhtmlxgantt.js?v=7.1.8"></script>
<link rel="stylesheet" href="../../codebase/dhtmlxgantt.css?v=7.1.8">
<script src="../common/testdata.js?v=7.1.8"></script>
<style>
html, body {
height: 100%;
padding: 0px;
margin: 0px;
overflow: hidden;
}
.weekend{
background: #F0DFE5 !important;
}
</style>
</head>
<body>
<div id="gantt_here" style='width:100%; height:100%;'></div>
<script>
gantt.config.min_column_width = 50;
gantt.config.scale_height = 90;
var weekScaleTemplate = function (date) {
var dateToStr = gantt.date.date_to_str("%d %M");
var endDate = gantt.date.add(gantt.date.add(date, 1, "week"), -1, "day");
return dateToStr(date) + " - " + dateToStr(endDate);
};
var daysStyle = function(date){
// you can use gantt.isWorkTime(date)
// when gantt.config.work_time config is enabled
// In this sample it's not so we just check week days
if(date.getDay() === 0 || date.getDay() === 6){
return "weekend";
}
return "";
};
gantt.config.scales = [
{unit: "month", step: 1, format: "%F, %Y"},
{unit: "week", step: 1, format: weekScaleTemplate},
{unit: "day", step:1, format: "%D", css:daysStyle }
];
gantt.init("gantt_here");
gantt.parse(demo_tasks);
</script>
</body>

33
samples/dhtmlx-gantt/samples/03_scales/02_month_days.html

@ -0,0 +1,33 @@
<!DOCTYPE html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Month view</title>
<script src="../../codebase/dhtmlxgantt.js?v=7.1.8"></script>
<link rel="stylesheet" href="../../codebase/dhtmlxgantt.css?v=7.1.8">
<script src="../common/testdata.js?v=7.1.8"></script>
<style>
html, body {
height: 100%;
padding: 0px;
margin: 0px;
overflow: hidden;
}
</style>
</head>
<body>
<div id="gantt_here" style='width:100%; height:100%;'></div>
<script>
gantt.config.scale_height = 50;
gantt.config.scales = [
{unit: "month", step: 1, format: "%F, %Y"},
{unit: "day", step: 1, format: "%j, %D"}
];
gantt.init("gantt_here");
gantt.parse(demo_tasks);
</script>
</body>

42
samples/dhtmlx-gantt/samples/03_scales/03_full_year.html

@ -0,0 +1,42 @@
<!DOCTYPE html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Year scale</title>
<script src="../../codebase/dhtmlxgantt.js?v=7.1.8"></script>
<link rel="stylesheet" href="../../codebase/dhtmlxgantt.css?v=7.1.8">
<script src="../common/testdata.js?v=7.1.8"></script>
<style>
html, body {
height: 100%;
padding: 0px;
margin: 0px;
overflow: hidden;
}
</style>
</head>
<body>
<div id="gantt_here" style='width:100%; height:100%;'></div>
<script>
gantt.config.min_column_width = 50;
gantt.config.scale_height = 90;
var monthScaleTemplate = function (date) {
var dateToStr = gantt.date.date_to_str("%M");
var endDate = gantt.date.add(date, 2, "month");
return dateToStr(date) + " - " + dateToStr(endDate);
};
gantt.config.scales = [
{unit: "year", step: 1, format: "%Y"},
{unit: "month", step: 3, format: monthScaleTemplate},
{unit: "month", step: 1, format: "%M"}
];
gantt.init("gantt_here");
gantt.parse(demo_tasks);
</script>
</body>

33
samples/dhtmlx-gantt/samples/03_scales/04_days.html

@ -0,0 +1,33 @@
<!DOCTYPE html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Day hours</title>
<script src="../../codebase/dhtmlxgantt.js?v=7.1.8"></script>
<link rel="stylesheet" href="../../codebase/dhtmlxgantt.css?v=7.1.8">
<script src="../common/testdata.js?v=7.1.8"></script>
<style>
html, body {
height: 100%;
padding: 0px;
margin: 0px;
overflow: hidden;
}
</style>
</head>
<body>
<div id="gantt_here" style='width:100%; height:100%;'></div>
<script>
gantt.config.min_column_width = 50;
gantt.config.scale_height = 54;
gantt.config.scales = [
{unit: "day", format: "%F %d"},
{unit: "hour", step: 3, format: "%H:%i"}
];
gantt.init("gantt_here");
gantt.parse(demo_tasks);
</script>
</body>

127
samples/dhtmlx-gantt/samples/03_scales/05_dynamic_scales.html

@ -0,0 +1,127 @@
<!DOCTYPE html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Dynamic scales</title>
<script src="../../codebase/dhtmlxgantt.js?v=7.1.8"></script>
<link rel="stylesheet" href="../../codebase/dhtmlxgantt.css?v=7.1.8">
<link rel="stylesheet" href="../common/controls_styles.css?v=7.1.8">
<script src="../common/testdata.js?v=7.1.8"></script>
<style>
html, body {
height: 100%;
padding: 0px;
margin: 0px;
overflow: hidden;
}
</style>
</head>
<body>
<form class="gantt_control">
<input type="button" value="Zoom In" onclick="zoomIn()">
<input type="button" value="Zoom Out" onclick="zoomOut()">
<input type="radio" id="scale1" class="gantt_radio" name="scale" value="day">
<label for="scale1">Day scale</label>
<input type="radio" id="scale2" class="gantt_radio" name="scale" value="week">
<label for="scale2">Week scale</label>
<input type="radio" id="scale3" class="gantt_radio" name="scale" value="month">
<label for="scale3">Month scale</label>
<input type="radio" id="scale4" class="gantt_radio" name="scale" value="quarter">
<label for="scale4">Quarter scale</label>
<input type="radio" id="scale5" class="gantt_radio" name="scale" value="year" checked>
<label for="scale5">Year scale</label>
</form>
<div id="gantt_here" style='width:100%; height:calc(100vh - 52px);'></div>
<script>
var zoomConfig = {
levels: [
{
name:"day",
scale_height: 27,
min_column_width:80,
scales:[
{unit: "day", step: 1, format: "%d %M"}
]
},
{
name:"week",
scale_height: 50,
min_column_width:50,
scales:[
{unit: "week", step: 1, format: function (date) {
var dateToStr = gantt.date.date_to_str("%d %M");
var endDate = gantt.date.add(date, -6, "day");
var weekNum = gantt.date.date_to_str("%W")(date);
return "#" + weekNum + ", " + dateToStr(date) + " - " + dateToStr(endDate);
}},
{unit: "day", step: 1, format: "%j %D"}
]
},
{
name:"month",
scale_height: 50,
min_column_width:120,
scales:[
{unit: "month", format: "%F, %Y"},
{unit: "week", format: "Week #%W"}
]
},
{
name:"quarter",
height: 50,
min_column_width:90,
scales:[
{unit: "month", step: 1, format: "%M"},
{
unit: "quarter", step: 1, format: function (date) {
var dateToStr = gantt.date.date_to_str("%M");
var endDate = gantt.date.add(gantt.date.add(date, 3, "month"), -1, "day");
return dateToStr(date) + " - " + dateToStr(endDate);
}
}
]
},
{
name:"year",
scale_height: 50,
min_column_width: 30,
scales:[
{unit: "year", step: 1, format: "%Y"}
]
}
]
};
gantt.ext.zoom.init(zoomConfig);
gantt.ext.zoom.setLevel("year");
gantt.ext.zoom.attachEvent("onAfterZoom", function(level, config){
document.querySelector(".gantt_radio[value='" +config.name+ "']").checked = true;
})
gantt.init("gantt_here", new Date(2017, 8, 1), new Date(2018, 10, 1));
gantt.parse(demo_tasks);
function zoomIn(){
gantt.ext.zoom.zoomIn();
}
function zoomOut(){
gantt.ext.zoom.zoomOut()
}
var radios = document.getElementsByName("scale");
for (var i = 0; i < radios.length; i++) {
radios[i].onclick = function (event) {
gantt.ext.zoom.setLevel(event.target.value);
};
}
</script>
</body>

48
samples/dhtmlx-gantt/samples/03_scales/06_custom_scales.html

@ -0,0 +1,48 @@
<!DOCTYPE html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Custom scales</title>
<script src="../../codebase/dhtmlxgantt.js?v=7.1.8"></script>
<link rel="stylesheet" href="../../codebase/dhtmlxgantt.css?v=7.1.8">
<script src="../common/testdata.js?v=7.1.8"></script>
<style>
html, body {
height: 100%;
padding: 0px;
margin: 0px;
overflow: hidden;
}
.gantt_container .gantt_grid_scale .gantt_grid_head_cell {
line-height: 43px;
}
.gantt_container .gantt_scale_cell {
padding-top: 4px;
line-height: 17px;
}
</style>
</head>
<body>
<div id="gantt_here" style='width:100%; height:100%;'></div>
<script>
gantt.config.scale_height = 44;
var dayNumber = function(date){
return gantt.columnIndexByDate(date) + 1;
}
var dateFormat = gantt.date.date_to_str("%F %d");
gantt.config.scales = [
{ unit: "day", step:1, format: function(date){
return "<strong>Day " + dayNumber(date) + "</strong><br/>" + dateFormat(date);
}}
]
gantt.init("gantt_here");
gantt.parse(demo_tasks);
</script>
</body>

65
samples/dhtmlx-gantt/samples/03_scales/07_minutes_scale.html

@ -0,0 +1,65 @@
<!DOCTYPE html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Minutes timeline</title>
<script src="../../codebase/dhtmlxgantt.js?v=7.1.8"></script>
<link rel="stylesheet" href="../../codebase/dhtmlxgantt.css?v=7.1.8">
<style>
html, body {
height: 100%;
padding: 0px;
margin: 0px;
overflow: hidden;
}
</style>
</head>
<body>
<div id="gantt_here" style='width:100%; height:100%;'></div>
<script>
gantt.config.date_format = "%d-%m-%Y %H:%i";
gantt.config.min_column_width = 20;
gantt.config.duration_unit = "minute";
gantt.config.duration_step = 60;
gantt.config.scale_height = 75;
gantt.config.scales = [
{unit: "hour", step: 1, format: "%g %a"},
{unit: "day", step: 1, format: "%j %F, %l"},
{unit: "minute", step: 15, format: "%i"}
];
gantt.init("gantt_here");
gantt.parse({
data: [
{id: 11, text: "Project #1", start_date: "01-04-2018 02:00", duration: "24", progress: 0.6, open: true},
{id: 12, text: "Task #1", start_date: "01-04-2018 02:00", duration: "5", parent: "11", progress: 1, open: true},
{id: 13, text: "Task #2", start_date: "01-04-2018 03:00", duration: "7", parent: "11", progress: 0.5, open: true},
{id: 14, text: "Task #3", start_date: "01-04-2018 04:00", duration: "6", parent: "11", progress: 0.8, open: true},
{id: 15, text: "Task #4", start_date: "01-04-2018 05:00", duration: "5", parent: "11", progress: 0.2, open: true},
{id: 16, text: "Task #5", start_date: "01-04-2018 06:00", duration: "7", parent: "11", progress: 0, open: true},
{id: 17, text: "Task #2.1", start_date: "01-04-2018 07:00", duration: "2", parent: "13", progress: 1, open: true},
{id: 18, text: "Task #2.2", start_date: "01-04-2018 08:00", duration: "3", parent: "13", progress: 0.8, open: true},
{id: 19, text: "Task #2.3", start_date: "01-04-2018 09:00", duration: "4", parent: "13", progress: 0.2, open: true},
{id: 20, text: "Task #2.4", start_date: "01-04-2018 11:00", duration: "4", parent: "13", progress: 0, open: true},
{id: 21, text: "Task #4.1", start_date: "01-04-2018 12:00", duration: "4", parent: "15", progress: 0.5, open: true},
{id: 22, text: "Task #4.2", start_date: "01-04-2018 06:00", duration: "4", parent: "15", progress: 0.1, open: true},
{id: 23, text: "Task #4.3", start_date: "01-04-2018 10:00", duration: "5", parent: "15", progress: 0, open: true}
],
links: [
{id: "10", source: "11", target: "12", type: "1"},
{id: "11", source: "11", target: "13", type: "1"},
{id: "12", source: "11", target: "14", type: "1"},
{id: "13", source: "11", target: "15", type: "1"},
{id: "14", source: "11", target: "16", type: "1"},
{id: "15", source: "13", target: "17", type: "1"},
{id: "16", source: "17", target: "18", type: "0"},
{id: "17", source: "18", target: "19", type: "0"},
{id: "18", source: "19", target: "20", type: "0"},
{id: "19", source: "15", target: "21", type: "2"},
{id: "20", source: "15", target: "22", type: "2"},
{id: "21", source: "15", target: "23", type: "2"}
]
});
</script>
</body>

52
samples/dhtmlx-gantt/samples/03_scales/08_scale_autoconfig.html

@ -0,0 +1,52 @@
<!DOCTYPE html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Auto resize scale</title>
<script src="../../codebase/dhtmlxgantt.js?v=7.1.8"></script>
<link rel="stylesheet" href="../../codebase/dhtmlxgantt.css?v=7.1.8">
<script src="../common/testdata.js?v=7.1.8"></script>
<style>
html, body {
height: 100%;
padding: 0px;
margin: 0px;
overflow: hidden;
}
</style>
</head>
<body>
<div id="gantt_here" style='width:100%; height:100%;'></div>
<script>
gantt.config.fit_tasks = true;
gantt.config.min_column_width = 50;
gantt.config.scale_height = 54;
gantt.config.scales = [
{unit: "day", format: "%F %d"},
{unit: "hour", step: 3, format: "%H:%i"}
];
gantt.init("gantt_here");
function showScaleDesc() {
var min = gantt.getState().min_date,
max = gantt.getState().max_date,
to_str = gantt.templates.task_date;
return gantt.message("Scale shows days from " + to_str(min) + " to " + to_str(max));
}
gantt.parse(demo_tasks);
setTimeout(showScaleDesc, 500);
setTimeout(function () {
gantt.message("Change date or duration of any task and scales will be adjusted");
}, 4500);
gantt.attachEvent("onScaleAdjusted", showScaleDesc);
</script>
</body>

68
samples/dhtmlx-gantt/samples/03_scales/10_working_hours.html

@ -0,0 +1,68 @@
<!DOCTYPE html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Show working hours</title>
<script src="../../codebase/dhtmlxgantt.js?v=7.1.8"></script>
<link rel="stylesheet" href="../../codebase/dhtmlxgantt.css?v=7.1.8">
<script src="../common/testdata.js?v=7.1.8"></script>
<style>
html, body {
height: 100%;
padding: 0px;
margin: 0px;
overflow: hidden;
}
.gantt_task_cell.day_end {
border-right-color: #C7DFFF;
}
</style>
</head>
<body>
<div id="gantt_here" style='width:100%; height:100%;'></div>
<script>
gantt.config.min_column_width = 20;
gantt.config.scale_height = 20 * 3;
gantt.templates.timeline_cell_class = function (task, date) {
if (date.getHours() == 8) {
return "day_start";
}
if (date.getHours() == 18) {
return "day_end";
}
return "";
};
var weekScaleTemplate = function (date) {
var dateToStr = gantt.date.date_to_str("%d %M");
var weekNum = gantt.date.date_to_str("(week %W)");
var endDate = gantt.date.add(gantt.date.add(date, 1, "week"), -1, "day");
return dateToStr(date) + " - " + dateToStr(endDate) + " " + weekNum(date);
};
gantt.config.scales = [
{unit: "day", format: "%l, %F %d"},
// {unit:"month", step:1, format:"%F, %Y"},
{unit: "week", step: 1, format: weekScaleTemplate},
{unit: "hour", step: 1, format: "%G"}
];
gantt.ignore_time = function (date) {
if (date.getDay() == 0 || date.getDay() == 6)
return true;
if (date.getHours() < 8 || date.getHours() > 18)
return true;
return false;
};
gantt.init("gantt_here");
gantt.parse(demo_tasks);
</script>
</body>

67
samples/dhtmlx-gantt/samples/03_scales/11_select_column.html

@ -0,0 +1,67 @@
<!DOCTYPE html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Selecting columns</title>
<script src="../../codebase/dhtmlxgantt.js?v=7.1.8"></script>
<link rel="stylesheet" href="../../codebase/dhtmlxgantt.css?v=7.1.8">
<script src="../common/testdata.js?v=7.1.8"></script>
<style>
html, body {
height: 100%;
padding: 0px;
margin: 0px;
overflow: hidden;
}
.highlighted-column {
background-color: #fff3a1;
}
.gantt_task_scale .gantt_scale_cell {
cursor: default;
}
.gantt_task_scale .gantt_scale_cell.highlighted-column {
color: #454545;
font-weight: bold;
}
</style>
</head>
<body>
<div id="gantt_here" style='width:100%; height:100%;'></div>
<script>
var selected_column = null;
gantt.attachEvent("onScaleClick", function (e, date) {
selected_column = date;
var pos = gantt.getScrollState();
gantt.render();
gantt.scrollTo(pos.x, pos.y);
});
function is_selected_column(column_date) {
if (selected_column && column_date.valueOf() == selected_column.valueOf()) {
return true;
}
return false;
}
gantt.templates.scale_cell_class = function (date) {
if (is_selected_column(date))
return "highlighted-column";
};
gantt.templates.timeline_cell_class = function (item, date) {
if (is_selected_column(date))
return "highlighted-column";
};
gantt.message("Click on any date in a scale to select a column");
gantt.init("gantt_here");
gantt.parse(demo_tasks);
</script>
</body>

53
samples/dhtmlx-gantt/samples/03_scales/12_year_quarters.html

@ -0,0 +1,53 @@
<!DOCTYPE html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Year quarters scale</title>
<script src="../../codebase/dhtmlxgantt.js?v=7.1.8"></script>
<link rel="stylesheet" href="../../codebase/dhtmlxgantt.css?v=7.1.8">
<script src="../common/testdata.js?v=7.1.8"></script>
<style>
html, body {
height: 100%;
padding: 0px;
margin: 0px;
overflow: hidden;
}
</style>
</head>
<body>
<div id="gantt_here" style='width:100%; height:100%;'></div>
<script>
gantt.config.min_column_width = 50;
gantt.config.scale_height = 90;
function quarterLabel(date) {
var month = date.getMonth();
var q_num;
if (month >= 9) {
q_num = 4;
} else if (month >= 6) {
q_num = 3;
} else if (month >= 3) {
q_num = 2;
} else {
q_num = 1;
}
return "Q" + q_num;
}
gantt.config.scales = [
{unit: "year", step: 1, format: "%Y"},
{unit: "quarter", step: 1, format: quarterLabel},
{unit: "month", step: 1, format: "%M"}
];
gantt.init("gantt_here");
gantt.parse(demo_tasks);
</script>
</body>

230
samples/dhtmlx-gantt/samples/03_scales/13_zoom_to_fit.html

@ -0,0 +1,230 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Zoom To Fit</title>
<script src="../../codebase/dhtmlxgantt.js?v=7.1.8"></script>
<script src="../common/testdata.js?v=7.1.8"></script>
<link rel="stylesheet" href="../../codebase/dhtmlxgantt.css?v=7.1.8">
<link rel="stylesheet" href="../common/controls_styles.css?v=7.1.8">
<style>
html, body {
height: 100%;
padding: 0px;
margin: 0px;
}
</style>
</head>
<body>
<div class="gantt_control">
<button class='zoom_toggle' onclick="toggleMode(this)">Zoom to Fit</button>
<input type=button value="Zoom In" onclick="zoom_in();">
<input type=button value="Zoom Out" onclick="zoom_out();">
</div>
<div id="gantt_here" style='width:100%; height:calc(100vh - 52px); position: relative;'></div>
<script>
function toggleMode(toggle) {
gantt.$zoomToFit = !gantt.$zoomToFit;
if (gantt.$zoomToFit) {
toggle.innerHTML = "Set default Scale";
//Saving previous scale state for future restore
saveConfig();
zoomToFit();
} else {
toggle.innerHTML = "Zoom to Fit";
//Restore previous scale state
restoreConfig();
gantt.render();
}
}
var cachedSettings = {};
function saveConfig() {
var config = gantt.config;
cachedSettings = {};
cachedSettings.scales = config.scales;
cachedSettings.start_date = config.start_date;
cachedSettings.end_date = config.end_date;
cachedSettings.scroll_position = gantt.getScrollState();
}
function restoreConfig() {
applyConfig(cachedSettings);
}
function applyConfig(config, dates) {
gantt.config.scales = config.scales;
// restore the previous scroll position
if (config.scroll_position) {
setTimeout(function(){
gantt.scrollTo(config.scroll_position.x, config.scroll_position.y)
},4)
}
}
function zoomToFit() {
var project = gantt.getSubtaskDates(),
areaWidth = gantt.$task.offsetWidth,
scaleConfigs = zoomConfig.levels;
for (var i = 0; i < scaleConfigs.length; i++) {
var columnCount = getUnitsBetween(project.start_date, project.end_date, scaleConfigs[i].scales[scaleConfigs[i].scales.length-1].unit, scaleConfigs[i].scales[0].step);
if ((columnCount + 2) * gantt.config.min_column_width <= areaWidth) {
break;
}
}
if (i == scaleConfigs.length) {
i--;
}
gantt.ext.zoom.setLevel(scaleConfigs[i].name);
applyConfig(scaleConfigs[i], project);
}
// get number of columns in timeline
function getUnitsBetween(from, to, unit, step) {
var start = new Date(from),
end = new Date(to);
var units = 0;
while (start.valueOf() < end.valueOf()) {
units++;
start = gantt.date.add(start, step, unit);
}
return units;
}
function zoom_in(){
gantt.ext.zoom.zoomIn();
gantt.$zoomToFit = false;
document.querySelector(".zoom_toggle").innerHTML = "Zoom to Fit";
}
function zoom_out(){
gantt.ext.zoom.zoomOut();
gantt.$zoomToFit = false;
document.querySelector(".zoom_toggle").innerHTML = "Zoom to Fit";
}
var zoomConfig = {
levels: [
// hours
{
name:"hour",
scale_height: 27,
scales:[
{unit:"day", step: 1, format:"%d %M"},
{unit:"hour", step: 1, format:"%H:%i"},
]
},
// days
{
name:"day",
scale_height: 27,
scales:[
{unit: "day", step: 1, format: "%d %M"}
]
},
// weeks
{
name:"week",
scale_height: 50,
scales:[
{unit: "week", step: 1, format: function (date) {
var dateToStr = gantt.date.date_to_str("%d %M");
var endDate = gantt.date.add(date, -6, "day");
var weekNum = gantt.date.date_to_str("%W")(date);
return "#" + weekNum + ", " + dateToStr(date) + " - " + dateToStr(endDate);
}},
{unit: "day", step: 1, format: "%j %D"}
]
},
// months
{
name:"month",
scale_height: 50,
scales:[
{unit: "month", step: 1, format: "%F, %Y"},
{unit: "week", step: 1, format: function (date) {
var dateToStr = gantt.date.date_to_str("%d %M");
var endDate = gantt.date.add(gantt.date.add(date, 1, "week"), -1, "day");
return dateToStr(date) + " - " + dateToStr(endDate);
}}
]
},
// quarters
{
name:"quarter",
height: 50,
scales:[
{
unit: "quarter", step: 3, format: function (date) {
var dateToStr = gantt.date.date_to_str("%M %y");
var endDate = gantt.date.add(gantt.date.add(date, 3, "month"), -1, "day");
return dateToStr(date) + " - " + dateToStr(endDate);
}
},
{unit: "month", step: 1, format: "%M"},
]
},
// years
{
name:"year",
scale_height: 50,
scales:[
{unit: "year", step: 5, format: function (date) {
var dateToStr = gantt.date.date_to_str("%Y");
var endDate = gantt.date.add(gantt.date.add(date, 5, "year"), -1, "day");
return dateToStr(date) + " - " + dateToStr(endDate);
}}
]
},
// decades
{
name:"year",
scale_height: 50,
scales:[
{unit: "year", step: 100, format: function (date) {
var dateToStr = gantt.date.date_to_str("%Y");
var endDate = gantt.date.add(gantt.date.add(date, 100, "year"), -1, "day");
return dateToStr(date) + " - " + dateToStr(endDate);
}},
{unit: "year", step: 10, format: function (date) {
var dateToStr = gantt.date.date_to_str("%Y");
var endDate = gantt.date.add(gantt.date.add(date, 10, "year"), -1, "day");
return dateToStr(date) + " - " + dateToStr(endDate);
}},
]
},
],
element: function(){
return gantt.$root.querySelector(".gantt_task");
}
};
gantt.config.fit_tasks = true;
gantt.ext.zoom.init(zoomConfig);
gantt.ext.zoom.setLevel("day");
gantt.$zoomToFit = false;
gantt.message({text: "Scale the Gantt chart to make the whole project fit the screen", expire: -1});
gantt.init("gantt_here");
gantt.parse(demo_tasks);
</script>
</body>

81
samples/dhtmlx-gantt/samples/03_scales/14_scale_zoom_by_wheelmouse.html

@ -0,0 +1,81 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Mouse wheel zoom</title>
<script src="../../codebase/dhtmlxgantt.js?v=7.1.8"></script>
<script src="../common/testdata.js?v=7.1.8"></script>
<link rel="stylesheet" href="../../codebase/dhtmlxgantt.css?v=7.1.8">
<link rel="stylesheet" href="../common/controls_styles.css?v=7.1.8">
<style>
html, body {
height: 100%;
padding: 0px;
margin: 0px;
}
</style>
</head>
<body>
<div id="gantt_here" style="width:100%; height:700px; position: relative;"></div>
<script>
var hourToStr = gantt.date.date_to_str("%H:%i");
var hourRangeFormat = function(step){
return function(date){
var intervalEnd = new Date(gantt.date.add(date, step, "hour") - 1)
return hourToStr(date) + " - " + hourToStr(intervalEnd);
};
};
gantt.config.min_column_width = 80;
var zoomConfig = {
minColumnWidth: 80,
maxColumnWidth: 150,
levels: [
[
{ unit: "month", format: "%M %Y", step: 1},
{ unit: "week", step: 1, format: function (date) {
var dateToStr = gantt.date.date_to_str("%d %M");
var endDate = gantt.date.add(date, -6, "day");
var weekNum = gantt.date.date_to_str("%W")(date);
return "Week #" + weekNum + ", " + dateToStr(date) + " - " + dateToStr(endDate);
}}
],
[
{ unit: "month", format: "%M %Y", step: 1},
{ unit: "day", format: "%d %M", step: 1}
],
[
{ unit: "day", format: "%d %M", step: 1},
{ unit: "hour", format: hourRangeFormat(12), step: 12}
],
[
{unit: "day", format: "%d %M",step: 1},
{unit: "hour",format: hourRangeFormat(6),step: 6}
],
[
{ unit: "day", format: "%d %M", step: 1 },
{ unit: "hour", format: "%H:%i", step: 1}
]
],
startDate: new Date(2018, 02, 27),
endDate: new Date(2018, 03, 20),
useKey: "ctrlKey",
trigger: "wheel",
element: function(){
return gantt.$root.querySelector(".gantt_task");
}
}
gantt.ext.zoom.init(zoomConfig);
gantt.init("gantt_here");
gantt.parse(demo_tasks);
gantt.message({
text:"Use <b>ctrl + mousewheel</b> in order to zoom",
expire: -1
});
</script>
</body>

234
samples/dhtmlx-gantt/samples/03_scales/index.html

@ -0,0 +1,234 @@
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="../common/docs.css">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="initial-scale = 1.0" />
<title>Gantt : Samples</title></title>
</head>
<body>
<div class='abstop_header'>
<div class='content_area'>
&nbsp;
</div>
</div>
<div class="page_header">
<div class='page_inner_header'>
<a href='https://dhtmlx.com'><div class='top_webix_logo'></div></a>
Samples
</div>
</div>
<div class="page_space">
<div class="webixdoc_page webixdoc_start">
<div id="webixContent" class='webixdoc_content'>
<div class="webixdoc_content_inner">
<div class="webixdoc_breadcrumb nav_breadcrumb">
<a href="https://docs.dhtmlx.com/gantt/" class="webixdoc_back">Documentation</a>
<a href="../" class="webixdoc_back">Samples</a>
<a href="../" class="webixdoc_back">Scales</a>
</div>
<table class='nav_table'>
<tr>
<td style='width:30px;'>
<a href='01_multiple_scales.html'>
<div class='nav_page_img'>&nbsp;</div>
</a>
</td>
<td>
<a href='01_multiple_scales.html'>Multiple scales</a>
</td>
</tr>
<tr>
<td style='width:30px;'>
<a href='02_month_days.html'>
<div class='nav_page_img'>&nbsp;</div>
</a>
</td>
<td>
<a href='02_month_days.html'>Month view</a>
</td>
</tr>
<tr>
<td style='width:30px;'>
<a href='03_full_year.html'>
<div class='nav_page_img'>&nbsp;</div>
</a>
</td>
<td>
<a href='03_full_year.html'>Year scale</a>
</td>
</tr>
<tr>
<td style='width:30px;'>
<a href='04_days.html'>
<div class='nav_page_img'>&nbsp;</div>
</a>
</td>
<td>
<a href='04_days.html'>Day hours</a>
</td>
</tr>
<tr>
<td style='width:30px;'>
<a href='05_dynamic_scales.html'>
<div class='nav_page_img'>&nbsp;</div>
</a>
</td>
<td>
<a href='05_dynamic_scales.html'>Dynamic scales</a>
</td>
</tr>
<tr>
<td style='width:30px;'>
<a href='06_custom_scales.html'>
<div class='nav_page_img'>&nbsp;</div>
</a>
</td>
<td>
<a href='06_custom_scales.html'>Custom scales</a>
</td>
</tr>
<tr>
<td style='width:30px;'>
<a href='07_minutes_scale.html'>
<div class='nav_page_img'>&nbsp;</div>
</a>
</td>
<td>
<a href='07_minutes_scale.html'>Minutes timeline</a>
</td>
</tr>
<tr>
<td style='width:30px;'>
<a href='08_scale_autoconfig.html'>
<div class='nav_page_img'>&nbsp;</div>
</a>
</td>
<td>
<a href='08_scale_autoconfig.html'>Auto resize scale</a>
</td>
</tr>
<tr>
<td style='width:30px;'>
<a href='10_working_hours.html'>
<div class='nav_page_img'>&nbsp;</div>
</a>
</td>
<td>
<a href='10_working_hours.html'>Show working hours</a>
</td>
</tr>
<tr>
<td style='width:30px;'>
<a href='11_select_column.html'>
<div class='nav_page_img'>&nbsp;</div>
</a>
</td>
<td>
<a href='11_select_column.html'>Selecting columns</a>
</td>
</tr>
<tr>
<td style='width:30px;'>
<a href='12_year_quarters.html'>
<div class='nav_page_img'>&nbsp;</div>
</a>
</td>
<td>
<a href='12_year_quarters.html'>Year quarters scale</a>
</td>
</tr>
<tr>
<td style='width:30px;'>
<a href='13_zoom_to_fit.html'>
<div class='nav_page_img'>&nbsp;</div>
</a>
</td>
<td>
<a href='13_zoom_to_fit.html'>Zoom To Fit</a>
</td>
</tr>
<tr>
<td style='width:30px;'>
<a href='14_scale_zoom_by_wheelmouse.html'>
<div class='nav_page_img'>&nbsp;</div>
</a>
</td>
<td>
<a href='14_scale_zoom_by_wheelmouse.html'>Mouse wheel zoom</a>
</td>
</tr>
</table>
</div>
</div>
</div>
</div>
<!--Side quick links -->
<div class="side_links">
<a class="reference_link" href="https://docs.dhtmlx.com/gantt/api__refs__gantt.html">
<span>API Reference</span>
</a>
<a class="sample_link" href="../">
<span>Code Samples</span>
</a>
<a class="forum_link" href="https://forum.dhtmlx.com/c/gantt">
<span>Developer Forum </span>
</a>
</div>
</div>
</div>
<div class="footer_linea">&nbsp;</div>
<div class="footer_lineb">
<div class='page_inner_header'>
<a href='https://dhtmlx.com'><div class='bottom_webix_block bottom_webix_logo' ></div></a>
<div class='copyright bottom_webix_block'>© 2021 XB Software Ltd.<br>
All rights reserved</div>
<div class='bottom_webix_also'>
<h4>Check also:</h4>
<li><a href='https://dhtmlx.com/docs/products/dhtmlxScheduler/' target='_blank'>DHTMLX Scheduler</a></li>
<li><a href='https://dhtmlx.com/docs/products/dhtmlxSpreadsheet/' target='_blank'>DHTMLX Spreadsheet</a></li>
<li><a href='https://dhtmlx.com/docs/products/dhtmlxSuite/' target='_blank'>Other DHTMLX components</a></li>
</div>
</div>
</div>
<script>
var msBrowser =
navigator.userAgent.indexOf("MSIE ") > 0 ||
navigator.userAgent.indexOf("Trident") > 0 ||
navigator.userAgent.indexOf("Edge") > 0
if (msBrowser){
var summaryElements = document.querySelectorAll(".list_samples");
for (var i = 0; i < summaryElements.length; i++) {
var navItem = summaryElements[i];
var link = navItem.querySelector("a");
var parent = navItem.parentNode;
parent.insertBefore(link, navItem);
navItem.style.display = 'none';
}
}
</script>
</body>
</html>

34
samples/dhtmlx-gantt/samples/04_customization/01_outer_content.html

@ -0,0 +1,34 @@
<!DOCTYPE html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Define side content</title>
<script src="../../codebase/dhtmlxgantt.js?v=7.1.8"></script>
<link rel="stylesheet" href="../../codebase/skins/dhtmlxgantt_meadow.css?v=7.1.8">
<script src="../common/testdata.js?v=7.1.8"></script>
<style>
html, body {
height: 100%;
padding: 0px;
margin: 0px;
overflow: hidden;
}
</style>
</head>
<body>
<div id="gantt_here" style='width:100%; height:100%'></div>
<script>
gantt.templates.rightside_text = function (start, end, task) {
return "ID: #" + task.id;
};
gantt.templates.leftside_text = function (start, end, task) {
return task.duration + " days";
};
gantt.init("gantt_here");
gantt.parse(demo_tasks);
</script>
</body>

66
samples/dhtmlx-gantt/samples/04_customization/02_custom_tree.html

@ -0,0 +1,66 @@
<!DOCTYPE html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Custom tree formatting</title>
<script src="../../codebase/dhtmlxgantt.js?v=7.1.8"></script>
<link rel="stylesheet" href="../../codebase/dhtmlxgantt.css?v=7.1.8">
<script src="../common/testdata.js?v=7.1.8"></script>
<style>
html, body {
height: 100%;
padding: 0px;
margin: 0px;
overflow: hidden;
}
.red .gantt_cell, .odd.red .gantt_cell,
.red .gantt_task_cell, .odd.red .gantt_task_cell {
background-color: #FDE0E0;
}
.green .gantt_cell, .odd.green .gantt_cell,
.green .gantt_task_cell, .odd.green .gantt_task_cell {
background-color: #BEE4BE;
}
</style>
</head>
<body>
<div id="gantt_here" style='width:100%; height:100%'></div>
<script>
gantt.config.grid_width = 380;
gantt.config.add_column = false;
gantt.templates.grid_row_class = function (start_date, end_date, item) {
if (item.progress == 0) return "red";
if (item.progress >= 1) return "green";
};
gantt.templates.task_row_class = function (start_date, end_date, item) {
if (item.progress == 0) return "red";
if (item.progress >= 1) return "green";
};
gantt.config.columns = [
{name: "text", label: "Task name", tree: true, width: '*'},
{
name: "progress", label: "Progress", width: 80, align: "center",
template: function (item) {
if (item.progress >= 1)
return "Complete";
if (item.progress == 0)
return "Not started";
return Math.round(item.progress * 100) + "%";
}
},
{
name: "assigned", label: "Assigned to", align: "center", width: 100,
template: function (item) {
if (!item.users) return "Nobody";
return item.users.join(", ");
}
}
];
gantt.init("gantt_here");
gantt.parse(users_data);
</script>
</body>

79
samples/dhtmlx-gantt/samples/04_customization/03_link_styles.html

@ -0,0 +1,79 @@
<!DOCTYPE html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Link styles</title>
<script src="../../codebase/dhtmlxgantt.js?v=7.1.8"></script>
<link rel="stylesheet" href="../../codebase/dhtmlxgantt.css?v=7.1.8">
<script src="../common/testdata.js?v=7.1.8"></script>
<style>
html, body {
height: 100%;
padding: 0px;
margin: 0px;
overflow: hidden;
}
.gantt_task_link.start_to_start .gantt_line_wrapper div {
background-color: #dd5640;
}
.gantt_task_link.start_to_start:hover .gantt_line_wrapper div {
box-shadow: 0 0 5px 0px #dd5640;
}
.gantt_task_link.start_to_start .gantt_link_arrow_right {
border-left-color: #dd5640;
}
.gantt_task_link.finish_to_start .gantt_line_wrapper div {
background-color: #7576ba;
}
.gantt_task_link.finish_to_start:hover .gantt_line_wrapper div {
box-shadow: 0 0 5px 0px #7576ba;
}
.gantt_task_link.finish_to_start .gantt_link_arrow_right {
border-left-color: #7576ba;
}
.gantt_task_link.finish_to_finish .gantt_line_wrapper div {
background-color: #55d822;
}
.gantt_task_link.finish_to_finish:hover .gantt_line_wrapper div {
box-shadow: 0 0 5px 0px #55d822;
}
.gantt_task_link.finish_to_finish .gantt_link_arrow_left {
border-right-color: #55d822;
}
</style>
</head>
<body>
<div id="gantt_here" style='width:100%; height:100%;'></div>
<script>
gantt.init("gantt_here");
gantt.templates.link_class = function (link) {
var types = gantt.config.links;
switch (link.type) {
case types.finish_to_start:
return "finish_to_start";
break;
case types.start_to_start:
return "start_to_start";
break;
case types.finish_to_finish:
return "finish_to_finish";
break;
}
};
gantt.parse(demo_tasks);
</script>
</body>

84
samples/dhtmlx-gantt/samples/04_customization/04_task_styles.html

@ -0,0 +1,84 @@
<!DOCTYPE html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Task styles</title>
<script src="../../codebase/dhtmlxgantt.js?v=7.1.8"></script>
<link rel="stylesheet" href="../../codebase/dhtmlxgantt.css?v=7.1.8">
<script src="../common/testdata.js?v=7.1.8"></script>
<style>
html, body {
height: 100%;
padding: 0px;
margin: 0px;
overflow: hidden;
}
.high {
border: 2px solid #d96c49;
color: #d96c49;
background: #d96c49;
}
.high .gantt_task_progress {
background: #db2536;
}
.medium {
border: 2px solid #34c461;
color: #34c461;
background: #34c461;
}
.medium .gantt_task_progress {
background: #23964d;
}
.low {
border: 2px solid #6ba8e3;
color: #6ba8e3;
background: #6ba8e3;
}
.low .gantt_task_progress {
background: #547dab;
}
</style>
</head>
<body>
<div id="gantt_here" style='width:100%; height:100%;'></div>
<script>
gantt.init("gantt_here");
gantt.config.columns = [
{name: "text", label: "Task name", tree: true, width: "*", resize: true},
{name: "start_date", label: "Start time", align: "center", resize: true},
{
name: "priority", label: "Priority", align: "center", template: function (obj) {
if (obj.priority == 1) {
return "High"
}
if (obj.priority == 2) {
return "Medium"
}
return "Low"
}
}
];
gantt.templates.task_class = function (start, end, task) {
switch (task.priority) {
case "1":
return "high";
break;
case "2":
return "medium";
break;
case "3":
return "low";
break;
}
};
gantt.parse(users_data);
</script>
</body>

39
samples/dhtmlx-gantt/samples/04_customization/05_tree_template.html

@ -0,0 +1,39 @@
<!DOCTYPE html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Template for tree nodes</title>
<script src="../../codebase/dhtmlxgantt.js?v=7.1.8"></script>
<link rel="stylesheet" href="../../codebase/dhtmlxgantt.css?v=7.1.8">
<script src="../common/testdata.js?v=7.1.8"></script>
<style>
.important {
color: red;
}
html, body{
padding:0;
margin: 0;
}
</style>
</head>
<body>
<div id="gantt_here" style='height:100vh;'></div>
<script>
gantt.config.columns = [
{name: "text", label: "Task name", tree: true, width: 230, template: function (task) {
if (task.priority == 1)
return "<div class='important'>" + task.text + " (" + task.users + ") </div>";
return task.text + " (" + task.users + ")";
}},
{name: "start_date", label: "Start time", align: "center"},
{name: "duration", label: "Duration", align: "center"}
];
gantt.init("gantt_here");
gantt.parse(users_data);
</script>
</body>

43
samples/dhtmlx-gantt/samples/04_customization/06_highlight_weekend.html

@ -0,0 +1,43 @@
<!DOCTYPE html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Highlighting weekends</title>
<script src="../../codebase/dhtmlxgantt.js?v=7.1.8"></script>
<link rel="stylesheet" href="../../codebase/dhtmlxgantt.css?v=7.1.8">
<script src="../common/testdata.js?v=7.1.8"></script>
<style>
html, body {
width: 100%;
height: 100%;
margin: 0;
}
.weekend {
background: #f4f7f4;
}
.gantt_selected .weekend {
background: #f7eb91;
}
</style>
</head>
<body>
<div id="gantt_here" style='width:100%; height:100%'></div>
<script>
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.init("gantt_here");
gantt.parse(demo_tasks);
</script>
</body>

37
samples/dhtmlx-gantt/samples/04_customization/07_progress_text.html

@ -0,0 +1,37 @@
<!DOCTYPE html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Text in the Progress bar</title>
<script src="../../codebase/dhtmlxgantt.js?v=7.1.8"></script>
<link rel="stylesheet" href="../../codebase/dhtmlxgantt.css?v=7.1.8">
<script src="../common/testdata.js?v=7.1.8"></script>
<style>
.gantt_task_progress {
text-align: left;
padding-left: 10px;
box-sizing: border-box;
color: white;
font-weight: bold;
}
html, body {
width: 100%;
height: 100%;
margin: 0;
}
</style>
</head>
<body>
<div id="gantt_here" style='width:100%; height:100%;'></div>
<script>
gantt.templates.progress_text = function (start, end, task) {
return "<span style='text-align:left;'>" + Math.round(task.progress * 100) + "% </span>";
};
gantt.init("gantt_here");
gantt.parse(demo_tasks);
</script>
</body>

69
samples/dhtmlx-gantt/samples/04_customization/08_templates.html

@ -0,0 +1,69 @@
<!DOCTYPE html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Styling task bars with events</title>
<script src="../../codebase/dhtmlxgantt.js?v=7.1.8"></script>
<link rel="stylesheet" href="../../codebase/dhtmlxgantt.css?v=7.1.8">
<script src="../common/testdata.js?v=7.1.8"></script>
<style>
html, body {
height: 100%;
padding: 0px;
margin: 0px;
overflow: hidden;
}
.important {
border: 2px solid red;
color: red;
background: red;
}
.important .gantt_task_progress {
background: #ff5956;
}
.normal {
border: 2px solid green;
}
.low {
border: 2px solid yellow;
}
.custom_row {
background: rgb(245, 248, 245);
}
</style>
</head>
<body>
<div id="gantt_here" style='height:100vh;'></div>
<script>
window.addEventListener('DOMContentLoaded', function (event) {
//defines the text inside the tak bars
gantt.templates.task_text = function (start, end, task) {
return "<b>Text:</b> " + task.text + ",<b> Holders:</b> " + task.users;
};
//defines the style of task bars
gantt.templates.grid_row_class = gantt.templates.task_row_class = function (start, end, task) {
return "custom_row";
};
gantt.templates.task_class = function (start, end, task) {
if (task.progress > 0.5) {
return "";
} else {
return "important";
}
};
gantt.init("gantt_here");
gantt.parse(users_data);
});
</script>
</body>

92
samples/dhtmlx-gantt/samples/04_customization/09_html_content.html

@ -0,0 +1,92 @@
<!DOCTYPE html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Custom html content</title>
<script src="../../codebase/dhtmlxgantt.js?v=7.1.8"></script>
<link rel="stylesheet" href="../../codebase/dhtmlxgantt.css?v=7.1.8">
<style>
html, body {
height: 100%;
padding: 0px;
margin: 0px;
overflow: hidden;
}
.custom_progress {
display: inline-block;
vertical-align: top;
text-align: center;
height: 100%;
}
.custom_progress.nearly_done {
background-color: #4CC259;
}
.custom_progress.in_progress {
background-color: #88BFF5;
}
.custom_progress.idle {
background-color: #d96c49;
}
</style>
</head>
<body>
<div id="gantt_here" style='width:100%; height:100%;'></div>
<script>
gantt.config.show_progress = false;
function percenToString(num) {
return Math.floor(num * 100) + '%';
}
function renderLabel(progress, sum) {
var relWidth = progress / sum * 100;
var cssClass = "custom_progress ";
if (progress > 0.6) {
cssClass += "nearly_done";
} else if (progress > 0.3) {
cssClass += "in_progress";
} else {
cssClass += "idle";
}
return "<div class='" + cssClass + "' style='width:" + relWidth + "%'>" + percenToString(progress) + "</div>";
}
gantt.templates.task_text = function (start, end, task) {
var summ = task.progress1 + task.progress2 + task.progress3;
return renderLabel(task.progress1, summ) + renderLabel(task.progress2, summ) + renderLabel(task.progress3, summ);
};
gantt.init("gantt_here");
gantt.parse({
data: [
{
id: 1, text: "Project #2", start_date: "01-04-2018",
progress1: 0.3, progress2: 0.5, progress3: 0.8, duration: 18, open: true
},
{
id: 2, text: "Task #1", start_date: "02-04-2018", duration: 8,
progress1: 0.6, progress2: 0.1, progress3: 0.8, parent: 1
},
{
id: 3, text: "Task #2", start_date: "11-04-2018", duration: 8,
progress1: 0.9, progress2: 0.4, progress3: 0.2, parent: 1
}
],
links: [
{id: 1, source: 1, target: 2, type: "1"},
{id: 2, source: 2, target: 3, type: "0"}
]
});
</script>
</body>

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save