Premium support for our pure JavaScript UI components


Post by damir »

I have multiple gantt in the page and I want to set the same timeline range in the view when gantt load.

For this first of all in gantt config via prop I set the start date as oldest start date of all projects and the end date as earliest end date of all projects.

Then I also run gantt.zoomTo with this same dates and zoom level 7:

[code]gantt.zoomTo({
	startDate: projectOldestStartDate,
	endDate: projectEarliestEndDate,
	level: 7,
});[/code]

The result is not exactly as expected, since I am not even able to scroll left and right, it's like when using zoomTo start/end date the gantt timeline time span is fixed. I can only use shift prev/next but the scrollbar doesn't appears.

I see there are several others options, and I would like to know what you suggest.

I am also not sure if is correct to set via config the oldest/earliest start/end date of all projects, the same for all project, even if their start/end is different.

Attached there is also screenshot how it appears.

Screenshot 2024-03-20 144513.png
Screenshot 2024-03-20 144513.png (455.85 KiB) Viewed 377 times

Thanks


Post by alex.l »

You just set start/end date of the timeline to avoid scrolling, just set proper values to allow scroll. You can play with configs here https://bryntum.com/products/gantt/examples/advanced/
Or use infinite scroll, demo is here https://bryntum.com/products/gantt/examples/infinite-scroll/
Btw, if you want to have all instances sync during use, partner them. Here is example of how to partner components https://bryntum.com/products/gantt/examples/gantt-schedulerpro/
Try to zoom and scroll to see result.

All the best,
Alex


Post by damir »

Thank you. Will check that examples.

About partner components, I saw them, but as I understand it's allowed to partner only two gantt, right?

I have more than two, so I didn't go with partner, but sync them manually with single command bar or via events (for example the splitter).


Post by alex.l »

You can use as many as you want, just set same instance as a partner for every next one.

All the best,
Alex


Post by damir »

Wow, sound good. Thanks, will definitely try.


Post by damir »

Thanks for tip, using partner works much better everything.

I would like to know how many gantt instances potentially can work simultaneosly?

I know that it also depend on machine, but what would be a min/max for an average laptop device.

I see that it works fine with below test in your demo up to 20 gantt instances.

When I increase that it start to lag in reacting to timeline change when you do like a zoom.

Below is the code that I tested here https://bryntum.com/products/gantt/examples/gantt-schedulerpro/

It require to add below style which I edited directly via developer tools:

// Required styles
// #container {
//    overflow-y: auto;
// }

JS Code:

import { Splitter, WidgetHelper, Gantt, SchedulerPro, ProjectModel } from '../../build/gantt.module.js?474872';
import shared from '../_shared/shared.module.js?474872';

let firstGantt;

Array(10).fill().map(p => {
	return new ProjectModel({
		calendar : 'general',
		transport : { load : { url : Math.floor(Math.random() * 11) < 5 ? '../_datasets/launch-saas.json' : '../_datasets/tasks-workedhours.json' }},
		autoLoad : true,
		validateResponse : true
	})
}).forEach(project => {
	console.log('adding project', project.get('name'));
	
const gantt = new Gantt({
	project,
	tbar : [
		{ type : 'widget', html : 'Zoom:' },
		{ ref: 'zoomInButton', icon: 'b-icon-search-plus',  tooltip: 'Zoom in', onAction: () => gantt.zoomIn()},
		{ ref: 'zoomOutButton', icon: 'b-icon-search-minus', tooltip: 'Zoom out', onAction: () => gantt.zoomOut()}
	],
	resourceImageFolderPath : '../_shared/images/users/',
	appendTo                : 'container',
	features                : {
		labels : {
			left : { field  : 'name', editor : {type : 'textfield'}}
		}
	},
	viewPreset  : 'weekAndDayLetter',
	columnLines : true,
	columns : [
		{ type : 'sequence', minWidth : 50, width : 50, text : '', align : 'right', resizable : false },
		{ type : 'name', width : 280 },
		{ type : 'percent', text : '% Completed', field : 'percentDone', showValue : false, width : 160 },
		{ type : 'resourceassignment', text : 'Assigned Resources', showAvatars : true, width : 160 }
	],
	startDate : '2015-01-01',
	endDate: '2030-01-01',    
	listeners : {
		beforeCellEditStart : ({ editorContext }) => editorContext.column.field !== 'percentDone' || editorContext.record.isLeaf
	},
	autoHeight: true
});

if (!firstGantt) firstGantt = gantt;

if (firstGantt !== gantt) {
	gantt.addPartner(firstGantt);
}
});

Post by alex.l »

Hi damir,

We did not do such tests. It very depends on data and features every instance has.
We never had test cases when user need more than 2 instances in one page. Could you please describe a bit why do you need 10+ Gantt instances on one page?

All the best,
Alex


Post by mlaukkanen »

Hi,
I'm working with Damir on this one so maybe I can explain the use case further.

It started as a bit of a special use case but is quickly evolving. Basically the users want to be able to manage a program of work in a single view, so being able to see each task list and Gantt aligned one above each other and then have the ability to quickly make small changes to one or more schedules.

The idea is to limit the number of projects, as I don't see a practical use case where dozens or hundreds of projects need to be shown at once and practically speaking that is unusable anyway. But it's good to know the limits, and as Damir has mentioned it works nicely up to our expected max projects 10-20 at a time.

Regards,


Post by mats »

Thanks for your feedback, so for your use case - all is working fine now?


Post by damir »

Hi,

All seems to works much better with Partner.

Sometimes happen issue with splitter button for collapse / expand, and it seems to happen more often only on third gantt.

So for reproduce this issue is just enough to have 3 gantt in partnership.

Video of bug:
https://www.youtube.com/watch?v=9IbRw_SlLSM

Code used to reproduce bug here https://bryntum.com/products/gantt/examples/gantt-schedulerpro/:

// Required styles only for be able to scroll main container
// #container {
//    overflow-y: auto;
// }

import { Splitter, WidgetHelper, Gantt, SchedulerPro, ProjectModel } from '../../build/gantt.module.js?474872';
import shared from '../_shared/shared.module.js?474872';

let firstGantt;

Array(3).fill().map(p => {
	return new ProjectModel({
		calendar : 'general',
		transport : { load : { url : Math.floor(Math.random() * 11) < 5 ? '../_datasets/launch-saas.json' : '../_datasets/tasks-workedhours.json' }},
		autoLoad : true,
		validateResponse : true
	})
}).forEach(project => {
	console.log('adding project', project.get('name'));
	
const gantt = new Gantt({
	project,
	tbar : [
		{ type : 'widget', html : 'Zoom:' },
		{ ref: 'zoomInButton', icon: 'b-icon-search-plus',  tooltip: 'Zoom in', onAction: () => gantt.zoomIn()},
		{ ref: 'zoomOutButton', icon: 'b-icon-search-minus', tooltip: 'Zoom out', onAction: () => gantt.zoomOut()}
	],
	resourceImageFolderPath : '../_shared/images/users/',
	appendTo                : 'container',
	features                : {
		labels : {
			left : { field  : 'name', editor : {type : 'textfield'}}
		}
	},
	viewPreset  : 'weekAndDayLetter',
	columnLines : true,
	columns : [
		{ type : 'sequence', minWidth : 50, width : 50, text : '', align : 'right', resizable : false },
		{ type : 'name', width : 280 },
		{ type : 'percent', text : '% Completed', field : 'percentDone', showValue : false, width : 160 },
		{ type : 'resourceassignment', text : 'Assigned Resources', showAvatars : true, width : 160 }
	],
	startDate : '2015-01-01',
	endDate: '2030-01-01',    
	listeners : {
		beforeCellEditStart : ({ editorContext }) => editorContext.column.field !== 'percentDone' || editorContext.record.isLeaf
	},
	autoHeight: true,
});

if (!firstGantt) firstGantt = gantt;
if (firstGantt !== gantt) {
	gantt.addPartner(firstGantt);
}
});

I use similar code where the first instance is always the one that others add as partner.

To overcome the problem of too many instances in partnership, I use Intersection Observer API where I add or remove the partner depending if is intersecting (in viewport or not), something like:

new IntersectionObserver(function (entries, obs) {
	entries.forEach(function (entry) {

	// Check if the entry is in the viewport
	if (entry.isIntersecting) {
               // add partner
           } else {
               // remove partner
           }
});
});

It seems to work pretty much well, it seems that adding/removing the partner is not expensive compared to gain performance using this way.

Another problem that I encounter is with zoom to fit. Since they are partner, all are zoom to fit on the same position (same as master instance). And that make sense. However how to reset the zoom when clicking on zoom to fit? For now I do something like below but it's not really the same timeline as when page load.

masterInstance.zoomTo({
							startDate: oldestStartDate,
							endDate: earliestEndDate,
							level: defaultLevel
						});

					masterInstance.scrollToDate(oldestStartDate, {edgeOffset: 40, animate: true, highlight: true});
					

Thanks


Post Reply