Skip to content

Instantly share code, notes, and snippets.

@jpcrs
Created November 7, 2024 18:04
Show Gist options
  • Save jpcrs/b94469410c7a2aca13b81ab1430a7227 to your computer and use it in GitHub Desktop.
Save jpcrs/b94469410c7a2aca13b81ab1430a7227 to your computer and use it in GitHub Desktop.
using Spectre.Console;
class Program
{
static async Task Main(string[] args)
{
var header = CreateHeader();
var metricsRule = CreateMetricsRule();
var stockTable = CreateStockTable();
var cpuTable = CreateCpuTable();
var logPanel = CreateLogPanel();
var tablesContainer = CreateContainerTable(stockTable, cpuTable);
var layout = CreateMainLayout(header, metricsRule, tablesContainer, logPanel);
await AnsiConsole.Live(layout)
.StartAsync(async ctx =>
{
var headerUpdateTask = UpdateHeader(ctx, layout);
var stockUpdateTask = UpdateStockTable(ctx, stockTable);
var cpuUpdateTask = UpdateCpuTable(ctx, cpuTable);
var logUpdateTask = UpdateLogPanel(ctx, layout);
await Task.WhenAll(headerUpdateTask, stockUpdateTask, cpuUpdateTask, logUpdateTask);
});
}
static Rule CreateMetricsRule()
{
return new Rule("[yellow]Metrics[/]")
.RuleStyle(Style.Parse("grey"))
.Centered();
}
static Table CreateMainLayout(Panel header, Rule metricsRule, Grid container, Panel logPanel)
{
return new Table()
.Border(TableBorder.None)
.AddColumn(new TableColumn(""))
.AddRow(header)
.AddRow(metricsRule)
.AddRow(container)
.AddRow(logPanel);
}
static Panel CreateHeader()
{
return new Panel("System Monitor")
.Header("🖥️ Live Dashboard", Justify.Center)
.Expand()
.BorderStyle(new Style(Color.Blue))
.Padding(1, 1);
}
static async Task UpdateHeader(LiveDisplayContext ctx, Table layout)
{
await Task.Run(async () =>
{
while (true)
{
var time = DateTime.Now.ToString("HH:mm:ss");
var date = DateTime.Now.ToString("yyyy-MM-dd");
var updatedHeader = new Panel($"System Monitor - [blue]{time}[/]\n[grey]Date: {date}[/]")
.Header($"{(DateTime.Now.Second % 2 == 0 ? "🖥️" : "⚡")} Live Dashboard", Justify.Center)
.Expand()
.BorderStyle(new Style(Color.Blue))
.Padding(1, 1);
layout.UpdateCell(0, 0, updatedHeader);
ctx.Refresh();
await Task.Delay(1000);
}
});
}
static Table CreateStockTable()
{
var table = new Table()
.Title("Stock Prices")
.AddColumn("Symbol")
.AddColumn("Price")
.AddColumn("Change")
.Expand();
table.AddRow("AAPL", "$150.00", "0%");
table.AddRow("GOOGL", "$2800.00", "0%");
table.AddRow("MSFT", "$280.00", "0%");
return table;
}
static Table CreateCpuTable()
{
var table = new Table()
.Title("CPU Usage")
.AddColumn("Core")
.AddColumn("Usage")
.AddColumn("Temperature")
.Expand();
table.AddRow("Core 0", "0%", "40°C");
table.AddRow("Core 1", "0%", "40°C");
table.AddRow("Core 2", "0%", "40°C");
return table;
}
static Panel CreateLogPanel()
{
return new Panel(string.Empty)
.Header("System Logs", Justify.Center)
.Expand()
.BorderStyle(new Style(Color.Yellow))
.Padding(1, 1);
}
static Grid CreateContainerTable(Table stockTable, Table cpuTable)
{
var container = new Grid();
container.AddColumn();
container.AddColumn();
container.AddRow(stockTable, cpuTable);
return container;
}
static async Task UpdateStockTable(LiveDisplayContext ctx, Table table)
{
var random = new Random();
var prices = new decimal[] { 150.00m, 2800.00m, 280.00m };
var symbols = new[] { "AAPL", "GOOGL", "MSFT" };
await Task.Run(async () =>
{
while (true)
{
table.Rows.Clear();
for (int j = 0; j < symbols.Length; j++)
{
var change = (decimal)(random.NextDouble() * 2 - 1);
prices[j] *= (1 + change/100);
var color = change >= 0 ? "green" : "red";
var arrow = change >= 0 ? "↑" : "↓";
table.AddRow(
symbols[j],
$"${prices[j]:F2}",
$"[{color}]{arrow}{change:F2}%[/]"
);
}
ctx.Refresh();
await Task.Delay(1000);
}
});
}
static async Task UpdateCpuTable(LiveDisplayContext ctx, Table table)
{
var random = new Random();
await Task.Run(async () =>
{
while (true)
{
table.Rows.Clear();
for (int core = 0; core < 3; core++)
{
var usage = random.Next(0, 100);
var temp = random.Next(40, 80);
var usageColor = usage > 80 ? "red" : (usage > 60 ? "yellow" : "green");
var tempColor = temp > 70 ? "red" : (temp > 60 ? "yellow" : "green");
table.AddRow(
$"Core {core}",
$"[{usageColor}]{usage}%[/]",
$"[{tempColor}]{temp}°C[/]"
);
}
ctx.Refresh();
await Task.Delay(800);
}
});
}
static async Task UpdateLogPanel(LiveDisplayContext ctx, Table layout)
{
var random = new Random();
var logQueue = new Queue<(DateTime Time, string Type, string Message)>();
var maxLogs = 10;
var logTypes = new[] {
("[blue]INFO[/]", "System check completed successfully"),
("[yellow]WARN[/]", "High memory usage detected"),
("[red]ERROR[/]", "Failed to connect to remote service"),
("[blue]INFO[/]", "Cache cleared automatically"),
("[yellow]WARN[/]", "CPU temperature above threshold"),
("[blue]INFO[/]", "Backup completed"),
("[red]ERROR[/]", "Database connection timeout"),
("[blue]INFO[/]", "New update available"),
("[yellow]WARN[/]", "Disk space running low"),
("[blue]INFO[/]", "Service restarted successfully")
};
await Task.Run(async () =>
{
while (true)
{
var (type, message) = logTypes[random.Next(logTypes.Length)];
var time = DateTime.Now;
logQueue.Enqueue((time, type, message));
while (logQueue.Count > maxLogs)
{
logQueue.Dequeue();
}
var logContent = string.Join("\n", logQueue.Select(log =>
$"[grey]{log.Time:HH:mm:ss}[/] {log.Type} - {log.Message}"));
var updatedLogPanel = new Panel(logContent)
.Header("System Logs", Justify.Center)
.Expand()
.BorderStyle(new Style(Color.Yellow))
.Padding(1, 1);
layout.UpdateCell(3, 0, updatedLogPanel); // Updated index to 3 because of new rule row
ctx.Refresh();
await Task.Delay(2000);
}
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment