How to structure your data for the Financial Report visualization
The Financial Report visualization in DashboardFox renders polished Income Statements (P&L) and Balance Sheets from your underlying data. To do that, DashboardFox needs your data in one of two shapes — Long format or Wide format — and needs a handful of columns that identify accounts, categories, amounts, and time periods.
This article walks through exactly what those two shapes look like, what columns DashboardFox needs, and how DashboardFox auto-detects column roles so you don't have to configure much.
1. Overview
You have two choices for structuring your data:
Long format — one row per account per date per value type (actual / budget / forecast). This is the natural shape from most accounting databases and is the easiest to produce from a SQL view or a system export.
Wide format — one row per account with many columns, one column per period-and-value-type combination (e.g.,
2024_03_actual,2024_03_budget). This is the shape a spreadsheet naturally produces.
You can use whichever is more convenient. DashboardFox detects which format you're using and converts long format to wide internally. If you can deliver either, long format is usually simpler to maintain — you don't need to add new columns every month.
Regardless of format, you need the same core information: which account, what category (e.g., Revenue, COGS, Current Assets), and what the value was.
2. Which format should I use?
If your data comes from… | Start with… |
|---|---|
A SQL database or data warehouse | Long format — produce a view that returns one row per account per date per value type |
A monthly Excel workbook you maintain by hand | Wide format — a column per month, values typed in each cell |
An accounting system export (Xero, QuickBooks, NetSuite, etc.) | Either — many exports come in long format naturally; spreadsheet exports tend to be wide |
An ETL pipeline you control | Long format — easier to append new periods without schema changes |
If you're not sure, pick long format. It's more flexible and DashboardFox will pivot it for you.
3. Required columns — both formats
Every row in your data needs these six pieces of information:
Field | Purpose | Example value |
|---|---|---|
Account code | Unique ID for the account (your GL number or similar) |
|
Account name | Human-readable label shown on the report |
|
Category | Which major section of the statement this account belongs to |
|
Subcategory | Optional grouping within a category |
|
Value | The dollar amount |
|
Period | The date (long) or period column (wide) the value applies to |
|
The category value is what tells DashboardFox whether an account is Revenue, COGS, Current Assets, etc. This is the single most important column to get right. See section 7 for the full list.
4. Long format
4.1 What it looks like
Each row is one observation: one account, one date, one value type, one amount. An account with 36 months of actual data and 36 months of budget data will appear on 72 rows (or more, if you have daily data).
| acct | name | category | subcategory | date | value_type | amount ||------|---------------|----------|-------------|------------|------------|----------|| 4000 | Product Sales | revenue | product | 2024-01-11 | actual | 85685.10 || 4000 | Product Sales | revenue | product | 2024-01-19 | budget | 78990.66 || 4000 | Product Sales | revenue | product | 2024-02-13 | actual | 84268.04 || 5000 | Materials | cogs | materials | 2024-01-11 | actual | 32100.00 |
4.2 Required columns for long format
Column | Default name DashboardFox looks for | Notes |
|---|---|---|
Account code |
| Your unique account identifier |
Account name |
| Shown as the row label on reports |
Category |
| See section 7 for accepted values |
Subcategory |
| Optional — leave blank if you don't group |
Date |
| See 4.3 for accepted formats |
Value type |
|
|
Amount |
| Numeric — the dollar value |
If your column names are different, DashboardFox will still auto-detect most of them (section 8), and anything that can't be auto-detected can be mapped manually in the report builder (section 9).
4.3 Accepted date formats
DashboardFox accepts a wide range of date formats in the date column. You don't need to reformat — pick whatever is natural for your data source.
Format | Example | Notes |
|---|---|---|
|
| Recommended. Unambiguous ISO format. |
|
| Monthly — use when data is already aggregated to months |
|
| Quarterly — use when data is aggregated to quarters |
|
| Yearly |
|
| US format (auto-detected via browser locale) |
|
| International format (auto-detected) |
|
| European dot format |
|
| Text month |
|
| Text month with comma |
Tip: If your accounting system gives you dates in multiple formats, use YYYY-MM-DD in your ETL output. It's unambiguous across every locale.
4.4 Value type values
The value type column tells DashboardFox whether each row is actual data, a budget figure, or a forecast. DashboardFox accepts exactly these three values (case-insensitive):
actual— historical / recorded valuesbudget— planned values, used for budget-vs-actual comparisonsforecast— projected values
If you only have actual data, every row can be actual. The budget and forecast comparisons will simply not appear in the report until you supply those rows.
5. Wide format
5.1 What it looks like
Each row is one account. Period and value-type are combined into column names, with one column per period-and-value-type pair.
| acct | name | category | subcategory | 2024_01_actual | 2024_01_budget | 2024_02_actual | 2024_02_budget | ...|------|---------------|----------|-------------|----------------|----------------|----------------|----------------|----| 4000 | Product Sales | revenue | product | 85685.10 | 78990.66 | 84268.04 | 82732.86 | ...| 5000 | Materials | cogs | materials | 32100.00 | 31500.00 | 33450.00 | 32800.00 | ...
5.2 Period column naming convention
This is the most important part of wide format — DashboardFox reads the time period out of the column name, so the name has to follow one of these patterns exactly:
Granularity | Pattern | Example |
|---|---|---|
Monthly |
|
|
Quarterly |
|
|
Yearly |
|
|
Rules:
Use underscores, not dashes or slashes (
2024_03_actual, never2024-03-actual)Month numbers can be
01-12or1-12— both workValue type is lowercase:
actual,budget, orforecastThe
Qin quarterly columns is case-insensitive (Q1orq1both work)
Columns that don't match the pattern are ignored as period data. They can still exist in your dataset — they just won't appear on the report's time axis.
5.3 Non-period columns in wide format
Alongside your period columns, wide format still needs the core identifying columns:
Column | Default name |
|---|---|
Account code |
|
Account name |
|
Category |
|
Subcategory |
|
Same column-name flexibility applies as in long format — DashboardFox will auto-detect these, or you can map them manually.
6. Minimum viable dataset — what you absolutely need
If you're starting from scratch and just want the simplest possible working dataset, here's the minimum:
Long format (smallest example):
| acct | name | category | date | value_type | amount ||------|-------|----------|------------|------------|---------|| 4000 | Sales | revenue | 2024-01-01 | actual | 10000.00|| 5000 | COGS | cogs | 2024-01-01 | actual | 4000.00|| 6000 | Rent | opex | 2024-01-01 | actual | 2000.00|
That's enough to produce a basic P&L for January 2024. Subcategory is optional. Add more months/years by adding more rows.
Wide format (smallest example):
| acct | name | category | 2024_01_actual ||------|-------|----------|----------------|| 4000 | Sales | revenue | 10000.00|| 5000 | COGS | cogs | 4000.00|| 6000 | Rent | opex | 2000.00|
Same three accounts, same result.
7. Category values — what to put in the category column
The category column is what tells DashboardFox how to classify each account into the report's structure. DashboardFox is forgiving about casing and spacing — "Current Assets", "current_assets", and "CURRENT ASSETS" are all treated the same. It also accepts common synonyms.
7.1 Income Statement (P&L) categories
Use this category for accounts that are… | Accepted values |
|---|---|
Revenue — sales income |
|
COGS — cost of goods/services sold |
|
Operating Expenses |
|
Other Income — non-operating income |
|
Other Expense — non-operating expense |
|
Tax |
|
7.2 Balance Sheet categories
Use this category for accounts that are… | Accepted values |
|---|---|
Current Assets |
|
Fixed / Non-current Assets |
|
Current Liabilities |
|
Long-term Liabilities |
|
Equity |
|
7.3 What happens if my category value doesn't match?
If you have a category value that doesn't match any of the accepted names (e.g., selling_expenses, intangibles, deferred_revenue), DashboardFox will flag it as "unmapped" in the report builder. You'll see a Category Mapping table where you can choose which canonical category each of your values should map to. This is a one-time setup per report.
Tip: If you control the SQL view that feeds DashboardFox, it's easiest to map to the canonical values directly in the view's CASE statement. If you're working from a spreadsheet export, use a lookup column to translate your source categories to the canonical ones.
8. Subcategory values — what to put in the subcategory column
Subcategory is optional and free-form. DashboardFox doesn't require specific values — whatever you put becomes a visual subgroup inside its category on the report.
For example, under revenue, you might have subcategories like product, service, subscription, licensing. Under current_assets, you might use cash, receivables, inventory, prepaid.
Suggestions for common subcategories:
Category | Common subcategories |
|---|---|
revenue | product, service, subscription, licensing |
cogs | materials, labor, overhead, shipping |
opex | sales_marketing, admin, technology, facilities, personnel, depreciation |
current_assets | cash, receivables, inventory, prepaid |
fixed_assets | equipment, furniture, leasehold |
current_liabilities | payables, accrued, short_term_debt |
long_term_liabilities | deferred, other |
Use the same subcategory spelling consistently. "Cash" and "cash" become two separate subgroups on the report.
If you don't want subgroups, either leave the subcategory column blank or omit it entirely.
9. Auto-detection — how DashboardFox matches your columns
When you build a report, DashboardFox scans your dataset's columns and tries to figure out which column plays which role. Here's exactly what it looks for:
Role | Matches column names containing… | Additional rule |
|---|---|---|
Account code |
| — |
Account name |
| Must be a text column |
Category |
| — |
Subcategory |
| — |
Date (long format) |
| Must be a date column |
Value type (long format) |
| — |
Amount (long format) |
| Must be a numeric column |
Matching rules:
Case-insensitive —
Account Name,ACCOUNT_NAME,account name,AccountNameall matchSpaces and underscores are interchangeable —
Value Typeandvalue_typematch the same wayPartial matches count — a column named
period_datewill match the "date" rule because it containsdate
9.1 What if auto-detect gets it wrong?
It happens — for example, a column named GL_Account_Number contains the word account, so DashboardFox might auto-detect it as the Account Name (label) column instead of the Account Code. Two things help:
The report builder always shows you what was detected. Review the column picks before saving.
You can manually override any pick in the builder's column-mapping section. See section 10 below.
9.2 What if my columns don't match any of these names?
You can use any column names you want — auto-detect just saves you a step. If your columns are GLAcct, Dept, FiscalPeriod, etc., DashboardFox won't auto-detect them, but you can manually map each column to its role in the report builder.
10. Manual column mapping — when auto-detect isn't enough
Every Financial Report has a column-mapping section in its settings where you can explicitly tell DashboardFox which of your columns plays which role. Use this when:
Your column names don't match the patterns in section 9
Auto-detect picked the wrong column for a role
You want to use a non-default column (e.g., use
LegalEntityas your Account Name instead ofacct)
The mapping section offers one dropdown per role (Account Code, Account Name, Category, Subcategory, Date, Value Type, Amount). You pick the column from your dataset for each role. DashboardFox remembers your picks and uses them on every render.
Tip: If you build many reports from the same dataset, it's easier to name your columns to match DashboardFox's auto-detect patterns once in your SQL view. Every new report starts correctly configured with zero clicks.
11. Building P&L vs Balance Sheet reports
Both report types use the same data shape. The difference is in which categories you provide:
A P&L (Income Statement) report expects accounts with categories:
revenue,cogs,opex,other_income,other_expense,taxA Balance Sheet report expects accounts with categories:
current_assets,fixed_assets,current_liabilities,long_term_liabilities,equity
If you have both kinds of accounts in one dataset, that's fine — DashboardFox will render each report using only the relevant categories and ignore the rest. You don't need separate datasets.
For Balance Sheet specifically: DashboardFox validates that Total Assets = Total Liabilities + Equity and shows an indicator on the report. If your data doesn't balance, you'll see a warning with the difference amount — useful for spotting data-quality issues.
12. Complete examples
12.1 P&L — Long format (first few rows)
| acct | name | category | subcategory | date | value_type | amount ||------|-------------------|-----------|-------------|------------|------------|----------|| 4000 | Product Sales | revenue | product | 2024-01-31 | actual | 85685.10 || 4000 | Product Sales | revenue | product | 2024-01-31 | budget | 78990.66 || 4100 | Service Revenue | revenue | service | 2024-01-31 | actual | 42150.00 || 5000 | Raw Materials | cogs | materials | 2024-01-31 | actual | 28400.00 || 5100 | Direct Labor | cogs | labor | 2024-01-31 | actual | 15200.00 || 6000 | Sales & Marketing | opex | sales_marketing | 2024-01-31 | actual | 12000.00 || 6100 | Office Rent | opex | facilities | 2024-01-31 | actual | 4500.00 || 8000 | Corporate Tax | tax | | 2024-01-31 | actual | 5820.00 |
12.2 P&L — Wide format (first few rows)
| acct | name | category | subcategory | 2024_01_actual | 2024_01_budget | 2024_02_actual | 2024_02_budget ||------|---------------|----------|-------------|----------------|----------------|----------------|----------------|| 4000 | Product Sales | revenue | product | 85685.10| 78990.66| 84268.04| 82732.86|| 5000 | Raw Materials | cogs | materials | 28400.00| 28000.00| 30100.00| 29500.00|| 6000 | Sales & Mkt | opex | sales_marketing | 12000.00| 12000.00| 13200.00| 12500.00|
12.3 Balance Sheet — Long format (first few rows)
| acct | name | category | subcategory | date | value_type | amount ||------|---------------------|-----------------------|-------------|------------|------------|-----------|| 1000 | Cash | current_assets | cash | 2024-01-31 | actual | 119812.66 || 1100 | Accounts Receivable | current_assets | receivables | 2024-01-31 | actual | 64300.00 || 1200 | Inventory | current_assets | inventory | 2024-01-31 | actual | 48500.00 || 1500 | Office Equipment | fixed_assets | equipment | 2024-01-31 | actual | 32000.00 || 2000 | Accounts Payable | current_liabilities | payables | 2024-01-31 | actual | 28900.00 || 2500 | Long-term Loan | long_term_liabilities | other | 2024-01-31 | actual | 125000.00 || 3000 | Retained Earnings | equity | | 2024-01-31 | actual | 110712.66 |
Note for Balance Sheet: because balance sheets are point-in-time (not totals over a period), the date column represents the date of the snapshot. If you're pre-aggregating to monthly, use the last day of each month.
12.4 Balance Sheet — Wide format (first few rows)
| acct | name | category | subcategory | 2024_01_actual | 2024_02_actual | 2024_03_actual ||------|---------------------|-----------------------|-------------|----------------|----------------|----------------|| 1000 | Cash | current_assets | cash | 119812.66| 121450.00| 123100.00|| 1100 | Accounts Receivable | current_assets | receivables | 64300.00| 68100.00| 71200.00|| 2000 | Accounts Payable | current_liabilities | payables | 28900.00| 30100.00| 31500.00|| 3000 | Retained Earnings | equity | | 110712.66| 115300.00| 120400.00|
13. Common pitfalls
Problem | Cause | Fix |
|---|---|---|
Report shows no data | Category values don't match any accepted value | Check section 7; map via the Category Mapping table in the builder |
Some accounts are missing from the report | Their category is | Every row needs a valid category value |
Balance Sheet shows "unbalanced" warning | Assets ≠ Liabilities + Equity in your data | Usually a data-quality issue upstream; DashboardFox is reporting what's in the data |
Wide format columns aren't recognized | Column name doesn't match the | Check section 5.2 — use underscores, lowercase value types |
Dates showing wrong period | Ambiguous slash format ( | Switch your source to |
Budget comparison empty | No rows have | Add budget data or remove the comparison from the report |
Auto-detect picked the wrong column | Partial-match heuristic collided (e.g., | Override manually in the builder's column mapping section |
14. Pre-built templates
If you pull financial data from a major accounting system (Xero, QuickBooks, NetSuite, etc.), we offer pre-built Excel templates that reshape those exports into the structure described above. See [link TBD] for the current list of available templates.
Summary
Pick a format — long for database/ETL, wide for spreadsheets. Long is usually easier to maintain.
Provide the core columns — account code, name, category, subcategory, value, and date/period.
Use the accepted category values in section 7 so DashboardFox recognizes your accounts without manual mapping.
For wide format, follow the column naming convention —
YYYY_MM_actual,YYYY_MM_budget, etc.Let auto-detect do the work. If it gets something wrong, override it in the builder's column mapping section.
If you can deliver data that matches this guide, building a financial report in DashboardFox is mostly a matter of picking the preset (P&L or Balance Sheet) and hitting save.