Opened 11 years ago

Closed 10 years ago

# Group tickets with milestones

Reported by: Owned by: Ryan J Ollos Chris Nelson high TracJsGanttPlugin normal falkb 0.11

### Description

Is there a way to group tickets under milestones? In the example below, #1, #2 and #3 would be grouped under milestone1. #4 and #5 would be grouped under milestone2.

### comment:1 follow-up:  2 Changed 11 years ago by Chris Nelson

Status: new → assigned

We've done some work locally to sort tasks more logically. I hope to push it to TH soon. It may not be exactly what you're talking about but it sure looks better to us.

### comment:2 in reply to:  1 ; follow-up:  3 Changed 11 years ago by Ryan J Ollos

We've done some work locally to sort tasks more logically. I hope to push it to TH soon. It may not be exactly what you're talking about but it sure looks better to us.

I've been hacking at the code a little bit and sort of had this working. It was easy enough to add an option to make all tickets children of their milestone. This alone causes them to be grouped in the chart under the milestone, but the milestones aren't collapsible. Assigning the milestone as the top-level parent of tickets is a bit more difficult and requires pretty extensive changes because of the way that the logic in the code uses the specification of parent in trac.ini.

Maybe I can send you a patch before the weekend for some feedback? It would be great to get some advice on how to implement this.

I'm comfortable working with Python, but not Javascript. Another option that I'd like to add, which probably requires code modifications in Javascript, is to have a macro argument that allow the parents to be specified as collapsed when the page is loaded.

### comment:3 in reply to:  2 ; follow-up:  4 Changed 11 years ago by Chris Nelson

We've done some work locally to sort tasks more logically. I hope to push it to TH soon. It may not be exactly what you're talking about but it sure looks better to us.

I've been hacking at the code a little bit and sort of had this working. It was easy enough to add an option to make all tickets children of their milestone. This alone causes them to be grouped in the chart under the milestone, but the milestones aren't collapsible. Assigning the milestone as the top-level parent of tickets is a bit more difficult and requires pretty extensive changes because of the way that the logic in the code uses the specification of parent in trac.ini.

We use Subtickets plugin to create parent tickets and this maps well onto what we're doing in the Gantt plugin (and the way JSGantt works). Having the milestone as the parent doesn't make a lot of sense to me.

We have toyed with the idea that a group ticket has an implicit milestone on it's due date and all children would be due then. We haven't quite worked out how we want to do that. We have too many places now where our idea of due date has to be maintained so we'd like to get this right this time.

Maybe I can send you a patch before the weekend for some feedback? It would be great to get some advice on how to implement this.

Sure, I'll try to take a look.

I'm comfortable working with Python, but not Javascript.

A bit of the opposite for me. ;-)

Another option that I'd like to add, which probably requires code modifications in Javascript, is to have a macro argument that allow the parents to be specified as collapsed when the page is loaded.

I have a plan to add open= and closed= options so you could say open=1|3|6,closed=2|4|5. Is that what you're looking for?

### comment:4 in reply to:  3 ; follow-up:  5 Changed 11 years ago by Ryan J Ollos

We use Subtickets plugin to create parent tickets and this maps well onto what we're doing in the Gantt plugin (and the way JSGantt works). Having the milestone as the parent doesn't make a lot of sense to me.

We have toyed with the idea that a group ticket has an implicit milestone on it's due date and all children would be due then. We haven't quite worked out how we want to do that. We have too many places now where our idea of due date has to be maintained so we'd like to get this right this time.

I'm using subtickets to create parents as well. I'd really just like to have the tickets for a milestone displayed beneath the milestone (i.e. grouped), so that if I have N milestones in a Gantt chart, I can collapse one of the milestones and hide all the tickets for it. It also would make it very clear for a Gantt chart showing multiple milestones which tickets are associated with a milestone without having to display the milestone as a column of the Gantt chart (which I'm not even sure is currently supported, but would just be one other way to go about doing it).

I have a plan to add open= and closed= options so you could say open=1|3|6,closed=2|4|5. Is that what you're looking for?

I might be getting a bit confused by the open and closed terms because they make me think of ticket status. However, if closed=2|4|5 causes tickets 2, 4 and 5 to be shown on the Gantt chart as initially collapsed (i.e. with their children hidden), then that is what I am looking for.

### comment:5 in reply to:  4 Changed 11 years ago by Chris Nelson

We use Subtickets plugin to create parent tickets and this maps well onto what we're doing in the Gantt plugin (and the way JSGantt works). Having the milestone as the parent doesn't make a lot of sense to me.

We have toyed with the idea that a group ticket has an implicit milestone on it's due date and all children would be due then. We haven't quite worked out how we want to do that. We have too many places now where our idea of due date has to be maintained so we'd like to get this right this time.

I'm using subtickets to create parents as well. I'd really just like to have the tickets for a milestone displayed beneath the milestone (i.e. grouped), so that if I have N milestones in a Gantt chart, I can collapse one of the milestones and hide all the tickets for it.

I assume by "milestone" you mean a Trac milestone. With that limitation, I can see some benefit to what you propose. However, I have a loser definition of milestone that makes what you suggest hard at best.

I don't much care for Trac milestones because they are not first-class objects (don't have history, etc.) so I've created a ticket type that I use for setting a due date. In Microsoft Project, a milestone is just a task with 0 duration and a due date. Similarly, my "inchpebble" Trac tickets are just a date. By using Master Tickets to make the inchpebbles require predecessor tickets, I get a Project-like behavior that works well for me. However, this scenario also allows (as does Project) a task to be required for more than one milestone. With that relationship, there is no single milestone a ticket is "under" where it can be hidden by collapsing the outline.

It also would make it very clear for a Gantt chart showing multiple milestones which tickets are associated with a milestone without having to display the milestone as a column of the Gantt chart (which I'm not even sure is currently supported, but would just be one other way to go about doing it).

The sorting work we've done should improve this by putting the milestone close to the tickets it requires.

I have a plan to add open= and closed= options so you could say open=1|3|6,closed=2|4|5. Is that what you're looking for?

I might be getting a bit confused by the open and closed terms because they make me think of ticket status. However, if closed=2|4|5 causes tickets 2, 4 and 5 to be shown on the Gantt chart as initially collapsed (i.e. with their children hidden), then that is what I am looking for.

Sorry my terms were kind of muddied. My "open" and "close" there refer to the state of the tree in the Gantt. I am also thinking about "closed=closed" meaning "collapse all the tickets that are done and show me the rest.

### comment:6 Changed 11 years ago by Chris Nelson

(In [10387]) Make task sorting more logical and attractive. Refs #8947.

Sort by end date with start date as a tie breaker.

### comment:8 follow-up:  9 Changed 11 years ago by Ryan J Ollos

[10387] definitely made the chart nicer, but I'd also still find it useful to have the option to group tickets under their milestones. I just need to find time to make a patch with that option ;)

### comment:9 in reply to:  8 ; follow-up:  10 Changed 11 years ago by Chris Nelson

[10387] definitely made the chart nicer, but I'd also still find it useful to have the option to group tickets under their milestones. I just need to find time to make a patch with that option ;)

Maybe I'm being too pedantic but making the milestone the group just seems contrary to every Gantt I've ever seen. It also concerns me that it requires a M-to-1 relationship between tasks and milestones whereas it is often the case that a task can be required for multiple milestones (M-to-M).

### comment:10 in reply to:  9 Changed 11 years ago by Ryan J Ollos

Maybe I'm being too pedantic but making the milestone the group just seems contrary to every Gantt I've ever seen. It also concerns me that it requires a M-to-1 relationship between tasks and milestones whereas it is often the case that a task can be required for multiple milestones (M-to-M).

I don't have much experience with MS Projects or Gantts in general. My reason for wanting this feature is that Trac forces an M to 1 relationship between tickets and milestones, and every ticket is assigned to a milestone (for typical use cases, at least). Therefore it seems natural to group all of the tickets under the milestone to which they are assigned ... this makes sense to me in Trac anyway.

Is your intent to work around these constraints that Trac imposes and provide some other, perhaps "true Gantt", functionality?

### comment:11 Changed 11 years ago by anonymous

yeah grouping by milestones make it nicer...was it done?

### comment:12 Changed 10 years ago by falkb

Currently, not grouping by milestone is the biggest complain about this plugin here. Some users here grumble the chart is quite useless without that grouping. This way they separate the different projects and their tickets.

It seems to me the current order in the chart is by (computed) enddate of the ticket.

### comment:13 Changed 10 years ago by falkb

Priority: normal → high

### comment:14 follow-up:  18 Changed 10 years ago by Chris Nelson

I think what throws me about the summary is "under". If it was "with" I'd be with you.

Would sorting by milestone then by date *within* milestone (with the milestone at the end of the group) work for you?

### comment:15 follow-up:  16 Changed 10 years ago by Ryan J Ollos

Trac groups tickets under milestones, which I think is why so many people are asking for this. I expect people will continue to ask for it because of the way Trac is designed. However, I'm not able to use the plugin anymore so I'm not wed to having this feature.

### comment:16 in reply to:  15 Changed 10 years ago by Chris Nelson

Trac groups tickets under milestones, ...

Where? Reports are tabular and Trac doesn't seem to have any native graphs. What am I forgetting?

### comment:17 Changed 10 years ago by Ryan J Ollos

You are missing nothing. It is just conceptual. You navigate to the roadmap, there is a list of milestones with reports, and then you select a report on the milestone progress bar to view the tickets. This presentation leads to people to think of the tickets being grouped within a milestone, and that is how I think about it as well.

### comment:18 in reply to:  14 Changed 10 years ago by falkb

I think what throws me about the summary is "under". If it was "with" I'd be with you.

I understood "under" just as "subordinated" or "grouped", respectively.

Would sorting by milestone then by date *within* milestone (with the milestone at the end of the group) work for you?

Fine with me. And yes, the milestone should be the last one in the group if you order each milestone ticket group by "earliest enddate first".

### comment:19 Changed 10 years ago by Chris Nelson

Summary: Group tickets under milestones → Group tickets with milestones

### comment:20 Changed 10 years ago by Chris Nelson

I believe I have to implement this in:

    def _compare_tickets(self, t1, t2):
# If t2 depends on t1, t2 is first
if t1['id'] in self.pm.successors(t2):
return 1
# If t1 depends on t2, t1 is first
elif t2['id'] in self.pm.successors(t1):
return -1
# If t1 ends first, it's first
elif self.pm.finish(t1) < self.pm.finish(t2):
return -1
# If t2 ends first, it's first
elif self.pm.finish(t1) > self.pm.finish(t2):
return 1
# End dates are same. If t1 starts later, it's later
elif self.pm.start(t1) > self.pm.start(t2):
return 1
# Otherwise, preserve order (assume t1 is before t2 when called)
else:
return 0


One approach would be to add

        # Compare milestones
if t1['milestone'] <  t2['milestone']:
return -1
elif t1['milestone'] >  t2['milestone']:
return 1


then continue, making the existing if an elif. While that groups by Trac milestone, it doesn't handle milestone-type tickets and it sorts by the lexical order of the Trac milestone name, not by it's due date. If you had B due before A, you'd see all of A's tasks then all of B's.

### comment:21 follow-up:  22 Changed 10 years ago by Chris Nelson

What if I took the "group" in the summary literally and when I encounter a Trac milestone, I create a pseudo-group internally and make all the tickets with that milestone children of that group? That would let the WBS computation take care of the grouping sought here and would allow folding by milestone. I'd have to decide if the omitMilestones option would hide the pseudo-task line at the bottom for the milestone, the pseudo-group line at the top, or both.

### comment:22 in reply to:  21 ; follow-up:  23 Changed 10 years ago by falkb

What if I took ...

What do you expect me to reply? If it groups, it'll be fine. :) Sounds good if it also allows folding as a side effect. It seems to me that your milestone handling is not only creating an internal "milestone"-ticket as last successor of all tickets of that milestone, but you must also create a second internal ticket for such milestone acting like a parent ticket of all tickets of that milestone. Well, this is just fast stupid brainstorming.

### comment:23 in reply to:  22 Changed 10 years ago by Chris Nelson

What if I took ...

What do you expect me to reply?

Nothing, really. Mostly thinking out loud but if someone overheads me and comments, I'll welcome the feedback.

If it groups, it'll be fine. :) Sounds good if it also allows folding as a side effect. It seems to me that your milestone handling is not only creating an internal "milestone"-ticket as last successor of all tickets of that milestone, but you must also create a second internal ticket for such milestone acting like a parent ticket of all tickets of that milestone.

Yes.

Well, this is just fast stupid brainstorming.

### comment:24 Changed 10 years ago by falkb

Maybe consider also imaginable requests coming in the future to group also by other criteria like 'owner'. This could be an option of the gantt chart configuration.

### comment:25 Changed 10 years ago by Chris Nelson

(In [11863]) Revert "Create group to hold all tickets in a milestone. Refs #8947."

This reverts commit 5bb6d3fa5828afacb1a7378e8399eaa0d1576470.

### comment:26 follow-up:  27 Changed 10 years ago by anonymous

Not sure why this didn't auto-link:

(In [11862]) Create group to hold all tickets in a milestone. Refs #8947.

The next change reverts it because I don't want the tip to be unstable. Please let me know if this seems to be going in the right direction.

### comment:27 in reply to:  26 Changed 10 years ago by Ryan J Ollos

Not sure why this didn't auto-link:

I've seen this problem from time to time as well, and finally created a ticket for it: #10211.

### comment:28 follow-ups:  29  30 Changed 10 years ago by falkb

Now I've time again to care about this topic again, but I'm not sure if I understand your latest commits correctly. Am I right, to test that improvement I have to update to [11862] and report back? Why did you revert it, what is unstable, is it usuable already or not?

### comment:29 in reply to:  28 Changed 10 years ago by Chris Nelson

Now I've time again to care about this topic again, but I'm not sure if I understand your latest commits correctly. Am I right, to test that improvement I have to update to [11862] and report back? Why did you revert it, what is unstable, is it usuable already or not?

### comment:30 in reply to:  28 Changed 10 years ago by Chris Nelson

Now I've time again to care about this topic again, but I'm not sure if I understand your latest commits correctly. Am I right, to test that improvement I have to update to [11862] and report back? Why did you revert it, what is unstable, is it usuable already or not?

I believe that the change is stable but I know it is not polished. I'd like to see if it is moving in the direction you need before I spend time making it ready for prime time.

### comment:31 follow-up:  32 Changed 10 years ago by falkb

I tested it a bit. After two little corrections in:

tracjsgantt.py

@@ -388,7 +388,9 @@
if (estimate == 0):
percent = 0
else:
-                worked = ticket[self.fields['worked']]
+                worked = ''
+                if self.fields['worked'] in ticket:
+                    worked = ticket[self.fields['worked']]
if worked == '':
percent = 0
else:


and tracpm.py

@@ -1594,7 +1610,8 @@
# Schedule the best eligible task
ticket = eligible.pop(nextIndex)
tid = ticket['id']
-                unscheduled.remove(tid)
+                if tid in unscheduled:
+                    unscheduled.remove(tid)
scheduleFunction(ticket)

# Decrement number of unscheduled successors for each


it started up and looked good at first sight. :-)

Just all milestones are displayed doubled in the chart, as pseudo-ticket and as milstone diamond.

### comment:32 in reply to:  31 Changed 10 years ago by falkb

it started up and looked good at first sight. :-)

Sorry, now at second sight I see it doesn't work properly for e.g.

[[TracJSGanttChart(display=owner:falkb,colorBy=milestone,format=week,status!=closed&resolution!=duplicate|invalid)]]


My tickets are in different milestones and the chart mixes them, they are not ordered. The milestones are not displayed (as pseudo tickets) either.

### comment:33 follow-up:  34 Changed 10 years ago by Chris Nelson

(In [12161]) Create group to hold all tickets in a milestone. Refs #8947.

A more robust implementation controlled by a milestoneAsGroup option.

### comment:34 in reply to:  33 ; follow-ups:  37  39 Changed 10 years ago by falkb

(In [12161]) Create group to hold all tickets in a milestone. Refs #8947.

A more robust implementation controlled by a milestoneAsGroup option.

Sorry, it doesn't work properly for e.g.

[[TracJSGanttChart(display=owner:falkb,colorBy=milestone,milestoneAsGroup=1,format=week,status!=closed&resolution!=duplicate|invalid)]]


Here I have about 10 tickets of 6 milestones. Some tickets of different milestones are listed inbetween. BTW: Colours are not unique for a certain milestone within one chart, some milestones have the same colour; though that's not a new problem.

### comment:35 Changed 10 years ago by falkb

The mentioned example chart doesn't display all milestones either. But this is what is essentially needed to understand the grouping.

### comment:36 Changed 10 years ago by falkb

I mean by "all" all milestones belonging to the tickets displayed in the chart

### comment:37 in reply to:  34 ; follow-up:  38 Changed 10 years ago by Chris Nelson

(In [12161]) Create group to hold all tickets in a milestone. Refs #8947.

A more robust implementation controlled by a milestoneAsGroup option.

Sorry, it doesn't work properly for e.g.

[[TracJSGanttChart(display=owner:falkb,colorBy=milestone,milestoneAsGroup=1,format=week,status!=closed&resolution!=duplicate|invalid)]]


Here I have about 10 tickets of 6 milestones. Some tickets of different milestones are listed inbetween. BTW: Colours are not unique for a certain milestone within one chart, some milestones have the same colour; though that's not a new problem.

Can you show me the chart?

### comment:38 in reply to:  37 ; follow-up:  41 Changed 10 years ago by falkb

Can you show me the chart?

and

where TicketsAndMilestones3.PNG is generated from  [[TicketQuery(owner=falkb&status!=closed&resolution!=duplicate|invalid&col=id&col=milestone,table)]]

### comment:39 in reply to:  34 Changed 10 years ago by Chris Nelson

... Here I have about 10 tickets of 6 milestones. ...

I wonder if the number of milestones is an issue? I think that the CSS was designed to color for priority with a little slack so there aren't that many colors. tracjsgantt.css only has 6 colors in it. That could be improved.

### comment:40 Changed 10 years ago by Chris Nelson

Do your milestones have due dates?

### comment:41 in reply to:  38 ; follow-up:  42 Changed 10 years ago by Chris Nelson

Can you show me the chart?

and

where TicketsAndMilestones3.PNG is generated from  [[TicketQuery(owner=falkb&status!=closed&resolution!=duplicate|invalid&col=id&col=milestone,table)]]

You appear to have omitMilestones set to 1 in your configuration? I don't see any milestones in the chart at all.

### comment:42 in reply to:  41 ; follow-up:  43 Changed 10 years ago by falkb

Do your milestones have due dates?

Yes, they all have

You appear to have omitMilestones set to 1 in your configuration? I don't see any milestones in the chart at all.

No omitMilestones. I think it's because I use  display=owner=falkb...snip .

If I try to use  [[TracJSGanttChart(milestoneAsGroup=1,colorBy=milestone,format=week,owner=falkb&status!=closed&resolution!=duplicate|invalid)]] , it just shows this error

Traceback (most recent call last):
File "build\bdist.win32\egg\trac\wiki\formatter.py", line 765, in _macro_formatter
return macro.ensure_inline(macro.process(args))
File "build\bdist.win32\egg\trac\wiki\formatter.py", line 356, in process
text = self.processor(text)
File "build\bdist.win32\egg\trac\wiki\formatter.py", line 343, in _macro_processor
text)
File "build\bdist.win32\egg\tracjsgantt\tracjsgantt.py", line 706, in expand_macro
File "build\bdist.win32\egg\tracjsgantt\tracjsgantt.py", line 519, in _format_ticket
File "build\bdist.win32\egg\tracjsgantt\tracpm.py", line 391, in percentComplete
worked = ticket[self.fields['worked']]
KeyError: u'totalhours'


### comment:43 in reply to:  42 ; follow-up:  46 Changed 10 years ago by falkb

No omitMilestones. I think it's because I use  display=owner=falkb...snip .

Typo.  display=owner:falkb...

### comment:44 Changed 10 years ago by Chris Nelson

(In [12170]) Don't sort again after filtering tickets. This breaks the WBS. Refs #8947.

### comment:45 Changed 10 years ago by Chris Nelson

(In [12171]) Improve "omitMilestones" handling. Refs #8947.

Without this milestones aren't queried so that the grouping can't happen properly.

### comment:46 in reply to:  43 ; follow-up:  47 Changed 10 years ago by Chris Nelson

No omitMilestones. I think it's because I use  display=owner=falkb...snip .

Typo.  display=owner:falkb...

I saw your problem in my test instance and the code I just posted seems to fix it for me. Please let me know.

### comment:47 in reply to:  46 ; follow-up:  48 Changed 10 years ago by falkb

I saw your problem in my test instance and the code I just posted seems to fix it for me. Please let me know.

• good news:
• tickets properly grouped by milestone now! :-)
• milestones ordered by datetime now :-)
• milestones are still not shown (why? missing option?)
• still that KeyError: u'totalhours' mentioned in 42

### comment:48 in reply to:  47 ; follow-up:  49 Changed 10 years ago by Chris Nelson

I saw your problem in my test instance and the code I just posted seems to fix it for me. Please let me know.

• good news:
• tickets properly grouped by milestone now! :-)
• milestones ordered by datetime now :-)
• milestones are still not shown (why? missing option?)

I believe you were right when you suggested that the display filter is removing the milestones. Since milestones have owner, an owner filter hides them.

• still that KeyError: u'totalhours' mentioned in 42

I'll look into that. Is this new? It works for me. What does your [TracPM] section of trac.ini look like?

### comment:49 in reply to:  48 ; follow-up:  50 Changed 10 years ago by falkb

I believe you were right when you suggested that the display filter is removing the milestones. Since milestones have owner, an owner filter hides them.

I wouldn't filter milestones by owner here. I even didn't know a milestone can have an owner.

• still that KeyError: u'totalhours' mentioned in 42

I'll look into that. Is this new?

Haven't seen that before. Likely since [12161].

It works for me. What does your [TracPM] section of trac.ini look like?

[trac-jsgantt]
option.colorby = owner
option.comp = 0
option.dur = 1
option.enddate = 0
option.lwidth = 400
option.res = 0
option.startdate = 0

[TracPM]
date_format = %Y-%m-%d
days_per_estimate = 0.125
default_estimate = 8.0
fields.estimate = estimatedhours
fields.finish = userfinish
fields.parent = parents
fields.pred = blockedby
fields.start = userstart
fields.succ = blocking
fields.worked = totalhours
milestone_type = milestone


### comment:50 in reply to:  49 ; follow-up:  51 Changed 10 years ago by Chris Nelson

I believe you were right when you suggested that the display filter is removing the milestones. Since milestones have owner, an owner filter hides them.

I wouldn't filter milestones by owner here. I even didn't know a milestone can have an owner.

They can't. That's a typo. Milestones don't have an owner so they essentially have an empty/null owner so if you say "display=owner:bob", then they don't match.

In the code, I set the owner of the pseudoticket for a milestone to . I guess if I set it to some string, you could do "display=owner:bob|msowner" or something.

• still that KeyError: u'totalhours' mentioned in 42

I'll look into that. Is this new?

Haven't seen that before. Likely since [12161].

OK. I'll look to see what changed.

It works for me. What does your [TracPM] section of trac.ini look like?

...

Thanks.

### comment:51 in reply to:  50 ; follow-up:  56 Changed 10 years ago by falkb

• still that KeyError: u'totalhours' mentioned in 42

This one helps:

• ## tracjsganttplugin/0.11/tracjsgantt/tracpm.py

 if (estimate == 0): percent = 0 else: worked = ticket[self.fields['worked']] field_worked = self.fields['worked'] worked = '' if field_worked in ticket: worked = ticket[field_worked] if worked == '': percent = 0 else:

### comment:52 follow-ups:  53  54 Changed 10 years ago by falkb

Now with the patch of 51 I see this chart:

Well

• Grouping doesn't work for the first two tickets. In spite of the other ones I can see they have explicit start and end dates set.
• I think this approach of displaying is not what I had in mind. This confuses too much since people associate the black bars with parent *tickets*. Please, use the known style for milestones, I mean the diamond ones with red arrows showing the dependencies! Then it's gonna be perfect...

### comment:53 in reply to:  52 Changed 10 years ago by falkb

Now with the patch of 51 I see this chart:

Just to clarify, TicketsAndMilestones4.PNG shows  [[TracJSGanttChart(format=week,milestoneAsGroup=1,res=0,colorBy=priority,owner=falkb&status!=closed&resolution!=duplicate|invalid)]]
which is different from  [[TracJSGanttChart(display=owner:falkb,format=week,milestoneAsGroup=1,res=0,colorBy=priority,status!=closed&resolution!=duplicate|invalid)]]

### comment:54 in reply to:  52 ; follow-up:  57 Changed 10 years ago by Chris Nelson

Now with the patch of 51 I see this chart:

Well

• Grouping doesn't work for the first two tickets. In spite of the other ones I can see they have explicit start and end dates set.

I don't know what's missing. What is the milestone for those tickets? Where would you expect them to be grouped.

• I think this approach of displaying is not what I had in mind. This confuses too much since people associate the black bars with parent *tickets*. Please, use the known style for milestones, I mean the diamond ones with red arrows showing the dependencies! Then it's gonna be perfect...

I think that's going to look odd but even if I didn't, I tried it and there's something in the JavaScript that doesn't like handling milestones with children. jsgantt.js is a big hunk of black magic that I wrap in Python and I get lost whenever I wander in. I don't really have time to do that now. Sorry.

### comment:55 Changed 10 years ago by Chris Nelson

(In [12172]) Pseudotickets should have a worked value. Refs #8947.

### comment:56 in reply to:  51 Changed 10 years ago by Chris Nelson

• still that KeyError: u'totalhours' mentioned in 42

This one helps:

• ## tracjsganttplugin/0.11/tracjsgantt/tracpm.py

 if (estimate == 0): percent = 0 else: worked = ticket[self.fields['worked']] field_worked = self.fields['worked'] worked = '' if field_worked in ticket: worked = ticket[field_worked] if worked == '': percent = 0 else:

I think [12172] is a better solution (though I don't see this problem so I'm not sure if it fixes it).

### comment:57 in reply to:  54 Changed 10 years ago by falkb

Now with the patch of 51 I see this chart:

Well

• Grouping doesn't work for the first two tickets. In spite of the other ones I can see they have explicit start and end dates set.

I don't know what's missing. What is the milestone for those tickets? Where would you expect them to be grouped.

Look at . They belong to milestone ...42...-M3.

• I think this approach of displaying is not what I had in mind. This confuses too much since people associate the black bars with parent *tickets*. Please, use the known style for milestones, I mean the diamond ones with red arrows showing the dependencies! Then it's gonna be perfect...

I think that's going to look odd but even if I didn't, I tried it and there's something in the JavaScript that doesn't like handling milestones with children. jsgantt.js is a big hunk of black magic that I wrap in Python and I get lost whenever I wander in. I don't really have time to do that now. Sorry.

I don't think you must create a milestone parent-node and break the whole visual design. My advice: On the contrary, keep it as it is, users are used to the current one! We just want you to group the tickets. This simply means that the list of tickets is ordered in a way that a contiguous block of tickets belong to *one* milestone, and there is only one block of tickets for a certain milestone. For such block of tickets all tickets point to their milestone diamond by all those fancy red arrows like we already used to it. This means no changed .js stuff, it's just a matter in which order tickets are sorted in the chart list.

### comment:58 Changed 10 years ago by falkb

...and the milestone is at the bottom of each partial ticket list block which is logical since what is next is more below.

### comment:59 Changed 10 years ago by Chris Nelson

So, "group by milestone" not "milestone as group". I think that should be an option because it would be valid/desireable to sort by dependency/WBS. Whatever I may call the option, I think it just makes milestone the highest priority field in the sort function.

### comment:60 Changed 10 years ago by falkb

Now I've read 21 and the two next ones again, and I think somehow we had misunderstood each other. I'm sorry for that. Sometimes a fotomontage would have helped more than 100 lines description... :)

### comment:61 Changed 10 years ago by Chris Nelson

I think I had an AHA! moment when I couldn't get to sleep last night: how about adding an order= option to the Gantt chart. The current, default behavior would be set with order=wbs but what this ticket asks for could be done with order=milestone|wbs.

### comment:62 follow-up:  63 Changed 10 years ago by falkb

Just guessing... do you mean 'work breakdown structure' when you're saying WBS?

An order criterion is a good idea. People here also have asked for ordering by user, version, project. They also have asked me for reordering at runtime, for instance by selecting the order from combobox.

For the use case that this gannt chart is used as survey over one's task list, for which this ticket #8947 is for, we want to order by milestone (although some people already asked me to order by custom field 'project')...

All in all, I wished I could order by any ticket field.

### comment:63 in reply to:  62 ; follow-up:  64 Changed 10 years ago by Chris Nelson

Just guessing... do you mean 'work breakdown structure' when you're saying WBS?

Yes

An order criterion is a good idea. People here also have asked for ordering by user, version, project.

Yeah, I can see that. The general applicability of reordering the chart was my breakthrough.

They also have asked me for reordering at runtime, for instance by selecting the order from combobox.

That's a lot more work. I don't see that on the horizon.

For the use case that this gannt chart is used as survey over one's task list, for which this ticket #8947 is for, we want to order by milestone (although some people already asked me to order by custom field 'project')...

All in all, I wished I could order by any ticket field.

I imagine that would naturally fall out of this work. I'm going to try to do it this week while I have the momentum and it's fresh in my mind.

### comment:64 in reply to:  63 Changed 10 years ago by falkb

I imagine that would naturally fall out of this work. I'm going to try to do it this week while I have the momentum and it's fresh in my mind.

Sounds good. Maybe you can also find a little moment to have a look at #10313... :-)

### comment:65 Changed 10 years ago by Chris Nelson

(In [12174]) Revert "Create group to hold all tickets in a milestone. Refs #8947."

This reverts commit ba5ce8db4e9d40907ffecc702524d9e64fb3feb6.

Conflicts:

tracjsgantt/tracpm.py

### comment:66 Changed 10 years ago by Chris Nelson

(In [12175]) Add order option. Refs #8947.

Defaults to WBS (old behavior) but can be set, for example, to order=milestone|wbs to sort by milestone first, then WBS within milestone.

### comment:67 Changed 10 years ago by Chris Nelson

Sometimes it just takes a few false starts to get to a good solution. I really like this. It solves a general problem with general code rather than a weird kludge.

### comment:68 follow-up:  69 Changed 10 years ago by falkb

Updated and it's definitely better! Look at

Just a tiny little bug is still visible:  #2847  is sorted to the wrong milestone. I've just replaced  milestoneAsGroup=1  by  order=milestone|wbs . It happens also without wbs being OR'ed. The ticket has some dependencies to other tickets, could that break things?

### comment:69 in reply to:  68 ; follow-up:  70 Changed 10 years ago by Chris Nelson

Updated and it's definitely better! Look at ...

Just a tiny little bug is still visible:  #2847  is sorted to the wrong milestone. I've just replaced  milestoneAsGroup=1  by  order=milestone|wbs . It happens also without wbs being OR'ed. The ticket has some dependencies to other tickets, could that break things?

If I am looking at that right, 2847 *is* grouped with it's milestone, it just happens to follow it. That is, there are no tickets from other milestones between 2847 and its milestone. There's nothing in the by-field sorting logic to make the ticket for the milestone itself sort to the end of the group for that milestone. Try order=milestone|type|wbs and see if milestone tickets end up at the end of their group.

### comment:70 in reply to:  69 ; follow-up:  72 Changed 10 years ago by falkb

Try order=milestone|type|wbs and see if milestone tickets end up at the end of their group.

Yeah, that's it, to use  [[TracJSGanttChart(format=week,order=milestone|type|wbs,res=0,colorBy=priority,owner=falkb&status!=closed&resolution!=duplicate|invalid)]]  makes very happy now -> it works!

Now I only remember

•  ...display=owner:falkb...  still doesn't show milestones
• there are not enough colours (only 6) when having many milestones

but I don't really care. So this ticket may be closed now.

### comment:71 follow-up:  73 Changed 10 years ago by Chris Nelson

(In [12177]) Force milestone-type tickets to the end of the milestone group. Refs #8947.

### comment:72 in reply to:  70 Changed 10 years ago by Chris Nelson

Try order=milestone|type|wbs and see if milestone tickets end up at the end of their group.

Yeah, that's it, to use  [[TracJSGanttChart(format=week,order=milestone|type|wbs,res=0,colorBy=priority,owner=falkb&status!=closed&resolution!=duplicate|invalid)]]  makes very happy now -> it works!

As long as you don't have a ticket type "nonsense" or "trouble" which sorts alphabetically after "milestone". The latest revision should fix that (I think).

Now I only remember

•  ...display=owner:falkb...  still doesn't show milestones

I can fix that if I can come up with an "invalid" owner value. Then I can give milestones that owner and you can do owner:realuser|fakemsowner.

• there are not enough colours (only 6) when having many milestones

but I don't really care. So this ticket may be closed now.

Yes, I need more colors. Low priority for me now.

### comment:73 in reply to:  71 ; follow-up:  74 Changed 10 years ago by falkb

(In [12177]) Force milestone-type tickets to the end of the milestone group. Refs #8947.

Don't really know what this commit technically tries to do, but I still need to add 'type' to the order option to get the milestone below of 2847, if it that was what it was aimed to.

### comment:74 in reply to:  73 ; follow-up:  75 Changed 10 years ago by Chris Nelson

(In [12177]) Force milestone-type tickets to the end of the milestone group. Refs #8947.

Don't really know what this commit technically tries to do, but I still need to add 'type' to the order option to get the milestone below of 2847, if it that was what it was aimed to.

Are you including WBS in your order setting? I think that 2847 sorted after its milestone because it has a later finish date. WBS is calculated after sorting by time so Task 1's children Task 1.p, 1.q, 1.r, etc. show up in time order when sorted by WBS.

### comment:75 in reply to:  74 ; follow-up:  76 Changed 10 years ago by falkb

Are you including WBS in your order setting?

 order=milestone|type|wbs  like said in 70.

I think that 2847 sorted after its milestone because it has a later finish date.

No, there is no date set for 2847. It's a master ticket having several subtickets set. When I look at the Gantt chart of its milestone (which shows the tickets for *all* users) I can see it's shown there finishing 2 1/2 weeks before its milestone.

### comment:76 in reply to:  75 ; follow-up:  77 Changed 10 years ago by falkb

I can see it's shown there finishing 2 1/2 weeks before its milestone.

Hey this is odd:  [[TracJSGanttChart(format=week,order=milestone|type|wbs,res=0,colorBy=priority,owner=falkb&status!=closed&resolution!=duplicate|invalid)]]  puts 2847 to another time than  [[TracJSGanttChart(milestone=...63...-M4,userMap=0,format=week,schedule=alap,resolution!=duplicate|invalid&keywords=~specification)]]

### comment:77 in reply to:  76 Changed 10 years ago by Chris Nelson

I can see it's shown there finishing 2 1/2 weeks before its milestone.

Hey this is odd:  [[TracJSGanttChart(format=week,order=milestone|type|wbs,res=0,colorBy=priority,owner=falkb&status!=closed&resolution!=duplicate|invalid)]]  puts 2847 to another time than  [[TracJSGanttChart(milestone=...63...-M4,userMap=0,format=week,schedule=alap,resolution!=duplicate|invalid&keywords=~specification)]]

So, removing common terms we have

order=milestone|type|wbs,res=0,colorBy=priority,owner=falkb&status!=closed


which

• Gets all your open tickets
• Schedules them by the ALAP or ASAP depending on trac.ini if set or the built-in default
• Displays them without the resource column, colored by priority, sorted by milestione, then WBS (with type forcing the milestone ticket to the end)

and

milestone=...63...-M4,userMap=0,schedule=alap,keywords=~specification

• Get all tickets in that milestone and all tickets with specification in the keywoards
• Schedule them ALAP

Since a very different set of tickets is queried and the schedule displayed is computed based on the queried tickets, I'm not at all surprised that these show different schedules.

I have work that I need to push to T-H to compute the scheudle in the database and allow the Gantt to display the pre-computed schedule. Sadly, it's extensive and may take weeks to publish.

### comment:78 Changed 10 years ago by falkb

OK, I understand it as you first filter the tickets, then compute the start and end and finally display it, and depending on the filtering, I may get different results, (although both charts of 76 use ALAP). Well, that's another story than the grouping topic of this #8947 and may be discussed elsewhere.

### comment:79 Changed 10 years ago by Chris Nelson

Resolution: → fixed assigned → closed

### comment:80 follow-up:  81 Changed 10 years ago by falkb

Thank you very much. Are you on Ohloh.net?

### comment:81 in reply to:  80 Changed 10 years ago by Chris Nelson

Thank you very much.

You're welcome. As I said, it was a mildly painful process but I think that the order= option ended up being quite nice.

Are you on Ohloh.net?

Since I don't know what that is, I guess not. ;-)

### Modify Ticket

Change Properties