Mat,
We are looking to create an interface that essentially is the interface you have created for the "Basic Gantt Chart" or "Advanced Gantt Chart", but has the UI row component you're using in the "Multiple rows per resource", in which you can add multiple "event" items in a row. We ran into some difficulties and were wondering if perhaps you already have an example like this, or perhaps something you could point us to in the way of integrating those two interfaces?
Support Forum
Hm, would you need the dependencies between tasks? If not then you should probably use the scheduler as a base. Only issue is it doesn't have tree support just yet (it's on the roadmap). The current Ext Gantt implementation is based on only one task per row. If you have a fixed/known number of items per row, you could solve it pretty easily with a few overrides of the gantt panel.
Hi Matt,mats wrote:If you have a fixed/known number of items per row, you could solve it pretty easily with a few overrides of the gantt panel.
How would you add multiple events/items on a row? I'm looking at displaying the driving route of a vehicle on the gantt chart. The chart is grouped by vehicles. When I expand a vehicle, I expect to see two rows below it:
The first row in left panel would display "Planned route" and the right panel would display the gantt chart of the planned route, e.g.: The time the vehicle reaches a stop, how long it spends at a stop and the time it leaves a stop (time intervals spent at the stops)... Each type of time intervals has a predefined colour.
The second row in the left panel would display "Actual route" and the right panel would display the gantt chart of the actual route, e.g.: The time the vehicle actually reaches a stop, how long it spends at a stop and the time it leaves a stop...
Hence, we can compare the differece between the planned and actual routes.
Appreciate your help.
Are you intending to show a baseline together with the current plan outline? Something like this? http://ext-scheduler.com/playpen/gantt- ... /dual.html
Well, basically all you do is to include another set of Start/End dates in your tasks and then adjust the task HTML template to include both. That's pretty much what's being done in the demo, and all the extra source needed is readable in full:
eventTemplate : new Ext.XTemplate(
'<div class="sch-event-wrap sch-gantt-task" style="left:{leftOffset}px;width:{width}px">',
// Task bar
'<div id="{id}" class="sch-gantt-item sch-gantt-task-bar {cls}" style="width:{width}px;{style}">',
// Left terminal
String.format(Sch.TreeGanttPanel.prototype.resizeHandleHtml, 'west'),
'<div class="sch-gantt-progress-bar" style="width:{percentDone}%"> </div>',
String.format(Sch.TreeGanttPanel.prototype.resizeHandleHtml, 'east'),
'</div>',
'</div>',
// Planned Task bar
'<tpl if="PlannedStartDate">',
'<div class="sch-event-wrap sch-gantt-task sch-planned" style="left:{plannedLeftOffset}px;width:{plannedWidth}px">',
'<div id="{id}-planned" class="sch-gantt-item sch-gantt-task-bar {cls}" style="left:{plannedLeftOffset}px;width:{plannedWidth}px;{style}">',
'</div>',
'</div>',
'</tpl>',
{
compiled: true,
disableFormats: true
}),
Ext.override(Sch.TreeGanttPanel, {
internalRenderer : function(v, m, event, row, col, ds) {
var cellResult = '',
grid = this,
viewStart = grid.getStart(),
viewEnd = grid.getEnd(),
cm = grid.getColumnModel(),
colWidth = cm.getColumnWidth(col),
colStart = grid.getColumnStart(col),
colEnd = grid.getColumnEnd(col);
// Call timeCellRenderer to be able to set css/style properties on individual grid cells
grid.timeCellRenderer.call(this, event, m, row, col, ds, colStart, colEnd, grid);
var start = event.get('StartDate'),
end = event.get('EndDate'),
startsInsideView = start.betweenLesser(colStart, colEnd);
// Determine if the event should be rendered or not
if (startsInsideView || (col == grid.nbrStaticColumns && start < colStart && end > colStart)) {
var availableTimeInColumn = Date.getDurationInMinutes(colStart, colEnd),
leftOffset = Math.floor((Date.getDurationInMinutes(colStart, startsInsideView ? start : colStart) / availableTimeInColumn) * colWidth),
// Get data from user "renderer"
eventData = grid.eventRenderer.call(this, event, row, col, ds) || {};
if (grid.isMilestone(event)) {
Ext.apply(eventData, {
// Core properties
id : grid.eventPrefix + event.id,
cls : (eventData.cls || '') + (event.dirty ? ' sch-dirty' : ''),
leftOffset : leftOffset - grid.milestoneOffset, // Remove half of the diamond width
// Gantt specific
leftLabel : event.get(grid.leftLabelField) || '',
rightLabel : event.get(grid.rightLabelField) || ''
});
cellResult += grid.milestoneTemplate.apply(eventData);
} else {
// Regular task
var itemWidth = Math.floor(grid.getXFromDate(Date.min(end, viewEnd)) - grid.getXFromDate(startsInsideView ? start : viewStart)),
endsOutsideView = end > viewEnd,
isLeaf = ds.isLeafNode(event);
if (!isLeaf) {
itemWidth += 2*grid.parentTaskOffset; // Add the down arrow width
leftOffset -= grid.parentTaskOffset; // Remove half of the down arrow width
} else {
if (event.get('PlannedStartDate')) {
eventData.plannedWidth = Math.floor(grid.getXFromDate(Date.min(event.get('PlannedEndDate'), viewEnd)) - grid.getXFromDate(Date.max(event.get('PlannedStartDate'), viewStart)));
eventData.plannedLeftOffset = Math.floor((Date.getDurationInMinutes(colStart, startsInsideView ? event.get('PlannedStartDate') : colStart) / availableTimeInColumn) * colWidth);
}
}
// Apply scheduler specific properties
Ext.apply(eventData, {
// Core properties
id : grid.eventPrefix + event.id,
cls : (eventData.cls || '') + (event.dirty ? ' sch-dirty' : '') + (endsOutsideView ? ' sch-event-endsoutside ' : '') + (startsInsideView ? '' : ' sch-event-startsoutside'),
width : Math.max(1, itemWidth - grid.eventBorderWidth),
leftOffset : leftOffset,
// Gantt specific
percentDone : event.get('PercentDone'),
leftLabel : event.get(grid.leftLabelField) || '',
rightLabel : event.get(grid.rightLabelField) || ''
});
eventData.text = eventData.text || ' ';
cellResult += grid[isLeaf ? "eventTemplate" : "parentEventTemplate"].apply(eventData);
}
}
m.css += ' sch-timetd';
// Z-index is trouble in IE, thanks Condor for this fix
if (Ext.isIE) {
m.attr = 'style="z-index:' + (grid.getColumnModel().getColumnCount() - col) + '"';
}
return cellResult;
}
});
I can't make it work. Here's an example I'm working on( I upload it to https://rapidshare.com/files/438362563/gantt_test.rar ) . When I add your code, and run and it shows empty gantt and loading icon ,then do nothing ( don't show any error in firebug ). Please help to make it work in my example.