BeepMetricTile
Dashboard metric tile with icon, value, and background silhouette for data visualization
📑 Table of Contents
Overview
BeepMetricTile is a sophisticated dashboard tile control designed to display key metrics in an attractive, informative format. It combines a title, large metric value, delta information, an icon, and an optional background silhouette to create visually appealing metric displays.
Built on the BeepControl foundation, BeepMetricTile features gradient backgrounds, shadow effects, multiple text elements with proper typography, icon integration, and semi-transparent background imagery. Perfect for dashboards, KPI displays, analytics interfaces, and executive summaries.
Key Features
📊 Multi-Element Layout
Title, metric value, delta text, and icon in a structured dashboard-friendly layout
🎨 Gradient Backgrounds
Beautiful gradient backgrounds with customizable colors and directions
🖼️ Icon Integration
Top-right icon display with support for SVG, PNG, and other image formats
👻 Background Silhouettes
Semi-transparent background images for visual enhancement and branding
✨ Visual Effects
Drop shadows, rounded corners, and smooth rendering for professional appearance
🎯 Interactive Areas
Built-in hit testing for clickable regions within the tile
Visual Preview
Examples of BeepMetricTile with different themes and data
Basic Usage
Simple Metric Tile
// Create a basic metric tile
var viewsTile = new BeepMetricTile
{
Size = new Size(150, 150),
Location = new Point(20, 20),
TitleText = "Page Views",
MetricValue = "2,847",
DeltaValue = "+12% today",
IconImage = "analytics-icon.svg",
BackgroundSilhouette = "chart-silhouette.png"
};
// Customize appearance
viewsTile.GradientStartColor = Color.FromArgb(102, 126, 234);
viewsTile.GradientEndColor = Color.FromArgb(118, 75, 162);
viewsTile.BorderRadius = 12;
viewsTile.ShowShadow = true;
this.Controls.Add(viewsTile);
Dashboard Layout
// Create multiple metric tiles for a dashboard
var tiles = new[]
{
new BeepMetricTile
{
TitleText = "Users",
MetricValue = "1,254",
DeltaValue = "+8.5% this week",
IconImage = "users-icon.svg",
GradientStartColor = Color.FromArgb(79, 172, 254),
GradientEndColor = Color.FromArgb(0, 242, 254)
},
new BeepMetricTile
{
TitleText = "Revenue",
MetricValue = "$18.2K",
DeltaValue = "+15% this month",
IconImage = "revenue-icon.svg",
GradientStartColor = Color.FromArgb(67, 233, 123),
GradientEndColor = Color.FromArgb(56, 249, 215)
},
new BeepMetricTile
{
TitleText = "Orders",
MetricValue = "346",
DeltaValue = "+23 today",
IconImage = "orders-icon.svg",
GradientStartColor = Color.FromArgb(250, 112, 154),
GradientEndColor = Color.FromArgb(254, 225, 64)
}
};
// Layout tiles in a grid
int x = 20, y = 20;
foreach (var tile in tiles)
{
tile.Size = new Size(150, 150);
tile.Location = new Point(x, y);
tile.BorderRadius = 12;
tile.ShowShadow = true;
this.Controls.Add(tile);
x += 170; // Move to next column
if (x > this.Width - 170) // Wrap to next row
{
x = 20;
y += 170;
}
}
Data Binding
// Bind tile to data source
public void UpdateMetricTile(BeepMetricTile tile, MetricData data)
{
tile.TitleText = data.Title;
tile.MetricValue = data.FormattedValue;
tile.DeltaValue = data.FormattedDelta;
// Update colors based on trend
if (data.Trend > 0)
{
tile.GradientStartColor = Color.FromArgb(67, 233, 123); // Green
tile.GradientEndColor = Color.FromArgb(56, 249, 215);
}
else if (data.Trend < 0)
{
tile.GradientStartColor = Color.FromArgb(255, 107, 107); // Red
tile.GradientEndColor = Color.FromArgb(255, 142, 142);
}
else
{
tile.GradientStartColor = Color.FromArgb(158, 158, 158); // Gray
tile.GradientEndColor = Color.FromArgb(189, 189, 189);
}
}
// Example usage with data model
var salesData = new MetricData
{
Title = "Sales",
Value = 15420.50m,
Trend = 8.5f,
FormattedValue = "$15.4K",
FormattedDelta = "+8.5% vs last month"
};
UpdateMetricTile(salesTile, salesData);
Properties
Text Properties
| Property | Type | Default | Description |
|---|---|---|---|
TitleText |
string | "Views" | Title displayed in the top-left corner |
MetricValue |
string | "31" | Main numeric or text metric value |
DeltaValue |
string | "+3 last day" | Delta or additional information text |
Image Properties
| Property | Type | Default | Description |
|---|---|---|---|
IconImage |
string | null | Icon shown in the top-right corner |
BackgroundSilhouette |
string | null | Semi-transparent background image |
Inherited Properties
BeepMetricTile inherits all properties from BeepControl, including:
- BorderRadius - Corner radius for rounded appearance
- ShowShadow - Enable/disable drop shadow
- UseGradientBackground - Enable gradient background
- GradientStartColor - Starting color for gradient
- GradientEndColor - Ending color for gradient
- GradientDirection - Direction of gradient effect
- Theme - Theme name for styling
Examples
Analytics Dashboard
public class AnalyticsDashboard : UserControl
{
private List metricTiles;
private Timer refreshTimer;
public AnalyticsDashboard()
{
InitializeDashboard();
SetupAutoRefresh();
}
private void InitializeDashboard()
{
metricTiles = new List();
// Create metric tiles for different analytics
var metrics = new[]
{
new { Title = "Page Views", Icon = "eye.svg", Color1 = Color.FromArgb(102, 126, 234), Color2 = Color.FromArgb(118, 75, 162) },
new { Title = "Unique Visitors", Icon = "users.svg", Color1 = Color.FromArgb(79, 172, 254), Color2 = Color.FromArgb(0, 242, 254) },
new { Title = "Bounce Rate", Icon = "trending-down.svg", Color1 = Color.FromArgb(255, 107, 107), Color2 = Color.FromArgb(255, 142, 142) },
new { Title = "Avg. Session", Icon = "clock.svg", Color1 = Color.FromArgb(67, 233, 123), Color2 = Color.FromArgb(56, 249, 215) },
new { Title = "Conversions", Icon = "target.svg", Color1 = Color.FromArgb(250, 112, 154), Color2 = Color.FromArgb(254, 225, 64) },
new { Title = "Revenue", Icon = "dollar-sign.svg", Color1 = Color.FromArgb(132, 94, 194), Color2 = Color.FromArgb(144, 175, 197) }
};
int x = 20, y = 20;
foreach (var metric in metrics)
{
var tile = new BeepMetricTile
{
Size = new Size(180, 160),
Location = new Point(x, y),
TitleText = metric.Title,
MetricValue = "Loading...",
DeltaValue = "Calculating...",
IconImage = metric.Icon,
GradientStartColor = metric.Color1,
GradientEndColor = metric.Color2,
BorderRadius = 16,
ShowShadow = true
};
metricTiles.Add(tile);
this.Controls.Add(tile);
x += 200;
if (x > this.Width - 200)
{
x = 20;
y += 180;
}
}
}
private void SetupAutoRefresh()
{
refreshTimer = new Timer { Interval = 30000 };
refreshTimer.Tick += async (s, e) => await RefreshMetrics();
refreshTimer.Start();
Task.Run(async () => await RefreshMetrics());
}
private async Task RefreshMetrics()
{
var analyticsService = new AnalyticsService();
var data = await analyticsService.GetRealTimeMetrics();
if (InvokeRequired)
{
Invoke(new Action(() => UpdateTiles(data)));
}
else
{
UpdateTiles(data);
}
}
private void UpdateTiles(AnalyticsData data)
{
metricTiles[0].MetricValue = data.PageViews.ToString("N0");
metricTiles[0].DeltaValue = $"{data.PageViewsDelta:+0.0;-0.0}% today";
metricTiles[1].MetricValue = data.UniqueVisitors.ToString("N0");
metricTiles[1].DeltaValue = $"{data.VisitorsDelta:+0.0;-0.0}% week";
metricTiles[2].MetricValue = $"{data.BounceRate:F1}%";
metricTiles[2].DeltaValue = $"{data.BounceRateDelta:+0.0;-0.0}% change";
metricTiles[3].MetricValue = FormatDuration(data.AvgSessionDuration);
metricTiles[3].DeltaValue = $"{data.SessionDelta:+0.0;-0.0}% avg";
metricTiles[4].MetricValue = data.Conversions.ToString("N0");
metricTiles[4].DeltaValue = $"{data.ConversionsDelta:+0.0;-0.0}% rate";
metricTiles[5].MetricValue = data.Revenue.ToString("C0");
metricTiles[5].DeltaValue = $"{data.RevenueDelta:+0.0;-0.0}% month";
}
private string FormatDuration(TimeSpan duration)
{
if (duration.TotalHours >= 1)
return $"{duration.TotalHours:F1}h";
else
return $"{duration.TotalMinutes:F0}m";
}
}
E-commerce Dashboard
public class EcommerceDashboard : UserControl
{
private BeepMetricTile salesTile;
private BeepMetricTile ordersTile;
private BeepMetricTile customersTile;
private BeepMetricTile inventoryTile;
public EcommerceDashboard()
{
InitializeEcommerceTiles();
LoadEcommerceData();
}
private void InitializeEcommerceTiles()
{
// Sales tile
salesTile = new BeepMetricTile
{
Size = new Size(200, 180),
Location = new Point(20, 20),
TitleText = "Total Sales",
IconImage = "shopping-cart.svg",
BackgroundSilhouette = "money-silhouette.png",
GradientStartColor = Color.FromArgb(67, 233, 123),
GradientEndColor = Color.FromArgb(56, 249, 215),
BorderRadius = 20,
ShowShadow = true
};
// Orders tile
ordersTile = new BeepMetricTile
{
Size = new Size(200, 180),
Location = new Point(240, 20),
TitleText = "Orders Today",
IconImage = "package.svg",
BackgroundSilhouette = "box-silhouette.png",
GradientStartColor = Color.FromArgb(79, 172, 254),
GradientEndColor = Color.FromArgb(0, 242, 254),
BorderRadius = 20,
ShowShadow = true
};
// Customers tile
customersTile = new BeepMetricTile
{
Size = new Size(200, 180),
Location = new Point(460, 20),
TitleText = "New Customers",
IconImage = "user-plus.svg",
BackgroundSilhouette = "users-silhouette.png",
GradientStartColor = Color.FromArgb(250, 112, 154),
GradientEndColor = Color.FromArgb(254, 225, 64),
BorderRadius = 20,
ShowShadow = true
};
// Inventory tile
inventoryTile = new BeepMetricTile
{
Size = new Size(200, 180),
Location = new Point(680, 20),
TitleText = "Low Stock Items",
IconImage = "alert-triangle.svg",
BackgroundSilhouette = "warehouse-silhouette.png",
GradientStartColor = Color.FromArgb(255, 107, 107),
GradientEndColor = Color.FromArgb(255, 142, 142),
BorderRadius = 20,
ShowShadow = true
};
this.Controls.AddRange(new Control[] {
salesTile, ordersTile, customersTile, inventoryTile
});
}
private async void LoadEcommerceData()
{
var ecommerceService = new EcommerceService();
var data = await ecommerceService.GetDashboardMetrics();
salesTile.MetricValue = data.TotalSales.ToString("C0");
salesTile.DeltaValue = $"{data.SalesGrowth:+0.0;-0.0}% vs yesterday";
ordersTile.MetricValue = data.OrdersToday.ToString("N0");
ordersTile.DeltaValue = $"{data.OrdersGrowth:+0;-0} vs yesterday";
customersTile.MetricValue = data.NewCustomers.ToString("N0");
customersTile.DeltaValue = $"{data.CustomerGrowth:+0.0;-0.0}% this week";
inventoryTile.MetricValue = data.LowStockItems.ToString("N0");
inventoryTile.DeltaValue = $"{data.LowStockChange:+0;-0} items";
// Update tile colors based on performance
UpdateTileColors(data);
}
private void UpdateTileColors(EcommerceMetrics data)
{
// Update sales tile color based on performance
if (data.SalesGrowth > 10)
{
salesTile.GradientStartColor = Color.FromArgb(67, 233, 123);
salesTile.GradientEndColor = Color.FromArgb(56, 249, 215);
}
else if (data.SalesGrowth < 0)
{
salesTile.GradientStartColor = Color.FromArgb(255, 107, 107);
salesTile.GradientEndColor = Color.FromArgb(255, 142, 142);
}
// Update inventory tile urgency
if (data.LowStockItems > 50)
{
inventoryTile.GradientStartColor = Color.FromArgb(220, 38, 127);
inventoryTile.GradientEndColor = Color.FromArgb(249, 168, 37);
}
}
}
Real-time System Monitoring
public class SystemMonitoringDashboard : UserControl
{
private BeepMetricTile cpuTile;
private BeepMetricTile memoryTile;
private BeepMetricTile diskTile;
private BeepMetricTile networkTile;
private PerformanceCounter cpuCounter;
private PerformanceCounter memoryCounter;
public SystemMonitoringDashboard()
{
InitializeSystemTiles();
InitializePerformanceCounters();
StartRealTimeUpdates();
}
private void InitializeSystemTiles()
{
cpuTile = new BeepMetricTile
{
Size = new Size(160, 160),
Location = new Point(20, 20),
TitleText = "CPU Usage",
IconImage = "cpu.svg",
BackgroundSilhouette = "processor-silhouette.png",
BorderRadius = 16,
ShowShadow = true
};
memoryTile = new BeepMetricTile
{
Size = new Size(160, 160),
Location = new Point(200, 20),
TitleText = "Memory",
IconImage = "memory.svg",
BackgroundSilhouette = "ram-silhouette.png",
BorderRadius = 16,
ShowShadow = true
};
diskTile = new BeepMetricTile
{
Size = new Size(160, 160),
Location = new Point(380, 20),
TitleText = "Disk Space",
IconImage = "hard-drive.svg",
BackgroundSilhouette = "storage-silhouette.png",
BorderRadius = 16,
ShowShadow = true
};
networkTile = new BeepMetricTile
{
Size = new Size(160, 160),
Location = new Point(560, 20),
TitleText = "Network",
IconImage = "wifi.svg",
BackgroundSilhouette = "network-silhouette.png",
BorderRadius = 16,
ShowShadow = true
};
this.Controls.AddRange(new Control[] {
cpuTile, memoryTile, diskTile, networkTile
});
}
private void InitializePerformanceCounters()
{
cpuCounter = new PerformanceCounter("Processor", "% Processor Time", "_Total");
memoryCounter = new PerformanceCounter("Memory", "Available MBytes");
}
private void StartRealTimeUpdates()
{
var updateTimer = new Timer { Interval = 2000 }; // 2 seconds
updateTimer.Tick += UpdateSystemMetrics;
updateTimer.Start();
}
private void UpdateSystemMetrics(object sender, EventArgs e)
{
try
{
// CPU Usage
float cpuUsage = cpuCounter.NextValue();
cpuTile.MetricValue = $"{cpuUsage:F1}%";
cpuTile.DeltaValue = GetCpuStatus(cpuUsage);
UpdateCpuTileColor(cpuUsage);
// Memory Usage
float availableMemory = memoryCounter.NextValue();
float totalMemory = GetTotalPhysicalMemory();
float memoryUsage = ((totalMemory - availableMemory) / totalMemory) * 100;
memoryTile.MetricValue = $"{memoryUsage:F1}%";
memoryTile.DeltaValue = $"{availableMemory:F0} MB free";
UpdateMemoryTileColor(memoryUsage);
// Disk Space
var driveInfo = new DriveInfo("C:");
long totalBytes = driveInfo.TotalSize;
long freeBytes = driveInfo.TotalFreeSpace;
float diskUsage = ((float)(totalBytes - freeBytes) / totalBytes) * 100;
diskTile.MetricValue = $"{diskUsage:F1}%";
diskTile.DeltaValue = $"{freeBytes / (1024 * 1024 * 1024):F1} GB free";
UpdateDiskTileColor(diskUsage);
// Network (simplified)
networkTile.MetricValue = "Online";
networkTile.DeltaValue = "Connected";
networkTile.GradientStartColor = Color.FromArgb(67, 233, 123);
networkTile.GradientEndColor = Color.FromArgb(56, 249, 215);
}
catch (Exception ex)
{
// Handle performance counter errors
System.Diagnostics.Debug.WriteLine($"Performance counter error: {ex.Message}");
}
}
private void UpdateCpuTileColor(float usage)
{
if (usage > 80)
{
cpuTile.GradientStartColor = Color.FromArgb(255, 107, 107);
cpuTile.GradientEndColor = Color.FromArgb(255, 142, 142);
}
else if (usage > 60)
{
cpuTile.GradientStartColor = Color.FromArgb(250, 112, 154);
cpuTile.GradientEndColor = Color.FromArgb(254, 225, 64);
}
else
{
cpuTile.GradientStartColor = Color.FromArgb(67, 233, 123);
cpuTile.GradientEndColor = Color.FromArgb(56, 249, 215);
}
}
private string GetCpuStatus(float usage)
{
if (usage > 80) return "High load";
if (usage > 60) return "Moderate load";
return "Normal";
}
}
Theming
BeepMetricTile provides comprehensive theming with automatic application of theme colors and fonts:
Theme Application
var metricTile = new BeepMetricTile
{
Theme = "DarkTheme",
UseThemeFont = true,
BorderRadius = 16,
ShowShadow = true
};
// Theme automatically applies:
// - DashboardBackColor: Main tile background
// - GradientStartColor: Theme gradient start
// - GradientEndColor: Theme gradient end
// - CardTitleForeColor: Title text color
// - CardSubTitleForeColor: Delta text color
// Apply theme manually if needed
metricTile.ApplyTheme();
Custom Color Schemes
// Success theme (green)
tile.GradientStartColor = Color.FromArgb(67, 233, 123);
tile.GradientEndColor = Color.FromArgb(56, 249, 215);
// Warning theme (orange)
tile.GradientStartColor = Color.FromArgb(250, 112, 154);
tile.GradientEndColor = Color.FromArgb(254, 225, 64);
// Error theme (red)
tile.GradientStartColor = Color.FromArgb(255, 107, 107);
tile.GradientEndColor = Color.FromArgb(255, 142, 142);
// Info theme (blue)
tile.GradientStartColor = Color.FromArgb(79, 172, 254);
tile.GradientEndColor = Color.FromArgb(0, 242, 254);
Typography Theming
- Title text - Uses CardTitleFont from theme
- Metric value - Large bold font (28pt) for prominence
- Delta text - Uses CardSubTitleFont from theme
- Color adaptation - Text colors adapt based on background contrast
Best Practices
📊 Data Presentation
- Clear metrics: Use concise, meaningful titles and properly formatted values
- Contextual deltas: Provide relevant comparison periods (today, week, month)
- Consistent formatting: Use consistent number formatting across similar metrics
- Meaningful icons: Choose icons that clearly represent the metric type
🎨 Visual Design
- Color coding: Use consistent colors to indicate performance (green=good, red=bad)
- Appropriate gradients: Choose gradient colors that maintain text readability
- Consistent sizing: Use uniform tile sizes within the same dashboard
- Subtle backgrounds: Keep background silhouettes subtle (20% opacity or less)
⚡ Performance
- Efficient updates: Update only changed values to minimize redraws
- Image optimization: Use appropriately sized images for icons and backgrounds
- Batch updates: Group multiple tile updates to reduce flicker
- Memory management: Dispose of large background images when not needed
📱 Responsiveness
- Scalable layouts: Design tiles to work at different sizes
- Text scaling: Ensure text remains readable at smaller tile sizes
- Grid layouts: Use responsive grid layouts for multiple tiles
- Touch targets: Ensure adequate size for touch interaction
Use a maximum of 6-8 metric tiles per dashboard view to avoid overwhelming users. Group related metrics together and use consistent color schemes for related data.
Implement real-time updates with proper error handling and fallback values to ensure your dashboard remains functional even when data sources are temporarily unavailable.
Ensure sufficient color contrast between text and background gradients, and provide alternative text representations for screen readers.