Install
$ agentstack add skill-devexpress-agent-skills-devexpress-blazor-gauges ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
DevExpress Blazor Visualization Components
A collection of specialized visualization components for Blazor:
DxBarGauge— Circular bar gauge displaying multiple values as arcsDxRangeSelector— Linear scale with draggable sliders for range selection; optionally displays a background chartDxSankey— Flow diagram showing value transfer between two entity setsDxSparkline— Compact trend line/bar embedded in other UI (e.g., inside a Grid column)DxMap— Geo map with markers and route display using Azure, Google, or GoogleStatic tiles
When to Use This Skill
- Display multiple gauge values as concentric arc bars (
DxBarGauge) - Let users visually select a date/numeric range by dragging sliders (
DxRangeSelector) - Visualize flow between categories or entities (
DxSankey) - Embed a compact trend chart inside a Grid cell or card (
DxSparkline) - Show geo locations, routes, or markers on a map (
DxMap) - Export gauge/sparkline/sankey as PNG/PDF/JPEG/GIF
Prerequisites & Installation
NuGet Package
| Package | Purpose | |---|---| | DevExpress.Blazor | All components in this skill |
# Install from NuGet.org:
dotnet add package DevExpress.Blazor
Register in Program.cs:
builder.Services.AddDevExpressBlazor();
> v26.1 note: DevExpress.Blazor no longer includes options.BootstrapVersion or DevExpress.Blazor.BootstrapVersion. Do not generate either API.
Add to _Imports.razor:
@using DevExpress.Blazor
Apply a theme and add client scripts in App.razor inside ``:
@using DevExpress.Blazor
@DxResourceManager.RegisterTheme(Themes.Fluent)
@DxResourceManager.RegisterScripts()
DxMap requires a GIS API key (Azure Maps, Google Maps, or GoogleStatic). Pass it via the DxMapApiKeys child component and set Provider.
Before You Start — Ask the Developer
Before generating code, ask:
- Render mode:
InteractiveServer,InteractiveWebAssembly,InteractiveAuto, or Static/SSR? (Range Selector dragging and Map/Sankey click events require interactivity) - Which component?: Bar Gauge, Range Selector, Sankey, Sparkline, or Map?
- Data source: Collection type and field names (for Sankey: source, target, weight fields; for Sparkline: argument, value fields)
- For Bar Gauge: How many values? What is the scale range (
StartValue/EndValue)? - For Range Selector: Numeric or DateTime scale? Does the user need a background chart?
Does the selected range need to filter or drive other components? (If yes → use ValueChanged event with RangeSelectorValueChangedEventArgs; never use @bind-SelectedRangeStartValue.)
- For Map: Which GIS provider? Do you have an API key?
Component Overview
DxBarGauge — Quick Pattern
@rendermode InteractiveServer
@code {
double[] Values = new double[] { 47.27, 65.32, 84.59 };
string[] Captions = new string[] { "Metacritic", "Rotten Tomatoes", "IMDb" };
}
DxSankey — Quick Pattern
DxSparkline — Quick Pattern
DxRangeSelector — Quick Pattern
s.Date)"
ValueField="@((DataPoint s) => s.Value)" />
DxMap — Quick Pattern
@rendermode InteractiveServer
> Note: DxMap requires a GIS provider API key. Use MapProvider.GoogleStatic for a quick static-image test without interactive tile setup.
Documentation & Navigation Guide
Bar Gauge
📄 [references/bar-gauge.md](references/bar-gauge.md)
When you need to: configure gauge geometry (start/end values, base value), labels, legend, tooltips, palette, or export.
Range Selector
📄 [references/range-selector.md](references/range-selector.md)
When you need to: configure scale (type, tick intervals, min/max range), set a predefined selected range, display a background chart, or handle selection change events.
Sankey
📄 [references/sankey.md](references/sankey.md)
When you need to: bind Sankey to data (source/target/weight fields), configure nodes/links/labels, handle click/hover events, or customize appearance.
Sparkline
📄 [references/sparkline.md](references/sparkline.md)
When you need to: embed a sparkline in a Grid column, choose series type, configure min/max highlighting, win/loss display, or export.
Map
📄 [references/map.md](references/map.md)
When you need to: display markers or routes on a geo map, set the GIS provider (Azure, Google, or GoogleStatic), configure the API key, handle marker click events, or customize map zoom and center.
Getting Started (All Components)
📄 [references/getting-started.md](references/getting-started.md)
When you need to: install and configure the NuGet package, add CSS/imports, or set up the first component.
Key Properties & API Surface
DxBarGauge
| Property | Type | Description | |---|---|---| | Values | double[] | Array of values to display as gauge arcs | | StartValue | double | Minimum scale value | | EndValue | double | Maximum scale value | | BaseValue | double | Base value for bars (bars grow from this value) | | Width / Height | string | Component dimensions | | Palette | string[] | Colors for each bar | | ExportAsync() | Task | Export as base64 image |
DxSankey
| Property | Type | Description | |---|---|---| | Data | IEnumerable | Data source | | SourceFieldName | string | Field name for the flow source node | | TargetFieldName | string | Field name for the flow target node | | WeightFieldName | string | Field name for the flow weight/volume | | Width / Height | string | Component dimensions |
DxSparkline
| Property | Type | Description | |---|---|---| | Data | IEnumerable | Data source | | ArgumentFieldName | string | Field name for argument values | | ValueFieldName | string | Field name for data values | | Type | SparklineType | Series type: Line, Bar, Spline, SplineArea, Area, StepLine, StepArea, WinLoss | | Width / Height | string | Component dimensions |
DxRangeSelector
| Property | Type | Description | |---|---|---| | Data | IEnumerable | Optional data source for background chart | | SelectedRangeStartValue | object | Initial start of the selected range | | SelectedRangeEndValue | object | Initial end of the selected range | | SelectedRangeLength | ChartAxisInterval | Length of initial selected range | | ValueChanged | EventCallback | Fires when the selected range changes. args.CurrentRange is a List with two items — use .Count (not .Length) to check availability. For DateTime ranges cast defensively: args.CurrentRange.FirstOrDefault() as DateTime? ?? fallback. For numeric ranges use Convert.ToInt32(args.CurrentRange.FirstOrDefault() ?? fallback). | | ValueChangeMode | RangeSelectorValueChangeMode | When to raise ValueChanged: OnHandleMove (live) or OnHandleRelease (on drop). Default: OnHandleRelease. |
DxMap
| Property | Type | Description | |---|---|---| | Provider | MapProvider | GIS provider: Azure, Google, GoogleStatic | | Zoom | int | Map zoom level | | DxMapApiKeys | child component | Supplies the API key; set Azure, Google, or GoogleStatic attribute to the appropriate key | | Markers | collection | Markers to display on the map | | Routes | collection | Routes to display on the map |
Common Patterns
Pattern 1: Bar Gauge with Labels and Legend
@code {
double[] Values = new double[] { 47.27, 65.32, 84.59, 81.86, 99 };
string[] LegendItemCaptions = new string[] { "Metacritic", "Ratingraph.com", "Rotten Tomatoes", "IMDb", "TV.com" };
string LabelFormat = "##.#'%' ";
}
Pattern 2: Sankey with Gradient Links
@code {
IEnumerable Data = Enumerable.Empty();
protected override void OnInitialized() {
Data = new List {
new SankeyDataPoint("Spain", "United States of America", 2),
new SankeyDataPoint("Germany", "United States of America", 8),
new SankeyDataPoint("France", "Great Britain", 4),
};
}
record SankeyDataPoint(string Source, string Target, int Weight);
}
Pattern 3: Range Selector with DateTime Scale
Pattern 4: Range Selector Filtering a Chart
> Critical: DxRangeSelector does NOT expose SelectedRangeStartValueChanged or SelectedRangeEndValueChanged. > Do not use @bind-SelectedRangeStartValue — it silently does nothing. > Always use the ValueChanged event to react to slider movement.
> CurrentRange runtime shape: RangeSelectorValueChangedEventArgs.CurrentRange is a List, not an array. Use .Count (not .Length) to guard against an empty collection. Access the start value with .FirstOrDefault() and the end value with .LastOrDefault(), then cast each item defensively to the target type.
@rendermode InteractiveServer
s.Date)"
ValueField="@((DataPoint s) => s.Value)" />
s.Date)"
ValueField="@((DataPoint s) => s.Value)"
Name="Value" />
@code {
DateTime RangeStart = new DateTime(2024, 1, 1);
DateTime RangeEnd = new DateTime(2024, 12, 31);
IEnumerable AllData = Enumerable.Empty();
IEnumerable FilteredData = Enumerable.Empty();
protected override void OnInitialized() {
AllData = GenerateData();
ApplyFilter();
}
void OnRangeChanged(RangeSelectorValueChangedEventArgs args) {
RangeStart = args.CurrentRange.FirstOrDefault() as DateTime? ?? RangeStart;
RangeEnd = args.CurrentRange.LastOrDefault() as DateTime? ?? RangeEnd;
ApplyFilter();
}
void ApplyFilter() =>
FilteredData = AllData.Where(d => d.Date >= RangeStart && d.Date ` rule applies — use `Convert.ToInt32()` for defensive numeric casting.
```razor
@rendermode InteractiveServer
@foreach (var order in FilteredOrders)
{
@order.Month — @order.Product: @order.Revenue.ToString("C")
}
@code {
int StartMonth = 1;
int EndMonth = 12;
List AllOrders = new()
{
new(1, "Widget A", 4200), new(2, "Widget A", 3800), new(3, "Widget B", 5100),
new(4, "Widget B", 4700), new(5, "Widget A", 5600), new(6, "Widget C", 3200),
new(7, "Widget C", 4100), new(8, "Widget A", 4900), new(9, "Widget B", 5300),
new(10, "Widget C", 4400), new(11, "Widget A", 6100), new(12, "Widget B", 5800),
};
IEnumerable FilteredOrders = Enumerable.Empty();
protected override void OnInitialized() => ApplyFilter();
void OnRangeChanged(RangeSelectorValueChangedEventArgs args)
{
if (args.CurrentRange.Count >= 2)
{
StartMonth = Convert.ToInt32(args.CurrentRange.FirstOrDefault() ?? StartMonth);
EndMonth = Convert.ToInt32(args.CurrentRange.LastOrDefault() ?? EndMonth);
}
ApplyFilter();
}
void ApplyFilter() =>
FilteredOrders = AllOrders.Where(o => o.Month >= StartMonth && o.Month ` (or `Google`/`GoogleStatic`) inside ``; check `Provider` matches the key |
| Sankey shows no nodes | Wrong field names | Verify `SourceFieldName`, `TargetFieldName`, `WeightFieldName` match actual C# property names (case-sensitive) |
| Bar Gauge shows no bars | `Values` is empty or null | Initialize `Values` array with numeric values in `OnInitialized` |
| Range Selector sliders not moveable | Static render mode | Add `@rendermode InteractiveServer` (or WASM/Auto) to the page |
| Range Selector slider moves but the chart doesn't update | `@bind-SelectedRangeStartValue` / `@bind-SelectedRangeEndValue` used — these properties have no `Changed` callbacks, so two-way binding is silently ignored | Remove `@bind-`. Use `ValueChanged="@OnRangeChanged"` and read `args.CurrentRange.FirstOrDefault()` / `LastOrDefault()` for the new DateTime values |
| Build fails: `'List' does not contain a definition for 'Length'` | `CurrentRange` is a `List`, not an array — `Length` is not defined on `List` | Replace `.Length` with `.Count`. For DateTime ranges cast items with `as DateTime? ?? fallback`; for numeric ranges use `Convert.ToInt32(item ?? fallback)` |
| Sparkline not visible in Grid cell | Width/Height not set | Set explicit `Width` and `Height` on `DxSparkline`; use `px` or `%` units |
| `ExportAsync()` returns empty | Called too early | Call from `OnAfterRenderAsync(firstRender: true)` after the component has rendered |
| `"Unhandled exception on the current circuit"` with no detail | `CircuitOptions.DetailedErrors` not set | Add `builder.Services.Configure(o => o.DetailedErrors = true);` in `Program.cs` (development only) |
| `"Component parameter 'ValueChanged' is used two or more times"` compile error | `@bind-Value` and `ValueChanged` used together | Use `@bind-Value="@val"` for two-way binding, or `Value="@val" ValueChanged="@handler"` — never both simultaneously |
| `dx-blazor.js` not found (404) behind a reverse proxy | Reverse proxy strips the app base path | Add `app.UsePathBase("/subpath")` before `app.MapBlazorHub()`, or set `` in `App.razor` |
| Static assets return 404 (`dx-blazor.css`, `dx-blazor.js`) | `UseStaticWebAssets()` not called | Add `app.UseStaticWebAssets();` in `Program.cs` before `app.UseStaticFiles()` |
| `"Could not find 'X' in 'window.DxBlazor'"` JavaScript error | Stale browser-cached JS from an older DevExpress version | Hard-refresh the browser (Ctrl+Shift+R), clear site data, or verify all DevExpress NuGet packages are the same version |
| `"Cannot pass the parameter 'X' to component 'Y' with rendermode"` | Non-serializable parameter passed across a render mode boundary | Move the component to a child `.razor` file with its own `@rendermode` directive; pass only serializable parameters |
## Constraints & Rules
CRITICAL — follow these rules in every interaction:
0. **Never invent API**: If a property, method, event, or feature is not documented in this skill or its references, do **not** assume it exists. When asked about an unfamiliar API, first try to verify it using the DevExpress documentation MCP (`devexpress_docs_search`) or the local `apidoc/` folder. Only after checking: if confirmed, use the API; if not found, explicitly state that it does not appear to be part of the DevExpress Blazor component API. Do not warn that a feature "may have been introduced in a recent version" as a way to justify inventing it.
1. **Build verification**: Run `dotnet build` after changes. Check for errors before reporting success.
2. **NuGet packages**: Use `DevExpress.Blazor` — the exact package listed in Prerequisites.
3. **Namespace imports**: Always include `@using DevExpress.Blazor`.
4. **Version consistency**: All DevExpress packages must use the same version.
5. **License**: DevExpress requires a valid license. Remind the developer if they hit license-related build errors.
6. **Map API key**: `DxMap` will not display without a valid GIS provider API key. Remind the developer to configure this.
7. **DxSankey field names**: `SourceFieldName`, `TargetFieldName`, `WeightFieldName` are plain string property names, not lambda expressions.
8. **DxSparkline field names**: `ArgumentFieldName` and `ValueFieldName` are plain string property names.
## Using DevExpress
…
## Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- **Author:** [DevExpress](https://github.com/DevExpress)
- **Source:** [DevExpress/agent-skills](https://github.com/DevExpress/agent-skills)
- **License:** MIT
- **Homepage:** https://www.devexpress.com
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.