Let's delve into a more advanced scenario where we'll use Blazor to create a real-time data visualization component.
Example: Real-time Stock Price Chart
Features Demonstrated:
Timers: Updating data and UI at regular intervals
External Data Sources: Fetching data from an API or a simulated stock ticker
Data Visualization: (Optional) Using a charting library to render an interactive chart
Blazor Lifecycle Methods: Managing component updates and cleanup
Setup
Project: Create a new Blazor Server project (or reuse an existing one). You can name it "RealtimeCharts"
Optional Charting Library: If you want a fully-featured chart, explore integrating a JavaScript charting library like Chart.js (Refer to the earlier "Interactive Chart" example for guidance)
Models
StockData.cs: (Inside a Models folder)
namespace RealtimeCharts.Models;
public class StockData
{
public string Symbol { get; set; }
public decimal Price { get; set; }
public DateTime Timestamp { get; set; }
}
Services (Optional)
StockTickerService.cs (Inside a Services folder - for simulation)
namespace RealtimeCharts.Services;
public class StockTickerService
{
private readonly Random _random = new Random();
private Timer _timer;
private List<StockData> _data = new List<StockData>(); // Holds the data
public event Action OnDataUpdate;
public StockTickerService()
{
// Add some initial sample data
...
}
public void Start()
{
_timer = new Timer(UpdateData, null, 1000, 1000); // Update every second
}
public void Stop()
{
_timer?.Dispose();
_timer = null;
}
public List<StockData> GetData() => _data.ToList();
private void UpdateData()
{
// Simulate price changes (replace this with an actual API call if needed)
...
OnDataUpdate?.Invoke();
}
}
Components
StockChart.razor
@inject StockTickerService TickerService
@implements IDisposable
<h3>Live Stock Chart</h3>
@* Replace this with charting library code if using one *@
<div class="chart-container">
@foreach (var dataPoint in TickerService.GetData())
{
<div class="data-point" style="height: @CalculateHeight(dataPoint.Price)px">
@dataPoint.Price
</div>
}
</div>
@code {
protected override void OnInitialized()
{
TickerService.OnDataUpdate += StateHasChanged;
TickerService.Start();
}
public void Dispose()
{
TickerService.OnDataUpdate -= StateHasChanged;
TickerService.Stop(); // Stop when the component is disposed
}
// Helper for basic visualization
private int CalculateHeight(decimal price)
{
// Adjust as needed
return (int)(price * 5);
}
}