@luquimbo/bi-superpowers 4.1.6 → 5.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +8 -6
- package/.claude-plugin/plugin.json +1 -1
- package/.claude-plugin/skill-manifest.json +35 -19
- package/.plugin/plugin.json +1 -1
- package/AGENTS.md +150 -26
- package/CHANGELOG.md +489 -14
- package/README.md +103 -114
- package/bin/cli.js +7 -1
- package/bin/commands/diff.js +2 -2
- package/bin/commands/install.js +58 -45
- package/bin/commands/lint.js +2 -2
- package/bin/commands/validate-projects.js +425 -0
- package/bin/lib/generators/claude-plugin.js +31 -7
- package/bin/lib/generators/shared.js +11 -7
- package/bin/lib/mcp-config.js +22 -2
- package/bin/lib/skills.js +8 -8
- package/bin/mcp/powerbi-modeling-launcher.js +8 -4
- package/bin/postinstall.js +14 -12
- package/bin/utils/mcp-detect.js +11 -11
- package/commands/bi-connect.md +418 -0
- package/commands/bi-dax.md +385 -0
- package/commands/{project-kickoff.md → bi-kickoff.md} +78 -47
- package/commands/bi-modeling.md +395 -0
- package/commands/bi-performance.md +455 -0
- package/commands/bi-start.md +39 -27
- package/desktop-extension/manifest.json +2 -2
- package/package.json +3 -2
- package/skills/bi-connect/SKILL.md +420 -0
- package/skills/{pbi-connect → bi-connect}/scripts/update-check.js +1 -1
- package/skills/bi-dax/SKILL.md +387 -0
- package/skills/{report-design → bi-dax}/scripts/update-check.js +1 -1
- package/skills/{project-kickoff → bi-kickoff}/SKILL.md +79 -48
- package/skills/{project-kickoff → bi-kickoff}/scripts/update-check.js +1 -1
- package/skills/bi-modeling/SKILL.md +397 -0
- package/skills/bi-modeling/scripts/update-check.js +403 -0
- package/skills/bi-performance/SKILL.md +457 -0
- package/skills/bi-performance/scripts/install-tabular-editor.ps1 +90 -0
- package/skills/bi-performance/scripts/run-bpa.ps1 +161 -0
- package/skills/bi-performance/scripts/update-check.js +403 -0
- package/skills/bi-start/SKILL.md +40 -28
- package/skills/bi-start/scripts/update-check.js +1 -1
- package/src/content/base.md +15 -10
- package/src/content/routing.md +15 -18
- package/src/content/skills/bi-connect.md +391 -0
- package/src/content/skills/bi-dax.md +358 -0
- package/src/content/skills/{project-kickoff.md → bi-kickoff.md} +75 -44
- package/src/content/skills/bi-modeling.md +368 -0
- package/src/content/skills/bi-performance/SKILL.md +428 -0
- package/src/content/skills/bi-performance/scripts/install-tabular-editor.ps1 +90 -0
- package/src/content/skills/bi-performance/scripts/run-bpa.ps1 +161 -0
- package/src/content/skills/bi-start.md +39 -27
- package/theme/BISuperpowers.json +3888 -0
- package/commands/pbi-connect.md +0 -253
- package/commands/report-design.md +0 -403
- package/skills/pbi-connect/SKILL.md +0 -255
- package/skills/report-design/SKILL.md +0 -405
- package/skills/report-design/references/cli-commands.md +0 -184
- package/skills/report-design/references/cli-setup.md +0 -101
- package/skills/report-design/references/close-write-open-pattern.md +0 -80
- package/skills/report-design/references/layouts/finance.md +0 -65
- package/skills/report-design/references/layouts/generic.md +0 -46
- package/skills/report-design/references/layouts/hr.md +0 -48
- package/skills/report-design/references/layouts/marketing.md +0 -45
- package/skills/report-design/references/layouts/operations.md +0 -44
- package/skills/report-design/references/layouts/sales.md +0 -50
- package/skills/report-design/references/native-visuals.md +0 -341
- package/skills/report-design/references/pbi-desktop-installation.md +0 -87
- package/skills/report-design/references/pbir-preview-activation.md +0 -40
- package/skills/report-design/references/slicer.md +0 -89
- package/skills/report-design/references/textbox.md +0 -101
- package/skills/report-design/references/themes/BISuperpowers.json +0 -915
- package/skills/report-design/references/troubleshooting.md +0 -135
- package/skills/report-design/references/visual-types.md +0 -78
- package/skills/report-design/scripts/apply-theme.js +0 -243
- package/skills/report-design/scripts/create-visual.js +0 -942
- package/skills/report-design/scripts/ensure-pbi-cli.sh +0 -41
- package/skills/report-design/scripts/validate-pbir.js +0 -351
- package/src/content/skills/pbi-connect.md +0 -226
- package/src/content/skills/report-design/SKILL.md +0 -376
- package/src/content/skills/report-design/references/cli-commands.md +0 -184
- package/src/content/skills/report-design/references/cli-setup.md +0 -101
- package/src/content/skills/report-design/references/close-write-open-pattern.md +0 -80
- package/src/content/skills/report-design/references/layouts/finance.md +0 -65
- package/src/content/skills/report-design/references/layouts/generic.md +0 -46
- package/src/content/skills/report-design/references/layouts/hr.md +0 -48
- package/src/content/skills/report-design/references/layouts/marketing.md +0 -45
- package/src/content/skills/report-design/references/layouts/operations.md +0 -44
- package/src/content/skills/report-design/references/layouts/sales.md +0 -50
- package/src/content/skills/report-design/references/native-visuals.md +0 -341
- package/src/content/skills/report-design/references/pbi-desktop-installation.md +0 -87
- package/src/content/skills/report-design/references/pbir-preview-activation.md +0 -40
- package/src/content/skills/report-design/references/slicer.md +0 -89
- package/src/content/skills/report-design/references/textbox.md +0 -101
- package/src/content/skills/report-design/references/themes/BISuperpowers.json +0 -915
- package/src/content/skills/report-design/references/troubleshooting.md +0 -135
- package/src/content/skills/report-design/references/visual-types.md +0 -78
- package/src/content/skills/report-design/scripts/apply-theme.js +0 -243
- package/src/content/skills/report-design/scripts/create-visual.js +0 -942
- package/src/content/skills/report-design/scripts/ensure-pbi-cli.sh +0 -41
- package/src/content/skills/report-design/scripts/validate-pbir.js +0 -351
|
@@ -1,184 +0,0 @@
|
|
|
1
|
-
# `pbi` CLI — commands this skill still uses
|
|
2
|
-
|
|
3
|
-
Historical context: this skill used to drive the entire report authoring via `pbi-cli-tool` (MIT, by MinaSaad1). That approach hit 3 regressions (see `native-visuals.md` → "Lo que este skill YA no hace via CLI"), so authoring moved to Node scripts (`apply-theme.js`, `create-visual.js`, `validate-pbir.js`).
|
|
4
|
-
|
|
5
|
-
The CLI is still useful for:
|
|
6
|
-
|
|
7
|
-
1. **Model introspection** via XMLA — `pbi connect`, `pbi measure list`, `pbi table list`, `pbi column list`. Microsoft Modeling MCP covers the same ground and is preferred when available.
|
|
8
|
-
2. **Page creation** — `pbi report add-page` still works fine.
|
|
9
|
-
3. **Schema-level sanity check** — `pbi report validate` catches malformed JSON, but NOT non-native visualTypes (use `validate-pbir.js` for that).
|
|
10
|
-
|
|
11
|
-
Everything else (add visual, bind visual, set theme, set-container for style) is superseded. The sections below cover only the supported flows.
|
|
12
|
-
|
|
13
|
-
All examples assume you're in the project root and `reportPath="./pbip-files/{proj}.Report"`.
|
|
14
|
-
|
|
15
|
-
---
|
|
16
|
-
|
|
17
|
-
## Global flags
|
|
18
|
-
|
|
19
|
-
- `-p, --path <path>` — path to the `.Report` folder. Prefer explicit `-p` over CWD auto-detection.
|
|
20
|
-
- `--no-sync` — skip Desktop auto-sync after writes. **Use during the generation loop** (Desktop is closed in PHASE 3 anyway).
|
|
21
|
-
- `--json` — machine-readable output for scripting.
|
|
22
|
-
|
|
23
|
-
---
|
|
24
|
-
|
|
25
|
-
## Model introspection (preferred via Microsoft Modeling MCP)
|
|
26
|
-
|
|
27
|
-
### Connect (once, after Desktop is open)
|
|
28
|
-
|
|
29
|
-
```bash
|
|
30
|
-
pbi connect
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
Auto-detects a running PBI Desktop instance on localhost and connects to its XMLA endpoint. Requires the standalone installer build (Microsoft Store version blocks this).
|
|
34
|
-
|
|
35
|
-
### List measures / tables / columns
|
|
36
|
-
|
|
37
|
-
```bash
|
|
38
|
-
pbi measure list --json
|
|
39
|
-
pbi table list --json
|
|
40
|
-
pbi column list --table "{tableName}" --json
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
Returns arrays of `{table, name, description, ...}` suitable for building a `Table[Field]` ref map to pass to `create-visual.js --bind`.
|
|
44
|
-
|
|
45
|
-
### Disconnect
|
|
46
|
-
|
|
47
|
-
```bash
|
|
48
|
-
pbi disconnect
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
Run before PHASE 3 (kill Desktop), otherwise the CLI keeps a stale socket.
|
|
52
|
-
|
|
53
|
-
---
|
|
54
|
-
|
|
55
|
-
## Pages (structure)
|
|
56
|
-
|
|
57
|
-
### List pages
|
|
58
|
-
|
|
59
|
-
```bash
|
|
60
|
-
pbi report -p "$reportPath" list-pages
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
### Add a page
|
|
64
|
-
|
|
65
|
-
```bash
|
|
66
|
-
pbi report --no-sync -p "$reportPath" add-page \
|
|
67
|
-
--name "{pageName}" \
|
|
68
|
-
--display-name "{Display Name}"
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
- `--name` — internal identifier (also folder name). Short lowercase ASCII or 20-char hex.
|
|
72
|
-
- `--display-name` — what shows on the page tab.
|
|
73
|
-
|
|
74
|
-
---
|
|
75
|
-
|
|
76
|
-
## Validation (two layers)
|
|
77
|
-
|
|
78
|
-
Always run both.
|
|
79
|
-
|
|
80
|
-
```bash
|
|
81
|
-
# 1. Schema sanity (CLI)
|
|
82
|
-
pbi report -p "$reportPath" validate
|
|
83
|
-
|
|
84
|
-
# 2. Allowlist + role checks (Node script)
|
|
85
|
-
node "{skillBundleDir}/scripts/validate-pbir.js" "$reportPath"
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
The CLI's `validate` reports `valid: True` even for `visualType: "stackedBarChart"` (not a native type — Desktop renders it as "objeto visual personalizado"). The Node validator catches that.
|
|
89
|
-
|
|
90
|
-
---
|
|
91
|
-
|
|
92
|
-
## Theme
|
|
93
|
-
|
|
94
|
-
Inspect the current theme:
|
|
95
|
-
|
|
96
|
-
```bash
|
|
97
|
-
pbi report -p "$reportPath" get-theme
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
Apply a custom theme **with the bundled helper, NOT `pbi report set-theme`** (the CLI's `set-theme` writes invalid metadata for PBI Desktop March 2026):
|
|
101
|
-
|
|
102
|
-
```bash
|
|
103
|
-
node "{skillBundleDir}/scripts/apply-theme.js" \
|
|
104
|
-
--report-path "$reportPath" \
|
|
105
|
-
--theme-file "{skillBundleDir}/references/themes/BISuperpowers.json"
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
For the full canonical `report.json` theme shape and why `set-theme` was replaced, see `apply-theme.js` header comment.
|
|
109
|
-
|
|
110
|
-
---
|
|
111
|
-
|
|
112
|
-
## Reload Desktop
|
|
113
|
-
|
|
114
|
-
```bash
|
|
115
|
-
pbi report -p "$reportPath" reload
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
Sends `Ctrl+Shift+F5` via pywin32. **NOT enough** to pick up externally-written visuals — Desktop must be fully killed and relaunched (see `close-write-open-pattern.md`). Use `reload` only for small in-session refreshes.
|
|
119
|
-
|
|
120
|
-
---
|
|
121
|
-
|
|
122
|
-
## Visuals (superseded — use `create-visual.js`)
|
|
123
|
-
|
|
124
|
-
`pbi visual add`, `pbi visual bind`, `pbi visual update`, `pbi visual delete`, `pbi visual bulk-bind`, `pbi visual set-container` are **no longer driven by this skill**. Reasons:
|
|
125
|
-
|
|
126
|
-
- `add --type` advertises 5 aliases (`card, line_chart, bar_chart, table, matrix`) but internally accepts ~20 more with PascalCase names. The inconsistency caused the skill's docs to lag behind the CLI's real capabilities.
|
|
127
|
-
- `add --type pie` silently creates a `donutChart` (alias bug).
|
|
128
|
-
- `add --type stackedBarChart` creates a visual with `visualType: "stackedBarChart"` that Desktop rejects at render time — not a native type.
|
|
129
|
-
- `bind` doesn't expose all PBIR roles (`--column`, `--line`, `--x`, `--y`, `--size`, `--breakdown` exist only in `bulk-bind`, not `bind`).
|
|
130
|
-
|
|
131
|
-
The replacement is a single Node script:
|
|
132
|
-
|
|
133
|
-
```bash
|
|
134
|
-
node "{skillBundleDir}/scripts/create-visual.js" \
|
|
135
|
-
-p "$reportPath" \
|
|
136
|
-
--page "$pageName" \
|
|
137
|
-
--type "{nativeVisualType}" \
|
|
138
|
-
-n "{visualName}" \
|
|
139
|
-
--x {x} --y {y} --width {w} --height {h} \
|
|
140
|
-
--bind "{role}={Table[Field]}" \
|
|
141
|
-
[--bind ...]
|
|
142
|
-
```
|
|
143
|
-
|
|
144
|
-
See `native-visuals.md` for the 27 supported types and their `--bind` roles.
|
|
145
|
-
|
|
146
|
-
---
|
|
147
|
-
|
|
148
|
-
## Key conventions (unchanged)
|
|
149
|
-
|
|
150
|
-
- **Binding syntax is `Table[Field]`**, quoting the table name with single quotes if it has spaces: `'Categorias Finanzas'[Categoria]`.
|
|
151
|
-
- **`--no-sync` on every write** during the generation loop.
|
|
152
|
-
- **`_Measures` prefix convention** — measures live in a hidden `_Measures` table (leading underscore); columns live in their fact or dim table. The Node scripts use this prefix as a disambiguation hint when a role accepts `any` kind (e.g. `tableEx.Values`).
|
|
153
|
-
|
|
154
|
-
---
|
|
155
|
-
|
|
156
|
-
## Full end-to-end example
|
|
157
|
-
|
|
158
|
-
```bash
|
|
159
|
-
# PHASE 0: model introspection
|
|
160
|
-
pbi connect
|
|
161
|
-
pbi measure list --json > measures.json
|
|
162
|
-
|
|
163
|
-
# PHASE 4.1: page
|
|
164
|
-
pbi report --no-sync -p ./pbip-files/Foo.Report add-page --name overview --display-name "Resumen"
|
|
165
|
-
|
|
166
|
-
# PHASE 4.2: visuals (via Node script)
|
|
167
|
-
node scripts/create-visual.js -p ./pbip-files/Foo.Report --page overview --type card \
|
|
168
|
-
-n kpi_revenue --x 24 --y 24 --width 280 --height 120 \
|
|
169
|
-
--bind values='_Measures[Total Revenue]' --title "Ingresos"
|
|
170
|
-
|
|
171
|
-
node scripts/create-visual.js -p ./pbip-files/Foo.Report --page overview --type lineChart \
|
|
172
|
-
-n revenue_trend --x 24 --y 200 --width 816 --height 320 \
|
|
173
|
-
--bind category='Fecha[Fecha]' --bind y='_Measures[Total Revenue]'
|
|
174
|
-
|
|
175
|
-
# PHASE 4.3: theme
|
|
176
|
-
node scripts/apply-theme.js --report-path ./pbip-files/Foo.Report --theme-file references/themes/BISuperpowers.json
|
|
177
|
-
|
|
178
|
-
# PHASE 4.4: validation (both layers)
|
|
179
|
-
pbi report -p ./pbip-files/Foo.Report validate
|
|
180
|
-
node scripts/validate-pbir.js ./pbip-files/Foo.Report
|
|
181
|
-
|
|
182
|
-
# PHASE 5: relaunch Desktop
|
|
183
|
-
powershell -Command "Start-Process -FilePath 'C:\Program Files\Microsoft Power BI Desktop\bin\PBIDesktop.exe' -ArgumentList '\"<abs-path.pbip>\"'"
|
|
184
|
-
```
|
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
# CLI setup — installing `pbi-cli-tool`
|
|
2
|
-
|
|
3
|
-
This skill requires the [`pbi-cli-tool`](https://github.com/MinaSaad1/pbi-cli) CLI (MIT, by MinaSaad1) and its `pywin32` dependency for Power BI Desktop auto-sync. All commands below are idempotent — running them on an already-set-up system is safe.
|
|
4
|
-
|
|
5
|
-
## Full setup sequence (run in order)
|
|
6
|
-
|
|
7
|
-
Check each prerequisite; if it's already satisfied, skip to the next.
|
|
8
|
-
|
|
9
|
-
### 1. Python 3.10+
|
|
10
|
-
|
|
11
|
-
```bash
|
|
12
|
-
python --version
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
If the output is `Python 3.10.x` or newer, continue. Otherwise install Python:
|
|
16
|
-
|
|
17
|
-
**Microsoft Store** (easiest on Windows — adds to PATH automatically):
|
|
18
|
-
- Open Microsoft Store → search "Python 3.13" (Publisher: Python Software Foundation) → Install
|
|
19
|
-
- **Close and reopen the terminal** after install so `python` is on PATH
|
|
20
|
-
|
|
21
|
-
**Manual from python.org**:
|
|
22
|
-
- Download installer from https://www.python.org/downloads/
|
|
23
|
-
- During install, check **"Add python.exe to PATH"**
|
|
24
|
-
- Close and reopen the terminal
|
|
25
|
-
|
|
26
|
-
### 2. `pipx`
|
|
27
|
-
|
|
28
|
-
```bash
|
|
29
|
-
pipx --version
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
If it reports a version, skip to step 3. Otherwise:
|
|
33
|
-
|
|
34
|
-
```bash
|
|
35
|
-
pip install --user pipx
|
|
36
|
-
python -m pipx ensurepath
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
Close and reopen the terminal so the new PATH entries take effect. Then verify:
|
|
40
|
-
|
|
41
|
-
```bash
|
|
42
|
-
pipx --version
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
### 3. `pbi-cli-tool`
|
|
46
|
-
|
|
47
|
-
```bash
|
|
48
|
-
pbi --version
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
If it reports `3.10.x` or newer, skip to step 4. Otherwise:
|
|
52
|
-
|
|
53
|
-
```bash
|
|
54
|
-
pipx install pbi-cli-tool
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
### 4. Inject `pywin32` into the pbi-cli pipx environment
|
|
58
|
-
|
|
59
|
-
The `pywin32` package lets `pbi` send keystrokes to Power BI Desktop for auto-sync. Without it, the CLI falls back to PowerShell-based signaling which is less reliable.
|
|
60
|
-
|
|
61
|
-
```bash
|
|
62
|
-
python -m pipx inject pbi-cli-tool pywin32
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
Verify the CLI picks it up:
|
|
66
|
-
|
|
67
|
-
```bash
|
|
68
|
-
pbi visual add --help
|
|
69
|
-
# If the previous run printed "Error: pywin32 is not installed", run the inject.
|
|
70
|
-
# If no such warning appears on subsequent runs, pywin32 is loaded.
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
### 5. Optional — upgrade later
|
|
74
|
-
|
|
75
|
-
```bash
|
|
76
|
-
pipx upgrade pbi-cli-tool
|
|
77
|
-
python -m pipx inject pbi-cli-tool pywin32 --force # refresh the injection
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
Run this periodically (monthly) since MinaSaad1 ships updates alongside Power BI Desktop schema bumps.
|
|
81
|
-
|
|
82
|
-
## Troubleshooting
|
|
83
|
-
|
|
84
|
-
**`pbi: command not found`** after install → terminal PATH needs refresh. Close and reopen. If still missing, `python -m pipx ensurepath` again.
|
|
85
|
-
|
|
86
|
-
**`pip: command not found`** with Python installed → the Microsoft Store install sometimes doesn't put `pip` on PATH. Use `python -m pip ...` instead.
|
|
87
|
-
|
|
88
|
-
**`Found a space in the pipx home path`** warning → harmless on Windows. The CLI works despite this.
|
|
89
|
-
|
|
90
|
-
**`Error: pywin32 is not installed`** when running `pbi visual add` → you ran `pip install --user pywin32` (wrong scope). Instead run `python -m pipx inject pbi-cli-tool pywin32` so it lands in the CLI's isolated venv.
|
|
91
|
-
|
|
92
|
-
## Sanity check (run after full setup)
|
|
93
|
-
|
|
94
|
-
```bash
|
|
95
|
-
pbi --version # should print a version
|
|
96
|
-
pbi setup # should print "Environment is ready."
|
|
97
|
-
pbi connect # should auto-detect running Power BI Desktop
|
|
98
|
-
pbi disconnect # clean disconnect
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
If all four commands succeed, the skill can proceed to PHASE 1.
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
# The close-write-open pattern
|
|
2
|
-
|
|
3
|
-
This is the most important pattern in the skill. Get it wrong and **none of the visuals you generate will render** — not because the JSON is invalid, but because Power BI Desktop refuses to re-read the files while it's open.
|
|
4
|
-
|
|
5
|
-
## The core fact
|
|
6
|
-
|
|
7
|
-
Power BI Desktop reads `visual.json`, `page.json`, and the rest of the PBIR tree **once**, when the `.pbip` is first loaded by the app process. After that, it holds the report in memory and ignores file changes on disk. This is **not** a bug we can work around with the public CLI — it's Desktop's current design.
|
|
8
|
-
|
|
9
|
-
Kurt Buhler documents this explicitly in the `power-bi-agentic-development/plugins/pbip/skills/pbip/SKILL.md`:
|
|
10
|
-
|
|
11
|
-
> **"PBI Desktop does not detect external changes. Close and reopen PBI Desktop after editing files externally."**
|
|
12
|
-
|
|
13
|
-
The subtle part: **"close"** here means kill the `PBIDesktop.exe` process, not `File → Close` inside the app. A file-level close keeps the app process alive with its cache intact. When the user then opens the file again via "Recent files" or drag, Desktop uses its cached state and silently ignores any new visual folders on disk.
|
|
14
|
-
|
|
15
|
-
## The correct sequence
|
|
16
|
-
|
|
17
|
-
```
|
|
18
|
-
1. User has Power BI Desktop open with the .pbip
|
|
19
|
-
2. Skill asks user to save any pending Desktop-side work
|
|
20
|
-
3. Skill kills PBIDesktop.exe (process-level)
|
|
21
|
-
4. Skill writes visuals via pbi CLI (while Desktop is dead)
|
|
22
|
-
5. Skill relaunches the .pbip via Start-Process
|
|
23
|
-
6. A new Desktop process boots, reads files from disk fresh, renders everything
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
## Commands
|
|
27
|
-
|
|
28
|
-
### Kill Desktop
|
|
29
|
-
|
|
30
|
-
Use `cmd //c` in Git Bash to avoid the MSYS path-mangling bug that eats the `/IM` flag:
|
|
31
|
-
|
|
32
|
-
```bash
|
|
33
|
-
cmd //c "taskkill /IM PBIDesktop.exe /F"
|
|
34
|
-
cmd //c "taskkill /IM msmdsrv.exe /F" # Analysis Services — Desktop usually kills this itself but belt-and-braces
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
Verify termination:
|
|
38
|
-
|
|
39
|
-
```bash
|
|
40
|
-
tasklist | grep -iE "PBIDesktop|msmdsrv" # should return no lines
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
### Relaunch the .pbip
|
|
44
|
-
|
|
45
|
-
PowerShell's `Start-Process` runs the shell-open association, which for `.pbip` files launches Power BI Desktop:
|
|
46
|
-
|
|
47
|
-
```bash
|
|
48
|
-
powershell -Command "Start-Process -FilePath './pbip-files/MyProject.pbip'"
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
Desktop takes ~10-20 seconds to fully load the model and render the visuals. The user sees "loading" screens during that window.
|
|
52
|
-
|
|
53
|
-
## What does NOT work (confirmed failures)
|
|
54
|
-
|
|
55
|
-
- **`File → Close` + `File → Open Recent`** — keeps the process alive, cache persists, new visuals ignored
|
|
56
|
-
- **`Ctrl+Shift+F5` (CLI `pbi report reload`)** — only triggers a data refresh, not a structural re-scan of disk
|
|
57
|
-
- **`File → Save` after external writes** — Desktop saves its in-memory state back to disk, which may OVERWRITE the externally-written files with the old state. Dangerous.
|
|
58
|
-
- **Reopening the file by path while the same Desktop process is running** — same process, same cache, same problem
|
|
59
|
-
|
|
60
|
-
## Why `pbi report reload` exists if it doesn't solve this
|
|
61
|
-
|
|
62
|
-
The reload command is useful for smaller cases: refreshing data, picking up a theme change, re-running a single-visual query. It's not meant to discover newly-added visual folders, and the CLI docs don't claim it does.
|
|
63
|
-
|
|
64
|
-
## Gotchas
|
|
65
|
-
|
|
66
|
-
- **User has unsaved work in Desktop**: killing the process without prompting loses that work. Always ask before taskkill. If they have changes, tell them to save first.
|
|
67
|
-
- **msmdsrv.exe lingering**: Desktop usually cleans it up, but occasionally it stays. Kill it separately to free port 53xxx that the CLI uses for `pbi connect`.
|
|
68
|
-
- **Start-Process can't find the .pbip**: the path needs to be relative to CWD or absolute. If you're in `bi-superpowers/` but the .pbip is under `examples/smoke-test/pbip-files/`, use the full relative path.
|
|
69
|
-
- **User has multiple Desktops open**: `taskkill /IM PBIDesktop.exe /F` kills ALL of them. If the user works with multiple .pbip files simultaneously, warn them or narrow the kill to the specific PID (via `tasklist` first).
|
|
70
|
-
- **Virus scanner delays**: some AV tools lock the .pbip briefly after relaunch, causing a ~5-10s delay before Desktop shows anything. Normal, just wait.
|
|
71
|
-
|
|
72
|
-
## How this maps to the skill phases
|
|
73
|
-
|
|
74
|
-
| Phase | What to do |
|
|
75
|
-
|---|---|
|
|
76
|
-
| PHASE 2 end | `pbi disconnect` before kill (socket cleanup) |
|
|
77
|
-
| PHASE 3 | Kill Desktop (with user confirmation) |
|
|
78
|
-
| PHASE 4 | Write via CLI (Desktop is dead — no sync conflicts) |
|
|
79
|
-
| PHASE 5 | Relaunch via `Start-Process` |
|
|
80
|
-
| Post-PHASE 5 | User visually confirms render |
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
# Finance layout (3 pages)
|
|
2
|
-
|
|
3
|
-
Assumed fact table: `GeneralLedger` (or similar). Common dims: `Date`, `Account`, `CostCenter`, `Scenario`. Key measures expected: total revenue, total expense, net profit, margin, variance vs budget.
|
|
4
|
-
|
|
5
|
-
Roles used below (to be resolved via the MCP):
|
|
6
|
-
- `primary-kpi` — top-line KPI (e.g., Net Revenue)
|
|
7
|
-
- `secondary-kpi-1/2/3` — 3 supporting KPIs (e.g., Gross Margin, EBITDA, Expense)
|
|
8
|
-
- `variance-measure` — signed delta (e.g., Variance vs Budget)
|
|
9
|
-
- `time-dim-column` — date column from Date dim
|
|
10
|
-
- `account-dim-column` — Account dim name or category
|
|
11
|
-
- `costcenter-dim-column` — CostCenter dim
|
|
12
|
-
|
|
13
|
-
---
|
|
14
|
-
|
|
15
|
-
## Page 1: `ResumenEjecutivo` / "Resumen Ejecutivo"
|
|
16
|
-
|
|
17
|
-
**Grid (1280×720):**
|
|
18
|
-
|
|
19
|
-
| Visual | Primitive | Position (x, y, w, h) | Bindings |
|
|
20
|
-
|---|---|---|---|
|
|
21
|
-
| Page title | textbox (manual JSON — see `references/textbox.md`) | 16, 16, 1152, 48 | static text "Resumen Ejecutivo" |
|
|
22
|
-
| KPI 1 | card | 16, 80, 280, 120 | `primary-kpi` |
|
|
23
|
-
| KPI 2 | card | 312, 80, 280, 120 | `secondary-kpi-1` |
|
|
24
|
-
| KPI 3 | card | 608, 80, 280, 120 | `secondary-kpi-2` |
|
|
25
|
-
| KPI 4 (variance, signed) | card + conditional color | 904, 80, 280, 120 | `variance-measure` |
|
|
26
|
-
| Revenue over time | line_chart | 16, 216, 816, 320 | `primary-kpi` × `time-dim-column` |
|
|
27
|
-
| Year slicer | slicer (manual JSON — see `references/slicer.md`) | 848, 216, 336, 80 | `'Date'[Year]` |
|
|
28
|
-
| Scenario slicer | slicer (manual JSON — see `references/slicer.md`) | 848, 312, 336, 80 | `Scenario[Scenario]` |
|
|
29
|
-
|
|
30
|
-
**Design notes:**
|
|
31
|
-
- Variance KPI: green/red conditional coloring is design intent only. Render as a plain card with theme/default colors unless a tested PBIR formatting implementation is available.
|
|
32
|
-
- Year slicer default: current year (single-select).
|
|
33
|
-
|
|
34
|
-
---
|
|
35
|
-
|
|
36
|
-
## Page 2: `AnalisisCuentas` / "Análisis por cuenta"
|
|
37
|
-
|
|
38
|
-
| Visual | Primitive | Position | Bindings |
|
|
39
|
-
|---|---|---|---|
|
|
40
|
-
| Page title | textbox (manual JSON — see `references/textbox.md`) | 16, 16, 1152, 48 | "Análisis por cuenta" |
|
|
41
|
-
| Year slicer | slicer (manual JSON — see `references/slicer.md`) | 16, 80, 280, 80 | `'Date'[Year]` |
|
|
42
|
-
| CostCenter slicer | slicer (manual JSON — see `references/slicer.md`) | 312, 80, 280, 80 | `CostCenter[Name]` |
|
|
43
|
-
| Top accounts bar | bar_chart (horizontal) | 16, 176, 608, 480 | `primary-kpi` by `account-dim-column`, TopN 15 |
|
|
44
|
-
| Detail matrix | matrix | 640, 176, 544, 480 | rows: `account-dim-column`, cols: `'Date'[Year]`, values: `primary-kpi` |
|
|
45
|
-
|
|
46
|
-
**Design notes:**
|
|
47
|
-
- Matrix uses gradient conditional formatting on the value column.
|
|
48
|
-
- Bar chart sorts descending by `primary-kpi`.
|
|
49
|
-
|
|
50
|
-
---
|
|
51
|
-
|
|
52
|
-
## Page 3: `DetalleVariance` / "Detalle de variance"
|
|
53
|
-
|
|
54
|
-
| Visual | Primitive | Position | Bindings |
|
|
55
|
-
|---|---|---|---|
|
|
56
|
-
| Page title | textbox (manual JSON — see `references/textbox.md`) | 16, 16, 1152, 48 | "Detalle de variance vs budget" |
|
|
57
|
-
| Year slicer | slicer (manual JSON — see `references/slicer.md`) | 16, 80, 280, 80 | `'Date'[Year]` |
|
|
58
|
-
| Scenario slicer | slicer (manual JSON — see `references/slicer.md`) | 312, 80, 280, 80 | `Scenario[Scenario]` |
|
|
59
|
-
| Variance by costcenter | bar_chart | 16, 176, 608, 320 | `variance-measure` by `costcenter-dim-column`, bars colored by sign (diverging) |
|
|
60
|
-
| Variance trend | line_chart | 640, 176, 544, 320 | `variance-measure` by `time-dim-column` |
|
|
61
|
-
| Account × Month matrix | matrix | 16, 512, 1168, 144 | rows: `account-dim-column`, cols: `'Date'[Month]`, values: `variance-measure` with diverging gradient |
|
|
62
|
-
|
|
63
|
-
**Design notes:**
|
|
64
|
-
- Variance-sign coloring (diverging palette) is design intent only. Render bars/matrix with theme/default colors unless a tested PBIR formatting implementation is available.
|
|
65
|
-
- The bottom matrix is short (144px) so it acts as a "heatmap strip" rather than a scrollable table.
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
# Generic layout (3 pages) — fallback
|
|
2
|
-
|
|
3
|
-
Use when `{domain}` is "otro" or unrecognized. Extract the "main" measure and "main" dimension from the model via MCP (usually the first fact-table measure and the first non-date dim column).
|
|
4
|
-
|
|
5
|
-
Roles:
|
|
6
|
-
- `primary-measure`, `secondary-measure`, `tertiary-measure` (whatever the model has)
|
|
7
|
-
- `primary-dim-column`, `secondary-dim-column`
|
|
8
|
-
|
|
9
|
-
---
|
|
10
|
-
|
|
11
|
-
## Page 1: `Resumen` / "Resumen"
|
|
12
|
-
|
|
13
|
-
| Visual | Primitive | Position | Bindings |
|
|
14
|
-
|---|---|---|---|
|
|
15
|
-
| Page title | textbox (manual JSON — see `references/textbox.md`) | 16, 16, 1152, 48 | "Resumen" |
|
|
16
|
-
| KPI 1 | card | 16, 80, 280, 120 | `primary-measure` |
|
|
17
|
-
| KPI 2 | card | 312, 80, 280, 120 | `secondary-measure` |
|
|
18
|
-
| KPI 3 | card | 608, 80, 280, 120 | `tertiary-measure` (or omit and widen KPI1) |
|
|
19
|
-
| KPI 4 | card | 904, 80, 280, 120 | any YoY / variance measure available, else omit |
|
|
20
|
-
| Main trend | line_chart | 16, 216, 816, 320 | `primary-measure` × `time-dim-column` |
|
|
21
|
-
| Year slicer | slicer (manual JSON — see `references/slicer.md`) | 848, 216, 336, 80 | `'Date'[Year]` |
|
|
22
|
-
| Primary dim slicer | slicer (manual JSON — see `references/slicer.md`) | 848, 312, 336, 80 | `primary-dim-column` |
|
|
23
|
-
|
|
24
|
-
If the model has no `Date` table at all, drop the line chart and replace with a second bar chart.
|
|
25
|
-
|
|
26
|
-
---
|
|
27
|
-
|
|
28
|
-
## Page 2: `Analisis` / "Análisis"
|
|
29
|
-
|
|
30
|
-
| Visual | Primitive | Position | Bindings |
|
|
31
|
-
|---|---|---|---|
|
|
32
|
-
| Page title | textbox (manual JSON — see `references/textbox.md`) | 16, 16, 1152, 48 | "Análisis" |
|
|
33
|
-
| Year slicer | slicer (manual JSON — see `references/slicer.md`) | 16, 80, 280, 80 | `'Date'[Year]` |
|
|
34
|
-
| By primary dim | bar_chart | 16, 176, 608, 480 | `primary-measure` by `primary-dim-column` |
|
|
35
|
-
| By secondary dim | bar_chart | 640, 176, 544, 480 | `primary-measure` by `secondary-dim-column` |
|
|
36
|
-
|
|
37
|
-
---
|
|
38
|
-
|
|
39
|
-
## Page 3: `Detalle` / "Detalle"
|
|
40
|
-
|
|
41
|
-
| Visual | Primitive | Position | Bindings |
|
|
42
|
-
|---|---|---|---|
|
|
43
|
-
| Page title | textbox (manual JSON — see `references/textbox.md`) | 16, 16, 1152, 48 | "Detalle" |
|
|
44
|
-
| Primary dim slicer | slicer (manual JSON — see `references/slicer.md`) | 16, 80, 280, 80 | `primary-dim-column` |
|
|
45
|
-
| Secondary dim slicer | slicer (manual JSON — see `references/slicer.md`) | 312, 80, 280, 80 | `secondary-dim-column` |
|
|
46
|
-
| Detail matrix | matrix | 16, 176, 1168, 480 | rows: `primary-dim-column`, cols: `secondary-dim-column`, values: `primary-measure` + `secondary-measure` |
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
# HR / People layout (3 pages)
|
|
2
|
-
|
|
3
|
-
Assumed fact table: `HeadcountSnapshot` (or `EmployeeFact`). Dims: `Date`, `Employee`, `Department`, `Position`. Measures: headcount, hires, terminations, attrition rate, avg tenure, avg comp.
|
|
4
|
-
|
|
5
|
-
Roles:
|
|
6
|
-
- `headcount-measure`, `hires-measure`, `terminations-measure`, `attrition-rate-measure`
|
|
7
|
-
- `department-dim-column`, `position-dim-column`
|
|
8
|
-
|
|
9
|
-
---
|
|
10
|
-
|
|
11
|
-
## Page 1: `ResumenPlantilla` / "Resumen de plantilla"
|
|
12
|
-
|
|
13
|
-
| Visual | Primitive | Position | Bindings |
|
|
14
|
-
|---|---|---|---|
|
|
15
|
-
| Page title | textbox (manual JSON — see `references/textbox.md`) | 16, 16, 1152, 48 | "Resumen de plantilla" |
|
|
16
|
-
| KPI — Headcount | card | 16, 80, 280, 120 | `headcount-measure` |
|
|
17
|
-
| KPI — Hires YTD | card | 312, 80, 280, 120 | `hires-measure` |
|
|
18
|
-
| KPI — Terminations YTD | card | 608, 80, 280, 120 | `terminations-measure` |
|
|
19
|
-
| KPI — Attrition % | card + conditional color | 904, 80, 280, 120 | `attrition-rate-measure` (red above threshold) |
|
|
20
|
-
| Headcount over time | line_chart | 16, 216, 816, 320 | `headcount-measure` × `time-dim-column` |
|
|
21
|
-
| Year slicer | slicer (manual JSON — see `references/slicer.md`) | 848, 216, 336, 80 | `'Date'[Year]` |
|
|
22
|
-
| Department slicer | slicer (manual JSON — see `references/slicer.md`) | 848, 312, 336, 80 | `department-dim-column` |
|
|
23
|
-
|
|
24
|
-
---
|
|
25
|
-
|
|
26
|
-
## Page 2: `AnalisisDepartamento` / "Análisis por departamento"
|
|
27
|
-
|
|
28
|
-
| Visual | Primitive | Position | Bindings |
|
|
29
|
-
|---|---|---|---|
|
|
30
|
-
| Page title | textbox (manual JSON — see `references/textbox.md`) | 16, 16, 1152, 48 | "Análisis por departamento" |
|
|
31
|
-
| Year slicer | slicer (manual JSON — see `references/slicer.md`) | 16, 80, 280, 80 | `'Date'[Year]` |
|
|
32
|
-
| Headcount by dept | bar_chart (horizontal) | 16, 176, 608, 480 | `headcount-measure` by `department-dim-column` |
|
|
33
|
-
| Attrition by dept | bar_chart (horizontal) | 640, 176, 544, 480 | `attrition-rate-measure` by `department-dim-column` with diverging color |
|
|
34
|
-
|
|
35
|
-
**Design notes:** Attrition chart colors bars by value (higher = redder) to surface hotspots immediately.
|
|
36
|
-
|
|
37
|
-
---
|
|
38
|
-
|
|
39
|
-
## Page 3: `DetalleEmpleados` / "Detalle de empleados"
|
|
40
|
-
|
|
41
|
-
| Visual | Primitive | Position | Bindings |
|
|
42
|
-
|---|---|---|---|
|
|
43
|
-
| Page title | textbox (manual JSON — see `references/textbox.md`) | 16, 16, 1152, 48 | "Detalle de empleados" |
|
|
44
|
-
| Department slicer | slicer (manual JSON — see `references/slicer.md`) | 16, 80, 280, 80 | `department-dim-column` |
|
|
45
|
-
| Position slicer | slicer (manual JSON — see `references/slicer.md`) | 312, 80, 280, 80 | `position-dim-column` |
|
|
46
|
-
| Employee matrix | matrix | 16, 176, 1168, 480 | rows: `Employee[FullName]`, cols: `'Date'[Year]`, values: `headcount-measure` (as snapshot) + tenure if available |
|
|
47
|
-
|
|
48
|
-
**Design notes:** If the model has PII, strongly suggest adding RLS (`/pbi-connect` → MCP) before sharing. Surface this to the user during kickoff.
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
# Marketing layout (3 pages)
|
|
2
|
-
|
|
3
|
-
Assumed fact: `Campaigns` / `MarketingSpend`. Dims: `Date`, `Channel`, `Audience`, `Product` / `Campaign`. Measures: spend, impressions, clicks, conversions, CPA, ROAS, CTR, conversion rate.
|
|
4
|
-
|
|
5
|
-
Roles:
|
|
6
|
-
- `spend-measure`, `conversions-measure`, `cpa-measure`, `roas-measure`
|
|
7
|
-
- `ctr-measure`, `conversion-rate-measure`
|
|
8
|
-
- `channel-dim-column`, `campaign-dim-column`, `audience-dim-column`
|
|
9
|
-
|
|
10
|
-
---
|
|
11
|
-
|
|
12
|
-
## Page 1: `ResumenMarketing` / "Resumen de marketing"
|
|
13
|
-
|
|
14
|
-
| Visual | Primitive | Position | Bindings |
|
|
15
|
-
|---|---|---|---|
|
|
16
|
-
| Page title | textbox (manual JSON — see `references/textbox.md`) | 16, 16, 1152, 48 | "Resumen de marketing" |
|
|
17
|
-
| KPI — Spend | card | 16, 80, 280, 120 | `spend-measure` |
|
|
18
|
-
| KPI — Conversions | card | 312, 80, 280, 120 | `conversions-measure` |
|
|
19
|
-
| KPI — CPA | card | 608, 80, 280, 120 | `cpa-measure` |
|
|
20
|
-
| KPI — ROAS | card + conditional | 904, 80, 280, 120 | `roas-measure` (green > 1, red < 1) |
|
|
21
|
-
| Spend trend | line_chart | 16, 216, 816, 320 | `spend-measure` × `time-dim-column` |
|
|
22
|
-
| Year slicer | slicer (manual JSON — see `references/slicer.md`) | 848, 216, 336, 80 | `'Date'[Year]` |
|
|
23
|
-
| Channel slicer | slicer (manual JSON — see `references/slicer.md`) | 848, 312, 336, 80 | `channel-dim-column` |
|
|
24
|
-
|
|
25
|
-
---
|
|
26
|
-
|
|
27
|
-
## Page 2: `AnalisisCanal` / "Análisis por canal"
|
|
28
|
-
|
|
29
|
-
| Visual | Primitive | Position | Bindings |
|
|
30
|
-
|---|---|---|---|
|
|
31
|
-
| Page title | textbox (manual JSON — see `references/textbox.md`) | 16, 16, 1152, 48 | "Análisis por canal" |
|
|
32
|
-
| Year slicer | slicer (manual JSON — see `references/slicer.md`) | 16, 80, 280, 80 | `'Date'[Year]` |
|
|
33
|
-
| Spend by channel | bar_chart | 16, 176, 608, 480 | `spend-measure` by `channel-dim-column` |
|
|
34
|
-
| ROAS by channel | bar_chart | 640, 176, 544, 480 | `roas-measure` by `channel-dim-column`, diverging color |
|
|
35
|
-
|
|
36
|
-
---
|
|
37
|
-
|
|
38
|
-
## Page 3: `FunnelCampañas` / "Funnel por campaña"
|
|
39
|
-
|
|
40
|
-
| Visual | Primitive | Position | Bindings |
|
|
41
|
-
|---|---|---|---|
|
|
42
|
-
| Page title | textbox (manual JSON — see `references/textbox.md`) | 16, 16, 1152, 48 | "Funnel por campaña" |
|
|
43
|
-
| Channel slicer | slicer (manual JSON — see `references/slicer.md`) | 16, 80, 280, 80 | `channel-dim-column` |
|
|
44
|
-
| Audience slicer | slicer (manual JSON — see `references/slicer.md`) | 312, 80, 280, 80 | `audience-dim-column` |
|
|
45
|
-
| Campaign matrix | matrix | 16, 176, 1168, 480 | rows: `campaign-dim-column`, values: `spend-measure` + `conversions-measure` + `ctr-measure` + `conversion-rate-measure` + `cpa-measure` with column conditional color |
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
# Operations / Supply Chain layout (3 pages)
|
|
2
|
-
|
|
3
|
-
Assumed fact: `Orders` or `Shipments`. Dims: `Date`, `Customer`, `Product`, `Facility`. Measures: volume (orders/units), SLA %, open orders, aging.
|
|
4
|
-
|
|
5
|
-
Roles:
|
|
6
|
-
- `volume-measure`, `sla-measure`, `open-orders-measure`, `aging-measure`
|
|
7
|
-
- `facility-dim-column`, `product-dim-column`
|
|
8
|
-
|
|
9
|
-
---
|
|
10
|
-
|
|
11
|
-
## Page 1: `ResumenOperaciones` / "Resumen operacional"
|
|
12
|
-
|
|
13
|
-
| Visual | Primitive | Position | Bindings |
|
|
14
|
-
|---|---|---|---|
|
|
15
|
-
| Page title | textbox (manual JSON — see `references/textbox.md`) | 16, 16, 1152, 48 | "Resumen operacional" |
|
|
16
|
-
| KPI — Volume | card | 16, 80, 280, 120 | `volume-measure` |
|
|
17
|
-
| KPI — SLA % | card + conditional | 312, 80, 280, 120 | `sla-measure` (red below target) |
|
|
18
|
-
| KPI — Open orders | card | 608, 80, 280, 120 | `open-orders-measure` |
|
|
19
|
-
| KPI — Aging (avg days) | card | 904, 80, 280, 120 | `aging-measure` |
|
|
20
|
-
| Volume trend | line_chart | 16, 216, 816, 320 | `volume-measure` × `time-dim-column` |
|
|
21
|
-
| Year slicer | slicer (manual JSON — see `references/slicer.md`) | 848, 216, 336, 80 | `'Date'[Year]` |
|
|
22
|
-
| Facility slicer | slicer (manual JSON — see `references/slicer.md`) | 848, 312, 336, 80 | `facility-dim-column` |
|
|
23
|
-
|
|
24
|
-
---
|
|
25
|
-
|
|
26
|
-
## Page 2: `AnalisisFacility` / "Análisis por facility"
|
|
27
|
-
|
|
28
|
-
| Visual | Primitive | Position | Bindings |
|
|
29
|
-
|---|---|---|---|
|
|
30
|
-
| Page title | textbox (manual JSON — see `references/textbox.md`) | 16, 16, 1152, 48 | "Análisis por facility" |
|
|
31
|
-
| Year slicer | slicer (manual JSON — see `references/slicer.md`) | 16, 80, 280, 80 | `'Date'[Year]` |
|
|
32
|
-
| SLA by facility | bar_chart | 16, 176, 608, 480 | `sla-measure` by `facility-dim-column`, diverging color (red below target) |
|
|
33
|
-
| Volume by facility | bar_chart | 640, 176, 544, 480 | `volume-measure` by `facility-dim-column` |
|
|
34
|
-
|
|
35
|
-
---
|
|
36
|
-
|
|
37
|
-
## Page 3: `DetalleOrdenes` / "Detalle de órdenes"
|
|
38
|
-
|
|
39
|
-
| Visual | Primitive | Position | Bindings |
|
|
40
|
-
|---|---|---|---|
|
|
41
|
-
| Page title | textbox (manual JSON — see `references/textbox.md`) | 16, 16, 1152, 48 | "Detalle de órdenes" |
|
|
42
|
-
| Facility slicer | slicer (manual JSON — see `references/slicer.md`) | 16, 80, 280, 80 | `facility-dim-column` |
|
|
43
|
-
| Status slicer | slicer (manual JSON — see `references/slicer.md`) | 312, 80, 280, 80 | order status column if present |
|
|
44
|
-
| Orders matrix | matrix | 16, 176, 1168, 480 | rows: `product-dim-column` + `facility-dim-column`, values: `volume-measure` + `open-orders-measure` + `aging-measure` with gradient |
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
# Sales / Revenue layout (3 pages)
|
|
2
|
-
|
|
3
|
-
Assumed fact table: `Sales`. Common dims: `Date`, `Customer`, `Product`, `Salesperson`. Key measures: revenue, units, AOV, orders, revenue YoY.
|
|
4
|
-
|
|
5
|
-
Roles:
|
|
6
|
-
- `primary-kpi` — revenue total
|
|
7
|
-
- `secondary-kpi-1/2/3` — units, orders, AOV
|
|
8
|
-
- `yoy-measure` — revenue YoY %
|
|
9
|
-
- `customer-dim-column`, `product-dim-column`, `salesperson-dim-column`
|
|
10
|
-
|
|
11
|
-
---
|
|
12
|
-
|
|
13
|
-
## Page 1: `ResumenVentas` / "Resumen de ventas"
|
|
14
|
-
|
|
15
|
-
| Visual | Primitive | Position | Bindings |
|
|
16
|
-
|---|---|---|---|
|
|
17
|
-
| Page title | textbox (manual JSON — see `references/textbox.md`) | 16, 16, 1152, 48 | "Resumen de ventas" |
|
|
18
|
-
| KPI 1 — revenue | card | 16, 80, 280, 120 | `primary-kpi` |
|
|
19
|
-
| KPI 2 — units | card | 312, 80, 280, 120 | `secondary-kpi-1` |
|
|
20
|
-
| KPI 3 — orders | card | 608, 80, 280, 120 | `secondary-kpi-2` |
|
|
21
|
-
| KPI 4 — YoY % | card + conditional color | 904, 80, 280, 120 | `yoy-measure` (signed) |
|
|
22
|
-
| Revenue over time | line_chart | 16, 216, 816, 320 | `primary-kpi` × `time-dim-column` |
|
|
23
|
-
| Year slicer | slicer (manual JSON — see `references/slicer.md`) | 848, 216, 336, 80 | `'Date'[Year]` |
|
|
24
|
-
| Channel / Segment slicer | slicer (manual JSON — see `references/slicer.md`) | 848, 312, 336, 80 | best available segmentation column |
|
|
25
|
-
|
|
26
|
-
---
|
|
27
|
-
|
|
28
|
-
## Page 2: `ClientesProductos` / "Clientes y productos"
|
|
29
|
-
|
|
30
|
-
| Visual | Primitive | Position | Bindings |
|
|
31
|
-
|---|---|---|---|
|
|
32
|
-
| Page title | textbox (manual JSON — see `references/textbox.md`) | 16, 16, 1152, 48 | "Clientes y productos" |
|
|
33
|
-
| Year slicer | slicer (manual JSON — see `references/slicer.md`) | 16, 80, 280, 80 | `'Date'[Year]` |
|
|
34
|
-
| Top customers bar | bar_chart (horizontal) | 16, 176, 608, 480 | `primary-kpi` by `customer-dim-column`, TopN 10 |
|
|
35
|
-
| Top products bar | bar_chart (horizontal) | 640, 176, 544, 480 | `primary-kpi` by `product-dim-column`, TopN 10 |
|
|
36
|
-
|
|
37
|
-
**Design notes:** Both bar charts share the year slicer. Use descending sort.
|
|
38
|
-
|
|
39
|
-
---
|
|
40
|
-
|
|
41
|
-
## Page 3: `PipelineDetalle` / "Pipeline y detalle"
|
|
42
|
-
|
|
43
|
-
| Visual | Primitive | Position | Bindings |
|
|
44
|
-
|---|---|---|---|
|
|
45
|
-
| Page title | textbox (manual JSON — see `references/textbox.md`) | 16, 16, 1152, 48 | "Pipeline y detalle" |
|
|
46
|
-
| Year slicer | slicer (manual JSON — see `references/slicer.md`) | 16, 80, 280, 80 | `'Date'[Year]` |
|
|
47
|
-
| Salesperson slicer | slicer (manual JSON — see `references/slicer.md`) | 312, 80, 280, 80 | `salesperson-dim-column` |
|
|
48
|
-
| Pipeline matrix | matrix | 16, 176, 1168, 480 | rows: `salesperson-dim-column`, cols: `'Date'[Month]`, values: `primary-kpi` + `secondary-kpi-2` |
|
|
49
|
-
|
|
50
|
-
**Design notes:** Matrix uses conditional color scale on revenue column. Subtotals enabled.
|