Display subtasks on project task

I’m trying to find a way to display some information about subtasks on a higher level task bar. For example, shade segments of the higher level task bar in different colors, or add small carets on the top of the task bar, to denote the subtasks beneath it.

I don’t have a rigid expectation of how this must look, which is why I am being a bit vague. In general, it should be possible to glance at the progress on a higher level task bar and see that it is past, for example, subtask 2/5 without having to expand the task in the grid. Is anything like this possible?

Hi,
you can redefine a template function for content text/html of the task object.
The template can return pretty any html string. So inside of the function you can inspect if task have subtask elements and generate appropriate html if necessary

Here is related docs:
docs.dhtmlx.com/gantt/api__gantt … plate.html
docs.dhtmlx.com/gantt/api__gantt … ldren.html

And example:
docs.dhtmlx.com/gantt/samples/04 … ntent.html

Ah, excellent. Thank you.

I came up with this:

function task_text(start, end, task) {
	var subtasks = gantt.getChildren(task.id);
	if (subtasks.length > 0 && task.type === "batch") {
		var text = "";
		for (var i = 0; i < subtasks.length; i++) {
			var subtask = gantt.getTask(subtasks[i]);
			var duration = gantt.calculateDuration(subtask.start_date, subtask.end_date);
			var style = "width:" + (duration * 70 + (i === 0 ? -1 : 0)) + "px;display:inline-block;" + (subtask.actualized === "true" ? "background-color:rgba(0,0,0,0.2);" : "");
			text += "<div style='" + style + "'>" + subtask.text + "</div>";
		}
		return text;
	} else {
		return task.text;
	}
}

On the surface, it works ok for the “day” view, but as you can see it is extremely brittle. The real problem is calculating the width of each subtask so I can make its overlay in the parent task match. I thought I could get it using getTaskNode(subtask.id), but that doesn’t seem to be available from this callback, probably because it is not rendered yet.

Is there a better solution?

Hi,
you can calculate width of the subtask right from dates

[code]var x_start = gantt.posFromDate(subtask.start_date),
x_end = gantt.posFromDate(subtask.end_date);

var width = x_end - x_start;
[/code]
In case subtasks can be parallel (meaning they can happen in a same time), probably you’ll need to use absolute positioning and manage overlapping somehow

CSS:.subtask_item{ position: absolute; height:100%; background-color:rgba(0,0,0,0.2); }
JS:

[code]gantt.attachEvent(“onTemplatesReady”, function(){
gantt.templates.task_text = function task_text(start, end, task) {
var subtasks = gantt.getChildren(task.id);

	var x_root = gantt.posFromDate(task.start_date);
	if (subtasks.length > 0 && task.type == gantt.config.types.project ) {
		var text = "";
		for (var i = 0; i < subtasks.length; i++) {
			var subtask = gantt.getTask(subtasks[i]);

			var x_start = gantt.posFromDate(subtask.start_date),
					x_end = gantt.posFromDate(subtask.end_date);

			var width = x_end - x_start;
			var style = "left:" + (x_start - x_root) + "px;width:" + (width) + "px;";
			text += "<div class='subtask_item' style='" + style + "'>" + subtask.text + "</div>";
		}
		return text;
	} else {
		return task.text;
	}
};

});[/code]
Note, I’ve removed several checks (task.type === “batch” and subtask.actualized === “true”) so I could run it in samples/01_initialization/16_projects_and_milestones.html example

Exceptional, works perfectly.

Does this work for Milestones too?

Thx

I mean, how can I see the “diamond” symbol of milestone in the Project task??

Hi,
project can contain any html, which is created explicitly in gantt.templates.task_text template.
So the milestones can be displayed the same way as any other objects, although may require a bit more CSS styling.
You can detect if subtask has a ‘milestone’ type, and generate appropriate HTML.
CSS:[code].subtask_item{
position: absolute;
height:100%;
background-color:rgba(0,0,0,0.2);
}

.gantt_task_content{
overflow: visible;
}

.subtask_milestone{
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-ms-transform: rotate(45deg);
-o-transform: rotate(45deg);
transform: rotate(45deg);

border-radius: 4px;

background-color: #d33daf;
border: 1px solid #a9328b;

width: 30px;
height: 30px;
margin-left: -15px;
position: absolute;

}[/code]
JS:[code]gantt.attachEvent(“onTemplatesReady”, function(){
gantt.templates.task_text = function task_text(start, end, task) {
var subtasks = gantt.getChildren(task.id);

	var x_root = gantt.posFromDate(task.start_date);
	if (subtasks.length > 0 && task.type == gantt.config.types.project ) {
		var text = "";
		for (var i = 0; i < subtasks.length; i++) {
			var subtask = gantt.getTask(subtasks[i]);

			var x_start = gantt.posFromDate(subtask.start_date),
					x_end = gantt.posFromDate(subtask.end_date);

			var width = x_end - x_start;
			var style = "left:" + (x_start - x_root) + "px;width:" + (width) + "px;";
			if(subtask.type == gantt.config.types.milestone){
				text += "<div class='subtask_milestone' style='left:" + (x_start - x_root) + "px;' title='"+subtask.text+"'></div>";
			}else{
				text += "<div class='subtask_item' style='" + style + "'>" + subtask.text + "</div>";
			}

		}
		return text;
	} else {
		return task.text;
	}
};

});[/code]