Getting started
Two ways to read this.
In a hurry? The Quick start below is eight steps and about five minutes. It takes you from an empty page to a dashboard you can hand to someone else, and it is complete on its own.
Want to see what the thing is actually for? The Investigations that follow are nine short worked examples on the same sample data. Each one asks a real question, answers it, and teaches a technique you can point at your own data. They are independent — read one, read all nine, or skip them until you need one.
Every step is something to do rather than something to know. Put this guide in one window and DashReporter in another, side by side — the button at the top opens the app in a new tab, and most systems will tile two windows if you drag one to each edge of the screen.
Nothing you open leaves your machine. The file is read by your browser, the query engine runs in your browser, and nothing is written to browser storage. Watch the network tab while you work; it stays quiet.
Quick start
Open the sample data
Click Try it with sample data. That loads
sales_actual.csv — about 58,000 order lines over 18 months — without downloading
anything.
You can also drag your own CSV, TSV, Parquet or .drd file onto the page at any
time. Each file gets its own tab.
Look at what it guessed
Click Edit model. Inference gets close and then gets things wrong, which is why the model is editable rather than hidden. On this file:
Order DateisM/d/yyyy H:mm:ss, a format most CSV sniffers do not parse. Without it there is no trend at all.Order Numberis a high-cardinality integer that is an identifier, not a quantity. Summed naively it produces a number in the trillions.Discount Rateis a rate, so it wantsAVG. Summed, it is meaningless.
One correction is worth making now, because two investigations depend on it: set
Territory to level 2 so it sits under Region. The tool
cannot infer that relationship — see the tangent — so it has to be declared. It only needs
declaring once; the correction is saved into any .drd you export.
Why can't it work out that Territory belongs to Region?
Because it doesn't. Metro appears under North, South and East;
Coastal under South and West. Knowing the territory does not tell you the region, so
no amount of looking at the data reveals the relationship. That is a ragged
hierarchy, and it is extremely common in real data — sales geographies name territories
locally all the time.
The contrast is in the same file: every Sales Rep belongs to exactly one territory,
so that relationship is discoverable, and the tool finds it unaided.
Category Level 1 / 2 / 3 are found automatically too, from their names.
Combine actuals with plan
Drag sales_budget.csv onto the page as well (or download it from the landing page),
then click Combine sources…, tick both, and Combine.
Rows are stacked, not joined. That distinction matters more than it sounds:
joining a fact table to a coarser plan multiplies rows and inflates every total, silently. Stacking
cannot. A Source column records which file each row came from, and a measure missing
from one file is simply null in those rows.
You now have Revenue and Budget Revenue as two measures on one
dataset.
Build "Actual vs Budget"
On the combined tab: Edit model→Derived measures. Name it Actual vs Budget and build:
Two things to notice. The aggregates are part of the formula rather than inherited from wherever
else, so the measure prints what it computes and can't change under you. And if you switch the
operator to /, both operands snap to SUM — a rate is the ratio of the
totals, and a ratio of averages ignores order size. The naive path is the correct one.
Build something incoherent anyway and you get a warning, inline, at the point of choice. It never blocks you.
Explore
Break down by picks the dimension in the table.
- Click a row to drill. Clicking
Southfilters to South and moves the breakdown down a level to its territories. - Drag across rows to take several at once — the only way to build a multi-row selection, since the table narrows to whatever you pick.
- The breadcrumb above the table is the way back. Click any level to return to it; that clears its filter and everything beneath it.
- The chips along the top are every filter currently applied. Click one to remove it.
- In the sidebar, ctrl-click a value to select only it — the fastest way to walk a dimension one value at a time while watching the trend redraw.
Change the shape of the chart
Four buttons next to the grain selector. How a chart is drawn is part of what it says:
| form | what it's for |
|---|---|
| line | trajectory and level — where a series went, how series compare |
| bars | one period against the next, as discrete quantities |
| stacked | the total, and what makes it up |
| 100% | the mix, with the total deliberately removed |
The last one is not decoration: composition shifting while the whole grows or shrinks is invisible in the other three.
Getting several bands on the chart at once
The trend draws one series per selected measure, not one per value of a
dimension. To get a band per customer segment, make them measures: Edit
model→Pivot a measure across a
dimension→Revenue across
Customer Segment.
That mints one measure per value, and they behave like any other — bands on the trend, columns in the breakdown (a genuine cross-tab), a tile each. The slices replace the source in the selection, because the parts and the whole stacked together count everything twice.
Save a view and pin it
Save view captures everything you navigated to: filters, date window, grain, breakdown, sort, which measures were on screen, and the chart form.
Then Pin it. Pinning nominates the view a .drd opens on.
That's a choice about what you're handing over — sometimes the point of a file is the finding,
sometimes it's the data with the filters left clean.
Save it, then drop it back
Generate report (PDF) prints a document: the filters in force, the totals, the trend, and a breakdown for every level of the drill path — not just the level on screen.
Save compiled data (.drd) writes your model, derived measures, saved views and the data into one file. It is columnar and compressed, so it is both smaller than the CSVs and dramatically faster to open — five million rows in about a second against roughly forty-two for raw CSV.
Now drag that .drd back onto the page. It opens on your pinned view, already there.
That is the whole point of the format: hand someone the file and they arrive where you left off,
which is the difference between sending a finding and sending a haystack.
That's the quick start. Everything below is optional.
Investigations
The sample data has nine things worth finding planted in it. Each one below is a worked example: the question, what to do, what you find, and the technique underneath.
They get harder. The first is a number sitting in plain sight; the last is an absence you can only reach by sorting for it.
The hardest part of real analysis is not finding something odd, it is deciding a finding is finished. Each investigation ends with a stated conclusion for exactly that reason. A finding is done when you can say what it is, where it lives, and whether it is local or general — not when you run out of curiosity.
1. A gap you can only see against plan
Territory = Lakeside
· break down by Channel ·
measures Revenue, Budget Revenue, Actual vs Budget.
Lakeside does no wholesale business at all, against a plan of nearly 1.2 million. It is the only channel-and-territory combination in the entire file that exists in budget and not in actuals.
In the actuals alone this is a row that isn't there — the hardest kind of thing to notice, because nothing draws your eye to a blank. Put the plan beside it and the same fact becomes the largest negative variance on the screen.
2. Is it behaviour, or is it policy?
Discount Rate (it should be
AVG; fix it in the model if not) · break down by
Region, then drill into East.
Now check whether it is uniform inside Valley: break down by category, by channel, by customer segment, by sales rep. It is ~35% in every one. Switch the trend to month grain — it is flat across all eighteen, never below 34.2% or above 35.6%.
Valley discounts at roughly 35% against about 9.5% everywhere else, uniformly and without variation over time.
If one rep or one product line were responsible, the average would be dragged by them and the rest of Valley would look normal. It isn't, so this is a rule someone set — a report that produces a phone call, not a coaching conversation.
3. A season, or a step change?
Category Level 3 =
Hoses · measures Revenue,
Budget Revenue · trend at month grain.
Through 2024 hoses oscillate around plan, which is what a seasonal product does. At the start of 2025 the line steps down and never recovers, while budget climbs into spring on the seasonal assumption. It is company-wide — every territory sits between 15% and 37% of plan in the first half of 2025.
Actuals alone show a decline that could be winter. The budget expected the opposite, and that divergence is the signal. And check the scope before you attribute it: found inside a territory filter, this looks like a local problem. It isn't.
4. Look at the shape, not just the total
Sales Rep
· measures Revenue and Rows
· sort by Revenue.
Abbott, Payton leads at about 1.7 million, more than double anyone else. Now look
at Rows, and filter to Basin to compare like with like:
A quarter the order count, ten times the order size. Not one big deal — every order is large. Zero of their 397 orders fall below the other reps' median.
Rows beside a measure turns a total into a distribution
A tempting explanation is a data-entry error — someone adding a digit. That theory dies on the count: a fat finger is sporadic, and there is no normal part of this book.
5. One customer type that only buys one way
Revenue across Channel
· break down by Customer Segment.
Public Sector — the largest segment at 37.8% of all revenue — buys through wholesale exclusively.
Pivoting one measure across a dimension gives you one measure per value, so a breakdown by anything else becomes a matrix. Three rows that look alike and one that doesn't is a pattern you can see in a second and would never find by drilling into segments one at a time.
Bonus: this also explains investigation 1 from the other side. Lakeside has no wholesale, and Public Sector only buys wholesale — so Lakeside has no Public Sector either. Two findings, one intersection.
6. Growing against a flat background
Units ·
break down by Territory · ctrl-click each territory in the
sidebar in turn, watching the trend redraw.
Overall the trend is flat and uniform. Highland alone starts low in early 2024 and climbs steadily through to the end of the data.
Highland is growing against a background that isn't.
Comparing eighteen-month shapes across nine territories is not something a single chart does well. Soloing each in turn and watching the same axes redraw makes an odd one obvious.
7. A specialist, not a lean
Sales Rep
· sort by Revenue ascending to find the small books
· filter to Naylor, Indigo ·
break down by Category Level 3.
Indigo Naylor sells power tools. Only power tools — not mostly, exclusively.
Every top seller has a category they lead in; that is ordinary. A rep with exactly one line is not. Check the whole breakdown, not just the top row.
Be careful with the story you attach: their revenue peaks in March and April, which looks like spring tool demand — but total company revenue peaks in March and April too. On a book of a few thousand a month, that is the season showing through, not evidence about them.
8. Hunting the axis a spike lives on
Category Level 3 =
Cookware · trend at month grain.
March 2025 roughly doubles: 237,605 against about 120,000 either side. Now find which dimension
it belongs to. Break down by Customer Segment and switch the chart to
100% — the mix does not move. Break down by Channel — all
three channels roughly double together. Break down by Sales Rep and drag
across the top four rows to select them all at once.
Those four reps are all in one territory: Foothills.
A single enormous month in cookware, in one territory, spread evenly across every channel and segment within it.
A spike that is mix-neutral across a dimension did not come from that dimension. Working through segment and channel that way costs two clicks each and eliminates them properly, rather than leaving you suspecting them.
9. Someone who stopped
Sales Rep
· tick Edges in the measures panel
· click the Last header to sort ascending.
One rep in the file stops mid-period and never comes back. Nobody joins.
"Who left?" is not an aggregate question and no measure answers it. With four hundred reps you
cannot eyeball it, and filtering to each in turn is hopeless. First and last dates turn it into a
sort, and Rows beside them separates someone who left from someone who was always
too small to notice.
Two mistakes worth making once
Both of these cost real time during the investigation that produced this tutorial. Neither is a bug — in both cases the chart was correct and the conclusion it invited was false.
The month that looks like a slump
Break down Units by month and February dips, in both years, in every region and
category.
It is the calendar. February has 28 days against 31. Units per day is flat straight through, and the 2024 dip is shallower than 2025's only because 2024 was a leap year.
The tell was there in the observation itself: "consistent across every region and category". A real February effect would be concentrated somewhere. A pattern that appears uniformly in every slice usually belongs to the axis, not the data.
The filter you forgot was on
Halfway through investigation 8, a filter from an earlier search was still applied. Cookware
looked like it had no wholesale spike and an online one instead — because the filter was
Territory = Lakeside, which has no wholesale at all, and the remaining online figures
were 2 to 10 orders a month.
The chips along the top of the screen were saying Territory: Lakeside the whole
time.
Two habits worth building:
- Read the chips before you conclude anything. They are the sentence your numbers are the answer to.
- Turn
Rowson when a pattern looks dramatic. Revenue rising from 236 to 1,835 sounds like a fourfold jump. The count beside it — 2 orders to 10 — says it is noise.
Where next
Open your own file. The techniques transfer directly:
- Combine an actuals extract with a plan or a prior period, and absences become numbers.
- Pivot a measure across a small dimension to get cross-tabs.
- Turn on
Edgeswhen you want to know what started or stopped. - Watch
Rowswhenever a percentage looks exciting.
And when you find something, save the view, pin it, and send the .drd. The person
who opens it lands exactly where you were standing.
Open DashReporter in a new tab ↗ · or go back to the tab you already have it in