Jira Burndown in Tableau: Planned, Actual & Projected on One Chart

A live-build companion deck for a Tableau tutoring session. It pivots three wide Jira date columns into a single long axis of Milestone Type and Milestone Date, then builds the FIXED-LOD running-percentage calculation that stops a self-normalizing Actual series from claiming 100% completion before it is true. It covers TODAY()-boundary and dashed-Projected styling, including the fallback for versions before 2023.2, and finishes with a data-hygiene audit of a real export - a column shift, three typo dates, and an orphan Parent Epic - that students must catch before trusting a single number.

Subject: Business Analytics · 113 slides · applied lesson

Open the interactive version of this deck · Homework for this lesson

What this lesson covers

The lesson, slide by slide

1. Jira Burndown in Tableau

Title

Business Analytics · Live Build Session

Planned, Actual, and Projected on one chart — connect, relate, pivot, and calculate your way to a single burn-up line, plus the data-hygiene issues and version limitations you'll actually hit.

2. What you'll walk away with today

Objectives

This session builds one chart from a real (messy) Jira export: Planned + Actual + Projected on a single burn-up line. By the end you can:

Concretely: everything above happens against one real (messy) Jira export — the same file you'll have open today. You'll build across 7 parts, roughly 60–75 minutes end to end, with two deliberate return trips to an audit mindset: once on the raw data (Part 2), once on the finished chart (Part 7).

3. What survived from The Data Analyst's Toolkit — First Session (Sports Business)?

Warm-up

Discussion prompt

Before we open Jira Burndown in Tableau: Planned, Actual & Projected on One Chart: without looking back, what was the main idea of The Data Analyst's Toolkit — First Session (Sports Business), and what could you do by the end of it that you could not do before?

Hint: One sentence for the idea, one for the skill. If the second one is blank, that is the part to revisit.

Answer:

Kickoff session for a student building a portfolio of end-to-end sports-business-operations analytics projects for internship interviews (31 slides). Introduces the five-tool stack — SQL, Python, Power BI, Excel, and GitHub — with the honest strengths and limits of each, where each fits in a project, and how they hand off to form one pipeline (extract → analyze → present → publish).

4. Show, don't tell: the finished chart

Concept

Before wiring anything up, look at where you're headed. The reference workbook's finished chart has three lines on one axis, colored by Milestone Type.

SeriesLookBehavior
PlannedGray-blue, solidRises to 100% (on the cleaned file)
ActualGreen, solidPlateaus at ~41% — the true resolved share
ProjectedLight green, dashedSparse — only ~11 of 44 features have a forecast

A vertical TODAY() line splits history from forecast. One chart tells the entire project story: what was planned, what's actually done, and what's expected next — and every piece of it comes from a real, occasionally messy, Jira export.

The takeaway: every line you're about to build is a promise about honesty — solid means it already happened, dashed means it's a guess, and the gap between Planned's 100% and Actual's 41% is the entire point of the chart.

5. Fill in: Look for Show, don't tell: the finished chart

Comparison

Comparison matrix

From Show, don't tell: the finished chart: refill the Look column from what you know. The rest of the table is as it appeared.

SeriesLookBehavior
PlannedGray-blue, solidRises to 100% (on the cleaned file)
ActualGreen, solidPlateaus at ~41% — the true resolved share
ProjectedLight green, dashedSparse — only ~11 of 44 features have a forecast

6. Part 1 — Connect & Relate

Section

Segment 1

7. Roadmap for Part 1

Concept

In this part: wire up the two Jira tables, see why a relationship (not a join) keeps every count honest, and build the validation sheet you'll lean on for the rest of the session. About 5 minutes in a live session — the shortest part, but everything downstream depends on getting it right.

8. Two tabs, one relationship

Concept

Before any pivot or calculation, Tableau needs to know how these two tables relate to each other — get this wrong and every count downstream is suspect. That's the job of this first part.

The export is two Excel tabs: Epics (Parents) — 5 rows — and Features (Children) — 44 rows — linked by Features.Parent Epic = Epics.Key.

relationship — A logical-layer link between two tables that keeps each table at its own grain — one row per epic, one row per feature — until a sheet actually needs to combine them. Contrast with a physical join, which flattens the tables into one.

In plain words: Epics and Features are separate lists that happen to reference each other; a relationship is just Tableau remembering that reference without merging the lists into one.

9. Break it if you can: Two tabs, one relationship

Counterexample

Discussion prompt

Before any pivot or calculation, Tableau needs to know how these two tables relate to each other — get this wrong and every count downstream is suspect. That's the job of this first part.

That is stated as though it always holds. Do one of two things: produce a case where it fails, or say precisely what rules such a case out. "It just does" is not on the menu.

Hint: Hunt at the extremes first — zero, one, negative, empty, equal. If every extreme survives, the reason they survive is the proof.

Answer:

The export is two Excel tabs: Epics (Parents) — 5 rows — and Features (Children) — 44 rows — linked by Features.Parent Epic = Epics.Key.

10. Relationships keep the grain; joins flatten it

Intuition

Picture Epics and Features as two separate stacks of index cards. A relationship is a note saying 'this card in stack B belongs to that card in stack A' — both stacks stay intact until you ask a question that needs both.

A physical join, by contrast, actually staples every matching pair of cards together into one new stack. At 49 total rows here it's invisible on a chart of sums — but every Feature row would duplicate for its Epic, and any Epic-level SUM() would silently double-count.

Another way to picture it: a relationship is like looking up a contact's phone number only when you need to call them. A join is like photocopying that phone number onto every page of a 44-page document — accurate today, but now there are 44 copies to keep in sync, and 44 chances to double-count if you ever SUM() that page.

11. Guess the shape of the answer: Connect and relate the tables

Estimation

Predict first

Click-path: Connect → Microsoft Excel → the workbook. Drag Epics (Parents) onto the canvas, then Features (Children) beside it — Tableau auto-detects Features.Parent Epic = Epics.Key as a relationship in the logical layer.

Commit before you compute: what does Connect and relate the tables come out to? A rough magnitude and the right form is enough — the point is to have something concrete to be wrong about.

Correct: Confirm the relationship in the canvas reads Features.Parent Epic = Epics.Key

Why: A prediction you can defend turns the computation into a check rather than a leap of faith — and an answer that contradicts it is caught on the spot. This is the logical (relationships) layer, not a physical join — worth pointing at explicitly so the distinction from the next trap slide is concrete, not abstract.

12. Connect and relate the tables

Worked example

Click-path: Connect → Microsoft Excel → the workbook. Drag Epics (Parents) onto the canvas, then Features (Children) beside it — Tableau auto-detects Features.Parent Epic = Epics.Key as a relationship in the logical layer.

Confirm the relationship in the canvas reads Features.Parent Epic = Epics.Key

Why: This is the logical (relationships) layer, not a physical join — worth pointing at explicitly so the distinction from the next trap slide is concrete, not abstract.

On screen right now: the Data Source canvas shows two boxes — Epics (Parents) and Features (Children) — connected by a thin line with a small relationship icon, not a solid join line. Clicking that connecting line pops up the editor showing Features.Parent Epic = Epics.Key.

13. Work backwards from the answer: Connect and relate the tables

Reverse engineer

Discussion prompt

Work backwards. The example finished here:

Confirm the relationship in the canvas reads Features.Parent Epic = Epics.Key

What was it asked to do, and what must it have been given? Reconstruct the problem from its answer.

Hint: Every quantity in the result had to enter somewhere. Account for each one.

Answer:

Click-path: Connect → Microsoft Excel → the workbook. Drag Epics (Parents) onto the canvas, then Features (Children) beside it — Tableau auto-detects Features.Parent Epic = Epics.Key as a relationship in the logical layer.

14. What has to be given first: Build the validation sheet

Missing information

Discussion prompt

That's 42 features under the 5 epics. The remaining 2 — DPN-060 and DPN-061 — don't show up under any epic filter yet. Hold that thought; it's Part 2's second teaching moment.

What do you need to know — or decide — before the first line can be written? List everything the problem has to hand you.

Hint: Anything you would have to invent to get started is a thing the problem must supply.

Answer:

A validation sheet before any chart answers one question: does every epic show the feature count you expect?

15. Build the validation sheet

Worked example

New worksheet → Epic Key on Rows, COUNTD([Key]) (Features) on Text

Why: A validation sheet before any chart answers one question: does every epic show the feature count you expect?

EpicFeature CountFeature Keys (sample)
DPN-0019DPN-006 … DPN-014
DPN-00211DPN-015 … DPN-025
DPN-0039DPN-026 … DPN-037 (with gaps)
DPN-00410DPN-038 … DPN-047
DPN-0053DPN-057, DPN-058, DPN-059

That's 42 features under the 5 epics. The remaining 2 — DPN-060 and DPN-061 — don't show up under any epic filter yet. Hold that thought; it's Part 2's second teaching moment.

On screen right now: Rows shows five epic keys (DPN-001…DPN-005), and Text shows five numbers that add up to 42 visible plus 2 hidden orphans — 44 total. If the sheet shows one blended total instead of five separate rows, Epic Key isn't on Rows yet.

16. What each one costs: Build the validation sheet

Trade off

Comparison matrix

From Build the validation sheet: every row here is a choice with a cost. Fill the Feature Count column, then say which row you would actually pick and what you give up for it.

EpicFeature CountFeature Keys (sample)
DPN-0019DPN-006 … DPN-014
DPN-00211DPN-015 … DPN-025
DPN-0039DPN-026 … DPN-037 (with gaps)
DPN-00410DPN-038 … DPN-047
DPN-0053DPN-057, DPN-058, DPN-059

17. Something is wrong here: joining instead of relating

Anomaly

Predict first

A student writes this, and it looks reasonable:

Why this is tempting: joins are the more familiar, SQL-style idea, and “just join them” sounds simpler than learning a Tableau-specific concept. At 49 total rows the mistake is also invisible on screen — nothing looks wrong until someone builds a SUM().

It is wrong. Say what breaks — and say it before you turn the page.

Correct: A physical join flattens the tables: each Feature row is stapled to its Epic row, so an Epic now repeats once per child Feature.

Use the logical (relationships) layer Tableau builds by default when you drag two tables onto the canvas without joining them.

Why: A physical join flattens the tables: each Feature row is stapled to its Epic row, so an Epic now repeats once per child Feature. SUM(anything) on the Epics side (budget, headcount) multiplies by however many features that epic has.

18. Trap: joining instead of relating

Trap

The trap

Why this is tempting: joins are the more familiar, SQL-style idea, and “just join them” sounds simpler than learning a Tableau-specific concept. At 49 total rows the mistake is also invisible on screen — nothing looks wrong until someone builds a SUM().

"A join is more standard, and it's faster — just join the tables."

Data Source canvas: drag Epics + Features onto the SAME physical layer
-> creates a physical join: Features.Parent Epic = Epics.Key

Every Epic-level SUM() now silently multiplies

Why: A physical join flattens the tables: each Feature row is stapled to its Epic row, so an Epic now repeats once per child Feature. SUM(anything) on the Epics side (budget, headcount) multiplies by however many features that epic has.

The fix

Use the logical (relationships) layer Tableau builds by default when you drag two tables onto the canvas without joining them.

Data Source canvas: drag Epics, then Features NEXT to it (not onto it)
-> Tableau infers a relationship: Features.Parent Epic = Epics.Key

Each table keeps its own grain

Why: Epics stays 1 row per epic; Features stays 1 row per feature. A sheet only combines them at the moment a viz actually asks for both — no duplication, no silent multiplication.

The takeaway: relate first, and only reach for a physical join when you have a specific reason — for example, you truly want one flattened row per Feature-and-its-Epic-fields.

19. Part 2 — Audit Before You Build

Section

Segments 2–3

20. Roadmap for Part 2

Concept

In this part: re-point the data source at the RAW file and watch a real count drop from 44 to 29, then track down why — a 15-row column shift, three typo dates, and two orphan foreign keys. About 20 minutes combined (10 for the validation-sheet discovery, 10 for the deep-dive) — the longest part of the session, because everything you build afterward is only as trustworthy as this audit.

21. The validation sheet's real job

Concept

This next stretch is the longest part of the session for a reason: everything you build on top of bad data is bad, so real time goes here first, making sure the data is actually what you think it is.

A validation sheet isn't busywork — it's the tripwire that catches a broken import before it reaches a chart. "Does this count make sense?" is the single most useful question in this whole session.

Rule of thumb: if a total looks smaller than it should, don't assume the project shrank. Assume the data did.

The takeaway: a validation sheet's job isn't to look tidy — it's to be the one place you'd actually notice if a count silently changed.

22. By analogy: The validation sheet's real job

Analogy

Discussion prompt

Explain The validation sheet's real job by analogy to something with no Business Analytics in it at all — a queue, a recipe, a map, a bank balance, whatever fits. Then say where your analogy breaks.

Hint: An analogy that never breaks is not an analogy, it is the same idea wearing a hat. Find the seam — that is the part that is actually new.

Answer:

Rule of thumb: if a total looks smaller than it should, don't assume the project shrank. Assume the data did.

23. Predict the next row: The count that shouldn't drop

Pattern

Predict first

The table runs: Planned (Due Date) | 44 / 44 features | 29 / 44 features · Projected | 11 / 44 features | 11 / 44 features

In The count that shouldn't drop, given the rows so far: what is the next one — the row where Series is Actual (Resolved)?

Correct: Actual (Resolved) | 18 / 44 features | 18 / 44 features

SeriesCleaned fileRaw file
Planned (Due Date)44 / 44 features29 / 44 features
Projected11 / 44 features11 / 44 features
Actual (Resolved)18 / 44 features18 / 44 features

Why: The relationship between the columns, not the individual numbers, is what generates the next row. Same workbook, same calcs, only the underlying file changes — isolating whether a problem is the chart or the data.

24. The count that shouldn't drop

Worked example

Setup: the reference workbook is built against a cleaned copy of the export. Now re-point that same data source at the untouched raw file instead and refresh.

Re-point the data source at Tableau_DemoNewProject.xlsx (raw) and refresh

Why: Same workbook, same calcs, only the underlying file changes — isolating whether a problem is the chart or the data.

SeriesCleaned fileRaw file
Planned (Due Date)44 / 44 features29 / 44 features
Projected11 / 44 features11 / 44 features
Actual (Resolved)18 / 44 features18 / 44 features

Planned drops from 44 to 29 — a loss of 15 features (~34% of the dataset). Projected and Actual don't move; their sparsity comes from a different, unrelated cause covered later. Ask: why did Planned alone just lose 15 features?

On screen right now: after refreshing to the raw file, the Planned count drops from 44 to 29 while Actual and Projected hold steady at 18 and 11 — that visible, single-series drop is the whole “aha” moment this segment is built around.

25. Column positions are part of the data contract

Intuition

Tableau's pivot doesn't read column headers at pivot time — it reads whatever sits in the columns you selected when you built the pivot. If a hand-edit shifts values one column left, the pivot faithfully reshapes the wrong cells: empty ones.

There's no error message, no red flag. The pivot just quietly produces nulls where dates should be — which is exactly the 15-feature gap you just found.

In plain words: Tableau trusts you drew the map correctly. It reads column H expecting a Due Date; if a hand-edit put that date in column G instead, Tableau doesn't go looking for it — it just reports column H as empty.

26. Diagnose the shift: DPN-038

Worked example

Open the Features sheet in Excel. Scroll to row 31 (DPN-038, the first row of Build 3A) and compare it with row 2 (DPN-006, a healthy Build-0 row).

RowKeyCol FCol GCol H (Due)Col I (Projected)Col J (Resolved)
2 (healthy)DPN-006Resolution stringStart datehas datehas date/emptyhas date/empty
31 (shifted)DPN-0382026-07-01 (46204)2026-09-30 (46295)[empty][empty][empty]

F and G hold dates that belong in G and H

Why: Rows 31–45 — Build 3A (DPN-038–047), Build 3B (DPN-057–059), and orphans DPN-060/061 — 15 rows total — were hand-edited with every value shifted one column left. Columns H, I, J, the three pivot columns, are empty for all fifteen.

Impact: these 15 rows contribute zero rows to Planned, Projected, and Actual after the pivot — that's the 44→29 drop, plus part of the Projected/Actual sparsity you'll see later.

On screen right now: scrolling to Excel row 31, columns F and G are filled with Excel serial numbers (46204, 46295) while H, I, and J sit empty — compare that instantly to row 2, where F holds a text string and G through J all hold real values.

27. Trap: assuming it's just sparse data

Trap

The trap

Why this is tempting: 29 out of 44 sounds like the ordinary kind of incompleteness you'd expect from an active project — nothing about the number 29 itself looks broken, so it's easy to accept it at face value and move on to building the chart.

"29 out of 44 planned dates — maybe some features just don't have a due date yet. That's normal for an active project."

Accept the 29 and move on

Why: This treats a structural defect as ordinary sparsity. It isn't: every one of the 15 missing rows DOES have a due date — it's just sitting one column to the left of where it belongs.

The fix

Spot-check a handful of rows across the range before trusting a count.

Click a few cells in rows 31–45 and read the column letter off the header

Why: Two minutes of clicking shows the real cause: dates ARE present, just shifted left. That distinction changes the fix — correct the source columns, not the story you tell about the data.

28. Typos slip through silently too

Concept

You just found a structural problem — a whole column shifted. This next stretch is about a quieter kind of problem: the values themselves being simply wrong, even though every column is in the right place.

A shifted column is a structural defect. A typo date is a value defect — and Tableau validates neither. Both flow straight into your chart unless you catch them first.

This export has three: one plain decade typo, one typo compounded with the column shift, and one date that just doesn't add up next to its neighbors.

29. Teach it back: Typos slip through silently too

Explain it

Discussion prompt

Explain Typos slip through silently too to a student a year behind you. No notation, no jargon they have not met — and it still has to be true.

Hint: If your explanation needs a symbol they have never seen, you are describing the notation rather than the idea.

Answer:

A shifted column is a structural defect. A typo date is a value defect — and Tableau validates neither. Both flow straight into your chart unless you catch them first.

30. DPN-013 — a decade typo

Worked example

DPN-013 (Build 0, epic DPN-001) is Closed / Resolution: Done — a legitimately finished feature.

FieldValue
Start Date2025-08-29
Due Date (Planned)2025-09-20
Resolved (Actual)2036-01-30

Filter the chart to DPN-013 and look at where its Resolved point lands

Why: The x-axis suddenly has to stretch out to 2036 to fit one point, compressing every other feature's real history into a narrow band on the left.

Likely correct value: 2026-01-30 — a plausible four-month slip past a September 2025 due date, not an eleven-year one.

On screen right now: with the chart filtered to just DPN-013, the Milestone Date axis suddenly stretches out to include the year 2036, squeezing every other feature's real 2025–2027 activity into a thin band on the left edge.

31. DPN-042 — a compound error

Worked example

DPN-042 (Build 3A, epic DPN-004, row 35) is already one of the 15 column-shifted rows — its H/I/J are empty, so it contributes nothing to any series yet. But look at where its values landed.

ColumnValueWhat it actually is
F2026-10-04 (46299)The Start Date, shifted left
G2016-12-09 (42713)The Due Date, shifted left AND a decade typo

Two defects stack on one row

Why: Fixing only the column shift isn't enough — once G moves back to H, it would still read 2016 instead of 2026. The intended Due Date is 2026-12-09: correct the position first, then the year.

On screen right now: DPN-042 doesn't appear anywhere on the chart yet — it's invisible, because its H/I/J pivot columns are empty. The only way to see the problem at all is to go back into the Excel source and read columns F and G directly.

32. DPN-021 — a coherence check

Worked example

DPN-021 (Build 1, epic DPN-002) isn't shifted or an obvious typo, but its three dates don't tell a consistent story.

FieldValue
Start Date2025-10-15
Due Date (Planned)2026-12-01
Resolved (Actual)2026-02-15

Compare Resolved to Due: the feature finished 2026-02-15 — ten months BEFORE its own 2026-12-01 due date

Why: Finishing early is possible, but a 14-month start-to-due window followed by a 4-month actual delivery is unusual enough to flag. Likely correct Due Date: 2025-12-01, a ~14-week target consistent with the Feb 2026 finish.

On screen right now: nothing looks visibly wrong on the chart itself — DPN-021 plots as an ordinary point. This is a spreadsheet-only catch, which is exactly why a coherence check has to be a deliberate step, not something you wait to stumble on visually.

33. Fill in: Value for DPN-021 — a coherence check

Comparison

Comparison matrix

From DPN-021 — a coherence check: refill the Value column from what you know. The rest of the table is as it appeared.

FieldValue
Start Date2025-10-15
Due Date (Planned)2026-12-01
Resolved (Actual)2026-02-15

34. Something is wrong here: "Tableau should catch these errors"

Anomaly

Predict first

A student writes this, and it looks reasonable:

Why this is tempting: most modern software validates input somewhere — a form won't let you submit an invalid email, a database can enforce constraints. It's a reasonable, common assumption that a mature tool like Tableau does something similar for dates. It doesn't.

It is wrong. Say what breaks — and say it before you turn the page.

Correct: Nothing happens. Tableau parses 2036-01-30 and 2016-12-09 exactly as written — they're valid dates, just wrong ones.

Treat Tableau as a presentation layer with zero validation gates, and audit upstream.

Why: Nothing happens. Tableau parses 2036-01-30 and 2016-12-09 exactly as written — they're valid dates, just wrong ones. A spreadsheet enforces no 'Resolved ≤ Due' rule.

35. Trap: "Tableau should catch these errors"

Trap

The trap

Why this is tempting: most modern software validates input somewhere — a form won't let you submit an invalid email, a database can enforce constraints. It's a reasonable, common assumption that a mature tool like Tableau does something similar for dates. It doesn't.

"Surely a decade-off date or a resolved-before-due feature throws an error somewhere."

Load the raw file and expect a warning

Why: Nothing happens. Tableau parses 2036-01-30 and 2016-12-09 exactly as written — they're valid dates, just wrong ones. A spreadsheet enforces no 'Resolved ≤ Due' rule.

The fix

Treat Tableau as a presentation layer with zero validation gates, and audit upstream.

Spot-check date ranges and date logic before building, in Excel or with a simple validation sheet

Why: The fix belongs in the Jira export process (or a pre-import script), not in Tableau. Tableau will faithfully chart whatever you hand it, typos included.

36. Orphan Parent Epic: a foreign key pointing nowhere

Concept

One more category of silent failure, and then Part 2 is done: what happens when a foreign key points at something that simply isn't there.

DPN-060 and DPN-061 both list Parent Epic = DPN-006. Check the Epics sheet: it only contains DPN-001 through DPN-005. DPN-006 is a Feature, not an Epic.

orphan row — A row whose foreign key value doesn't match any row on the other side of a relationship. The relationship match simply fails — the row isn't deleted, it just never joins into any epic-scoped view.

37. Take the definitions apart: relationship vs orphan row

Definition probe

Sort into buckets

Every line below is part of the definition of relationship or of orphan row — one or the other, never both. Put each where it belongs.

relationship
A logical-layer link between two tables that keeps each table at its own grain; one row per epic, one row per feature; until a sheet actually needs to combine them.
orphan row
A row whose foreign key value doesn't match any row on the other side of a relationship.; The relationship match simply fails; the row isn't deleted, it just never joins into any epic-scoped view.
b1
A logical-layer link between two tables that keeps each table at its own grain — one row per epic, one row per feature — until a sheet actually needs to combine them. Contrast with a physical join, which flattens the tables into one.
b2
A row whose foreign key value doesn't match any row on the other side of a relationship. The relationship match simply fails — the row isn't deleted, it just never joins into any epic-scoped view.

38. Find the missing two

Worked example

Filter the validation sheet to Epic DPN-001. You see exactly 9 features — correct, matching the table from Part 1.

Ask: shouldn't DPN-060/061 also appear, since DPN-006 (their parent) is itself part of DPN-001?

Why: Jira's data model here only supports Epic → Feature, one level. DPN-060/061 point to a Feature acting as a pseudo-parent, which the Epics relationship can't traverse.

Inspect Parent Epic for DPN-060/061 → DPN-006 → look it up in the Epics sheet → not found

Why: Features.Parent Epic = Epics.Key has no match for DPN-006 on the Epics side, so DPN-060/061 are silently excluded from every epic-filtered view — no error, just two missing rows.

On screen right now: filtering the validation sheet to DPN-001 shows exactly 9 rows — correct on its face — and nothing on screen hints that two more features (DPN-060/061) exist anywhere. Their absence IS the lesson; there's no error banner to notice.

39. Draw the shape of it: Find the missing two

Blank canvas

Draw it

Draw what Find the missing two just did — the shape of it, not the line-by-line working. One picture, labels only where you need them. Then check it against the steps: anything you could not draw is a step you followed rather than understood.

40. Trap: "I'll just delete the bad rows"

Trap

The trap

Why this is tempting: deleting the broken rows makes the chart look clean immediately, and under time pressure it feels like “cleanup” rather than data loss — the goal in the moment is just a working chart on screen.

"DPN-060/061 are broken and DPN-038–047 are all empty after the pivot — cut them from the source file so the chart looks clean."

Delete the offending rows from the Excel source

Why: This destroys real project data — 13 legitimate Build-3A/3B/orphan features — to hide a formatting problem, and leaves no record that anything was ever wrong.

The fix

Audit, document, and fix the positions and values — never the row count.

Un-shift Build 3A/3B back into H/I/J, correct the three typo dates, and flag DPN-060/061's Parent Epic for a Jira-side fix

Why: The cleaned copy keeps every feature; only the broken cells change. The raw file stays untouched as the before/after teaching artifact.

41. Break it on purpose: "I'll just delete the bad rows"

Break the constraint

Discussion prompt

The rule this trap just fixed:

The cleaned copy keeps every feature; only the broken cells change. The raw file stays untouched as the before/after teaching artifact.

Now break it on purpose. Build a case that violates it and follow the consequences until something visibly fails. Where does the failure first show up — and would you have noticed it if you had not been looking?

Hint: The dangerous rules are the ones whose violation still produces an answer. If yours fails loudly, try to find one that fails quietly.

Answer:

This destroys real project data — 13 legitimate Build-3A/3B/orphan features — to hide a formatting problem, and leaves no record that anything was ever wrong.

42. Part 3 — Pivot to Long Format

Section

Segment 4

43. Roadmap for Part 3

Concept

In this part: reshape three wide date columns into one long Milestone Type / Milestone Date pair, so a single axis can hold all three series. About 5 minutes — short and mechanical, and the one step that makes everything after it possible.

44. Wide data can't share one axis

Concept

The data is clean now (or you know exactly what's still broken). Before the chart can show three lines, the data itself has to change shape — that's this part.

Right now Due Date, Planned Completion, and Resolved are three separate columns. Tableau can only put ONE date field on a continuous axis — you'd need a dual axis (caps at two) or Measure Values (visually noisy) to force three.

tidy data — Data shaped so each row is one observation and each column is one variable. Here, one 'feature' isn't one observation — one (feature, milestone type) pair is.

In plain words: tidy data means one row = one observation. Right now one feature spans three columns of dates; after the pivot, one feature spans three ROWS, one per milestone — which is what lets a single axis show all three.

45. Pivot = turn columns into rows

Intuition

Picture the three date columns as three separate lanes on a highway. A pivot merges them into a single lane with a sign on each car saying which lane it came from — one axis (Milestone Date), one label (Milestone Type) a color encoding can read directly.

Every feature that had three date columns now becomes three rows: one row for its Planned date, one for its Projected date, one for its Actual date.

Another way to say it: a wide layout is like a sign-in sheet with three separate columns for “Monday visit,” “Tuesday visit,” and “Wednesday visit.” A tidy, pivoted version has one column for “visit date” and one column for “which day” — every visit gets its own row, sign-in-sheet style, no matter how many days someone came in.

46. Where does each piece belong: Jira Burndown in Tableau: Planned, Actual &…

Sorting

Sort into buckets

These are the pieces of Jira Burndown in Tableau: Planned, Actual & Projected on One Chart, out of order. Put each one back under the part of the lesson it belongs to.

Part 1 — Connect & Relate
Roadmap for Part 1; Two tabs, one relationship; Relationships keep the grain; joins flatten it
Part 2 — Audit Before You Build
Roadmap for Part 2; The validation sheet's real job; The count that shouldn't drop
Part 3 — Pivot to Long Format
Roadmap for Part 3; Wide data can't share one axis; Pivot = turn columns into rows
s1
Part 1 — Connect & Relate is where Jira Burndown in Tableau: Planned, Actual & Projected on One Chart puts Roadmap for Part 1, Two tabs, one relationship, Relationships keep the grain; joins flatten it. Knowing which part of the lesson a problem belongs to is most of knowing which method to reach for.
s2
Part 2 — Audit Before You Build is where Jira Burndown in Tableau: Planned, Actual & Projected on One Chart puts Roadmap for Part 2, The validation sheet's real job, The count that shouldn't drop. Knowing which part of the lesson a problem belongs to is most of knowing which method to reach for.
s3
Part 3 — Pivot to Long Format is where Jira Burndown in Tableau: Planned, Actual & Projected on One Chart puts Roadmap for Part 3, Wide data can't share one axis, Pivot = turn columns into rows. Knowing which part of the lesson a problem belongs to is most of knowing which method to reach for.

47. Guess the shape of the answer: Build the pivot

Estimation

Predict first

Click-path: open the Features table's physical layer. Select Due Date (Planned), Planned Completion (Projected), and Resolved (Actual) (Ctrl/Cmd-click all three) → right-click → Pivot.

Commit before you compute: what does Build the pivot come out to? A rough magnitude and the right form is enough — the point is to have something concrete to be wrong about.

Correct: Alias the three Milestone Type values to Planned / Projected / Actual

Why: A prediction you can defend turns the computation into a check rather than a leap of faith — and an answer that contradicts it is caught on the spot. The raw pivot values are the original column headers verbatim — alias them to the short labels the legend and tooltips will show.

48. Build the pivot

Worked example

Click-path: open the Features table's physical layer. Select Due Date (Planned), Planned Completion (Projected), and Resolved (Actual) (Ctrl/Cmd-click all three) → right-click → Pivot.

Rename the two new fields: Pivot Field Names -> Milestone Type, Pivot Field Values -> Milestone Date

Why: The generated names are meaningless placeholders; renaming makes every downstream shelf and calc readable.

Alias the three Milestone Type values to Planned / Projected / Actual

Why: The raw pivot values are the original column headers verbatim — alias them to the short labels the legend and tooltips will show.

KeyMilestone TypeMilestone Date
DPN-006Planned2025-XX-XX
DPN-006Projected(null or date)
DPN-006Actual(null or date)

On screen right now: the Features physical table used to show one row per feature with three separate date columns; after Pivot, the same table shows three rows per feature sharing two new columns — Milestone Type and Milestone Date — with the original three date columns folded into them (reshaped, not deleted).

49. Watch it run: Build the pivot

Pattern

Step through it

Step through Build the pivot one row at a time. What is driving the change, and what would the row after the last one be?

  1. Step 1: Key is DPN-006
  2. Step 2: Key is DPN-006
  3. Step 3: Key is DPN-006

50. Null dates are signal, not noise

Concept

One immediate side effect of the pivot needs addressing before you build anything on top of it: some of those new rows will have a blank date. That's expected — how you handle it matters.

An unresolved feature has no Actual date; a Build-0 feature might have no Projected date. After the pivot those rows still exist — with Milestone Date = null — because "not done yet" and "no forecast issued" are real, true facts about the project.

Handling rule: exclude nulls per-visualization (a Milestone Date filter on the sheet), never delete them from the source. Deleting would erase the fact that a feature exists and just hasn't hit that milestone.

51. Something is wrong here: three measures on a shared axis instead

Anomaly

Predict first

A student writes this, and it looks reasonable:

Why this is tempting: dragging three familiar date fields straight onto Columns feels more direct than learning a new reshaping step — the same instinct as the join-instead-of-relate trap back in Part 1: skip the unfamiliar step, use what you already know.

It is wrong. Say what breaks — and say it before you turn the page.

Correct: Tableau accepts only one continuous date per axis without a dual axis or Measure Values — forcing three onto two axis slots (or blending them into Measure Names/Values) produces overlapping, hard-to-label lines.

Pivot first, so there is only ever ONE date field to place.

Why: Tableau accepts only one continuous date per axis without a dual axis or Measure Values — forcing three onto two axis slots (or blending them into Measure Names/Values) produces overlapping, hard-to-label lines.

52. Trap: three measures on a shared axis instead

Trap

The trap

Why this is tempting: dragging three familiar date fields straight onto Columns feels more direct than learning a new reshaping step — the same instinct as the join-instead-of-relate trap back in Part 1: skip the unfamiliar step, use what you already know.

"Why pivot? Just put Due Date, Planned Completion, and Resolved on the same chart directly."

Try to drag all three date fields onto Columns

Why: Tableau accepts only one continuous date per axis without a dual axis or Measure Values — forcing three onto two axis slots (or blending them into Measure Names/Values) produces overlapping, hard-to-label lines.

The fix

Pivot first, so there is only ever ONE date field to place.

One Milestone Date on Columns, Milestone Type on Color

Why: The reshape does the work up front so the chart-building step is trivial: one axis, one color legend, no dual-axis synchronization to fight.

53. Part 4 — The Running % Complete Calc

Section

Segments 5–6

54. Roadmap for Part 4

Concept

In this part: build a raw running count with COUNTD, then turn it into a percentage using a FIXED-LOD denominator that refuses to let any one series grade its own homework. About 11 minutes (3 for the raw count, 8 for the calculation and its table-calc scope) — this is the conceptual heart of the whole session.

55. Before a percentage, get a raw count

Concept

Every percentage is a fraction wearing a costume. Before writing the % formula, build its numerator out in the open so you can see exactly what's being counted.

Drag Milestone Date (continuous) to Columns and COUNTD([Key]) to Rows, Milestone Type to Color. You now see three lines of raw cumulative feature counts, rising left to right.

Why COUNTD, not COUNT(rows): the pivot just tripled every feature into three rows. COUNT([Number of Records]) would count each feature three times over; COUNTD([Key]) counts each distinct feature key exactly once per date it appears.

56. The raw counts you should see

Worked example

On the raw file, the running COUNTD per series should climb toward:

SeriesRaw count (of 44)
Planned29
Actual18
Projected11

If any series shows a number near 44×3 = 132, the wrong aggregation is in play

Why: That would mean COUNT(rows) slipped in somewhere instead of COUNTD([Key]) — a dead giveaway of the pivot-triplication trap.

On screen right now: three lines climb from left to right, topping out at three different heights: Planned's line reaches highest (29), Actual reaches partway (18), and Projected reaches lowest (11) — this is the raw file, before any of Part 2's fixes are applied.

57. Watch it run: The raw counts you should see

Pattern

Step through it

Step through The raw counts you should see one row at a time. What is driving the change, and what would the row after the last one be?

  1. Step 1: Series is Planned
  2. Step 2: Series is Actual
  3. Step 3: Series is Projected

58. Something is wrong here: COUNT(rows) after a pivot

Anomaly

Predict first

A student writes this, and it looks reasonable:

Why this is tempting: COUNT is the everyday word for “how many,” and before the pivot, COUNT(rows) and COUNTD(feature) would have given the same answer — the trap only exists because the pivot quietly tripled the row count out from under that old assumption.

It is wrong. Say what breaks — and say it before you turn the page.

Correct: The pivot turned 44 features into 132 rows.

Count distinct feature keys, not rows.

Why: The pivot turned 44 features into 132 rows. A plain row count triples every series' total, and any percentage built on it is meaningless.

59. Trap: COUNT(rows) after a pivot

Trap

The trap

Why this is tempting: COUNT is the everyday word for “how many,” and before the pivot, COUNT(rows) and COUNTD(feature) would have given the same answer — the trap only exists because the pivot quietly tripled the row count out from under that old assumption.

"Just count the rows — that's what COUNT does."

COUNT([Milestone Date])   -- or SUM([Number of Records])

Every feature counts up to three times

Why: The pivot turned 44 features into 132 rows. A plain row count triples every series' total, and any percentage built on it is meaningless.

The fix

Count distinct feature keys, not rows.

Use COUNTD([Key]) wherever the denominator or a raw count is needed

Why: COUNTD collapses the pivot's triplication back down to one count per feature, regardless of how many milestone rows that feature now has.

60. The % Complete formula

Concept

Before the formula itself, here's what each piece needs to do in plain English: RUNNING_SUM just means ‘keep a running tally as we move left to right along the dates.’ COUNT means ‘how many features hit this exact date.’ FIXED means ‘count something once, over the whole table, no matter what date or series we happen to be looking at.’ Put together: a running tally of features-per-date, divided by one constant total.

Create a calculated field named % Complete (running):

RUNNING_SUM(COUNT([Milestone Date])) / ATTR({FIXED : COUNTD([Key])})

COUNT([Milestone Date]) counts features per date, skipping nulls automatically. RUNNING_SUM(...) accumulates that count left to right along the date axis. ATTR({FIXED : COUNTD([Key])}) is a constant: the total distinct feature count (44), computed once, ignoring series or nulls.

61. Why per-series totals lie

Intuition

Imagine dividing the Actual series by its OWN non-null total instead — 18 resolved features divided by 18 (its own count). That reaches 100%. But 18 out of the project's real 44 features is only 41% complete. The series would be lying about the whole project by only ever grading itself.

The FIXED LOD sidesteps this entirely: the denominator is the same 44 for every series, every date, no matter how many of that series' own rows are null.

The takeaway: “percent complete” only means something if everyone agrees what 100% is. A FIXED denominator forces every series to agree: 100% is always all 44 features, not just the ones that happen to have data in that particular series.

62. Predict the next row: Configure the table calculation

Pattern

Predict first

The table runs: Date checked, Type unchecked (correct) | Three independent rising lines · Date + Type both checked | Lines compete for one sum; no partition

In Configure the table calculation, given the rows so far: what is the next one — the row where Compute Using setting is Type checked, Date unchecked?

Correct: Type checked, Date unchecked | Each series jumps once, then flat-lines

Compute Using settingVisual result
Date checked, Type unchecked (correct)Three independent rising lines
Date + Type both checkedLines compete for one sum; no partition
Type checked, Date uncheckedEach series jumps once, then flat-lines

Why: The relationship between the columns, not the individual numbers, is what generates the next row. This is the running axis: the sum accumulates left to right as dates increase.

63. Configure the table calculation

Worked example

Right-click the % Complete (running) pill on Rows → Edit Table Calculation → Compute Using → Specific Dimensions.

Check Milestone Date

Why: This is the running axis: the sum accumulates left to right as dates increase.

Uncheck Milestone Type

Why: Unchecking it makes the sum restart (partition) for each series — so Planned, Actual, and Projected each run their own independent accumulation instead of blending into one merged total.

Compute Using settingVisual result
Date checked, Type unchecked (correct)Three independent rising lines
Date + Type both checkedLines compete for one sum; no partition
Type checked, Date uncheckedEach series jumps once, then flat-lines

On screen right now: three separate lines, each starting near 0% at its own earliest date and climbing independently. If instead you see one merged line, or three lines that all jump straight to 100%, Compute Using is set wrong — recheck the settings table two beats back.

64. Trap: the Actual series self-normalizes to 100%

Trap

The trap

Why this is tempting: it feels more “accurate” to only count features that could possibly have an Actual date — dividing by the whole project can look like padding the denominator with irrelevant rows. The catch: “irrelevant to Actual” is exactly the 26 unresolved features the chart exists to show you.

"The denominator should just be however many features actually have a Resolved date — why divide by the whole project?"

RUNNING_SUM(COUNT([Milestone Date])) / ATTR({FIXED : COUNTD(IF NOT ISNULL([Resolved]) THEN [Key] END)})

Actual climbs to a false 100%

Why: 18 resolved out of 18-with-a-date is 100% — but that hides the 26 features still unresolved. The chart would claim the project is finished when it's really at 18/44 ≈ 41%.

The fix

Keep the denominator FIXED over ALL distinct features, every series, no exceptions.

ATTR({FIXED : COUNTD([Key])})

Actual correctly plateaus at ~41% (18/44)

Why: The true resolved share is visible precisely because unresolved features stay in the denominator even though they never contribute to the numerator.

65. Part 5 — Style: Color, TODAY(), Line Pattern

Section

Segments 7–8

66. Roadmap for Part 5

Concept

In this part: give the three series meaningful colors, mark today's date with a reference line, and encode Projected as a dashed line (with a fallback for older Tableau versions). About 7 minutes (2 for color, 5 for the TODAY() line and line pattern) — the math is already done, so this is where the chart starts telling its story without you narrating it.

67. Color must encode meaning

Concept

The math is done; the rest of this part is about making the chart tell its story to someone who's only glancing at it for three seconds.

Milestone Type on Color already separates the three lines. But which colors say what you mean matters: a chart reader should feel confidence differences at a glance, not just count distinct hues.

SeriesSuggested colorWhat it signals
PlannedNeutral gray-blue (#6B8DAE)The baseline everyone's working toward
ActualSaturated green (#2E7D32)Confirmed fact — this happened
ProjectedLight tint (#A5D6A7)A forecast — tentative, not yet real

68. What each one costs: Color must encode meaning

Trade off

Comparison matrix

From Color must encode meaning: every row here is a choice with a cost. Fill the What it signals column, then say which row you would actually pick and what you give up for it.

SeriesSuggested colorWhat it signals
PlannedNeutral gray-blue (#6B8DAE)The baseline everyone's working toward
ActualSaturated green (#2E7D32)Confirmed fact — this happened
ProjectedLight tint (#A5D6A7)A forecast — tentative, not yet real

69. Assign the series colors

Worked example

Right-click the Milestone Type pill on Color -> Edit Colors

Why: Opens the per-value color picker for the three aliased labels (Planned / Actual / Projected).

Set Planned = #6B8DAE, Actual = #2E7D32, Projected = #A5D6A7

Why: Saturation now carries meaning: the darkest, most confident color is reserved for what's already happened.

On screen right now: the legend reads Planned / Actual / Projected in gray-blue, dark green, and pale green — glance at the chart and the darkest line is immediately the one you can trust most (Actual), which is the whole design intent.

70. Something is wrong here: three equally bright colors

Anomaly

Predict first

A student writes this, and it looks reasonable:

Why this is tempting: bright, saturated colors are the default instinct for “making a chart pop,” and nothing about picking red/blue/yellow feels wrong in isolation — the problem only shows up once a viewer tries to guess which line is the confirmed fact and which is the guess.

It is wrong. Say what breaks — and say it before you turn the page.

Correct: Bright, fully-saturated hues all look equally 'real' to a viewer.

Reserve saturation for certainty; use a light tint for anything forecasted.

Why: Bright, fully-saturated hues all look equally 'real' to a viewer. Nothing distinguishes a confirmed Actual point from a Projected guess except the legend text — which most viewers never read.

71. Trap: three equally bright colors

Trap

The trap

Why this is tempting: bright, saturated colors are the default instinct for “making a chart pop,” and nothing about picking red/blue/yellow feels wrong in isolation — the problem only shows up once a viewer tries to guess which line is the confirmed fact and which is the guess.

"Just pick three colors that pop — red, blue, yellow."

All three lines read as equally certain

Why: Bright, fully-saturated hues all look equally 'real' to a viewer. Nothing distinguishes a confirmed Actual point from a Projected guess except the legend text — which most viewers never read.

The fix

Reserve saturation for certainty; use a light tint for anything forecasted.

Keep Projected visibly lighter than Planned and Actual

Why: The eye reads a light tint as tentative before it even reads the legend. Encoding does work the legend alone can't.

72. Which of these survive contact with Jira Burndown in Tableau: Planned, Actual &…?

Two truths and a lie

Sort into buckets

Some of these hold up and some are the exact mistakes this lesson is built to prevent. Sort them.

Holds up
Before wiring anything up, look at where you're headed. The reference workbook's finished chart has three lines on one axis, colored by Milestone Type.; The export is two Excel tabs: Epics (Parents) — 5 rows — and Features (Children) — 44 rows — linked by Features.Parent Epic = Epics.Key.; Rule of thumb: if a total looks smaller than it should, don't assume the project shrank. Assume the data did.
Breaks
"A join is more standard, and it's faster — just join the tables."; "29 out of 44 planned dates — maybe some features just don't have a due date yet. That's normal for an active project."
sound
These are stated as this lesson states them — each one survives the edge cases Jira Burndown in Tableau: Planned, Actual & Projected on One Chart puts it through.
flawed
Each of these is lifted from a trap in this deck: reasonable-sounding, and wrong in a way that only shows up once you rely on it.

73. TODAY() marks history vs. forecast

Concept

One more encoding decision before line style: where does “now” sit on this chart, and how does a viewer know it without reading a single label?

A reference line at TODAY() is the one visual element that tells a viewer, without reading anything, where fact ends and forecast begins.

Click-path: right-click the Milestone Date axis → Add Reference Line → Scope: Entire Table, Line: Constant, Value: TODAY(), Label: "Today", Style: solid gray.

74. Add the reference line

Worked example

Build the constant reference line at TODAY()

Why: Everything left of the line is confirmed history (Planned/Actual points that already happened); everything right of it is forecast territory (remaining Planned dates and all Projected points).

Optionally shade the region right of TODAY() with a reference band

Why: A light background tint reinforces the same past/future split without relying on the line alone.

On screen right now: a single vertical gray line now crosses the chart at today's date, with a small “Today” label — every Planned/Actual point to its left is confirmed history; everything to its right, including the whole Projected series, is forecast territory.

75. Encoding uncertainty with line style

Concept

Color already tells Planned/Actual/Projected apart, so why add a second signal? Because not every viewer reads a legend carefully, and dashed-vs-solid still works even for someone who can't quite tell your two greens apart.

Color already separates the three series, but a dashed Projected line adds a second, redundant signal: "this is a guess, not a fact" — useful for anyone who can't easily distinguish the two greens.

Tableau 2023.2 added a Path-shelf Line Pattern for exactly this: per-series solid vs. dashed rendering on one chart, no workaround required.

76. Build the Line Pattern

Worked example

Before the formula: this calc doesn't compute anything numeric — it's just a label-switch. Read it as ‘if this row's series is Projected, call it Dashed; otherwise call it Solid,’ which the Path shelf then turns into an actual stroke style.

Create a calculated field Line Pattern:

IF [Milestone Type] = "Projected" THEN "Dashed" ELSE "Solid" END

Drag Line Pattern to the Path shelf (Marks card → right-click → Path if not visible)

Why: The Path shelf controls how a mark connects to its neighbors along the line; assigning it a dimension lets each value get its own stroke style.

Edit Path -> assign "Solid" and "Dashed" to the two values

Why: Planned and Actual render as solid strokes (fact); Projected renders dashed (forecast) — visually redundant with color, which is exactly the point.

On screen right now: Planned and Actual render as solid strokes; Projected renders as a dashed stroke — the same visual vocabulary as a blueprint's dashed “proposed” lines versus its solid “built” ones.

77. Limitation: Line Pattern needs Tableau 2023.2+

Concept

Before moving on, one honest pause: the step you just did doesn't exist on every Tableau install. Worth knowing before you promise it to a student or colleague.

Limitation callout: the Path-shelf Line Pattern feature doesn't exist before Tableau 2023.2. On an older install, the Path shelf simply won't offer dashed/solid styling — there's no error, the option is just absent.

Check the student's Tableau version before promising this step. If it's older, the fallback below still gets a visually distinct Projected line — just with more setup.

78. Teach it back: Limitation: Line Pattern needs Tableau 2023.2+

Explain it

Discussion prompt

Explain Limitation: Line Pattern needs Tableau 2023.2+ to a student a year behind you. No notation, no jargon they have not met — and it still has to be true.

Hint: If your explanation needs a symbol they have never seen, you are describing the notation rather than the idea.

Answer:

Before moving on, one honest pause: the step you just did doesn't exist on every Tableau install. Worth knowing before you promise it to a student or colleague.

79. Fallback: split-at-TODAY() calcs

Worked example

Pre-2023.2, build two calculated fields that split the SAME measure at the boundary, so they visually overlap and appear to connect:

// % Complete (Historical)
IF [Milestone Date] <= TODAY() THEN [% Complete (running)] END

// % Complete (Forecast)
IF [Milestone Date] >= TODAY() THEN [% Complete (running)] END

Use <= and >= (not < and >) on the two calcs

Why: The overlapping comparison means both calcs return a value exactly on TODAY() itself — the one point where the two segments meet — so the lines touch instead of leaving a visible gap.

Style each calc's line independently (solid for Historical, dashed for Forecast)

Why: Because they're two separate measures now, Tableau lets you format each one's line style without needing the Path-shelf feature at all.

On screen right now (pre-2023.2): two measures instead of one, each formatted with its own line style, meeting at a single shared point directly on the TODAY() line — from a normal viewing distance the join is invisible and the chart reads as one continuous, correctly-styled line.

80. Inspect it line by line: Fallback: split-at-TODAY() calcs

Error analysis

Annotate

Walk the callouts on Fallback: split-at-TODAY() calcs. Each one is a place this is easy to get subtly wrong.

  • The overlapping comparison means both calcs return a value exactly on TODAY() itself — the one point where the two segments meet — so the lines touch instead of leaving a visible gap.
  • Because they're two separate measures now, Tableau lets you format each one's line style without needing the Path-shelf feature at all.

81. Part 6 — Forecast Limitation & Formatting

Section

Segment 9 + limitations

82. Roadmap for Part 6

Concept

In this part: see exactly why Tableau's built-in Forecast feature can't touch a table-calc measure, then spend about 5 minutes on formatting — percentage axis, date axis, tooltips, legend order — the small polish that turns a working chart into a readable one.

83. Limitation: Forecast is greyed out on table calcs

Concept

Here's a second honest limitation, worth knowing before a student asks you to “just have Tableau predict the rest.”

Limitation callout: Tableau's built-in Forecast (exponential smoothing) cannot run on a table-calculation measure. % Complete (running) is a table calc, so Forecast is disabled for it — greyed out in the Analytics pane, no explanation given.

This is exactly why the session uses the export's OWN Planned Completion (Projected) column instead of asking Tableau to forecast anything. It's arguably better data anyway: it's the team's own revised estimate, not a generic statistical extrapolation.

84. What has to be given first: See the limitation, then use the real fix

Missing information

Discussion prompt

If a real statistical forecast is ever needed, it has to be computed outside Tableau (Python, R) and imported as a column — Tableau's Forecast feature is a presentation tool here, not a data-science one.

What do you need to know — or decide — before the first line can be written? List everything the problem has to hand you.

Hint: Anything you would have to invent to get started is a thing the problem must supply.

Answer:

The Forecast option is greyed out / does nothing, because the measure is a table calc.

85. See the limitation, then use the real fix

Worked example

Drag Analytics -> Forecast onto the sheet with % Complete (running) in view

Why: The Forecast option is greyed out / does nothing, because the measure is a table calc.

Confirm the Projected series is already doing this job

Why: Milestone Type = Projected, sourced from the export's own Planned Completion column, plots exactly where a forecast would — without fighting Tableau's Forecast restriction at all.

If a real statistical forecast is ever needed, it has to be computed outside Tableau (Python, R) and imported as a column — Tableau's Forecast feature is a presentation tool here, not a data-science one.

On screen right now: the Analytics pane's Forecast option sits greyed out with no tooltip explaining why — nothing in the UI tells you it's because the measure is a table calc, which is exactly why this is worth demonstrating live rather than just describing.

86. Draw the shape of it: See the limitation, then use the real fix

Blank canvas

Draw it

Draw what See the limitation, then use the real fix just did — the shape of it, not the line-by-line working. One picture, labels only where you need them. Then check it against the steps: anything you could not draw is a step you followed rather than understood.

87. Formatting is clarity, not decoration

Concept

The chart is functionally complete. What's left is making sure nobody has to do mental math or guess a date format just to read it.

A misformatted axis actively confuses a reader: an Excel serial number instead of a date, or a raw 0.41 instead of 41%, forces them to do translation work the chart should have done for them.

Four formatting moves finish the chart: percentage axis, date axis title, tooltip contents, and legend order.

88. By analogy: Formatting is clarity, not decoration

Analogy

Discussion prompt

Explain Formatting is clarity, not decoration by analogy to something with no Business Analytics in it at all — a queue, a recipe, a map, a bank balance, whatever fits. Then say where your analogy breaks.

Hint: An analogy that never breaks is not an analogy, it is the same idea wearing a hat. Find the seam — that is the part that is actually new.

Answer:

The chart is functionally complete. What's left is making sure nobody has to do mental math or guess a date format just to read it.

89. What has to happen first: Finish the formatting

Ranking

Put in order

Put the moves of Finish the formatting into the order they have to happen.

  1. Right-click the % Complete axis -> Format -> Numbers -> Percentage, 0 decimals
  2. Right-click the Milestone Date axis -> Edit Axis -> Automatic date format, title "Milestone Date"
  3. Right-click Marks -> Tooltip -> show Milestone Type, Milestone Date, % Complete (running), and COUNTD([Key])
  4. Reorder the legend to Planned, Actual, Projected

Why: These are the moves of the worked example in the order it makes them, and each one is set up by the one before it. Shows "41%" instead of "0.41" or a false-precision "41.11%" the raw counts don't justify.

90. Finish the formatting

Worked example

Right-click the % Complete axis -> Format -> Numbers -> Percentage, 0 decimals

Why: Shows "41%" instead of "0.41" or a false-precision "41.11%" the raw counts don't justify.

Right-click the Milestone Date axis -> Edit Axis -> Automatic date format, title "Milestone Date"

Why: Confirms the axis reads as calendar dates, not Excel serial numbers.

Right-click Marks -> Tooltip -> show Milestone Type, Milestone Date, % Complete (running), and COUNTD([Key])

Why: A hover should answer 'which series, which date, what percent, how many features' without the viewer clicking anything else.

Reorder the legend to Planned, Actual, Projected

Why: Matches the reading order of the lesson itself: baseline, then what happened, then what's forecast.

On screen right now: the % axis reads in clean percentages (like 41%, not 0.41), the date axis reads as calendar dates (not a five-digit Excel serial number), and hovering any point pops up a tooltip naming the series, date, percent, and feature count together.

91. Work backwards from the answer: Finish the formatting

Reverse engineer

Discussion prompt

Work backwards. The example finished here:

Reorder the legend to Planned, Actual, Projected

What was it asked to do, and what must it have been given? Reconstruct the problem from its answer.

Hint: Every quantity in the result had to enter somewhere. Account for each one.

Answer:

On screen right now: the % axis reads in clean percentages (like 41%, not 0.41), the date axis reads as calendar dates (not a five-digit Excel serial number), and hovering any point pops up a tooltip naming the series, date, percent, and feature count together.

92. Part 7 — Validate & Wrap Up

Section

Segment 10

93. Roadmap for Part 7

Concept

In this part: spot-check the finished chart's numbers against the audit from Part 2, walk the eight-step recipe that generalizes to any burndown, and answer five check questions before the recap. About 5 minutes for the validation pass itself, plus the pattern and checks.

94. Validation is the last hygiene step, not an afterthought

Concept

One last discipline before you call this done: check the finished chart's numbers the same skeptical way you checked the raw data back in Part 2.

A chart that LOOKS reasonable isn't the same as a chart that IS correct. Before calling the build done, spot-check every series against numbers you already know from Parts 2 and 4.

This is the same audit mindset from Part 2, applied one more time — to the finished chart instead of the raw data.

95. Break it if you can: Validation is the last hygiene step, not an…

Counterexample

Discussion prompt

One last discipline before you call this done: check the finished chart's numbers the same skeptical way you checked the raw data back in Part 2.

That is stated as though it always holds. Do one of two things: produce a case where it fails, or say precisely what rules such a case out. "It just does" is not on the menu.

Hint: Hunt at the extremes first — zero, one, negative, empty, equal. If every extreme survives, the reason they survive is the proof.

Answer:

A chart that LOOKS reasonable isn't the same as a chart that IS correct. Before calling the build done, spot-check every series against numbers you already know from Parts 2 and 4.

96. Guess the shape of the answer: The full spot-check

Estimation

Predict first

On screen right now: hover the rightmost point of each line — Planned should read 100% on the cleaned file (66% on raw), Actual should read 41% on both files, and Projected should read 25% on both files. Any other number means a step upstream needs revisiting.

Commit before you compute: what does The full spot-check come out to? A rough magnitude and the right form is enough — the point is to have something concrete to be wrong about.

Correct: If Actual ever reaches 100%, the FIXED-LOD denominator was swapped for a series-specific one

Why: A prediction you can defend turns the computation into a check rather than a leap of faith — and an answer that contradicts it is caught on the spot. 41% is the true resolved share; only a self-normalizing denominator (Part 4's trap) would push it higher.

97. The full spot-check

Worked example

SeriesRaw fileCleaned file
Planned29/44 -> 66%44/44 -> 100%
Actual18/44 -> 41%18/44 -> 41% (unchanged)
Projected11/44 -> 25%11/44 -> 25% (unchanged)

If Planned reaches only 66% on the cleaned file, the column shift wasn't actually fixed

Why: 100% on Planned is the tell that all 44 due dates are now in column H where they belong.

If Actual ever reaches 100%, the FIXED-LOD denominator was swapped for a series-specific one

Why: 41% is the true resolved share; only a self-normalizing denominator (Part 4's trap) would push it higher.

On screen right now: hover the rightmost point of each line — Planned should read 100% on the cleaned file (66% on raw), Actual should read 41% on both files, and Projected should read 25% on both files. Any other number means a step upstream needs revisiting.

98. Fill in: Cleaned file for The full spot-check

Comparison

Comparison matrix

From The full spot-check: refill the Cleaned file column from what you know. The rest of the table is as it appeared.

SeriesRaw fileCleaned file
Planned29/44 -> 66%44/44 -> 100%
Actual18/44 -> 41%18/44 -> 41% (unchanged)
Projected11/44 -> 25%11/44 -> 25% (unchanged)

99. Without one step: The end-to-end recipe

Constraint

Discussion prompt

Run The end-to-end recipe with this step confiscated:

Count distinct keys (COUNTD), never raw rows, once the pivot has triplicated them.

Is it still possible? If it is, say what takes its place and what it costs you. If it is not, say exactly what that step was providing that nothing else does.

Hint: A step you can drop for free was never load-bearing. If you cannot drop it, name the thing that goes wrong the moment it is gone.

Answer:

  1. Connect & relate the tables in the logical layer — never a physical join.
  2. Validate: a count-by-epic sheet, checked on BOTH the raw and a cleaned copy of the file.
  3. Audit the raw data for column shifts, typo dates, and orphan foreign keys before pivoting.
  4. Pivot the wide date columns into one Milestone Type / Milestone Date pair; keep nulls, exclude per-viz.
  5. Count distinct keys (COUNTD), never raw rows, once the pivot has triplicated them.
  6. Calculate running % with a FIXED-LOD denominator over ALL distinct features — never a series-own total.
  7. Style with meaningful color + a TODAY() line + a dashed Projected series (or its pre-2023.2 fallback).
  8. Validate again: spot-check the finished chart's numbers against the audit from step 2.

100. The end-to-end recipe

Pattern

Every multi-series burndown you build this way follows the same eight moves. The topic changes; the shape doesn't:

  1. Connect & relate the tables in the logical layer — never a physical join.
  2. Validate: a count-by-epic sheet, checked on BOTH the raw and a cleaned copy of the file.
  3. Audit the raw data for column shifts, typo dates, and orphan foreign keys before pivoting.
  4. Pivot the wide date columns into one Milestone Type / Milestone Date pair; keep nulls, exclude per-viz.
  5. Count distinct keys (COUNTD), never raw rows, once the pivot has triplicated them.
  6. Calculate running % with a FIXED-LOD denominator over ALL distinct features — never a series-own total.
  7. Style with meaningful color + a TODAY() line + a dashed Projected series (or its pre-2023.2 fallback).
  8. Validate again: spot-check the finished chart's numbers against the audit from step 2.

The takeaway: none of these eight moves are Tableau trivia — they're the same eight questions (“how do these tables relate,” “is the data actually what I think,” “can one axis hold this,” “what's my real denominator,” “does the encoding tell the truth”) you'd ask of any burndown, in any tool, built from any messy export.

101. Where does it stop working: The end-to-end recipe

Edge cases

Discussion prompt

The end-to-end recipe works on the cases you have just seen. Push it to the edge: what is the most degenerate input it still handles — empty, zero, one item, everything equal — and what is the first case where it stops being true? Name the case, not just "it breaks".

Hint: Try the smallest legal input, then the largest, then the one where two things collide. Methods are specified at their edges; the middle takes care of itself.

Answer:

Every multi-series burndown you build this way follows the same eight moves. The topic changes; the shape doesn't:

102. Rule out three: Check yourself: relationship vs. join

Elimination

Eliminate the wrong options

Epics has 5 rows; Features has 44. If they're combined with a physical JOIN instead of a relationship, what happens to a SUM() built on an Epics-level field (like a budget column)?

3 of these 4 are wrong. Strike them one at a time, and say what rules each one out before you strike the next. The survivor is the answer.

  • A. It silently multiplies, because each Epic row now repeats once per matching Feature row
  • B. It stays correct, because Tableau automatically de-duplicates joined tables
  • C. It throws a duplicate-key error and the sheet won't build
  • D. It's cut in half, because the join drops half the Feature rows

Survives elimination: A

Why: A physical join flattens the two tables into one, repeating each Epic row once per matching Feature row. A SUM() on an Epics-only field then adds that same value in as many times as the epic has features — a silent multiplication with no warning.

103. Check yourself: relationship vs. join

Check

Recall what happens when two tables share the SAME physical layer instead of a relationship.

Check your understanding

Epics has 5 rows; Features has 44. If they're combined with a physical JOIN instead of a relationship, what happens to a SUM() built on an Epics-level field (like a budget column)?

  • A. It silently multiplies, because each Epic row now repeats once per matching Feature row (correct)
  • B. It stays correct, because Tableau automatically de-duplicates joined tables
  • C. It throws a duplicate-key error and the sheet won't build
  • D. It's cut in half, because the join drops half the Feature rows

Answer: A

Why: A physical join flattens the two tables into one, repeating each Epic row once per matching Feature row. A SUM() on an Epics-only field then adds that same value in as many times as the epic has features — a silent multiplication with no warning.

Why B tempts people
Tableau does not de-duplicate joined rows automatically; the duplication is the literal, unflagged result of the join.
Why C tempts people
There's no uniqueness constraint enforced here — the join just produces extra rows, with no error at all.
Why D tempts people
A join based on a valid Parent Epic match doesn't drop rows; it repeats the Epic side, it doesn't remove Feature rows.

104. Answer it before you see the options: Check yourself: the denominator

Prediction

Predict first

On the raw file, the Actual series's running % Complete formula uses ATTR({FIXED : COUNTD([Key])}) as its denominator. Why does the Actual line correctly stop at ~41% instead of 100%?

Answer it in your own words, now, with nothing to choose from. The options are on the next slide — and picking the right one off a list is an easier skill than producing it.

Correct: Because the denominator is fixed at all 44 features, but only 18 have a non-null Resolved date

Why: The FIXED LOD denominator counts all 44 distinct features regardless of series or nulls. The numerator (RUNNING_SUM of COUNT) only grows when a Resolved date exists — 18 of 44 — so the ratio tops out at 18/44 ≈ 41%, correctly reflecting that 26 features are still unresolved.

105. Check yourself: the denominator

Check

Think through what each denominator actually measures before you answer.

Check your understanding

On the raw file, the Actual series's running % Complete formula uses ATTR({FIXED : COUNTD([Key])}) as its denominator. Why does the Actual line correctly stop at ~41% instead of 100%?

  • A. Because the denominator is fixed at all 44 features, but only 18 have a non-null Resolved date (correct)
  • B. Because Tableau caps every percentage measure at 41% by default
  • C. Because the pivot deletes unresolved features from the data
  • D. Because the Milestone Date axis only shows dates up to today

Answer: A

Why: The FIXED LOD denominator counts all 44 distinct features regardless of series or nulls. The numerator (RUNNING_SUM of COUNT) only grows when a Resolved date exists — 18 of 44 — so the ratio tops out at 18/44 ≈ 41%, correctly reflecting that 26 features are still unresolved.

Why B tempts people
There's no built-in cap; 41% is a computed result (18÷44), not a Tableau default or limit.
Why C tempts people
The pivot keeps every feature; unresolved features get a null Milestone Date row, they are never deleted from the data.
Why D tempts people
The axis extends through all Milestone Dates in the data, including future Projected dates well past today — the plateau comes from the calc's denominator, not the axis range.

106. How sure are you: Check yourself: reading the raw vs. cleaned…

Commit first

Predict first

The Planned series reaches 29/44 (~66%) on the raw file but 44/44 (100%) on the cleaned file. What single fix explains the entire jump?

Commit to an answer, then rate it — certain, fairly sure, or guessing — and write the rating down before you turn the page.

Correct: Un-shifting the 15 column-shifted rows (Build 3A, Build 3B, and the two orphans) so their Due Date values land back in column H

Why: The column shift (Issue 0) is what emptied H/I/J for exactly those 15 rows. Moving each value back one column restores all 15 Due Dates, taking Planned from 29/44 to the full 44/44 — the other fixes (typos, orphan parent) don't touch the Due Date column at all.

The rating matters as much as the answer: confident-and-wrong is the combination that survives revision, because nothing about it feels like it needs revisiting.

107. Check yourself: reading the raw vs. cleaned counts

Check

Recall Part 2's numbers before answering.

Check your understanding

The Planned series reaches 29/44 (~66%) on the raw file but 44/44 (100%) on the cleaned file. What single fix explains the entire jump?

  • A. Un-shifting the 15 column-shifted rows (Build 3A, Build 3B, and the two orphans) so their Due Date values land back in column H (correct)
  • B. Deleting the 15 broken rows so only 29 features remain
  • C. Correcting the DPN-013 decade typo
  • D. Fixing DPN-060/061's Parent Epic reference

Answer: A

Why: The column shift (Issue 0) is what emptied H/I/J for exactly those 15 rows. Moving each value back one column restores all 15 Due Dates, taking Planned from 29/44 to the full 44/44 — the other fixes (typos, orphan parent) don't touch the Due Date column at all.

Why B tempts people
Deleting rows would shrink the denominator too (from 44 to 29), keeping the percentage near 100% of a smaller, wrong total — not the same as restoring the real count.
Why C tempts people
The DPN-013 typo is in the Resolved (Actual) column, not Due Date — it affects the Actual series' date range, not Planned's count.
Why D tempts people
DPN-060/061's Parent Epic affects which EPIC filter they appear under, not whether their Due Date column is populated.

108. Answer it before you see the options: Check yourself: choosing the denominator

Prediction

Predict first

A colleague suggests changing the % Complete denominator to ATTR({FIXED : COUNTD(IF NOT ISNULL([Resolved]) THEN [Key] END)}) for the Actual series specifically. What breaks?

Answer it in your own words, now, with nothing to choose from. The options are on the next slide — and picking the right one off a list is an easier skill than producing it.

Correct: Actual climbs to a false 100%, because it now divides resolved features by only the resolved features themselves

Why: That denominator counts only features with a non-null Resolved date — exactly the numerator's own population. 18 resolved / 18 resolved = 100%, hiding that 26 of 44 features are still unresolved. The whole point of the FIXED-LOD-over-ALL-features denominator is to prevent a series from grading only itself.

109. Check yourself: choosing the denominator

Check

This is the trap from Part 4, restated as a choice.

Check your understanding

A colleague suggests changing the % Complete denominator to ATTR({FIXED : COUNTD(IF NOT ISNULL([Resolved]) THEN [Key] END)}) for the Actual series specifically. What breaks?

  • A. Actual climbs to a false 100%, because it now divides resolved features by only the resolved features themselves (correct)
  • B. Nothing breaks — it's a valid simplification
  • C. The chart throws an aggregation error
  • D. Planned and Projected would also jump to 100%

Answer: A

Why: That denominator counts only features with a non-null Resolved date — exactly the numerator's own population. 18 resolved / 18 resolved = 100%, hiding that 26 of 44 features are still unresolved. The whole point of the FIXED-LOD-over-ALL-features denominator is to prevent a series from grading only itself.

Why B tempts people
It parses fine and returns a number — the problem is what that number MEANS, not a syntax or aggregation error.
Why C tempts people
ATTR() and FIXED LOD are used correctly here syntactically; this is a logic bug, not something Tableau flags.
Why D tempts people
Planned and Projected keep their own FIXED-LOD denominators in this hypothetical, unaffected by an Actual-only change — only Actual's percentage would be wrong.

110. Rule out three: Check yourself: the version limitation

Elimination

Eliminate the wrong options

A student on Tableau 2022.1 wants a dashed Projected line. What should you tell them?

3 of these 4 are wrong. Strike them one at a time, and say what rules each one out before you strike the next. The survivor is the answer.

  • A. Build two split-at-TODAY() calcs with overlapping <= / >= comparisons and style each one's line separately
  • B. Upgrade Tableau mid-session before continuing
  • C. It's impossible before 2023.2, so drop the Projected series entirely
  • D. Use the Forecast feature instead to generate the dashed line

Survives elimination: A

Why: The Path-shelf Line Pattern feature is 2023.2+ only, but the split-at-TODAY() calc pair — using <= and >= so the segments touch at TODAY() — reproduces a visually distinct, independently-stylable line on any Tableau version. It's the documented fallback for exactly this limitation.

111. Check yourself: the version limitation

Check

Consider what actually changes when the Tableau version is older.

Check your understanding

A student on Tableau 2022.1 wants a dashed Projected line. What should you tell them?

  • A. Build two split-at-TODAY() calcs with overlapping <= / >= comparisons and style each one's line separately (correct)
  • B. Upgrade Tableau mid-session before continuing
  • C. It's impossible before 2023.2, so drop the Projected series entirely
  • D. Use the Forecast feature instead to generate the dashed line

Answer: A

Why: The Path-shelf Line Pattern feature is 2023.2+ only, but the split-at-TODAY() calc pair — using <= and >= so the segments touch at TODAY() — reproduces a visually distinct, independently-stylable line on any Tableau version. It's the documented fallback for exactly this limitation.

Why B tempts people
Upgrading Tableau isn't a build-session task and isn't necessary — the fallback calc pattern works on the installed version.
Why C tempts people
Dropping the series throws away real information; a light color alone (or the split-calc fallback) still communicates it without needing dashed lines.
Why D tempts people
Forecast is disabled on table-calc measures entirely (a different limitation covered earlier) — it can't produce a styled line for this measure at all.

112. Connect it up: Jira Burndown in Tableau: Planned, Actual & Projected on One Chart

Connect it up

Draw it

One page, no notation unless you need it: draw how these connect — Part 1 — Connect & Relate · Part 2 — Audit Before You Build · Part 3 — Pivot to Long Format · Part 4 — The Running % Complete Calc · Part 5 — Style: Color, TODAY(), Line Pattern · Part 6 — Forecast Limitation & Formatting. Put an arrow wherever one of them is what makes another possible, and label the arrow with why.

113. Recap — one chart, three honest series

Recap

You can now build — and defend — a one-chart Planned/Actual/Projected burndown from a real, messy Jira export:

StepWhat it prevents
Relationship, not joinRow duplication on Epic-level aggregates
Validate before pivotingTrusting a count that's silently wrong
Pivot to long formatNeeding a dual axis or Measure Values
COUNTD + FIXED LODTriplicated counts and a self-normalizing 100%
Color + TODAY() + Line PatternA chart where fact and forecast look identical

Two Tableau limits worth remembering: Forecast doesn't run on table calcs, and per-series line styling needs 2023.2+ (or the split-at-TODAY() fallback). Bring your own export next time — the audit steps here (column shift, typo dates, orphan keys) generalize to almost any Jira data you'll pull.

Plain words, one more time: build the relationship, audit before you trust a count, reshape wide into long, count what's real, calculate against one honest denominator, and make the encoding say what's true.

Sources

  1. Tableau Help — Pivot Data from Columns to Rows
  2. Tableau Help — Forecasting overview
  3. Tableau Help — Resolve forecasting errors (why Forecast is unavailable on table-calc measures)
  4. Every per-epic count, raw/cleaned series count, calculated-field formula, and data-quality figure copied verbatim from this session's DATA-QUALITY-NOTES.md, TABLEAU-SPEC-CALCULATIONS.md, and LESSON-PLAN.md. — Author verification pass, 2026-07-26.

Want this taught 1-on-1? Alexander tutors Business Analytics — $55/session, free consultation.

Book on Wyzant · Text (657) 465-8108