Index of a subtask
Index of a subtask
How I can get the index of a subtask in a gantt chart when I click left button of the mouse.
Now I can get the index of the main task from the CategoryItemEntity but I can't know which is the subtask I clicked.
Thanks.
Now I can get the index of the main task from the CategoryItemEntity but I can't know which is the subtask I clicked.
Thanks.
The source code
EntityCollection entities = chart.getChartRenderingInfo().getEntityCollection();
Insets insets = getInsets();
int x = (int) ((e.getTrigger().getX() - insets.left) / chart.getScaleX());
int y = (int) ((e.getTrigger().getY() - insets.top) / chart.getScaleY());
entity = entities.getEntity(x, y);
CategoryPlot plot = chart.getChart().getCategoryPlot();
GanttCategoryDataset dataset = (GanttCategoryDataset)plot.getDataset();
TaskSeriesCollection taskseries = (TaskSeriesCollection)plot.getDataset();
List list = taskseries.getRowKeys();
TaskSeries taskserie = (TaskSeries)list.get(0);
List tasks = taskserie.getTasks();
Task task = (Task)tasks.get(((CategoryItemEntity)entity).getCategoryIndex());
if( task.getSubtaskCount() == 0 )
{
task.setPercentComplete(0.0);
taskseries.remove(taskserie);
taskseries.add(taskserie);
}else
{
Task subTask = task.getSubtask( ??? );
subTask.setPercentComplete(0.0);
taskseries.remove(taskserie);
taskseries.add(taskserie);
}
Insets insets = getInsets();
int x = (int) ((e.getTrigger().getX() - insets.left) / chart.getScaleX());
int y = (int) ((e.getTrigger().getY() - insets.top) / chart.getScaleY());
entity = entities.getEntity(x, y);
CategoryPlot plot = chart.getChart().getCategoryPlot();
GanttCategoryDataset dataset = (GanttCategoryDataset)plot.getDataset();
TaskSeriesCollection taskseries = (TaskSeriesCollection)plot.getDataset();
List list = taskseries.getRowKeys();
TaskSeries taskserie = (TaskSeries)list.get(0);
List tasks = taskserie.getTasks();
Task task = (Task)tasks.get(((CategoryItemEntity)entity).getCategoryIndex());
if( task.getSubtaskCount() == 0 )
{
task.setPercentComplete(0.0);
taskseries.remove(taskserie);
taskseries.add(taskserie);
}else
{
Task subTask = task.getSubtask( ??? );
subTask.setPercentComplete(0.0);
taskseries.remove(taskserie);
taskseries.add(taskserie);
}
Code: Select all
I want this too
I am dying to know the answer to this also... Does anyone know?? I need to display tooltips of individual subtasks, but right now my program just gives me the time that the overall task takes place in, which is useless to me.
balh
I am already extending the IntervalCategoryToolTipGenerator and setting it in setBaseToolTipGenerator...
My code for the extension is this:
My problem here is that the time is being displayed as the time for the full task. I do not know how to get the value for the particular subtask for which the mouse is hovering over. If anyone knows how to do this that would be most appreciated.
My code for the extension is this:
Code: Select all
private class CustomToolTipGenerator extends IntervalCategoryToolTipGenerator {
public CustomToolTipGenerator() {
super();
}
@Override
protected Object[] createItemArray(CategoryDataset dataset, int row, int column) {
/**
* Creates the array of items that can be passed to the
* <code>MessageFormat</code> class for creating labels.
*
* @param dataset the dataset (<code>null</code> not permitted).
* @param row the row index (zero-based).
* @param column the column index (zero-based).
*
* @return The items (never <code>null</code>).
*/
GregorianCalendar cal = new GregorianCalendar();
Object[] result = new Object[5];
result[0] = dataset.getRowKey(row).toString();
result[1] = dataset.getColumnKey(column).toString();
Number value = dataset.getValue(row, column);
cal.setTimeInMillis(value.longValue());
result[2] = cal.getTime();
if (dataset instanceof IntervalCategoryDataset) {
IntervalCategoryDataset icd = (IntervalCategoryDataset) dataset;
TaskSeriesCollection collection = (TaskSeriesCollection) icd;
Number start = collection.getStartValue(row, column);
Number end = collection.getEndValue(row, column);
cal.setTimeInMillis(start.longValue());
result[3] = cal.getTime();
cal.setTimeInMillis(end.longValue());
result[4] = cal.getTime();
}
return result;
}
}
-
- JFreeChart Project Leader
- Posts: 11734
- Joined: Fri Mar 14, 2003 10:29 am
- antibot: No, of course not.
- Contact:
Getting this to work will require some special case code in the drawTasks() method in the GanttRenderer. Near the end of that method, you'll see that the tool tip generator is used to create a tool tip for the subtask, but it never sees the sub task index (so the same tool tip is generated for all subtasks). Here you could check for a special class of tool tip generator, and if it is found call a special method for generating the tooltip (one that accepts the subtask index as an argument). It would probably be worth also creating a new subclass of the CategoryItemEntity class to record the subtask index in the entity also.
The above would be a bit of an ugly hack, but probably in keeping with the rest of the Gantt chart code.
The above would be a bit of an ugly hack, but probably in keeping with the rest of the Gantt chart code.

David Gilbert
JFreeChart Project Leader
Read my blog
Support JFree via the Github sponsorship program
JFreeChart Project Leader


fixed
Thanks for the reply David, that really helped!
I have the Gantt chart now working with subtask tooltips. I have yet to implement the new subclass of CategoryItemEntity but that also does sound like a good idea. What I did was just overload all the methods that are required to make a tool tip in a Gantt chart. You can edit the code and make your own jars..but for now I am just extending everything and writing custom private classes. So, here is the code to do this if you want your subtasks to display appropriate tool tips.:
First, I changed this part in the drawTasks() method in the GanttRenderer:
(This is at the very bottom of the drawTasks() method.)
The only change in the above is to pass the subinterval into generateToolTip() and also to cast getToolTipGenerator to CustomToolTipGenerator.
So now we are calling generateToolTip, but this overloaded method doesn't exist yet, so I created it in my CustomToolTipGenerator class, which looks like this:
This method overloads createItemArray, generateLabelString, and generateToolTip.
Hope this helps everyone!
And thanks again David, I really appreciate the help.
Craig
I have the Gantt chart now working with subtask tooltips. I have yet to implement the new subclass of CategoryItemEntity but that also does sound like a good idea. What I did was just overload all the methods that are required to make a tool tip in a Gantt chart. You can edit the code and make your own jars..but for now I am just extending everything and writing custom private classes. So, here is the code to do this if you want your subtasks to display appropriate tool tips.:
First, I changed this part in the drawTasks() method in the GanttRenderer:
Code: Select all
// collect entity and tool tip information...
if (state.getInfo() != null) {
EntityCollection entities
= state.getInfo().getOwner().getEntityCollection();
if (entities != null) {
String tip = null;
if (getToolTipGenerator(row, column) != null) {
tip = ((CustomToolTipGenerator)getToolTipGenerator(row, column)).generateToolTip(
dataset, row, column, subinterval
);
}
String url = null;
if (getItemURLGenerator(row, column) != null) {
url = getItemURLGenerator(row, column).generateURL(
dataset, row, column
);
}
CategoryItemEntity entity = new CategoryItemEntity(
bar, tip, url, dataset, row,
dataset.getColumnKey(column), column
);
entities.add(entity);
}
}
The only change in the above is to pass the subinterval into generateToolTip() and also to cast getToolTipGenerator to CustomToolTipGenerator.
So now we are calling generateToolTip, but this overloaded method doesn't exist yet, so I created it in my CustomToolTipGenerator class, which looks like this:
Code: Select all
private class CustomToolTipGenerator extends IntervalCategoryToolTipGenerator {
public CustomToolTipGenerator() {
super();
}
@Override
public String generateToolTip(CategoryDataset arg0, int arg1, int arg2) {
// TODO Auto-generated method stub
return super.generateToolTip(arg0, arg1, arg2);
}
public String generateToolTip(CategoryDataset arg0, int arg1, int arg2, int arg3) {
// TODO Auto-generated method stub
return generateLabelString(arg0, arg1, arg2, arg3);
}
/**
* Generates a for the specified item.
*
* @param dataset the dataset (<code>null</code> not permitted).
* @param row the row index (zero-based).
* @param column the column index (zero-based).
*
* @return The label (possibly <code>null</code>).
*/
protected String generateLabelString(CategoryDataset dataset,
int row, int column, int subtask) {
if (dataset == null) {
throw new IllegalArgumentException("Null 'dataset' argument.");
}
String result = null;
Object[] items = createItemArray(dataset, row, column, subtask);
result = MessageFormat.format(getLabelFormat(), items);
return result;
}
@Override
protected Object[] createItemArray(CategoryDataset dataset, int row, int column) {
/**
* Creates the array of items that can be passed to the
* <code>MessageFormat</code> class for creating labels.
*
* @param dataset the dataset (<code>null</code> not permitted).
* @param row the row index (zero-based).
* @param column the column index (zero-based).
*
* @return The items (never <code>null</code>).
*/
GregorianCalendar cal = new GregorianCalendar();
Object[] result = new Object[5];
result[0] = dataset.getRowKey(row).toString();
result[1] = dataset.getColumnKey(column).toString();
Number value = dataset.getValue(row, column);
/*if (getNumberFormat() != null) {
result[2] = getNumberFormat().format(value);
}
else if (getDateFormat() != null) {
result[2] = getDateFormat().format(value);
}*/
//result[2] = getDateFormat().format(value);
cal.setTimeInMillis(value.longValue());
result[2] = cal.getTime();
if (dataset instanceof IntervalCategoryDataset) {
IntervalCategoryDataset icd = (IntervalCategoryDataset) dataset;
TaskSeriesCollection collection = (TaskSeriesCollection) icd;
//TODO: add a mouselistener here to find out which subtask is being hovered over
//this way tool tips will be able to be displayed correctly.
Number start = collection.getStartValue(row, column, 0); //row, column, subtask
//Number start = icd.getStartValue(row, column);
Number end = collection.getEndValue(row, column, 0);
//if (getNumberFormat() != null) {
cal.setTimeInMillis(start.longValue());
result[3] = cal.getTime();
cal.setTimeInMillis(end.longValue());
result[4] = cal.getTime();
}
return result;
}
protected Object[] createItemArray(CategoryDataset dataset, int row, int column, int subtask) {
/**
* Creates the array of items that can be passed to the
* <code>MessageFormat</code> class for creating labels.
*
* @param dataset the dataset (<code>null</code> not permitted).
* @param row the row index (zero-based).
* @param column the column index (zero-based).
*
* @return The items (never <code>null</code>).
*/
GregorianCalendar cal = new GregorianCalendar();
Object[] result = new Object[5];
result[0] = dataset.getRowKey(row).toString();
result[1] = dataset.getColumnKey(column).toString();
Number value = dataset.getValue(row, column);
/*if (getNumberFormat() != null) {
result[2] = getNumberFormat().format(value);
}
else if (getDateFormat() != null) {
result[2] = getDateFormat().format(value);
}*/
//result[2] = getDateFormat().format(value);
cal.setTimeInMillis(value.longValue());
result[2] = cal.getTime();
if (dataset instanceof IntervalCategoryDataset) {
IntervalCategoryDataset icd = (IntervalCategoryDataset) dataset;
TaskSeriesCollection collection = (TaskSeriesCollection) icd;
//TODO: add a mouselistener here to find out which subtask is being hovered over
//this way tool tips will be able to be displayed correctly.
Number start = collection.getStartValue(row, column, subtask); //row, column, subtask
//Number start = icd.getStartValue(row, column);
Number end = collection.getEndValue(row, column, subtask);
//if (getNumberFormat() != null) {
cal.setTimeInMillis(start.longValue());
result[3] = cal.getTime();
cal.setTimeInMillis(end.longValue());
result[4] = cal.getTime();
}
return result;
}
}
Hope this helps everyone!
And thanks again David, I really appreciate the help.
Craig

-
- Posts: 2
- Joined: Mon Nov 14, 2005 8:30 am
still don't work
I do like this,but still don't show correctly.the sub task show the tips same as the main task.
could you give me your source compelely?
could you give me your source compelely?
Are there any plans to add this support to the next version?
Seems like this is something a lot of folks (us included) would like to have.
Hi,
I am also trying to get the index of subtask.
I need to get the index of subtask in drawTasks() method of GanttRenderer and then I need to fetch the description for that subtask.
With this code, I can fetch all the subtasks index.
List list = taskseries.getRowKeys();
TaskSeries taskserie = (TaskSeries)list.get(0);
List tasks = taskserie.getTasks();
But in the GanttRenderer, there is a for loop which draws all the subtasks with the subinterval count.
I want to know in this for loop, how can i access individual subtask's description as subinterval's index is not a subtask's index.
Depending on the subtask description, i need to set the color of the rectangle.
Please help me out to achieve this.
Thanks,
Pavani.
I am also trying to get the index of subtask.
I need to get the index of subtask in drawTasks() method of GanttRenderer and then I need to fetch the description for that subtask.
With this code, I can fetch all the subtasks index.
List list = taskseries.getRowKeys();
TaskSeries taskserie = (TaskSeries)list.get(0);
List tasks = taskserie.getTasks();
But in the GanttRenderer, there is a for loop which draws all the subtasks with the subinterval count.
I want to know in this for loop, how can i access individual subtask's description as subinterval's index is not a subtask's index.
Depending on the subtask description, i need to set the color of the rectangle.
Please help me out to achieve this.
Thanks,
Pavani.
Re: Index of a subtask
Hello,
does anybody have a solution for this problem by now? I tried out Craigs solution, but it doesn't work for me because of a Class Cast Exception when I try to cast to CustomToolTipGenerator.
And beyond that do I not know how to create an appropriate MouseListener which is mentioned in Craigs code...
I even tried many ways of Trial And Error but none could give me a way to see the desired tooltips.
I would be glad to read of someone who managed this problem
Greetings, Selene
does anybody have a solution for this problem by now? I tried out Craigs solution, but it doesn't work for me because of a Class Cast Exception when I try to cast to CustomToolTipGenerator.
And beyond that do I not know how to create an appropriate MouseListener which is mentioned in Craigs code...
I even tried many ways of Trial And Error but none could give me a way to see the desired tooltips.
I would be glad to read of someone who managed this problem

Greetings, Selene
-
- Posts: 1
- Joined: Tue Dec 20, 2011 5:24 pm
- antibot: No, of course not.
Re: Index of a subtask
Wow.. It really worked great.. Thanks for the post.. Really appreciated.. Spread the news guys.. there are a ton of people looking out a solution for this problem.. Thanks guys..