@luquimbo/bi-superpowers 1.0.0
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/plugin.json +8 -0
- package/.mcp.json +25 -0
- package/AGENTS.md +244 -0
- package/CHANGELOG.md +265 -0
- package/LICENSE +21 -0
- package/README.md +211 -0
- package/bin/build-plugin.js +30 -0
- package/bin/cli.js +1064 -0
- package/bin/commands/add.js +533 -0
- package/bin/commands/add.test.js +77 -0
- package/bin/commands/build-desktop.js +166 -0
- package/bin/commands/changelog.js +443 -0
- package/bin/commands/diff.js +325 -0
- package/bin/commands/lint.js +419 -0
- package/bin/commands/lint.test.js +103 -0
- package/bin/commands/mcp-setup.js +246 -0
- package/bin/commands/pull.js +287 -0
- package/bin/commands/pull.test.js +36 -0
- package/bin/commands/push.js +231 -0
- package/bin/commands/push.test.js +14 -0
- package/bin/commands/search.js +344 -0
- package/bin/commands/search.test.js +115 -0
- package/bin/commands/setup.js +545 -0
- package/bin/commands/setup.test.js +46 -0
- package/bin/commands/sync-profile.js +405 -0
- package/bin/commands/sync-profile.test.js +14 -0
- package/bin/commands/sync-source.js +418 -0
- package/bin/commands/sync-source.test.js +14 -0
- package/bin/commands/watch.js +206 -0
- package/bin/lib/generators/claude-plugin.js +266 -0
- package/bin/lib/generators/claude-plugin.test.js +110 -0
- package/bin/lib/generators/index.js +116 -0
- package/bin/lib/generators/shared.js +282 -0
- package/bin/lib/licensing/index.js +35 -0
- package/bin/lib/licensing/storage.js +364 -0
- package/bin/lib/licensing/storage.test.js +55 -0
- package/bin/lib/licensing/validator.js +213 -0
- package/bin/lib/licensing/validator.test.js +137 -0
- package/bin/lib/microsoft-mcp.js +176 -0
- package/bin/lib/microsoft-mcp.test.js +106 -0
- package/bin/lib/skills.js +84 -0
- package/bin/mcp/powerbi-modeling-launcher.js +38 -0
- package/bin/postinstall.js +44 -0
- package/bin/utils/errors.js +159 -0
- package/bin/utils/git.js +298 -0
- package/bin/utils/logger.js +142 -0
- package/bin/utils/mcp-detect.js +274 -0
- package/bin/utils/mcp-detect.test.js +105 -0
- package/bin/utils/pbix.js +305 -0
- package/bin/utils/pbix.test.js +37 -0
- package/bin/utils/profiles.js +312 -0
- package/bin/utils/projects.js +168 -0
- package/bin/utils/readline.js +206 -0
- package/bin/utils/readline.test.js +47 -0
- package/bin/utils/tui.js +314 -0
- package/bin/utils/tui.test.js +127 -0
- package/commands/contributions.md +265 -0
- package/commands/data-model-design.md +468 -0
- package/commands/dax-doctor.md +248 -0
- package/commands/fabric-scripts.md +452 -0
- package/commands/migration-assistant.md +290 -0
- package/commands/model-documenter.md +242 -0
- package/commands/pbi-connect.md +239 -0
- package/commands/project-kickoff.md +905 -0
- package/commands/report-layout.md +296 -0
- package/commands/rls-design.md +533 -0
- package/commands/theme-tweaker.md +624 -0
- package/config.example.json +23 -0
- package/config.json +23 -0
- package/desktop-extension/manifest.json +37 -0
- package/desktop-extension/package.json +10 -0
- package/desktop-extension/server.js +95 -0
- package/docs/openrouter-free-models.md +92 -0
- package/library/examples/README.md +151 -0
- package/library/examples/finance-reporting/README.md +351 -0
- package/library/examples/finance-reporting/data-model.md +267 -0
- package/library/examples/finance-reporting/measures.dax +557 -0
- package/library/examples/hr-analytics/README.md +371 -0
- package/library/examples/hr-analytics/data-model.md +315 -0
- package/library/examples/hr-analytics/measures.dax +460 -0
- package/library/examples/marketing-analytics/README.md +37 -0
- package/library/examples/marketing-analytics/data-model.md +62 -0
- package/library/examples/marketing-analytics/measures.dax +110 -0
- package/library/examples/retail-analytics/README.md +439 -0
- package/library/examples/retail-analytics/data-model.md +288 -0
- package/library/examples/retail-analytics/measures.dax +481 -0
- package/library/examples/supply-chain/README.md +37 -0
- package/library/examples/supply-chain/data-model.md +69 -0
- package/library/examples/supply-chain/measures.dax +77 -0
- package/library/examples/udf-library/README.md +228 -0
- package/library/examples/udf-library/functions.dax +571 -0
- package/library/snippets/dax/README.md +292 -0
- package/library/snippets/dax/business-domains.md +576 -0
- package/library/snippets/dax/calculate-patterns.md +276 -0
- package/library/snippets/dax/calculation-groups.md +489 -0
- package/library/snippets/dax/error-handling.md +495 -0
- package/library/snippets/dax/iterators-and-aggregations.md +474 -0
- package/library/snippets/dax/kpis-and-metrics.md +293 -0
- package/library/snippets/dax/rankings-and-topn.md +235 -0
- package/library/snippets/dax/security-patterns.md +413 -0
- package/library/snippets/dax/text-and-formatting.md +316 -0
- package/library/snippets/dax/time-intelligence.md +196 -0
- package/library/snippets/dax/user-defined-functions.md +477 -0
- package/library/snippets/dax/virtual-tables.md +546 -0
- package/library/snippets/excel-formulas/README.md +84 -0
- package/library/snippets/excel-formulas/aggregations.md +330 -0
- package/library/snippets/excel-formulas/dates-and-times.md +361 -0
- package/library/snippets/excel-formulas/dynamic-arrays.md +314 -0
- package/library/snippets/excel-formulas/lookups.md +169 -0
- package/library/snippets/excel-formulas/text-functions.md +363 -0
- package/library/snippets/governance/naming-conventions.md +97 -0
- package/library/snippets/governance/review-checklists.md +107 -0
- package/library/snippets/power-query/README.md +389 -0
- package/library/snippets/power-query/api-integration.md +707 -0
- package/library/snippets/power-query/connections.md +434 -0
- package/library/snippets/power-query/data-cleaning.md +298 -0
- package/library/snippets/power-query/error-handling.md +526 -0
- package/library/snippets/power-query/parameters.md +350 -0
- package/library/snippets/power-query/performance.md +506 -0
- package/library/snippets/power-query/transformations.md +330 -0
- package/library/snippets/report-design/accessibility.md +78 -0
- package/library/snippets/report-design/chart-selection.md +54 -0
- package/library/snippets/report-design/layout-patterns.md +87 -0
- package/library/templates/data-models/README.md +93 -0
- package/library/templates/data-models/finance-model.md +627 -0
- package/library/templates/data-models/retail-star-schema.md +473 -0
- package/library/templates/excel/README.md +83 -0
- package/library/templates/excel/budget-tracker.md +432 -0
- package/library/templates/excel/data-entry-form.md +533 -0
- package/library/templates/power-bi/README.md +72 -0
- package/library/templates/power-bi/finance-report.md +449 -0
- package/library/templates/power-bi/kpi-scorecard.md +461 -0
- package/library/templates/power-bi/sales-dashboard.md +281 -0
- package/library/themes/excel/README.md +436 -0
- package/library/themes/power-bi/README.md +271 -0
- package/library/themes/power-bi/accessible.json +307 -0
- package/library/themes/power-bi/bi-superpowers-default.json +858 -0
- package/library/themes/power-bi/corporate-blue.json +291 -0
- package/library/themes/power-bi/dark-mode.json +291 -0
- package/library/themes/power-bi/minimal.json +292 -0
- package/library/themes/power-bi/print-friendly.json +309 -0
- package/package.json +93 -0
- package/skills/contributions/SKILL.md +267 -0
- package/skills/data-model-design/SKILL.md +470 -0
- package/skills/data-modeling/SKILL.md +254 -0
- package/skills/data-quality/SKILL.md +664 -0
- package/skills/dax/SKILL.md +708 -0
- package/skills/dax-doctor/SKILL.md +250 -0
- package/skills/dax-udf/SKILL.md +489 -0
- package/skills/deployment/SKILL.md +320 -0
- package/skills/excel-formulas/SKILL.md +463 -0
- package/skills/fabric-scripts/SKILL.md +454 -0
- package/skills/fast-standard/SKILL.md +509 -0
- package/skills/governance/SKILL.md +205 -0
- package/skills/migration-assistant/SKILL.md +292 -0
- package/skills/model-documenter/SKILL.md +244 -0
- package/skills/pbi-connect/SKILL.md +241 -0
- package/skills/power-query/SKILL.md +406 -0
- package/skills/project-kickoff/SKILL.md +907 -0
- package/skills/query-performance/SKILL.md +480 -0
- package/skills/report-design/SKILL.md +207 -0
- package/skills/report-layout/SKILL.md +298 -0
- package/skills/rls-design/SKILL.md +535 -0
- package/skills/semantic-model/SKILL.md +237 -0
- package/skills/testing-validation/SKILL.md +643 -0
- package/skills/theme-tweaker/SKILL.md +626 -0
- package/src/content/base.md +237 -0
- package/src/content/mcp-requirements.json +69 -0
- package/src/content/routing.md +203 -0
- package/src/content/skills/contributions.md +259 -0
- package/src/content/skills/data-model-design.md +462 -0
- package/src/content/skills/data-modeling.md +246 -0
- package/src/content/skills/data-quality.md +656 -0
- package/src/content/skills/dax-doctor.md +242 -0
- package/src/content/skills/dax-udf.md +481 -0
- package/src/content/skills/dax.md +700 -0
- package/src/content/skills/deployment.md +312 -0
- package/src/content/skills/excel-formulas.md +455 -0
- package/src/content/skills/fabric-scripts.md +446 -0
- package/src/content/skills/fast-standard.md +501 -0
- package/src/content/skills/governance.md +197 -0
- package/src/content/skills/migration-assistant.md +284 -0
- package/src/content/skills/model-documenter.md +236 -0
- package/src/content/skills/pbi-connect.md +233 -0
- package/src/content/skills/power-query.md +398 -0
- package/src/content/skills/project-kickoff.md +899 -0
- package/src/content/skills/query-performance.md +472 -0
- package/src/content/skills/report-design.md +199 -0
- package/src/content/skills/report-layout.md +290 -0
- package/src/content/skills/rls-design.md +527 -0
- package/src/content/skills/semantic-model.md +229 -0
- package/src/content/skills/testing-validation.md +635 -0
- package/src/content/skills/theme-tweaker.md +618 -0
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
# KPIs and Metrics DAX Patterns
|
|
2
|
+
|
|
3
|
+
Reusable DAX measures for business metrics, variance analysis, and KPI calculations.
|
|
4
|
+
|
|
5
|
+
## Variance Analysis
|
|
6
|
+
|
|
7
|
+
### Absolute Variance
|
|
8
|
+
```dax
|
|
9
|
+
Variance_Actual_vs_Budget =
|
|
10
|
+
[ActualSales] - [BudgetSales]
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
### Variance Percentage
|
|
14
|
+
```dax
|
|
15
|
+
Variance_Pct =
|
|
16
|
+
DIVIDE(
|
|
17
|
+
[ActualSales] - [BudgetSales],
|
|
18
|
+
[BudgetSales]
|
|
19
|
+
)
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### Variance with Direction Indicator
|
|
23
|
+
```dax
|
|
24
|
+
Variance_Indicator =
|
|
25
|
+
VAR _Variance = [ActualSales] - [BudgetSales]
|
|
26
|
+
RETURN
|
|
27
|
+
SWITCH(
|
|
28
|
+
TRUE(),
|
|
29
|
+
_Variance > 0, "Above",
|
|
30
|
+
_Variance < 0, "Below",
|
|
31
|
+
"On Target"
|
|
32
|
+
)
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### Variance Icon (for Conditional Formatting)
|
|
36
|
+
```dax
|
|
37
|
+
Variance_Icon =
|
|
38
|
+
VAR _Pct = [Variance_Pct]
|
|
39
|
+
RETURN
|
|
40
|
+
SWITCH(
|
|
41
|
+
TRUE(),
|
|
42
|
+
_Pct >= 0.05, "Up", -- 5%+ above
|
|
43
|
+
_Pct >= 0, "Flat", -- 0-5% above
|
|
44
|
+
_Pct >= -0.05, "Flat", -- 0-5% below
|
|
45
|
+
"Down" -- 5%+ below
|
|
46
|
+
)
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Growth Metrics
|
|
50
|
+
|
|
51
|
+
### Year-over-Year Growth
|
|
52
|
+
```dax
|
|
53
|
+
YoY_Growth =
|
|
54
|
+
VAR _Current = [TotalSales]
|
|
55
|
+
VAR _PY = [Sales_PY]
|
|
56
|
+
RETURN
|
|
57
|
+
DIVIDE(_Current - _PY, _PY)
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Month-over-Month Growth
|
|
61
|
+
```dax
|
|
62
|
+
MoM_Growth =
|
|
63
|
+
VAR _Current = [TotalSales]
|
|
64
|
+
VAR _PM = [Sales_PM]
|
|
65
|
+
RETURN
|
|
66
|
+
DIVIDE(_Current - _PM, _PM)
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Compound Annual Growth Rate (CAGR)
|
|
70
|
+
```dax
|
|
71
|
+
CAGR =
|
|
72
|
+
VAR _StartValue = CALCULATE([TotalSales], FIRSTDATE('Date'[Date]))
|
|
73
|
+
VAR _EndValue = CALCULATE([TotalSales], LASTDATE('Date'[Date]))
|
|
74
|
+
VAR _Years = DATEDIFF(MIN('Date'[Date]), MAX('Date'[Date]), YEAR)
|
|
75
|
+
RETURN
|
|
76
|
+
IF(
|
|
77
|
+
_Years > 0 && _StartValue > 0,
|
|
78
|
+
POWER(DIVIDE(_EndValue, _StartValue), DIVIDE(1, _Years)) - 1,
|
|
79
|
+
BLANK()
|
|
80
|
+
)
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Ratios and Margins
|
|
84
|
+
|
|
85
|
+
### Profit Margin
|
|
86
|
+
```dax
|
|
87
|
+
ProfitMargin =
|
|
88
|
+
DIVIDE(
|
|
89
|
+
[TotalProfit],
|
|
90
|
+
[TotalRevenue]
|
|
91
|
+
)
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Gross Margin
|
|
95
|
+
```dax
|
|
96
|
+
GrossMargin =
|
|
97
|
+
DIVIDE(
|
|
98
|
+
[TotalRevenue] - [TotalCOGS],
|
|
99
|
+
[TotalRevenue]
|
|
100
|
+
)
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Contribution Margin
|
|
104
|
+
```dax
|
|
105
|
+
ContributionMargin =
|
|
106
|
+
DIVIDE(
|
|
107
|
+
[TotalRevenue] - [VariableCosts],
|
|
108
|
+
[TotalRevenue]
|
|
109
|
+
)
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### Return on Investment (ROI)
|
|
113
|
+
```dax
|
|
114
|
+
ROI =
|
|
115
|
+
DIVIDE(
|
|
116
|
+
[TotalProfit] - [Investment],
|
|
117
|
+
[Investment]
|
|
118
|
+
)
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## Conversion and Efficiency
|
|
122
|
+
|
|
123
|
+
### Conversion Rate
|
|
124
|
+
```dax
|
|
125
|
+
ConversionRate =
|
|
126
|
+
DIVIDE(
|
|
127
|
+
[CompletedOrders],
|
|
128
|
+
[TotalVisits]
|
|
129
|
+
)
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### Customer Acquisition Cost (CAC)
|
|
133
|
+
```dax
|
|
134
|
+
CAC =
|
|
135
|
+
DIVIDE(
|
|
136
|
+
[MarketingSpend],
|
|
137
|
+
[NewCustomers]
|
|
138
|
+
)
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Customer Lifetime Value (CLV)
|
|
142
|
+
```dax
|
|
143
|
+
CLV =
|
|
144
|
+
[AverageOrderValue] * [PurchaseFrequency] * [CustomerLifespan]
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### CLV to CAC Ratio
|
|
148
|
+
```dax
|
|
149
|
+
CLV_CAC_Ratio =
|
|
150
|
+
DIVIDE([CLV], [CAC])
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
## Performance Indicators
|
|
154
|
+
|
|
155
|
+
### Target Achievement %
|
|
156
|
+
```dax
|
|
157
|
+
TargetAchievement =
|
|
158
|
+
DIVIDE([ActualSales], [TargetSales])
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### Traffic Light Status
|
|
162
|
+
```dax
|
|
163
|
+
Status_TrafficLight =
|
|
164
|
+
VAR _Achievement = [TargetAchievement]
|
|
165
|
+
RETURN
|
|
166
|
+
SWITCH(
|
|
167
|
+
TRUE(),
|
|
168
|
+
_Achievement >= 1, "Green",
|
|
169
|
+
_Achievement >= 0.8, "Yellow",
|
|
170
|
+
"Red"
|
|
171
|
+
)
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### Status with Numeric Code
|
|
175
|
+
```dax
|
|
176
|
+
Status_Code =
|
|
177
|
+
VAR _Achievement = [TargetAchievement]
|
|
178
|
+
RETURN
|
|
179
|
+
SWITCH(
|
|
180
|
+
TRUE(),
|
|
181
|
+
_Achievement >= 1, 3, -- Green
|
|
182
|
+
_Achievement >= 0.8, 2, -- Yellow
|
|
183
|
+
1 -- Red
|
|
184
|
+
)
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
## Average Metrics
|
|
188
|
+
|
|
189
|
+
### Average Order Value (AOV)
|
|
190
|
+
```dax
|
|
191
|
+
AOV =
|
|
192
|
+
DIVIDE(
|
|
193
|
+
[TotalRevenue],
|
|
194
|
+
[OrderCount]
|
|
195
|
+
)
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### Average Revenue per User (ARPU)
|
|
199
|
+
```dax
|
|
200
|
+
ARPU =
|
|
201
|
+
DIVIDE(
|
|
202
|
+
[TotalRevenue],
|
|
203
|
+
[UniqueCustomers]
|
|
204
|
+
)
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### Weighted Average
|
|
208
|
+
```dax
|
|
209
|
+
WeightedAvgPrice =
|
|
210
|
+
DIVIDE(
|
|
211
|
+
SUMX(Sales, Sales[Quantity] * Sales[UnitPrice]),
|
|
212
|
+
SUM(Sales[Quantity])
|
|
213
|
+
)
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
## Dynamic Metrics
|
|
217
|
+
|
|
218
|
+
### Selected Metric (Slicer-Driven)
|
|
219
|
+
```dax
|
|
220
|
+
SelectedMetric =
|
|
221
|
+
VAR _Selection = SELECTEDVALUE('Metrics'[MetricName], "Sales")
|
|
222
|
+
RETURN
|
|
223
|
+
SWITCH(
|
|
224
|
+
_Selection,
|
|
225
|
+
"Sales", [TotalSales],
|
|
226
|
+
"Profit", [TotalProfit],
|
|
227
|
+
"Margin", [ProfitMargin],
|
|
228
|
+
"Orders", [OrderCount],
|
|
229
|
+
[TotalSales]
|
|
230
|
+
)
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
### Dynamic Title
|
|
234
|
+
```dax
|
|
235
|
+
ChartTitle =
|
|
236
|
+
VAR _Metric = SELECTEDVALUE('Metrics'[MetricName], "Sales")
|
|
237
|
+
VAR _Period = SELECTEDVALUE('Date'[Year])
|
|
238
|
+
RETURN
|
|
239
|
+
_Metric & " Performance - " & _Period
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
## Benchmarking
|
|
243
|
+
|
|
244
|
+
### Percentile Rank
|
|
245
|
+
```dax
|
|
246
|
+
PercentileRank =
|
|
247
|
+
VAR _CurrentValue = [TotalSales]
|
|
248
|
+
VAR _AllValues =
|
|
249
|
+
ADDCOLUMNS(
|
|
250
|
+
ALL(Products),
|
|
251
|
+
"@Sales", [TotalSales]
|
|
252
|
+
)
|
|
253
|
+
VAR _CountBelow =
|
|
254
|
+
COUNTROWS(FILTER(_AllValues, [@Sales] < _CurrentValue))
|
|
255
|
+
VAR _Total = COUNTROWS(_AllValues)
|
|
256
|
+
RETURN
|
|
257
|
+
DIVIDE(_CountBelow, _Total)
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
### Distance from Average
|
|
261
|
+
```dax
|
|
262
|
+
Distance_From_Avg =
|
|
263
|
+
VAR _Current = [TotalSales]
|
|
264
|
+
VAR _Avg = AVERAGEX(ALL(Products), [TotalSales])
|
|
265
|
+
RETURN
|
|
266
|
+
_Current - _Avg
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
### Z-Score
|
|
270
|
+
```dax
|
|
271
|
+
ZScore =
|
|
272
|
+
VAR _Current = [TotalSales]
|
|
273
|
+
VAR _AllValues =
|
|
274
|
+
ADDCOLUMNS(ALL(Products), "@Sales", [TotalSales])
|
|
275
|
+
VAR _Avg = AVERAGEX(_AllValues, [@Sales])
|
|
276
|
+
VAR _StdDev =
|
|
277
|
+
SQRT(
|
|
278
|
+
AVERAGEX(
|
|
279
|
+
_AllValues,
|
|
280
|
+
POWER([@Sales] - _Avg, 2)
|
|
281
|
+
)
|
|
282
|
+
)
|
|
283
|
+
RETURN
|
|
284
|
+
DIVIDE(_Current - _Avg, _StdDev)
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
## Usage Notes
|
|
288
|
+
|
|
289
|
+
- Always use DIVIDE() for safe division
|
|
290
|
+
- Consider BLANK() handling for incomplete data periods
|
|
291
|
+
- Use variables for complex calculations (readability + performance)
|
|
292
|
+
- Test metrics with various filter contexts
|
|
293
|
+
- Document expected ranges for KPIs
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
# Rankings and Top N DAX Patterns
|
|
2
|
+
|
|
3
|
+
Reusable DAX measures for ranking and top/bottom analysis.
|
|
4
|
+
|
|
5
|
+
## Basic Rankings
|
|
6
|
+
|
|
7
|
+
### Simple Rank (Descending)
|
|
8
|
+
```dax
|
|
9
|
+
ProductRank =
|
|
10
|
+
RANKX(
|
|
11
|
+
ALL(Products[ProductName]),
|
|
12
|
+
[TotalSales],
|
|
13
|
+
,
|
|
14
|
+
DESC,
|
|
15
|
+
DENSE
|
|
16
|
+
)
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
### Rank within Category
|
|
20
|
+
```dax
|
|
21
|
+
ProductRank_InCategory =
|
|
22
|
+
RANKX(
|
|
23
|
+
ALLEXCEPT(Products, Products[Category]),
|
|
24
|
+
[TotalSales],
|
|
25
|
+
,
|
|
26
|
+
DESC,
|
|
27
|
+
DENSE
|
|
28
|
+
)
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### Dynamic Rank (Respects Filters)
|
|
32
|
+
```dax
|
|
33
|
+
ProductRank_Dynamic =
|
|
34
|
+
IF(
|
|
35
|
+
HASONEVALUE(Products[ProductName]),
|
|
36
|
+
RANKX(
|
|
37
|
+
ALLSELECTED(Products[ProductName]),
|
|
38
|
+
[TotalSales],
|
|
39
|
+
,
|
|
40
|
+
DESC,
|
|
41
|
+
DENSE
|
|
42
|
+
)
|
|
43
|
+
)
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Top N Analysis
|
|
47
|
+
|
|
48
|
+
### Top 5 Products Sales
|
|
49
|
+
```dax
|
|
50
|
+
Top5_Products_Sales =
|
|
51
|
+
CALCULATE(
|
|
52
|
+
[TotalSales],
|
|
53
|
+
TOPN(
|
|
54
|
+
5,
|
|
55
|
+
ALL(Products[ProductName]),
|
|
56
|
+
[TotalSales],
|
|
57
|
+
DESC
|
|
58
|
+
)
|
|
59
|
+
)
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Top N with Parameter
|
|
63
|
+
```dax
|
|
64
|
+
TopN_Sales =
|
|
65
|
+
VAR _N = SELECTEDVALUE('Parameters'[TopN], 10)
|
|
66
|
+
RETURN
|
|
67
|
+
CALCULATE(
|
|
68
|
+
[TotalSales],
|
|
69
|
+
TOPN(
|
|
70
|
+
_N,
|
|
71
|
+
ALL(Products[ProductName]),
|
|
72
|
+
[TotalSales],
|
|
73
|
+
DESC
|
|
74
|
+
)
|
|
75
|
+
)
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Top N % of Total
|
|
79
|
+
```dax
|
|
80
|
+
TopN_Pct_of_Total =
|
|
81
|
+
VAR _TopN = [Top5_Products_Sales]
|
|
82
|
+
VAR _Total = CALCULATE([TotalSales], ALL(Products))
|
|
83
|
+
RETURN
|
|
84
|
+
DIVIDE(_TopN, _Total)
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Bottom N Analysis
|
|
88
|
+
|
|
89
|
+
### Bottom 5 Products
|
|
90
|
+
```dax
|
|
91
|
+
Bottom5_Products_Sales =
|
|
92
|
+
CALCULATE(
|
|
93
|
+
[TotalSales],
|
|
94
|
+
TOPN(
|
|
95
|
+
5,
|
|
96
|
+
ALL(Products[ProductName]),
|
|
97
|
+
[TotalSales],
|
|
98
|
+
ASC
|
|
99
|
+
)
|
|
100
|
+
)
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Bottom Performers (Below Threshold)
|
|
104
|
+
```dax
|
|
105
|
+
BelowThreshold_Sales =
|
|
106
|
+
VAR _Threshold = 1000
|
|
107
|
+
RETURN
|
|
108
|
+
CALCULATE(
|
|
109
|
+
[TotalSales],
|
|
110
|
+
FILTER(
|
|
111
|
+
ALL(Products[ProductName]),
|
|
112
|
+
[TotalSales] < _Threshold
|
|
113
|
+
)
|
|
114
|
+
)
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## "Others" Category
|
|
118
|
+
|
|
119
|
+
### Top 5 + Others
|
|
120
|
+
```dax
|
|
121
|
+
Sales_Top5_Others =
|
|
122
|
+
VAR _CurrentProduct = SELECTEDVALUE(Products[ProductName])
|
|
123
|
+
VAR _Rank = [ProductRank]
|
|
124
|
+
VAR _Sales = [TotalSales]
|
|
125
|
+
RETURN
|
|
126
|
+
IF(
|
|
127
|
+
_Rank <= 5,
|
|
128
|
+
_Sales,
|
|
129
|
+
BLANK()
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
-- Separate measure for "Others"
|
|
133
|
+
Sales_Others =
|
|
134
|
+
VAR _Top5 = [Top5_Products_Sales]
|
|
135
|
+
VAR _Total = CALCULATE([TotalSales], ALL(Products))
|
|
136
|
+
RETURN
|
|
137
|
+
_Total - _Top5
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## Percentile Rankings
|
|
141
|
+
|
|
142
|
+
### Percentile Rank
|
|
143
|
+
```dax
|
|
144
|
+
PercentileRank =
|
|
145
|
+
VAR _CurrentValue = [TotalSales]
|
|
146
|
+
VAR _AllValues =
|
|
147
|
+
ADDCOLUMNS(
|
|
148
|
+
ALL(Products[ProductName]),
|
|
149
|
+
"@Sales", [TotalSales]
|
|
150
|
+
)
|
|
151
|
+
VAR _CountBelow =
|
|
152
|
+
COUNTROWS(
|
|
153
|
+
FILTER(_AllValues, [@Sales] < _CurrentValue)
|
|
154
|
+
)
|
|
155
|
+
VAR _Total = COUNTROWS(_AllValues)
|
|
156
|
+
RETURN
|
|
157
|
+
DIVIDE(_CountBelow, _Total)
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### Quartile Assignment
|
|
161
|
+
```dax
|
|
162
|
+
Quartile =
|
|
163
|
+
VAR _Pct = [PercentileRank]
|
|
164
|
+
RETURN
|
|
165
|
+
SWITCH(
|
|
166
|
+
TRUE(),
|
|
167
|
+
_Pct >= 0.75, "Q1 (Top 25%)",
|
|
168
|
+
_Pct >= 0.50, "Q2",
|
|
169
|
+
_Pct >= 0.25, "Q3",
|
|
170
|
+
"Q4 (Bottom 25%)"
|
|
171
|
+
)
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
## Ranking with Ties
|
|
175
|
+
|
|
176
|
+
### Skip Rank (Standard)
|
|
177
|
+
```dax
|
|
178
|
+
Rank_Skip =
|
|
179
|
+
RANKX(
|
|
180
|
+
ALL(Products[ProductName]),
|
|
181
|
+
[TotalSales],
|
|
182
|
+
,
|
|
183
|
+
DESC,
|
|
184
|
+
SKIP -- 1, 2, 2, 4 (skips 3)
|
|
185
|
+
)
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
### Dense Rank
|
|
189
|
+
```dax
|
|
190
|
+
Rank_Dense =
|
|
191
|
+
RANKX(
|
|
192
|
+
ALL(Products[ProductName]),
|
|
193
|
+
[TotalSales],
|
|
194
|
+
,
|
|
195
|
+
DESC,
|
|
196
|
+
DENSE -- 1, 2, 2, 3 (no gaps)
|
|
197
|
+
)
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
## ABC Analysis
|
|
201
|
+
|
|
202
|
+
### ABC Classification
|
|
203
|
+
```dax
|
|
204
|
+
ABC_Class =
|
|
205
|
+
VAR _CumulativePct = [CumulativePct_of_Total]
|
|
206
|
+
RETURN
|
|
207
|
+
SWITCH(
|
|
208
|
+
TRUE(),
|
|
209
|
+
_CumulativePct <= 0.70, "A",
|
|
210
|
+
_CumulativePct <= 0.90, "B",
|
|
211
|
+
"C"
|
|
212
|
+
)
|
|
213
|
+
|
|
214
|
+
-- Supporting measure
|
|
215
|
+
CumulativePct_of_Total =
|
|
216
|
+
VAR _CurrentRank = [ProductRank]
|
|
217
|
+
VAR _CumulativeSales =
|
|
218
|
+
CALCULATE(
|
|
219
|
+
[TotalSales],
|
|
220
|
+
FILTER(
|
|
221
|
+
ALL(Products[ProductName]),
|
|
222
|
+
[ProductRank] <= _CurrentRank
|
|
223
|
+
)
|
|
224
|
+
)
|
|
225
|
+
VAR _TotalSales = CALCULATE([TotalSales], ALL(Products))
|
|
226
|
+
RETURN
|
|
227
|
+
DIVIDE(_CumulativeSales, _TotalSales)
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
## Usage Notes
|
|
231
|
+
|
|
232
|
+
- DENSE vs SKIP: Use DENSE when you need consecutive ranks without gaps
|
|
233
|
+
- Always specify ASC or DESC explicitly for clarity
|
|
234
|
+
- Use ALLEXCEPT for rankings within groups
|
|
235
|
+
- Consider using HASONEVALUE to avoid showing ranks in totals
|