Hi
I want the baseline to be the same like the task
(multi-line in one row).
Can I do it?
gantt.attachEvent("onTaskClosed", function(id) {
show_hidden_baseline(gantt.getTask(id));
});
function show_hidden_baseline (task) {
if (!task.$open && gantt.hasChild(task.id)) {
var sub_tasks = gantt.getChildren(task.id);
substasks = [];
for (var i = 0; i < sub_tasks.length; i++) {
var child = gantt.getTask(sub_tasks[i]);
var child_sizes = gantt.getTaskPosition(child, child.planned_start, child.planned_end);
var left_position = child_sizes.left - gantt.getTaskPosition(task).left;
var task_width = child_sizes.width;
var task_top = child_sizes.top - 12;
var task_height = child_sizes.height - 6;
current_subtask = "<span class='subtask_base' style='position: absolute; left: "+left_position+"px; height: "+task_height+"px; width: "+task_width+"px; '></span >"
substasks.push(current_subtask)
}
var baselineString = '';
for (var i = 0; i < substasks.length; i++) {
baselineString += substasks[i];
}
document.getElementById('baseline_'+task.id).innerHTML = baselineString;
}
return false;
};
I succeeded with innerHTML.
However, if you do something different, the baseline disappears.
Can’t it be frozen until I open it?
Hi @chang,
the usual approach for adding extra elements into the chart is using gantt.addTaskLayer
method.
Similarly to what is done in our baselines example, you can add additional lines into the chart:
https://docs.dhtmlx.com/gantt/samples/04_customization/15_baselines.html
If you want parent tasks to show the summary baseline for all nested tasks, it’s done the same way:
// get start/end dates of the baseline for a specific task
function getBaselineRange(task){
// use tasks own baseline dates
var range = { start_date: task.planned_start,
end_date: task.planned_end};
// but if it's closed parent task - get min/max dates of all nested baselines
if(!task.$open && gantt.hasChild(task.id)){
range.start_date = null;
range.end_date = null;
gantt.eachTask(function(child){
if(child.planned_start && child.planned_end){
if(!range.start_date || child.planned_start.valueOf() < range.start_date.valueOf()){
range.start_date = child.planned_start;
}
if(!range.end_date || child.planned_end.valueOf() > range.end_date.valueOf()){
range.end_date = child.planned_end;
}
}
}, task.id);
}else if(gantt.hasChild(task.id)){
// if it's opened parent task - do not show baseline at all
range.start_date = null;
range.end_date = null;
}
return range;
}
addTaskLayer function:
gantt.addTaskLayer({
renderer: {
render: function draw_planned(task) {
var range = getBaselineRange(task);
if (range.start_date && range.end_date) {
var sizes = gantt.getTaskPosition(task, range.start_date, range.end_date);
var el = document.createElement('div');
el.className = 'baseline';
el.style.left = sizes.left + 'px';
el.style.width = sizes.width + 'px';
el.style.top = sizes.top + gantt.config.task_height + 13 + 'px';
return el;
}
return false;
},
// define getRectangle in order to hook layer with the smart rendering
getRectangle: function(task, view){
var range = getBaselineRange(task);
if (range.start_date && range.end_date) {
return gantt.getTaskPosition(task, range.start_date, range.end_date);
}
return null;
}
}
});
Live demo: http://snippet.dhtmlx.com/5/eacb4acbd
hi:)
I want the child information to be shown in each parent, not a summary.
With the example given, can the child information be shown in one row each?
And does addTaskLayer work even if I specify multiple??
Do you mean you want to display baselines of each individual child in the parent row? I.e. not one element which goes from the start of the earliest baseline to the end of the latest baseline, but multiple individual baselines?
If you want gantt.addTaskLayer
to make multiple visible elements, you need to create one parent node, append all visible elements to that parent node and return it from the render function.
Here is the modified example:
http://snippet.dhtmlx.com/5/618f4cd89
I’ve moved code that creates absolutely positioned item into a separate function:
// adding baseline display
function renderElement(row, start, end){
// row - a task at which row the element will be displayed
// start/end - dates
var sizes = gantt.getTaskPosition(row, start, end);
var el = document.createElement('div');
el.className = 'baseline';
el.style.left = sizes.left + 'px';
el.style.width = sizes.width + 'px';
el.style.top = sizes.top + gantt.config.task_height + 13 + 'px';
return el;
}
And here is how gantt.addTaskLayer
can look after the changes:
gantt.addTaskLayer({
renderer: {
render: function draw_planned(task) {
var result = null;
if(gantt.hasChild(task.id)){
// create a node element that will be returned from the function
result = document.createElement("div");
gantt.eachTask(function(child){
if(child.planned_start && child.planned_end){
// where you need to display multiple elements - you append them to the node you've created before
// since element we create uses absolute positioning, they all will be visible
var childEl = renderElement(task, child.planned_start, child.planned_end);
result.appendChild(childEl);
}
}, task.id);
} else if (task.planned_start && task.planned_end) {
result = renderElement(task, task.planned_start, task.planned_end);
}
// return the DOM element
return result;
},
// define getRectangle in order to hook layer with the smart rendering
getRectangle: function(task, view){
return true;
var range = getBaselineRange(task);
if (range.start_date && range.end_date) {
return gantt.getTaskPosition(task, range.start_date, range.end_date);
}
return null;
}
}
});
HI!
The way I want is like a picture.
We completed the desired method using Aliaksandr’s function!
Here’s how I used it
gantt.addTaskLayer(function draw_planned(task) {
if(!task.$open && gantt.hasChild(task.id) && task.planned_start && task.planned_end){
var el = document.createElement('div');
gantt.eachTask(function(child){
if(child.planned_start && child.planned_end){
// where you need to display multiple elements - you append them to the node you've created before
// since element we create uses absolute positioning, they all will be visible
var childEl = renderElement(task, child.planned_start, child.planned_end);
el.appendChild(childEl);
}
}, task.id);
return el;
} else if (task.$open && task.planned_start && task.planned_end) {
var el = renderElement(task, task.planned_start, task.planned_end);
return el;
}
return false;
});
Thank you.