mirror of
https://github.com/MinaSaad1/pbi-cli
synced 2026-04-21 13:37:19 +00:00
fix: add TrendLine to kpi and MaxValue to gauge queryState roles
Confirmed from Sales_Report.Report Desktop export: kpi visuals have a third queryState key TrendLine (date/axis column for the sparkline), and gauge visuals have a second queryState key MaxValue (a measure role). - kpi.json template: add TrendLine projection slot - gauge.json template: add MaxValue projection slot - VISUAL_DATA_ROLES: updated kpi and gauge role lists - ROLE_ALIASES: added trend_line/trend aliases for kpi, max/max_value/target for gauge - MEASURE_ROLES: added MaxValue (TrendLine binds to Column, not Measure) - tests: 6 new tests covering template structure and alias resolution
This commit is contained in:
parent
628a5fb758
commit
9f2a7b044e
4 changed files with 75 additions and 5 deletions
|
|
@ -53,8 +53,8 @@ VISUAL_DATA_ROLES: dict[str, list[str]] = {
|
|||
"tableEx": ["Values"],
|
||||
"pivotTable": ["Rows", "Values", "Columns"],
|
||||
"slicer": ["Values"],
|
||||
"kpi": ["Indicator", "Goal"],
|
||||
"gauge": ["Y"],
|
||||
"kpi": ["Indicator", "Goal", "TrendLine"],
|
||||
"gauge": ["Y", "MaxValue"],
|
||||
"donutChart": ["Category", "Y", "Legend"],
|
||||
# v3.1.0 additions
|
||||
"columnChart": ["Category", "Y", "Legend"],
|
||||
|
|
@ -92,6 +92,8 @@ MEASURE_ROLES: frozenset[str] = frozenset({
|
|||
"ColumnY", "LineY", "X", "Size",
|
||||
# v3.4.0 additions
|
||||
"Data",
|
||||
# v3.8.0 additions
|
||||
"MaxValue",
|
||||
})
|
||||
|
||||
# User-friendly role aliases to PBIR role names
|
||||
|
|
@ -103,8 +105,19 @@ ROLE_ALIASES: dict[str, dict[str, str]] = {
|
|||
"tableEx": {"value": "Values", "column": "Values"},
|
||||
"pivotTable": {"row": "Rows", "value": "Values", "column": "Columns"},
|
||||
"slicer": {"value": "Values", "field": "Values"},
|
||||
"kpi": {"indicator": "Indicator", "value": "Indicator", "goal": "Goal"},
|
||||
"gauge": {"value": "Y"},
|
||||
"kpi": {
|
||||
"indicator": "Indicator",
|
||||
"value": "Indicator",
|
||||
"goal": "Goal",
|
||||
"trend_line": "TrendLine",
|
||||
"trend": "TrendLine",
|
||||
},
|
||||
"gauge": {
|
||||
"value": "Y",
|
||||
"max": "MaxValue",
|
||||
"max_value": "MaxValue",
|
||||
"target": "MaxValue",
|
||||
},
|
||||
"donutChart": {"category": "Category", "value": "Y", "legend": "Legend"},
|
||||
# v3.1.0 additions
|
||||
"columnChart": {"category": "Category", "value": "Y", "legend": "Legend"},
|
||||
|
|
|
|||
|
|
@ -15,6 +15,9 @@
|
|||
"queryState": {
|
||||
"Y": {
|
||||
"projections": []
|
||||
},
|
||||
"MaxValue": {
|
||||
"projections": []
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -18,6 +18,9 @@
|
|||
},
|
||||
"Goal": {
|
||||
"projections": []
|
||||
},
|
||||
"TrendLine": {
|
||||
"projections": []
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -959,4 +959,55 @@ def test_multi_row_card_template_uses_values_role(report_with_page: Path) -> Non
|
|||
qs = data["visual"]["query"]["queryState"]
|
||||
assert "Values" in qs
|
||||
assert isinstance(qs["Values"], dict)
|
||||
assert "Fields" not in qs
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# v3.8.0 -- kpi TrendLine + gauge MaxValue role fixes
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
def test_kpi_template_has_trend_line_role(report_with_page: Path) -> None:
|
||||
"""kpi template must include TrendLine queryState key (confirmed from Desktop)."""
|
||||
r = visual_add(report_with_page, "test_page", "kpi", x=0, y=0)
|
||||
vfile = (
|
||||
report_with_page / "pages" / "test_page" / "visuals" / r["name"] / "visual.json"
|
||||
)
|
||||
data = json.loads(vfile.read_text())
|
||||
qs = data["visual"]["query"]["queryState"]
|
||||
assert "TrendLine" in qs
|
||||
assert isinstance(qs["TrendLine"], dict)
|
||||
assert "Indicator" in qs
|
||||
assert "Goal" in qs
|
||||
|
||||
|
||||
def test_gauge_template_has_max_value_role(report_with_page: Path) -> None:
|
||||
"""gauge template must include MaxValue queryState key (confirmed from Desktop)."""
|
||||
r = visual_add(report_with_page, "test_page", "gauge", x=0, y=0)
|
||||
vfile = (
|
||||
report_with_page / "pages" / "test_page" / "visuals" / r["name"] / "visual.json"
|
||||
)
|
||||
data = json.loads(vfile.read_text())
|
||||
qs = data["visual"]["query"]["queryState"]
|
||||
assert "MaxValue" in qs
|
||||
assert isinstance(qs["MaxValue"], dict)
|
||||
assert "Y" in qs
|
||||
|
||||
|
||||
@pytest.mark.parametrize("alias,expected_role", [
|
||||
("trend_line", "TrendLine"),
|
||||
("trend", "TrendLine"),
|
||||
("goal", "Goal"),
|
||||
])
|
||||
def test_kpi_role_aliases(alias: str, expected_role: str) -> None:
|
||||
from pbi_cli.core.visual_backend import ROLE_ALIASES
|
||||
assert ROLE_ALIASES["kpi"][alias] == expected_role
|
||||
|
||||
|
||||
@pytest.mark.parametrize("alias,expected_role", [
|
||||
("max", "MaxValue"),
|
||||
("max_value", "MaxValue"),
|
||||
("target", "MaxValue"),
|
||||
])
|
||||
def test_gauge_role_aliases(alias: str, expected_role: str) -> None:
|
||||
from pbi_cli.core.visual_backend import ROLE_ALIASES
|
||||
assert ROLE_ALIASES["gauge"][alias] == expected_role
|
||||
|
|
|
|||
Loading…
Reference in a new issue