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

Page Views
📈
📊
Users
👥
👤
Revenue
💰
💵
Orders
📦
🛒

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
💡 Design Tip

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.

✅ Success Pattern

Implement real-time updates with proper error handling and fallback values to ensure your dashboard remains functional even when data sources are temporarily unavailable.

⚠️ Accessibility Note

Ensure sufficient color contrast between text and background gradients, and provide alternative text representations for screen readers.