Ibnu hamdani
3 years ago
commit
b33489323f
2070 changed files with 245702 additions and 0 deletions
File diff suppressed because one or more lines are too long
@ -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" |
||||
} |
||||
] |
||||
} |
@ -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" |
||||
} |
||||
] |
||||
} |
@ -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); |
@ -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; |
||||
} |
||||
}; |
@ -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" |
||||
} |
||||
} |
@ -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; |
@ -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; |
@ -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 + "..."); |
||||
}); |
||||
|
||||
}; |
@ -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; |
@ -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; |
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -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">'</span></button> |
||||
<button onclick="$('#workSpace').trigger('redo.gantt');return false;" class="button textual icon requireCanWrite" title="redo"><span class="teamworkIcon">·</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">¢</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">£</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">§</span></button> |
||||
|
||||
<button onclick="editResources();" class="button textual requireWrite" title="edit resources"><span class="teamworkIcon">M</span></button> |
||||
|
||||
<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> |
||||
<input type="checkbox" id="startIsMilestone" name="startIsMilestone" value="yes"> <label for="startIsMilestone">is milestone</label> |
||||
<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> |
||||
<input type="checkbox" id="endIsMilestone" name="endIsMilestone" value="yes"> <label for="endIsMilestone">is milestone</label> |
||||
<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"> |
||||
</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> |
@ -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. |
@ -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" |
||||
} |
||||
} |
@ -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 |
@ -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> |
@ -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> |
@ -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> |
@ -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> |
@ -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> |
@ -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> |
@ -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> |
@ -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> |
@ -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> |
@ -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> |
@ -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> |
@ -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> |
@ -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> |
@ -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> |
@ -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 & UI Widgets" |
||||
href="https://dhtmlx.com/docs/products/dhtmlxGantt/">© 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> |
@ -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> |
@ -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> |
@ -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> |
@ -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> |
@ -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'> |
||||
|
||||
</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'> </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'> </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'> </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'> </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'> </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'> </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'> </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'> </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'> </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'> </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'> </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'> </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'> </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'> </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'> </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'> </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'> </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'> </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'> </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"> </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> |
@ -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> |
@ -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> |
@ -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> |
@ -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> |
@ -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> |
@ -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> |
@ -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> |
@ -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> |
@ -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> |
@ -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> |
@ -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> |
@ -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> |
@ -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> |
@ -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> |
@ -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> |
@ -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> |
@ -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> |
@ -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> |
@ -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> |
@ -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" |
||||
} |
||||
] |
||||
} |
@ -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" |
||||
} |
||||
] |
||||
} |
@ -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'> |
||||
|
||||
</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'> </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'> </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'> </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'> </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'> </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'> </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'> </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'> </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'> </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'> </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'> </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'> </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'> </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'> </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'> </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'> </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'> </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'> </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'> </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"> </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> |
@ -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> |
@ -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> |
@ -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> |
@ -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> |
@ -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> |
@ -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> |
@ -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> |
@ -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> |
@ -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> |
@ -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> |
@ -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> |
@ -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> |
@ -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> |
@ -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'> |
||||
|
||||
</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'> </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'> </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'> </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'> </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'> </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'> </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'> </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'> </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'> </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'> </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'> </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'> </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'> </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"> </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> |
@ -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> |
@ -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> |
@ -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> |
@ -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> |
@ -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> |
@ -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> |
@ -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> |
@ -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> |
@ -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…
Reference in new issue