visual-selector
Skill1 starsChanged 6 months agoMITView on GitHub
Determines the best Power BI visual type based on the measures and dimensions in a query. Use this skill when deciding which chart or visual to generate for a given data profile (e.g., cardVisual for single KPIs, lineChart for time series, clusteredColumnChart for categorical comparisons). This is Stage 2 of the query-to-pbip pipeline.
1 other project uses a version of this.
Adopted by
Most recently taken up by
- shiruijun/claude-skilltheir own version, first seen Jun 11, 2026
Other versions1 project uses a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 1
- shiruijun/claude-skill★ 0same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository8 other files it gives its agents.
- bi-dash-creatorSkill
- data-source-connectorSkill
- nlq-dashboard-orchestratorSkill
- project-packagerSkill
- query-to-pbipSkill
- semantic-mapperSkill
- theme-brandingSkill
- visual-generatorSkill
The file
We split this skill into the rules it gives an agent
10 rules. About 0 are common, 4 are distinctive, and 6 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈4
Distinctive · estimate
This author's own choices. Worth a look.
6
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 60
If the measure compares two dates but the query says "by delivery month", use the delivery date role for Category and filters
- Very specific: line 61
If the measure compares two dates but the query says "by purchase month" or just "monthly orders/revenue", use dim_date
- Distinctive: line 108
When derived fields are available from Stage 1, map them using these defaults:
- Very specific: line 110
If a derived categorical field exists and chart already has a primary category axis, place the derived field in Series (legend/color split).
- Very specific: line 111
If a derived binary flag exists (for example Top Flag), prioritize Series mapping over replacing the main category.
- Very specific: line 112
If a derived temporal field exists, prefer it for Category on trend visuals.
- Very specific: line 113
If a derived numeric aggregate/ratio exists, map it to value buckets (Y, Values, Size) as a measure.
- Distinctive: line 118
After selecting the visual type, map fields to the correct data buckets:
- Distinctive: line 278
When multiple visual types could satisfy the same query pattern, prefer the primary source template.
- Very specific: line 356
When building a visual.json, find the reference template that most closely matches the target visual type and follow its patterns for:
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Visual Selector
Determine the optimal Power BI visual type for a given query based on the number and classification of measures and dimensions. This skill analyzes the data profile from the semantic mapper output and produces a visual type recommendation with field-to-bucket mappings.
When to Use This Skill
- Choosing the best visual type for a Genie query result
- Mapping measures and dimensions to visual data buckets (Category, Y, Data, Values, etc.)
- Selecting chart types as part of the query-to-pbip pipeline (Stage 2)
- Recommending page layouts based on visual type
Inputs
- Measures — List of measure names, data types, and format types from Stage 1
- Dimensions — List of dimension names, source tables, and data types from Stage 1
- Derived fields — SQL aliases materialized in Stage 1 as calculated columns or measures
- Query intent (optional) — Original natural language query for override signal detection
Outputs
visualType— The PBIR visual type string (e.g.,cardVisual,clusteredColumnChart,lineChart)bucketMapping— Which fields go into which visual data bucketslayoutPosition— Recommended position coordinates for the visual
Visual Selection Decision Tree
The selection rules below serve as defaults. The agent has the flexibility to decide the best way to display any visual by utilizing the available tables, models, and relationships from the semantic model. When the semantic model provides sort columns, hierarchies, or other metadata that informs a better display choice, the agent should leverage that information rather than rigidly following the decision tree.
Step 1: Count Measures and Dimensions
From the semantic mapper output, count:
- Measures: Aggregated values (SUM, COUNT, AVG, etc.)
- Dimensions: Grouping/slicing columns
Step 2: Classify Each Dimension
| Indicator | Classification | Examples |
Name contains date, month, year, quarter, time | Temporal | order_date, Month |
Name contains state, city, country, region, zip | Geographic | customer_state, Region |
Source table is dim_date, dim_date_delivery, or another date dimension | Temporal | Any role-playing date column |
| All other columns | Nominal | category_name, seller_id |
Derived field classification defaults:
- Derived text/binary aliases (
CASE, bucketing labels, flags) => Nominal - Derived date/time aliases (
DATE_TRUNC, period buckets) => Temporal - Derived numeric aggregates/ratios => Measure
Role-specific temporal routing:
- Purchase/order trends default to
dim_date - Delivery/shipping/fulfilled trends default to the matching role-playing date table (for example
dim_date_delivery) - If the measure compares two dates but the query says "by delivery month", use the delivery date role for Category and filters
- If the measure compares two dates but the query says "by purchase month" or just "monthly orders/revenue", use
dim_date
Step 3: Apply the Selection Matrix
| Measures | Dimensions | Dimension Type | Visual Type |
| 1 | 0 | — | cardVisual |
| 2–4 | 0 | — | cardVisual (one per measure, row layout) |
| 5+ | 0 | — | tableEx |
| 1 | 1 | Temporal | lineChart |
| 1 | 1 | Nominal | clusteredColumnChart |
| 1 | 1 | Geographic | filledMap |
| 2+ | 1 | Temporal | lineChart |
| 2+ | 1 | Nominal | clusteredBarChart |
| 2 | 1 | Nominal + "scatter"/"correlation" keywords | scatter-bubble-chart (secondary) |
| 3 | 1 | Nominal + "bubble" keyword | scatter-bubble-chart with size (secondary) |
| 2–4 | 1 | Nominal | clustered-column-multi-measure (secondary, alternative to clusteredBarChart) |
| 2+ | 1 | Temporal | line-chart-multi-y (secondary, alternative to lineChart) |
| 1 | 2 | Both Nominal | pivotTable (matrix) |
| 1 | 2 | Temporal + Nominal | lineChart with Series |
| Any | 3+ | Any | tableEx |
Step 4: Check for Override Signals
Scan the original query text for keywords that override the default selection:
| Signal Words | Override To |
| "trend", "over time", "timeline" | lineChart |
| "compare", "comparison", "versus" | clusteredBarChart |
| "top N", "ranking", "rank" | clusteredColumnChart (sorted desc) |
| "breakdown", "distribution", "share" | pieChart |
| "detail", "list", "all records" | tableEx |
| "filter", "slicer", "select" | Add companion slicer visual |
| "map", "geographic", "location" | filledMap |
| "scatter", "correlation", "relationship" | scatter-bubble-chart |
| "bubble" | scatter-bubble-chart |
| "donut" | donutChart |
| "gradient", "heatmap" (when geographic dimension present) | azure-map-gradient |
| "range", "between" (when date dimension present) | slicer-between-date |
| "last N months", "past N months", "last N days" | Keep temporal chart/slicer choice and add current-date-relative filter intent |
| "latest N months in the data", "most recent N months in data" | Keep temporal chart/slicer choice and add data-anchored filter intent |
| "dropdown" (when slicer context) | slicer-dropdown |
| "multiselect", "multiple" (when slicer context) | slicer-list-multiselect |
Step 5: Apply Derived Field Routing Rules
When derived fields are available from Stage 1, map them using these defaults:
- If a derived categorical field exists and chart already has a primary category axis, place the derived field in
Series(legend/color split). - If a derived binary flag exists (for example
Top Flag), prioritizeSeriesmapping over replacing the main category. - If a derived temporal field exists, prefer it for
Categoryon trend visuals. - If a derived numeric aggregate/ratio exists, map it to value buckets (
Y,Values,Size) as a measure. - For
tableExandpivotTable, include derived fields as explicit columns/rows/values rather than legend-only metadata.
Query Bucket Mapping
After selecting the visual type, map fields to the correct data buckets:
cardVisual
{
"Data": ["<measure>"]
}clusteredColumnChart / clusteredBarChart
{
"Category": ["<dimension>"],
"Y": ["<measure1>", "<measure2>"],
"Series": ["<optional_derived_categorical_dimension>"]
}lineChart
{
"Category": ["<temporal_dimension>"],
"Y": ["<measure>"],
"Series": ["<optional_nominal_dimension>"]
}lineClusteredColumnComboChart
{
"Category": ["<temporal_dimension>"],
"Y": ["<primary_measure>"],
"Y2": ["<secondary_measure>"]
}tableEx
{
"Values": ["<dim1>", "<dim2>", "<measure1>", "<measure2>"]
}pivotTable (matrix)
{
"Rows": ["<dimension1>"],
"Columns": ["<dimension2>"],
"Values": ["<measure>"]
}slicer
{
"Values": ["<dimension>"]
}filledMap
{
"Category": ["<geographic_dimension>"],
"Size": ["<measure>"]
}scatter-bubble-chart
{
"X": ["<x_measure>"],
"Y": ["<y_measure>"],
"Details": ["<category_dimension>"],
"Size": ["<optional_size_measure>"]
}azure-map-gradient
{
"Location": ["<geographic_dimension>"],
"Gradient": ["<measure>"]
}azure-map-bubble
{
"Location": ["<geographic_dimension>"],
"Size": ["<measure>"]
}slicer-between-date
{
"Values": ["<date_dimension>"]
}slicer-dropdown
{
"Values": ["<dimension>"]
}slicer-list-multiselect
{
"Values": ["<dimension>"]
}Visual Type to PBIR Type Mapping
| Display Name | PBIR visualType | Data Bucket(s) |
| Card (new) | cardVisual | Data |
| Clustered Column Chart | clusteredColumnChart | Category, Y |
| Clustered Bar Chart | clusteredBarChart | Category, Y, Series |
| Line Chart | lineChart | Category, Y, Series |
| Combo Chart | lineClusteredColumnComboChart | Category, Y, Y2 |
| Table | tableEx | Values |
| Matrix | pivotTable | Rows, Columns, Values |
| Slicer | slicer | Values |
| Filled Map | filledMap | Category, Size |
| Pie Chart | pieChart | Category, Y |
| Donut Chart | donutChart | Category, Y |
| Scatter/Bubble Chart | scatterChart | X, Y, Details, Size |
| Azure Map (Gradient) | azureMap | Location, Gradient |
| Azure Map (Bubble) | azureMap | Location, Size |
| Line Chart (Multi-Y) | lineChart | Category, Y (multiple measures) |
| Clustered Column (Multi-Measure) | clusteredColumnChart | Category, Y (multiple measures) |
| Matrix (Basic) | pivotTable | Rows, Columns, Values |
| Slicer (Date Range) | slicer | Values |
| Slicer (Dropdown) | slicer | Values |
| Slicer (Multi-select) | slicer | Values |
Template Source Priority
The visual-selector references templates from two sources with the following priority:
- Primary:
skills/query-to-pbip/assets/visual-templates/- These templates are checked first - Secondary: cn-dataworks-pbir-visuals research templates - Used when primary templates don't cover the use case
When multiple visual types could satisfy the same query pattern, prefer the primary source template. Secondary templates are used for specialized visualizations not available in the primary set (e.g., scatter plots, Azure maps, enhanced slicers).
Layout Recommendations
| Visual Type | Recommended Layout | Position |
Single cardVisual | Centered | x:440, y:260, w:400, h:200 |
Multi cardVisual (2–4) | Header row | x:20/340/660/980, y:20, w:300, h:150 |
clusteredColumnChart / lineChart | Full page | x:20, y:20, w:1240, h:680 |
tableEx / pivotTable | Full page | x:20, y:20, w:1240, h:680 |
Chart + slicer | Slicer corner, chart main | Slicer: x:0, y:0, w:110, h:110; Chart: x:110, w:1170 |
Example Walkthroughs
"What is total revenue?"
- Measures: 1 (Total Revenue)
- Dimensions: 0
- Result:
cardVisual, Data: [Total Revenue]
"Revenue by state"
- Measures: 1 (Total Revenue)
- Dimensions: 1 (customer_state → Nominal)
- Result:
clusteredColumnChart, Category: [customer_state], Y: [Total Revenue]
"Units sold by category with top flag"
- Measures: 1 (
Units Sold) - Dimensions: 2 (
category_name, derivedTop Flag) - Result:
clusteredBarChart - Bucket mapping:
Category: [category_name], Y: [Units Sold], Series: [Top Flag]
"Monthly revenue trend"
- Measures: 1 (Total Revenue)
- Dimensions: 1 (month → Temporal)
- Result:
lineChart, Category: [month], Y: [Total Revenue]
"Revenue and rolling revenue by month"
- Measures: 2 (Total Revenue, Rolling 1 Month)
- Dimensions: 1 (month_name → Temporal)
- Result:
lineClusteredColumnComboChart, Category: [month_name], Y: [Total Revenue], Y2: [Rolling 1 Month]
"Average delivery time by delivery month for the latest 12 months in the data"
- Measures: 1 (
Avg Delivery Time) - Dimensions: 1 (
dim_date_deliverymonth/date → Temporal) - Filter intent: data-anchored last 12 months
- Result:
lineChart, Category: [dim_date_deliverymonth hierarchy], Y: [Avg Delivery Time]
"Average delivery time trend for the last 12 months"
- Measures: 1 (
Avg Delivery Time) - Dimensions: 1 (temporal)
- Filter intent: current-date-relative last 12 months
- Result:
lineChart, Category aligned to the requested business timeline, Y: [Avg Delivery Time]
"Revenue by state and category"
- Measures: 1 (Total Revenue)
- Dimensions: 2 (customer_state → Nominal, category_name → Nominal)
- Result:
pivotTable, Rows: [customer_state], Columns: [category_name], Values: [Total Revenue]
Error Handling
| Situation | Resolution |
| No measures found | Default to tableEx showing all available dimensions |
| Ambiguous dimension type | Default to Nominal |
| Conflicting override signals | Use the first matched signal |
| Too many measures for card layout (5+) | Fall back to tableEx |
Reference Templates
Before constructing a visual.json output, consult the template files in skills/visual-selector/references/. Each template provides a complete worked example showing a user question, the corresponding Genie SQL query, and the full visual.json output. Use these templates as learning material to inform decisions about visual type selection, field-to-bucket mappings, formatting options, sorting configuration, and filter application.
When building a visual.json, find the reference template that most closely matches the target visual type and follow its patterns for:
- Query structure — How
queryStatebuckets (Category, Series, Y, Tooltips) are populated with field projections - Sort definitions — How
sortDefinitionis configured for the visual type - Object formatting — How
objectsproperties (axis settings, labels, legends, gridlines, markers) are set - Visual container objects — How titles, backgrounds, borders, and other container-level properties are configured
- Filter configuration — How
filterConfigentries are structured, including TopN subquery filters and Advanced filters
references/
barChart.md— Bar chart template with Category/Series/Y buckets, categorical axis configuration, and ascending sortlineChart.md— Line chart template with temporal Category hierarchy, Series dimension, marker/line styles, and TopN filterlineClusteredColumnComboChart.md— Combo chart template with Y column axis, reference lines (min/max/average/median/percentile), and Advanced measure filterspieChart.md— Pie chart template with Category/Y buckets, outside label positioning with percent-of-total style, and TopN filterstackedColumnChart.md— Stacked column chart template with Category hierarchy, Series split, Tooltip measures, and multi-filter configurationclusteredColumnChart.md— Clustered column chart template with Category/Y buckets, categorical axis configuration, and descending sort
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

