Gantt Charts: can sub-tasks be displayed at all? (v1.0 rc1)

A discussion forum for JFreeChart (a 2D chart library for the Java platform).
Locked
nsequeira
Posts: 10
Joined: Fri Apr 11, 2003 9:20 pm

Gantt Charts: can sub-tasks be displayed at all? (v1.0 rc1)

Post by nsequeira » Tue Jul 26, 2005 9:06 pm

I've been using JFreeChart for a few years, but have only recently attempted to add Gantt chart support to my app. My data could potentially consist of multiple levels of sub-tasks.

In my initial attempt, I had three TaskSeries containing tasks with sub-tasks going about three levels deep. Many tasks had had "owners", i.e. people assigned to the tasks. I added the owners as sub-tasks, each with his/her own "percent complete" value.

Sadly, my graph came out with only the top-level tasks getting displayed. I used the default ChartFactory.createGanttChart() method.

Any ideas? What's are the capabilities for rendering sub-tasks within JFreeChart? Thanks.

Here's what the chart looks like right now:

Image

-- Nathan

doofusLARGE
Posts: 11
Joined: Thu Jul 07, 2005 7:40 pm

Post by doofusLARGE » Wed Jul 27, 2005 4:23 pm

Post some code and we'll take a look. The subtask feature does work, so there must be something you're missing or doing incorrectly.

Guest

Post by Guest » Wed Jul 27, 2005 11:59 pm

Here's what my dataset looks like. This is debug output straight from the generated TaskSeriesCollection. The indented lines indicate a subtask (they go a few levels deep). Each line shows its duration and percent complete.

I did notice that some of the tasks have zero percent complete, while their subtasks have real values for percent complete. What's odd is that I for those zero percent values, I didn't explicitly set the percent complete value for those Task objects at all.

{TaskSeries 0} - Phase 1 - Overview

Installer Information transfer {11-08-2004 - 11-11-2004} 0.0%
/-----S. McCarver {11-08-2004 - 11-11-2004} 100.0%
/-----M. Carpenter {11-08-2004 - 11-11-2004} 100.0%
Information transfer SF to SF {11-08-2004 - 11-12-2004} 0.0%
/-----D. Jackson {11-08-2004 - 11-12-2004} 100.0%
/-----J. Johnson {11-08-2004 - 11-12-2004} 100.0%
/-----N. James {11-08-2004 - 11-12-2004} 100.0%
Knowledge gathered from people leaving {11-12-2004 - 11-12-2004} 0.0%
Create Builder Overiew Presentations {11-15-2004 - 11-26-2004} 0.0%
/-----Introduction {11-15-2004 - 11-16-2004} 0.0%
/-----/-----D. Jackson {11-15-2004 - 11-16-2004} 50.0%
/-----Development Environment {11-15-2004 - 11-16-2004} 0.0%
/-----/-----N. James {11-15-2004 - 11-16-2004} 75.0%
/-----The Builder {11-15-2004 - 11-22-2004} 0.0%
/-----/-----Metadata Object Model {11-15-2004 - 11-17-2004} 0.0%
/-----/-----/-----J. Johnson {11-15-2004 - 11-17-2004} 0.0%
/-----/-----JSP/Screens {11-17-2004 - 11-22-2004} 0.0%
/-----/-----/-----N. James {11-17-2004 - 11-22-2004} 100.0%
/-----Runtime {11-17-2004 - 11-22-2004} 0.0%
/-----/-----D. Jackson {11-17-2004 - 11-22-2004} 0.0%
/-----Integration {11-23-2004 - 11-26-2004} 0.0%
/-----/-----D. Jackson {11-23-2004 - 11-26-2004} 0.0%
/-----Import/Export {11-18-2004 - 11-23-2004} 0.0%
/-----/-----J. Johnson {11-18-2004 - 11-23-2004} 0.0%
QA Overview {11-15-2004 - 11-26-2004} 0.0%
/-----K. Snopes {11-15-2004 - 11-26-2004} 0.0%
Hire Offshore Tech Lead {11-08-2004 - 11-26-2004} 0.0%
/-----J. Summers {11-08-2004 - 11-26-2004} 10.0%
VAB/VAP Install/Demo/Work {11-08-2004 - 11-26-2004} 0.0%
/-----J. Astaire {11-08-2004 - 11-26-2004} 50.0%
/-----M. Carpenter {11-08-2004 - 11-26-2004} 50.0%
/-----J. Summers {11-08-2004 - 11-26-2004} 50.0%
Deliver Presentations to Team {11-29-2004 - 12-03-2004} 0.0%
/-----D. Jackson {11-29-2004 - 12-03-2004} 0.0%
/-----S. McCarver {11-29-2004 - 12-03-2004} 0.0%
/-----J. Johnson {11-29-2004 - 12-03-2004} 0.0%
/-----N. James {11-29-2004 - 12-03-2004} 0.0%
/-----J. Summers {11-29-2004 - 12-03-2004} 0.0%
/-----J. Astaire {11-29-2004 - 12-03-2004} 0.0%
/-----M. Carpenter {11-29-2004 - 12-03-2004} 0.0%
Complete Technical Overview {12-03-2004 - 12-03-2004} 0.0%


{TaskSeries 1} - Phase 2 - 7.0.1

7.0.1 Release Development Training {12-06-2004 - 02-11-2005} 0.0%
/-----7.0.1 Vicket Fixing - Pair Programming {12-06-2004 - 02-11-2005} 0.0%
/-----/-----D. Jackson {12-06-2004 - 02-11-2005} 0.0%
/-----/-----J. Astaire {12-06-2004 - 02-11-2005} 0.0%
/-----7.0.1 Vicket Fixing - Pair Programming {12-06-2004 - 02-11-2005} 0.0%
/-----/-----N. James {12-06-2004 - 02-11-2005} 0.0%
/-----/-----S. McCarver {12-06-2004 - 02-11-2005} 0.0%
/-----/-----M. Carpenter {12-06-2004 - 02-11-2005} 0.0%
/-----7.0.1 Vicket Fixing - Pair Programming {12-06-2004 - 02-11-2005} 0.0%
/-----/-----J. Johnson {12-06-2004 - 02-11-2005} 0.0%
/-----/-----J. Summers {12-06-2004 - 02-11-2005} 0.0%
7.0.1 QA {02-14-2005 - 03-04-2005} 0.0%
/-----K. Snopes {02-14-2005 - 03-04-2005} 0.0%
7.0.1 RTM {03-04-2005 - 03-04-2005} 0.0%


{TaskSeries 2} - Phase 3 - 7.1 Transition

7.1 New Feature Work Transition {03-07-2005 - 04-29-2005} 0.0%
/-----7.1 Pair Programming {03-07-2005 - 04-29-2005} 0.0%



As far as the creation of the actual chart, this was my method call (the "ganttChartDataset" variable is an instance of TaskSeriesCollection and is cast here as a GanttCategoryDataset):

ChartFactory.createGanttChart(title, null, null, ganttChartDataset, true, false, false)

That's pretty much it. Any ideas?

nsequeira
Posts: 10
Joined: Fri Apr 11, 2003 9:20 pm

Post by nsequeira » Thu Jul 28, 2005 12:01 am

Please note that the last message was from me ... somehow I wasn't logged in.

doofusLARGE
Posts: 11
Joined: Thu Jul 07, 2005 7:40 pm

Post by doofusLARGE » Thu Jul 28, 2005 2:44 pm

It would be more useful to me if you post the actual code that creates the dataset. I believe that's where the problem can be found,

nsequeira
Posts: 10
Joined: Fri Apr 11, 2003 9:20 pm

Post by nsequeira » Thu Jul 28, 2005 11:14 pm

Ok. I've changed this post (and my code) to simply build the dataset manually. It's all hard-coded, and I'm still not seeing the sub-tasks in the rendered chart.

Here's the code creating the dataset:

Code: Select all

GanttCategoryDataset getFakeData() {
    TaskSeriesCollection dataset = new TaskSeriesCollection();

    TaskSeries ts1 = new TaskSeries("Phase 1 - Overview");

    Task t1 = new Task("Installer Information transfer",date(11,8,2004),date(11,11,2004));
    t1.setPercentComplete(0);
        Task t2 = new Task("S. McCarver",date(11,8,2004),date(11,11,2004));
        t2.setPercentComplete(100);
        Task t3 = new Task("M. Carpenter",date(11,8,2004),date(11,11,2004));
        t3.setPercentComplete(100);
    t1.addSubtask(t2);
    t1.addSubtask(t3);

    Task t4 = new Task("Information transfer SF to SF", date(11,8,2004), date(11,12,2004));
    t4.setPercentComplete(0);
        Task t5 = new Task("D. Jackson", date(11,8,2004), date(11,12,2004));
        t5.setPercentComplete(100.0);
        Task t6 = new Task("J. Johnson", date(11,8,2004), date(11,12,2004));
        t6.setPercentComplete(100.0);
        Task t7 = new Task("N. James", date(11,8,2004), date(11,12,2004));
    t7.setPercentComplete(100.0);
    t4.addSubtask(t5);
    t4.addSubtask(t6);
    t4.addSubtask(t7);

    Task t8 = new Task("Knowledge gathered from people leaving", date(11,12,2004), date(11,12,2004));
    t8.setPercentComplete(0.0);
    Task t9 = new Task("Create Builder Overiew Presentations", date(11,15,2004), date(11,26,2004));
    t9.setPercentComplete(0.0);
        Task t10 = new Task("Introduction", date(11,15,2004), date(11,16,2004));
        t10.setPercentComplete(0.0);
            Task t11 = new Task("D. Jackson", date(11,15,2004), date(11,16,2004));
            t11.setPercentComplete(50.0);

        t10.addSubtask(t11);

        Task t12 = new Task("Development Environment", date(11,15,2004), date(11,16,2004));
        t12.setPercentComplete(0.0);
            Task t13 = new Task("N. James", date(11,15,2004), date(11,16,2004));
            t13.setPercentComplete(75.0);
        t12.addSubtask(t13);

        Task t14 = new Task("The Builder", date(11,15,2004), date(11,22,2004));
        t14.setPercentComplete(0.0);
            Task t15 = new Task("Metadata Object Model", date(11,15,2004), date(11,17,2004));
            t15.setPercentComplete(0.0);
                Task t16 = new Task("J. Johnson", date(11,15,2004), date(11,17,2004));
                t16.setPercentComplete(0.0);
            t15.addSubtask(t16);

            Task t17 = new Task("JSP/Screens", date(11,17,2004), date(11,22,2004));
            t17.setPercentComplete(0.0);
                Task t18 = new Task("N. James", date(11,17,2004), date(11,22,2004));
                t18.setPercentComplete(100.0);
            t17.addSubtask(t18);
        t14.addSubtask(t15);
        t14.addSubtask(t17);

        Task t19 = new Task("Runtime", date(11,17,2004), date(11,22,2004));
        t19.setPercentComplete(0.0);
            Task t20 = new Task("D. Jackson", date(11,17,2004), date(11,22,2004));
            t20.setPercentComplete(0.0);
        t19.addSubtask(t20);
        Task t21 = new Task("Integration", date(11,23,2004), date(11,26,2004));
        t21.setPercentComplete(0.0);
            Task t22 = new Task("D. Jackson", date(11,23,2004), date(11,26,2004));
            t22.setPercentComplete(0.0);
        t21.addSubtask(t22);
        Task t23 = new Task("Import/Export", date(11,18,2004), date(11,23,2004));
        t23.setPercentComplete(0.0);
            Task t24 = new Task("J. Johnson", date(11,18,2004), date(11,23,2004));
            t24.setPercentComplete(0.0);
        t23.addSubtask(t24);
    t9.addSubtask(t10);
    t9.addSubtask(t12);
    t9.addSubtask(t14);
    t9.addSubtask(t19);
    t9.addSubtask(t21);
    t9.addSubtask(t23);

    Task t25 = new Task("QA Overview", date(11,15,2004), date(11,26,2004));
    t25.setPercentComplete(0.0);
        Task t26 = new Task("K. Snopes", date(11,15,2004), date(11,26,2004));
        t26.setPercentComplete(0.0);
    t25.addSubtask(t26);
    Task t27 = new Task("Hire Offshore Tech Lead", date(11,8,2004), date(11,26,2004));
    t27.setPercentComplete(0.0);
        Task t28 = new Task("J. Summers", date(11,8,2004), date(11,26,2004));
        t28.setPercentComplete(10.0);
    t27.addSubtask(t28);
    Task t29 = new Task("VAB/VAP Install/Demo/Work", date(11,8,2004), date(11,26,2004));
    t29.setPercentComplete(0.0);
        Task t30 = new Task("J. Astaire", date(11,8,2004), date(11,26,2004));
        t30.setPercentComplete(50.0);
        Task t31 = new Task("M. Carpenter", date(11,8,2004), date(11,26,2004));
        t31.setPercentComplete(50.0);
        Task t32 = new Task("J. Summers", date(11,8,2004), date(11,26,2004));
        t32.setPercentComplete(50.0);
    t29.addSubtask(t30);
    t29.addSubtask(t31);
    t29.addSubtask(t32);
    Task t33 = new Task("Deliver Presentations to Team", date(11,29,2004), date(12,03,2004));
    t33.setPercentComplete(0.0);
        Task t34 = new Task("D. Jackson", date(11,29,2004), date(12,03,2004));
        t34.setPercentComplete(0.0);
        Task t35 = new Task("S. McCarver", date(11,29,2004), date(12,03,2004));
        t35.setPercentComplete(0.0);
        Task t36 = new Task("J. Johnson", date(11,29,2004), date(12,03,2004));
        t36.setPercentComplete(0.0);
        Task t37 = new Task("N. James", date(11,29,2004), date(12,03,2004));
        t37.setPercentComplete(0.0);
        Task t38 = new Task("J. Summers", date(11,29,2004), date(12,03,2004));
        t38.setPercentComplete(0.0);
        Task t39 = new Task("J. Astaire", date(11,29,2004), date(12,03,2004));
        t39.setPercentComplete(0.0);
        Task t40 = new Task("M. Carpenter", date(11,29,2004), date(12,03,2004));
        t40.setPercentComplete(0.0);
    t33.addSubtask(t34);
    t33.addSubtask(t35);
    t33.addSubtask(t36);
    t33.addSubtask(t37);
    t33.addSubtask(t38);
    t33.addSubtask(t39);
    t33.addSubtask(t40);
    Task t41 = new Task("Complete Technical Overview", date(12,03,2004), date(12,03,2004));
    t41.setPercentComplete(0.0);

    ts1.add(t1);
    ts1.add(t4);
    ts1.add(t8);
    ts1.add(t9);
    ts1.add(t25);
    ts1.add(t27);
    ts1.add(t29);
    ts1.add(t33);
    ts1.add(t41);

    TaskSeries ts2 = new TaskSeries("Phase 2 - 7.0.1");

    Task t42 = new Task("7.0.1 Release Development Training", date(12,06,2004), date(02,11,2005));
    t42.setPercentComplete(0.0);
        Task t43 = new Task("7.0.1 Vicket Fixing - Pair Programming", date(12,06,2004), date(02,11,2005));
        t43.setPercentComplete(0.0);
            Task t44 = new Task("D. Jackson", date(12,06,2004), date(02,11,2005));
            t44.setPercentComplete(0.0);
            Task t45 = new Task("J. Astaire", date(12,06,2004), date(02,11,2005));
            t45.setPercentComplete(0.0);
        t43.addSubtask(t44);
        t43.addSubtask(t45);
        Task t46 = new Task("7.0.1 Vicket Fixing - Pair Programming", date(12,06,2004), date(02,11,2005));
        t46.setPercentComplete(0.0);
            Task t47 = new Task("N. James", date(12,06,2004), date(02,11,2005));
            t47.setPercentComplete(0.0);
            Task t48 = new Task("S. McCarver", date(12,06,2004), date(02,11,2005));
            t48.setPercentComplete(0.0);
            Task t49 = new Task("M. Carpenter", date(12,06,2004), date(02,11,2005));
            t49.setPercentComplete(0.0);
        t46.addSubtask(t47);
        t46.addSubtask(t48);
        t46.addSubtask(t49);
        Task t50 = new Task("7.0.1 Vicket Fixing - Pair Programming", date(12,06,2004), date(02,11,2005));
        t50.setPercentComplete(0.0);
            Task t51 = new Task("J. Johnson", date(12,06,2004), date(02,11,2005));
            t51.setPercentComplete(0.0);
            Task t52 = new Task("J. Summers", date(12,06,2004), date(02,11,2005));
            t52.setPercentComplete(0.0);
        t50.addSubtask(t51);
        t50.addSubtask(t52);
    t42.addSubtask(t43);
    t42.addSubtask(t46);
    t42.addSubtask(t50);
    Task t53 = new Task("7.0.1 QA", date(02,14,2005), date(03,04,2005));
    t53.setPercentComplete(0.0);
        Task t54 = new Task("K. Snopes", date(02,14,2005), date(03,04,2005));
        t54.setPercentComplete(0.0);
    t53.addSubtask(t54);
    Task t55 = new Task("7.0.1 RTM", date(03,04,2005), date(03,04,2005));
    t55.setPercentComplete(0.0);

    ts2.add(t42);
    ts2.add(t53);
    ts2.add(t55);


    TaskSeries ts3 = new TaskSeries("Phase 3 - 7.1 Transition");

    Task t56 = new Task("7.1 New Feature Work Transition", date(03,07,2005), date(04,29,2005));
    t56.setPercentComplete(0.0);
        Task t57 = new Task("7.1 Pair Programming", date(03,07,2005), date(04,29,2005));
        t57.setPercentComplete(0.0);
    t56.addSubtask(t57);

    ts3.add(t56);

    dataset.add(ts1);
    dataset.add(ts2);
    dataset.add(ts3);

    return dataset;
}

/**
 * Utility method for creating <code>Date</code> objects.
 *
 * @param day  the date.
 * @param month  the month.
 * @param year  the year.
 *
 * @return A date.
 */
private static Date date(int month, int day, int year) {

    Calendar calendar = Calendar.getInstance();
    calendar.set(year, month, day);
    final Date result = calendar.getTime();
    return result;

}

Here's the code I use to create the chart:

Code: Select all

GanttCategoryDataset ganttChartDataset = getFakeData();
JFreeChart chart = ChartFactory.createGanttChart("project chart", null, null, ganttChartDataset, true, false, false);
I'm completely stumped. What am I doing wrong? Where are my sub-tasks?
Last edited by nsequeira on Tue Aug 02, 2005 12:52 am, edited 5 times in total.

nsequeira
Posts: 10
Joined: Fri Apr 11, 2003 9:20 pm

Post by nsequeira » Mon Aug 01, 2005 8:39 pm

Sorry to bump this up again, but we are making a decision regarding the use of Gantt charts in our product in the next day or two, so I need to know if this is viable. I've simplified my code to just create the dataset manually without any dynamic logic (and I modified my last post to reflect that change). However, my sub-tasks are still missing from the chart. It looks almost identical to the last chart (see my first post), although it appears that a few of the tasks get rendered a little differently. Also, my legend is missing for some reason.

Image

Any ideas?

BigWillyStyle42
Posts: 58
Joined: Wed Jun 02, 2004 1:37 pm

Post by BigWillyStyle42 » Tue Aug 02, 2005 1:56 am

I don't think you've quite understood what the GanttCharts that are produced are supposed to look like. Adding subtasks allows you to make a task stop and start multiple times instead of going straight from say 1pm to 6pm you could have it go from 1pm to 3pm then again from 3:30pm to 6pm.

I've only recently started messing around with GanttCharts but I don't believe you're going to be able to accomplish what you're trying to do without heavily modifying some JFreeChart code. What might be helpful for us was if you could draw a picture of what you'd like the chart to look like in paint or something and then post that somewhere so we could take a look.

Here is an example of a Gantt chart with subtasks:

Image

nsequeira
Posts: 10
Joined: Fri Apr 11, 2003 9:20 pm

Post by nsequeira » Tue Aug 02, 2005 7:40 pm

Well, my idea of Gantt charts came from Microsoft Project, where sub-tasks are graphically rendered along with the parent tasks. Here's an example:

Image

I'm not expecting all of these features to exist in JFreeChart (vertical lines, etc.), but I was hoping that the sub-tasks would at least appear.

nsequeira
Posts: 10
Joined: Fri Apr 11, 2003 9:20 pm

Post by nsequeira » Wed Aug 03, 2005 12:38 am

Well, it turns out I had a misconception of what a "TaskSeries" object represents. Now I understand that, for every task, you can have multiple rendered durations -- each represented by an entry in a different TaskSeries (using the same task name with a different duration). Somehow I missed that part.

Now I've reorganized my data to use only one task series, and I have a chart with three primary tasks, broken up into several levels of sub-tasks. The sample data is the same as entered in my previous posts (the three top-level tasks are "Phase 1 - Overview", "Phase 2 - 7.0.1", and "Phase 3 - 7.1 Transition").

The result is the chart below.

Image

Clearly not that useful. Any more ideas?

mister snaggs

Post by mister snaggs » Wed Jan 11, 2006 3:08 pm

I've recently come across the same problem, but managed to diagnose the problem, after several hours of pain.

It turns out that a task that contains any subtasks must have a start and end time that encompasses the start/end times of all of its subtasks.

I just glanced over your sample code and you seem to already be doing this, so this may not help you.

Anyway, I hope this helps someone.[/img]

Locked