For showing tooltips on Gantt Charts, just go to "Gantt Chart > Attributes > Tooltip" and select "Yes" for "Show" option. However, this will show standard tooltip and there is no option for customization. In APEX ver. 20.1, there are few more granular options to control on data we want to display in the tooltip. However, still we need to choose from existing options.
Luckily, we can implement custom tooltips in relatively easy way.
If you are new to Gantt charts, I recommend you to read Few tips on Gantt Charts blogpost first.
Gantt Chart Options
First, we need to specify JavaScript function name, which will return a tooltip element, in the Gantt chart options. In below code "showCustomTooltip" is JavaScript function which return the tooltip element.
function (options)
{
options.tooltip = {"renderer":showCustomTooltip};
// with older APEX (JET) versions use below code
// options.tooltip = showCustomTooltip;
return options;
}
We need to keep this code in "Gantt Chart > Attributes > Advanced > JavaScript Initialization Code" section. Now, whenever we hover mouse on any task bar, then this JS function will be invoked.
"dataContext" Object
By default, "dataContext" object is passed as input parameter for the tooltip function. Using this object, we can access current task data and as-well as current row data. For e.g. if we put below code as function definition for "showCustomTooltip" function,
function showCustomTooltip(dataContext)
{
var taskData = dataContext.data
,rowData = dataContext.rowData;
console.log(dataContext.data);
console.log(dataContext.rowData);
return "Custom Tooltip Test";
}
and then, if we hover mouse on any task, then we will see below output (something similar based on the Gantt chart) in browser console log.
Output for "console.log(dataContext.data);"
end: "2020-06-17T23:59:00"
id: "TK1"
label: "Employee 1 Task"
labelPosition: "none"
start: "2020-06-13T00:00:00"
svgClassName: " "
Output for "console.log(dataContext.rowData);"
id: "EMP1"
label: "employee1@xyz.com"
tasks: [<emp1-task-1>,<emp2-task-2>..]
I also suggest, to try "console.log(dataContext);" and observe all the information available for the tooptip function, especially "dataContext.parentElement" object.
Gantt Chart Series SQL Query
As explained above, "dataContext" Object gives us some information about current task and current row. However, if we want to pass additional information to tooltip function, then we can use "task_name" column (column selected at "Gantt Chart > Series > Column Mapping > Task Name").
For the current example, my query is something like this..
SELECT
'TK' || task.task_id task_id
,'EMP' || emp.emp_id parent_task_id
,emp.email_address email_address
/* all the data required for tooltip function is stuffed into JSON object */
,'{ '
|| '"task_name": "'||apex_escape.json(task.task_name)||'"'
|| ',"task_type": "'||apex_escape.json(task.task_type)||'"'
|| ',"start_date": "'||apex_escape.json(TO_CHAR(task.start_date,'Dy, DD-Mon-YYYY'))||'"'
|| ',"end_date": "'||apex_escape.json(TO_CHAR(task.end_date,'Dy, DD-Mon-YYYY'))||'"'
||'}' task_name
,task.start_date start_date
,task.end_date + 1 - 1 / 1440 end_date
,task.task_type
,CASE
WHEN task.task_type = 'LEAVE' THEN
'demo-f-orange'
END || ' '
|| CASE WHEN task.billable_flag = 'N' THEN 'demo-b-red' ELSE NULL END css_class
FROM emp
JOIN blog_gantt_tasks_v task ON task.email_address = emp.email_address
Observe "task_name" column code. Here, we are preparing a JSON object, with all the data that is required in the tooltip function. "task_name" column data is passed as "label" for "dataContext.data" object. i.e. we can access task_name data using "dataContext.data.label" syntax in the tooltip function. If we don't need any additional data in the tooltip function, then we can just use "task.task_name task_name" for task_name column.
Define Template
Next, let's define a HTML template, which we can use to show the tooltip. In this case, I am using a simple HTML table and I am also using template tag to define the template.
<template id="tooltip-template">
<div id="tooltip-main">
<table>
<tr id="emp-name"><th align="center" colspan="2"></th></tr>
<tr id="task-name"><th align="right">Task Name</th><td></td></tr>
<tr id="task-type"><th align="right">Task Type</th><td></td></tr>
<tr id="start-date"><th align="right">Start Date</th><td></td></tr>
<tr id="end-date"><th align="right">End Date</th><td></td></tr>
</table>
</div>
</template>
We can put above template code in "Page > Header and Footer > Footer Text" section.
There is another approach where we don't need to define template and we can dynamically create tooltip template using "document.createElement" JavaScript function. We can observe this approach in JET documentation example.
Tooltip Function
Here is the tooltip function "showCustomTooltip" code. For explanation, please go through the inline comments.
function showCustomTooltip(dataContext)
{
// get task and row data from dataContext object
var taskData = dataContext.data
,rowData = dataContext.rowData;
// we are passing custom data required for tooltip as taskData.label and in JSON format
// convert label text to JSON object
var taskDataCustom = JSON.parse(taskData.label);
// get the template element defined in HTML footer section
var tooltipTemp = document.getElementById("tooltip-template");
// clone it to make a copy. don't modify tooltipTemp object as it will impact the template defined in HTML footer section.
var clon = tooltipTemp.content.cloneNode(true);
// add data to the cloned template
// observe, we are reading custom data we have passed as JSON object, in series SQL query (column task_name)
// and using that data to fill tooptip template
$("tr#emp-name > th",clon).html(rowData.label);
$("tr#task-name > td",clon).html(taskDataCustom.task_name);
$("tr#task-type > td",clon).html(taskDataCustom.task_type);
$("tr#start-date > td",clon).html(taskDataCustom.start_date);
$("tr#end-date > td",clon).html(taskDataCustom.end_date);
// finally return the cloned template filled with task data
return clon;
}
Note: In 20.1, there is new option "Custom Tooltip" under "Gantt Chart > Series > Column Mapping". This looks like what exactly we need, however, I was not able to get this working.
Here is the demo link
Thank you.
Comments
Thanks in advance,
Peter
I have not worked with Gantt chart with dependencies. Regarding handling two data sources for plug-in, that's an interesting question. I suggest you to post it in APEX Forums or in Twitter with #orclapex and #orclapexworld hashtags. I am sure someone might have handled this case already for any other region type plug-in.
Thank you.
thanks again!
Peter
I realy love your examples, very interrested in building someting like this task-schedule.
But as a almost complete newbie to APEX development is there any easy step-by-step tutorial or dokumentation on how to create the gantt and tables/views needed from scratch?
Best regards
/Pertti
Have you checked below blogpost?
https://srihariravva.blogspot.com/2019/12/few-tips-on-gantt-charts.html
If you are stuck at any specific step, please let me know. I can try to share more info.
Regards,
Hari
Thanks for the reply.
Yes, I have read all your posts on the matter but I'm still struggling to get it right.
I managed to get it halfway there but the "users" have one row per task in the gantt chart instread of all on the same row as the username.
Would it be possible for you to post the tables/views and queries used in your example?
Thanks in advance!
Regards
/Pertti
I have added "Download" button to below demo page. Please use this button to download APEX application with Gantt chart example.
https://apex.oracle.com/pls/apex/hari/r/demo_app/gantt-chart-tips
Regards,
Hari
Yes, that made it a lot easier for me to get grips on things.
Very helpful, thanks!
Would it be possible to get Download links to the other demos as well?
There's still stuff that I'd like to learn from your examples.
Thanks in advance.
Regards
/Pertti
Yes, I will do it and that's in my roadmap. But, I need to get time for this as I have other priorities at the moment.
Mean while if you have any specific questions, post in respective blog post or alternatively you can post your questions in APEX Forum.
Regards,
Hari