With Mingle 1.1 came several great new features, including date fields. Now you can track the date that you complete tickets by adding a Date Done field (along with a Complete transition that sets the Date Done field to today) and locking the Status field to be editable only by transition.
This works great for newly completed cards, but what about all the cards you already have in your system? Sure you could go without burn-up charts and date stats for those cards, but what's the fun in that?

Fortunately, Mingle tracks every card change in a history table. Each change in the history table has a date associated with it, so all we need to do is figure out how to extract the dates we care about. I must warn you, this is a little complicated, and I'm sure ThoughtWorks doesn't at all condone you mucking around in your Mingle database manually, so please please back up your database before attempting this and of course I'm not responsible for any damage you do. That said, here's how I was able to retroactively add dates for our two date fields: Date Done, and Date Published.
- Back up your Mingle DB. Really.
- You'll need to identify the field you use to track status. We use Status. We have Status of 'Not Done', 'Done', and 'Published'.
- Then connect to your Mingle database and find the name of your cards table and your card_versions table. Our project is called "eleutian_speakeng" so our tables are "eleutian_speakeng_cards" and "eleutian_speakeng_card_versions".
- Add the date fields you want to populate if you don't already have them. We have "Date Added", "Date Published" and "Date Done".
- Figure out which fields in the two tables you identified map to your status and dates (this is usually as easy as prepending cp_ and box_caring your names. For us we have cp_status, cp_date_published, cp_date_done, cp_date_added.
- Edit the following queries to add in your table/field names and values (these are the exact queries I ran, you'll need to change the red things):
UPDATE eleutian_speakeng_cards SET cp_date_added = created_at
UPDATE eleutian_speakeng_cards card SET card.cp_date_done = (
SELECT MAX(b.updated_at)
FROM eleutian_speakeng_card_versions a
INNER JOIN eleutian_speakeng_card_versions b ON a.number = b.number
AND b.version=a.version+1
WHERE card.number = a.number
AND (a.cp_status='Not Done' OR a.cp_status IS NULL) AND b.cp_status='Done'
) WHERE card.cp_status = 'Done'
UPDATE eleutian_speakeng_cards card SET card.cp_date_published = (
SELECT MAX(b.updated_at)
FROM eleutian_speakeng_card_versions a
INNER JOIN eleutian_speakeng_card_versions b ON a.number = b.number
AND b.version=a.version+1
WHERE card.number = a.number
AND (a.cp_status IN ('Done', 'Not Done') OR a.cp_status IS NULL)
AND b.cp_status='Published'
) WHERE card.cp_status = 'Published'
- Once you've got that taken care of, go ahead and run the queries (you backed up right?) and you should be good to go.
So now that you've got your dates in your database, how do you get the cool burn up chart? Like this (mold to your project):
{{
stack-bar-chart
x-label-start: SELECT MIN('Date Added')
x-label-end: Today
x-label-step: 14
chart-height: 600
chart-width: 700
plot-height: 500
plot-width: 550
conditions: Type IN (Bug, Story, Task)
three-d: true
cumulative: true
series:
- label: 'Not Done'
color: #e6a800
data: SELECT 'Date Added', COUNT(*)
type: area
- label: Done
color: #1bcc00
type: area
data: SELECT 'Date Done', Count(*) WHERE 'Date Done' IS NOT NULL
- label: Published
color: #0079bf
type: area
data: SELECT 'Date Published', COUNT(*) WHERE 'Date Published' IS NOT NULL
}}