gantt icon indicating copy to clipboard operation
gantt copied to clipboard

it is possible to make many tasks in one row in the gantt ?

Open sbaiti opened this issue 6 years ago • 20 comments

sbaiti avatar Aug 08 '18 14:08 sbaiti

image

like this many tasks in one row , someone support please ?

sbaiti avatar Aug 14 '18 11:08 sbaiti

Not possible currently. Can you explain any use case that needs such arrangement of tasks ?

netchampfaris avatar Aug 18 '18 16:08 netchampfaris

we need to show the blocked time Frame of a user like this gantt multiple users 67f66106-abd7-48d5-aaf5-3c8b4706447e 1

sbaiti avatar Aug 27 '18 07:08 sbaiti

We would also be interested in this feature!

fooksem avatar Sep 03 '18 06:09 fooksem

+1 Voted for this feature.

chuongtrh avatar Nov 16 '18 10:11 chuongtrh

+1

kkarabiber-s avatar Apr 10 '19 14:04 kkarabiber-s

Would also like to see this option. Is there any update on this feature?

MartijnHarmenzon avatar Sep 16 '19 08:09 MartijnHarmenzon

Also like to see this option. Is there any update on this feature?

satya5561 avatar Jan 06 '20 13:01 satya5561

image

like this many tasks in one row , someone support please ?

image

like this many tasks in one row , someone support please ?

have you got anything

satya5561 avatar Jan 06 '20 13:01 satya5561

I have a simple workaround. Not sure if it is ready for PR, but solved my problem...

Search for this lines in index.js:107

// cache index
task._index = i;

and add this code right after:

if (typeof task.custom_index === 'number') {
    task._index = task.custom_index;
}

When you pass task data with optional parameter custom_index, you will get inline task rendered in row based on that index. You have to compute it in your own and pass as number:

// example data for inline tasks

let taskData = {
 custom_index: 0,
 id: "some-udid-a",
 name: "task-A",
 start: "YYYY-MM-DD",
 end: "YYYY-MM-DD",
 progress: 0,
 dependencies: ''
},{
 custom_index: 0,
 id: "some-udid-b",
 name: "task-B",
 start: "YYYY-MM-DD",
 end: "YYYY-MM-DD",
 progress: 0,
 dependencies: ''
},{
 custom_index: 1,
 id: "some-udid-a",
 name: "task-C",
 start: "YYYY-MM-DD",
 end: "YYYY-MM-DD",
 progress: 0,
 dependencies: ''
};

Resulted in:

image

Overlapping tasks wil be also rendered ... overlapping each other, the latter on the top. You can use different css class (e.g. lower opacity) to make the overlap visible ;)

Not tested with dependent rows.

qool avatar Apr 01 '20 14:04 qool

Thank you! This works like a charme! Renamed custom_index to row in my code and now that look pretty natural.

joergviola avatar May 17 '20 20:05 joergviola

Thanks @qool, this worked perfectly!

JelleWolbers avatar Aug 03 '20 12:08 JelleWolbers

It's a very nice solution. In 2021, it brings the tasks onto the 'custom_index' distinct rows, however the total number of rows aren't reduced. 2021-05-22 (11)

William-Wildridge avatar May 22 '21 16:05 William-Wildridge

@William-Wildridge I struggled with this issue, as wel.. After much tinkering I have created a fix. Do note that I am by no means a JS expert. But this does work for me.

I have modified @qool 's fix by using the term row_id, like so: // cache index task._index = i; if (typeof task.row_id === 'number') { task._index = task.row_id; }

Then I needed to know how many unique row_id's I have and iterate over these unique rows, instead of iterating over the tasks. I did this by editing the make_grid_rows() like so:

make_grid_rows() {
        let counter_rows = 0;
        const distinctRows = [...new Set(this.tasks.map(x => x.row_id))];
        for (let row of distinctRows){
            counter_rows = counter_rows + 1;
        }
        console.log(counter_rows + " unique rows")

        const rows_layer = createSVG('g', { append_to: this.layers.grid });
        const lines_layer = createSVG('g', { append_to: this.layers.grid });
        const row_width = this.dates.length * this.options.column_width;
        const row_height = this.options.bar_height + this.options.padding;

        let row_y = this.options.header_height + this.options.padding / 2;
        //var counter = 0;

        for (let row of distinctRows) {
            // console.log("for each log");
            // console.log(counter);
            // counter = counter + 1;
            // console.log(counter);
            // console.log('row id:' + task.row_id)

            createSVG('rect', {
                x: 0,
                y: row_y,
                width: row_width,
                height: row_height,
                class: 'grid-row',
                append_to: rows_layer
            });

            createSVG('line', {
                x1: 0,
                y1: row_y + row_height,
                x2: row_width,
                y2: row_y + row_height,
                class: 'row-line',
                append_to: lines_layer
            });

            row_y += this.options.bar_height + this.options.padding;
        }
    }

I hope someone finds this fix useful!

bg

Jelle

jellederijke avatar Jan 06 '22 16:01 jellederijke

I have a simple workaround. Not sure if it is ready for PR, but solved my problem...

Search for this lines in index.js:107

// cache index task._index = i; and add this code right after:

if (typeof task.custom_index === 'number') { task._index = task.custom_index; } When you pass task data with optional parameter custom_index, you will get inline task rendered in row based on that index. You have to compute it in your own and pass as number:

// example data for inline tasks

let taskData = { custom_index: 0, id: "some-udid-a", name: "task-A", start: "YYYY-MM-DD", end: "YYYY-MM-DD", progress: 0, dependencies: '' },{ custom_index: 0, id: "some-udid-b", name: "task-B", start: "YYYY-MM-DD", end: "YYYY-MM-DD", progress: 0, dependencies: '' },{ custom_index: 1, id: "some-udid-a", name: "task-C", start: "YYYY-MM-DD", end: "YYYY-MM-DD", progress: 0, dependencies: '' }; Resulted in:

image

Overlapping tasks wil be also rendered ... overlapping each other, the latter on the top. You can use different css class (e.g. lower opacity) to make the overlap visible ;)

Not tested with dependent rows.

Thanks for the solution,but it will add an extra empty row at the end chart

Nikhilbk1705 avatar Jan 12 '22 06:01 Nikhilbk1705

I have a simple workaround. Not sure if it is ready for PR, but solved my problem... Search for this lines in index.js:107 // cache index task._index = i; and add this code right after: if (typeof task.custom_index === 'number') { task._index = task.custom_index; } When you pass task data with optional parameter custom_index, you will get inline task rendered in row based on that index. You have to compute it in your own and pass as number: // example data for inline tasks let taskData = { custom_index: 0, id: "some-udid-a", name: "task-A", start: "YYYY-MM-DD", end: "YYYY-MM-DD", progress: 0, dependencies: '' },{ custom_index: 0, id: "some-udid-b", name: "task-B", start: "YYYY-MM-DD", end: "YYYY-MM-DD", progress: 0, dependencies: '' },{ custom_index: 1, id: "some-udid-a", name: "task-C", start: "YYYY-MM-DD", end: "YYYY-MM-DD", progress: 0, dependencies: '' }; Resulted in: image Overlapping tasks wil be also rendered ... overlapping each other, the latter on the top. You can use different css class (e.g. lower opacity) to make the overlap visible ;) Not tested with dependent rows.

Thanks for the solution,but it will add an extra empty row at the end chart

Please see my above post to fix your issue.

jellederijke avatar Jan 12 '22 08:01 jellederijke

I have a simple workaround. Not sure if it is ready for PR, but solved my problem... Search for this lines in index.js:107 // cache index task._index = i; and add this code right after: if (typeof task.custom_index === 'number') { task._index = task.custom_index; } When you pass task data with optional parameter custom_index, you will get inline task rendered in row based on that index. You have to compute it in your own and pass as number: // example data for inline tasks let taskData = { custom_index: 0, id: "some-udid-a", name: "task-A", start: "YYYY-MM-DD", end: "YYYY-MM-DD", progress: 0, dependencies: '' },{ custom_index: 0, id: "some-udid-b", name: "task-B", start: "YYYY-MM-DD", end: "YYYY-MM-DD", progress: 0, dependencies: '' },{ custom_index: 1, id: "some-udid-a", name: "task-C", start: "YYYY-MM-DD", end: "YYYY-MM-DD", progress: 0, dependencies: '' }; Resulted in: image Overlapping tasks wil be also rendered ... overlapping each other, the latter on the top. You can use different css class (e.g. lower opacity) to make the overlap visible ;) Not tested with dependent rows.

Thanks for the solution,but it will add an extra empty row at the end chart

Please see my above post to fix your issue.

Thanks for the quick response, so kind of you. My issue is , i am getting the multiple bar in each row, but for every multiple bar i render in the single row, i don't know why ,there is an extra empty row added at bottom of chart, i will attach picture of my issue it will give you better idea and my task array screenshot is also attached.

issue image

Nikhilbk1705 avatar Jan 12 '22 08:01 Nikhilbk1705

Thanks for the quick response, so kind of you. My issue is , i am getting the multiple bar in each row, but for every multiple bar i render in the single row, i don't know why ,there is an extra empty row added at bottom of chart, i will attach picture of my issue it will give you better idea and my task array screenshot is also attached.

issue image

This is the exact issue that my above fix solves. So please try to look into this fix in order to solve your empty rows.

jellederijke avatar Jan 12 '22 12:01 jellederijke

Thanks for the quick response, so kind of you. My issue is , i am getting the multiple bar in each row, but for every multiple bar i render in the single row, i don't know why ,there is an extra empty row added at bottom of chart, i will attach picture of my issue it will give you better idea and my task array screenshot is also attached. issue image

This is the exact issue that my above fix solves. So please try to look into this fix in order to solve your empty rows.

Thank you so much for your quick reply, it worked like CHARM!!!. Previously i was looking into your earlier solution, so i didn't able to solve, then i noticed your latest solution then I am able solve the issue. Once again thank you so much, it helped alot.

Nikhilbk1705 avatar Jan 13 '22 04:01 Nikhilbk1705

@William-Wildridge I struggled with this issue, as wel.. After much tinkering I have created a fix. Do note that I am by no means a JS expert. But this does work for me.

I have modified @qool 's fix by using the term row_id, like so: // cache index task._index = i; if (typeof task.row_id === 'number') { task._index = task.row_id; }

Then I needed to know how many unique row_id's I have and iterate over these unique rows, instead of iterating over the tasks. I did this by editing the make_grid_rows() like so:

make_grid_rows() {
        let counter_rows = 0;
        const distinctRows = [...new Set(this.tasks.map(x => x.row_id))];
        for (let row of distinctRows){
            counter_rows = counter_rows + 1;
        }
        console.log(counter_rows + " unique rows")

        const rows_layer = createSVG('g', { append_to: this.layers.grid });
        const lines_layer = createSVG('g', { append_to: this.layers.grid });
        const row_width = this.dates.length * this.options.column_width;
        const row_height = this.options.bar_height + this.options.padding;

        let row_y = this.options.header_height + this.options.padding / 2;
        //var counter = 0;

        for (let row of distinctRows) {
            // console.log("for each log");
            // console.log(counter);
            // counter = counter + 1;
            // console.log(counter);
            // console.log('row id:' + task.row_id)

            createSVG('rect', {
                x: 0,
                y: row_y,
                width: row_width,
                height: row_height,
                class: 'grid-row',
                append_to: rows_layer
            });

            createSVG('line', {
                x1: 0,
                y1: row_y + row_height,
                x2: row_width,
                y2: row_y + row_height,
                class: 'row-line',
                append_to: lines_layer
            });

            row_y += this.options.bar_height + this.options.padding;
        }
    }

I hope someone finds this fix useful!

bg

Jelle

For anyone interested, if you want the total grid background to scale to the number of unique rows, add the following into the make_grid_background() in index.js (line ~310):

const distinct_rows = [...new Set(this.tasks.map(x => x.row_id))];

And then grid_height needs to be dependent on the length of distinct_rows instead of this.tasks

const grid_height =
            this.options.header_height +
            this.options.padding +
            (this.options.bar_height + this.options.padding) *
                distinct_rows.length;

Full make_grid_background() function:

make_grid_background() {
        const grid_width = this.dates.length * this.options.column_width;
        // check distinct rows so the grid height isn't relative to the total tasks
        const distinct_rows = [...new Set(this.tasks.map(x => x.row_id))];
        const grid_height =
            this.options.header_height +
            this.options.padding +
            (this.options.bar_height + this.options.padding) *
                distinct_rows.length;

        createSVG('rect', {
            x: 0,
            y: 0,
            width: grid_width,
            height: grid_height,
            class: 'grid-background',
            append_to: this.layers.grid,
        });

        $.attr(this.$svg, {
            // +XX is required so info is shown correctly - 50 seems like a good middle ground
            height: grid_height + this.options.padding + 50, 
            width: '100%',
        });
    }

tallvincent avatar Jun 22 '23 04:06 tallvincent