From 0a680e12bb545d56547c0fa7b3e4c2eb6d5c41f8 Mon Sep 17 00:00:00 2001 From: M Inam <34743206+iaminamcom@users.noreply.github.com> Date: Tue, 22 Oct 2024 11:26:53 +0500 Subject: [PATCH 01/12] Added option to enable grouping --- index.html | 21 ++++++++++----------- src/index.js | 38 +++++++++++++++++++++++++------------- 2 files changed, 35 insertions(+), 24 deletions(-) diff --git a/index.html b/index.html index 419d47cc..23c631b1 100644 --- a/index.html +++ b/index.html @@ -31,7 +31,7 @@ font-size: 0.775em; } - +
@@ -338,20 +338,22 @@

Frappe Gantt - for you.

{ start: daysSince(-2), end: daysSince(2), + name: 'Write new content', + id: 'Task 1', + progress: 5, + // important: true, + group: 0, + }, + { name: 'Redesign website', id: 'Task 0', progress: random(), + group: 0, }, { start: daysSince(3), - duration: '6d', - name: 'Write new content', - id: 'Task 1', progress: random(), - important: true, dependencies: 'Task 0', - }, - { start: daysSince(4), duration: '2d', name: 'Apply new styles', @@ -461,7 +463,6 @@

Frappe Gantt - for you.

duration: '7d', name: 'Create prototype', id: 'Task 3', - dependencies: 'Task 2', progress: random(), }, { @@ -473,11 +474,9 @@

Frappe Gantt - for you.

progress: random(), important: true, }, - { start: daysSince(5), end: daysSince(10), name: 'Write technical documentation', - id: 'Task 5', progress: random(), }, { @@ -509,7 +508,6 @@

Frappe Gantt - for you.

id: 'Task 9', progress: random(), important: true, - }, ]; const HOLIDAYS = [ @@ -543,6 +541,7 @@

Frappe Gantt - for you.

'#bfdbfe': [], '#a3e635': HOLIDAYS, }, + enable_grouping: true, }); const ignore = new Gantt('#ignore', tasks, { diff --git a/src/index.js b/src/index.js index 054d3e2c..b7e6a309 100644 --- a/src/index.js +++ b/src/index.js @@ -165,6 +165,12 @@ export default class Gantt { // cache index task._index = i; + // ********** Fix for single row grouping + if (this.options.enable_grouping && typeof task.group === 'number') { + task._index = task.group; + } + // ********** end of fix + // if hours is not set, assume the last day is full day // e.g: 2018-09-09 becomes 2018-09-09 23:59:59 const task_end_values = date_utils.get_date_values(task._end); @@ -199,6 +205,8 @@ export default class Gantt { return task; }) .filter((t) => t); + this.groups = this.options.enable_grouping ? [...new Set(this.tasks.map(t => t.group))] : this.tasks; + this.setup_dependencies(); } @@ -399,7 +407,7 @@ export default class Gantt { this.config.header_height + this.options.padding + (this.options.bar_height + this.options.padding) * - this.tasks.length - + this.groups.length; 10, this.options.container_height !== 'auto' ? this.options.container_height @@ -430,12 +438,9 @@ export default class Gantt { const row_width = this.dates.length * this.config.column_width; const row_height = this.options.bar_height + this.options.padding; - let y = this.config.header_height; - for ( - let y = this.config.header_height; - y < this.grid_height; - y += row_height - ) { + let row_y = this.options.header_height; + + for (let _ of this.groups) { createSVG('rect', { x: 0, y, @@ -444,6 +449,12 @@ export default class Gantt { class: 'grid-row', append_to: rows_layer, }); + + row_y += row_height; + + if (row_y >= this.grid_height) { + break; + } } } @@ -512,7 +523,8 @@ export default class Gantt { if (this.options.lines === 'none') return; let tick_x = 0; let tick_y = this.config.header_height; - let tick_height = this.grid_height - this.config.header_height; + let tick_height = (this.grid_height - this.config.header_height)* + this.groups.length; let $lines_layer = createSVG('g', { class: 'lines_layer', @@ -524,11 +536,7 @@ export default class Gantt { const row_width = this.dates.length * this.config.column_width; const row_height = this.options.bar_height + this.options.padding; if (this.options.lines !== 'vertical') { - for ( - let y = this.config.header_height; - y < this.grid_height; - y += row_height - ) { + for (let _ of this.groups) { createSVG('line', { x1: 0, y1: row_y + row_height, @@ -538,6 +546,10 @@ export default class Gantt { append_to: $lines_layer, }); row_y += row_height; + + if (row_y >= this.grid_height) { + break; + } } } if (this.options.lines === 'horizontal') return; From 0fdf3c8fdae2b5213166dc6e2d55909b0a6fb4de Mon Sep 17 00:00:00 2001 From: M Inam <34743206+iaminamcom@users.noreply.github.com> Date: Tue, 22 Oct 2024 11:33:21 +0500 Subject: [PATCH 02/12] added readme --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 5195f34d..a01e0e7e 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,12 @@ ## Frappe Gantt Gantt charts are bar charts that visually illustrate a project's tasks, schedule, and dependencies. With Frappe Gantt, you can build beautiful, customizable, Gantt charts with ease. +## 🆕 Note about update +I made it to work with grouping so that more than one tasks can go in same row. +Check `index.html` to see working example. + +You need to pass an option `enable_grouping: true` this way behevior can be controlled. + You can use it anywhere from hobby projects to tracking the goals of your team at the worksplace. From 3ebfe673413a79730441459301bbcd426258e7f1 Mon Sep 17 00:00:00 2001 From: M Inam <34743206+iaminamcom@users.noreply.github.com> Date: Tue, 22 Oct 2024 11:58:32 +0500 Subject: [PATCH 03/12] fix for personal publish --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3bd7e0f3..cb4dbd4c 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "frappe-gantt", + "name": "frappe-gantt-fix-for-grouping", "version": "1.0.3", "description": "A simple, modern, interactive gantt library for the web", "main": "src/index.js", From b20b49d023e3261f36e161c60829d454b90b6475 Mon Sep 17 00:00:00 2001 From: M Inam <34743206+iaminamcom@users.noreply.github.com> Date: Tue, 22 Oct 2024 12:29:19 +0500 Subject: [PATCH 04/12] update readme --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index cb4dbd4c..fcfcc6ed 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ }, "repository": { "type": "git", - "url": "git+https://github.com/frappe/gantt.git" + "url": "git+https://github.com/iaminamcom/gantt-fix" }, "files": [ "src", From c10ba3aa01c554ba31496a51a920c9a1d1564173 Mon Sep 17 00:00:00 2001 From: M Inam <34743206+iaminamcom@users.noreply.github.com> Date: Thu, 24 Oct 2024 15:07:20 +0500 Subject: [PATCH 05/12] added the option for custom index --- README.md | 10 +++++++++- index.html | 1 + src/index.js | 10 +++++++++- 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a01e0e7e..928171c8 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ Gantt charts are bar charts that visually illustrate a project's tasks, schedule I made it to work with grouping so that more than one tasks can go in same row. Check `index.html` to see working example. -You need to pass an option `enable_grouping: true` this way behevior can be controlled. +You need to pass an option `enable_grouping: true` this way behevior can be controlled. You can also set custom grups indices like `groups: [0,1,2,3,4]`. You can use it anywhere from hobby projects to tracking the goals of your team at the worksplace. @@ -44,6 +44,14 @@ Include it in your HTML: ``` +To set custom index you can do like this is useful if you want to set labels with fixed values +```js +new Gantt('.gantt-target', tasks, { + enable_grouping: true, + groups: [0,1,2,3,4], + // Other options... +}); +``` Or from the CDN: ```html diff --git a/index.html b/index.html index 23c631b1..b66e4e22 100644 --- a/index.html +++ b/index.html @@ -542,6 +542,7 @@

Frappe Gantt - for you.

'#a3e635': HOLIDAYS, }, enable_grouping: true, + groups: [0,1,2,3,4], }); const ignore = new Gantt('#ignore', tasks, { diff --git a/src/index.js b/src/index.js index b7e6a309..20591cf1 100644 --- a/src/index.js +++ b/src/index.js @@ -205,7 +205,15 @@ export default class Gantt { return task; }) .filter((t) => t); - this.groups = this.options.enable_grouping ? [...new Set(this.tasks.map(t => t.group))] : this.tasks; + this.groups = this.tasks; + if (this.options?.enable_grouping) { + if (this.options?.groups) { + this.groups = this.options.groups; + } else { + this.groups = [...new Set(this.tasks.map((t) => t.group))]; + } + } + console.log(this.groups); this.setup_dependencies(); } From 409bfced13f3875b205cced988c5a2bc1f505583 Mon Sep 17 00:00:00 2001 From: M Inam <34743206+iaminamcom@users.noreply.github.com> Date: Fri, 15 Nov 2024 11:16:14 +0500 Subject: [PATCH 06/12] forgot to build --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index fcfcc6ed..17675818 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,8 @@ "build": "vite build", "lint": "eslint src/**/*.js", "prettier": "prettier --write \"{src/*,tests/*,rollup.config}.js\"", - "prettier-check": "prettier --check \"{src/*,tests/*,rollup.config}.js\"" + "prettier-check": "prettier --check \"{src/*,tests/*,rollup.config}.js\"", + "prepublishOnly": "yarn run build" }, "repository": { "type": "git", From 6d520fb34720c2952de6e5bf8087a2352388a6ae Mon Sep 17 00:00:00 2001 From: "Stephen J. Maher" Date: Wed, 2 Apr 2025 15:33:37 +0100 Subject: [PATCH 07/12] rebases to complete PR --- src/index.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/index.js b/src/index.js index 20591cf1..17ddf8b1 100644 --- a/src/index.js +++ b/src/index.js @@ -415,7 +415,7 @@ export default class Gantt { this.config.header_height + this.options.padding + (this.options.bar_height + this.options.padding) * - this.groups.length; + this.groups.length, 10, this.options.container_height !== 'auto' ? this.options.container_height @@ -446,12 +446,12 @@ export default class Gantt { const row_width = this.dates.length * this.config.column_width; const row_height = this.options.bar_height + this.options.padding; - let row_y = this.options.header_height; + let row_y = this.config.header_height; for (let _ of this.groups) { createSVG('rect', { x: 0, - y, + y : row_y, width: row_width, height: row_height, class: 'grid-row', From 148860c4251a64ec3603a7de0fa50525523d74b9 Mon Sep 17 00:00:00 2001 From: stephenjmaher Date: Thu, 3 Apr 2025 06:16:51 +0100 Subject: [PATCH 08/12] Update README.md --- README.md | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/README.md b/README.md index 928171c8..5195f34d 100644 --- a/README.md +++ b/README.md @@ -9,12 +9,6 @@ ## Frappe Gantt Gantt charts are bar charts that visually illustrate a project's tasks, schedule, and dependencies. With Frappe Gantt, you can build beautiful, customizable, Gantt charts with ease. -## 🆕 Note about update -I made it to work with grouping so that more than one tasks can go in same row. -Check `index.html` to see working example. - -You need to pass an option `enable_grouping: true` this way behevior can be controlled. You can also set custom grups indices like `groups: [0,1,2,3,4]`. - You can use it anywhere from hobby projects to tracking the goals of your team at the worksplace. @@ -44,14 +38,6 @@ Include it in your HTML: ``` -To set custom index you can do like this is useful if you want to set labels with fixed values -```js -new Gantt('.gantt-target', tasks, { - enable_grouping: true, - groups: [0,1,2,3,4], - // Other options... -}); -``` Or from the CDN: ```html From 0e46955b182170111e0107ddc7e3d9718d71ffa2 Mon Sep 17 00:00:00 2001 From: stephenjmaher Date: Thu, 3 Apr 2025 06:23:53 +0100 Subject: [PATCH 09/12] fixes errors in pr --- src/index.js | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/index.js b/src/index.js index 17ddf8b1..a5a789a3 100644 --- a/src/index.js +++ b/src/index.js @@ -165,11 +165,10 @@ export default class Gantt { // cache index task._index = i; - // ********** Fix for single row grouping - if (this.options.enable_grouping && typeof task.group === 'number') { - task._index = task.group; - } - // ********** end of fix + // enables singe row grouping + if (this.options.enable_grouping && typeof task.group === 'number') { + task._index = task.group; + } // if hours is not set, assume the last day is full day // e.g: 2018-09-09 becomes 2018-09-09 23:59:59 @@ -205,6 +204,7 @@ export default class Gantt { return task; }) .filter((t) => t); + this.groups = this.tasks; if (this.options?.enable_grouping) { if (this.options?.groups) { @@ -213,7 +213,6 @@ export default class Gantt { this.groups = [...new Set(this.tasks.map((t) => t.group))]; } } - console.log(this.groups); this.setup_dependencies(); } @@ -415,7 +414,7 @@ export default class Gantt { this.config.header_height + this.options.padding + (this.options.bar_height + this.options.padding) * - this.groups.length, + this.groups.length - 10, this.options.container_height !== 'auto' ? this.options.container_height From 059cdbb2567c2a189c08788dd2cf1ec893e32096 Mon Sep 17 00:00:00 2001 From: stephenjmaher Date: Thu, 3 Apr 2025 06:25:15 +0100 Subject: [PATCH 10/12] reverts changes to package.json --- package.json | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 17675818..3bd7e0f3 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "frappe-gantt-fix-for-grouping", + "name": "frappe-gantt", "version": "1.0.3", "description": "A simple, modern, interactive gantt library for the web", "main": "src/index.js", @@ -10,12 +10,11 @@ "build": "vite build", "lint": "eslint src/**/*.js", "prettier": "prettier --write \"{src/*,tests/*,rollup.config}.js\"", - "prettier-check": "prettier --check \"{src/*,tests/*,rollup.config}.js\"", - "prepublishOnly": "yarn run build" + "prettier-check": "prettier --check \"{src/*,tests/*,rollup.config}.js\"" }, "repository": { "type": "git", - "url": "git+https://github.com/iaminamcom/gantt-fix" + "url": "git+https://github.com/frappe/gantt.git" }, "files": [ "src", From ea4c406b7011dbe0b6f3be27a5ae9c898fba04a5 Mon Sep 17 00:00:00 2001 From: "Stephen J. Maher" Date: Thu, 3 Apr 2025 06:39:12 +0100 Subject: [PATCH 11/12] fixes grouping example --- index.html | 49 ++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 38 insertions(+), 11 deletions(-) diff --git a/index.html b/index.html index b66e4e22..7675dca0 100644 --- a/index.html +++ b/index.html @@ -31,7 +31,7 @@ font-size: 0.775em; } - +
@@ -338,22 +338,20 @@

Frappe Gantt - for you.

{ start: daysSince(-2), end: daysSince(2), - name: 'Write new content', - id: 'Task 1', - progress: 5, - // important: true, - group: 0, - }, - { name: 'Redesign website', id: 'Task 0', progress: random(), - group: 0, }, { start: daysSince(3), + duration: '6d', + name: 'Write new content', + id: 'Task 1', progress: random(), + important: true, dependencies: 'Task 0', + }, + { start: daysSince(4), duration: '2d', name: 'Apply new styles', @@ -376,6 +374,15 @@

Frappe Gantt - for you.

name: 'Redesign website', id: 'Task 0', progress: random(), + group : 0, + }, + { + start: daysSince(-5), + end: daysSince(0), + name: 'Redesign website - part 2', + id: 'Task 0', + progress: random(), + group : 0, }, { start: daysSince(-15), @@ -384,6 +391,16 @@

Frappe Gantt - for you.

id: 'Task 1', progress: random(), important: true, + group : 1, + }, + { + start: daysSince(7), + duration: '2d', + name: 'Edit new content', + id: 'Task 1', + progress: random(), + important: true, + group : 1, }, { start: daysSince(10), @@ -391,6 +408,7 @@

Frappe Gantt - for you.

name: 'Review', id: 'Task 3', progress: random(), + group : 2, }, { start: daysSince(-3), @@ -398,6 +416,7 @@

Frappe Gantt - for you.

name: 'Publish', id: 'Task 4', progress: random(), + group : 3, }, ]; @@ -463,6 +482,7 @@

Frappe Gantt - for you.

duration: '7d', name: 'Create prototype', id: 'Task 3', + dependencies: 'Task 2', progress: random(), }, { @@ -474,9 +494,11 @@

Frappe Gantt - for you.

progress: random(), important: true, }, + { start: daysSince(5), end: daysSince(10), name: 'Write technical documentation', + id: 'Task 5', progress: random(), }, { @@ -508,6 +530,7 @@

Frappe Gantt - for you.

id: 'Task 9', progress: random(), important: true, + }, ]; const HOLIDAYS = [ @@ -534,6 +557,8 @@

Frappe Gantt - for you.

today_button: true, view_mode_select: true, holidays: null, + enable_grouping: true, + groups: [0, 1, 2, 3], }); const holidays = new Gantt('#holidays', tasksSpread, { @@ -541,8 +566,8 @@

Frappe Gantt - for you.

'#bfdbfe': [], '#a3e635': HOLIDAYS, }, - enable_grouping: true, - groups: [0,1,2,3,4], + enable_grouping: true, + groups: [0, 1, 2, 3], }); const ignore = new Gantt('#ignore', tasks, { @@ -562,6 +587,8 @@

Frappe Gantt - for you.

snap_at: '1d', auto_move_label: false, scroll_to: 'today', + enable_grouping: true, + groups: [0, 1, 2, 3], }); const UPDATES = [ From a37bf67b78414cd466498e5294e6652648865d12 Mon Sep 17 00:00:00 2001 From: "Stephen J. Maher" Date: Thu, 3 Apr 2025 10:22:12 +0100 Subject: [PATCH 12/12] enables the setting of arbitrary groups and missing groups --- index.html | 3 +-- src/index.js | 29 ++++++++++++++++++++--------- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/index.html b/index.html index 7675dca0..0fb9712e 100644 --- a/index.html +++ b/index.html @@ -416,7 +416,6 @@

Frappe Gantt - for you.

name: 'Publish', id: 'Task 4', progress: random(), - group : 3, }, ]; @@ -567,7 +566,7 @@

Frappe Gantt - for you.

'#a3e635': HOLIDAYS, }, enable_grouping: true, - groups: [0, 1, 2, 3], + groups: [0, 1, 2], }); const ignore = new Gantt('#ignore', tasks, { diff --git a/src/index.js b/src/index.js index a5a789a3..ba3fa254 100644 --- a/src/index.js +++ b/src/index.js @@ -165,11 +165,6 @@ export default class Gantt { // cache index task._index = i; - // enables singe row grouping - if (this.options.enable_grouping && typeof task.group === 'number') { - task._index = task.group; - } - // if hours is not set, assume the last day is full day // e.g: 2018-09-09 becomes 2018-09-09 23:59:59 const task_end_values = date_utils.get_date_values(task._end); @@ -201,19 +196,35 @@ export default class Gantt { task.id = `${task.id}`; } + // setting a dummy group if the group is not specified + if (typeof task.group == 'undefined') { + task.group = 'group-' + task.id; + } + return task; }) .filter((t) => t); this.groups = this.tasks; if (this.options?.enable_grouping) { + // the groups are the union of the specified groups and the groups + // from the tasks. + let groupset = new Set() if (this.options?.groups) { - this.groups = this.options.groups; - } else { - this.groups = [...new Set(this.tasks.map((t) => t.group))]; + groupset = groupset.union(new Set(this.options.groups)); + } + const extendedset = groupset.union(new Set(this.tasks.map((t) => t.group))); + this.groups = Array.from(extendedset); + + // the index of the tasks depend on the groups array. This allows + // for arbitrary naming of groups (not only numeric). Further, if + // the group is not specified, then the index of the task is + // updated correctly. + for (let task of this.tasks) { + task._index = this.groups.indexOf(task.group); } - } + } this.setup_dependencies(); }