Skip to content
ConsoleMonster

Chart and table

Pick a sample in the table and the chart's crosshair follows; move along the chart and the row follows.

Demos Terminal apps

Use it when a table of measurements is easier to read with its trend beside it, and the trend needs exact values.

  • Live
  • 88×24
  • PowerShell 7.4+
  • .NET 8.0+
Chart and table 88×2424-bitFull

How it's built

The whole program in one file, with its sample data at the top. It drew the recording above; all three styles produce the same frame bytes.

PowerShellchart-table.ps1View on GitHub
# Explore a load chart linked to the table of samples it was drawn from.

Import-Module -Name ConsoleMonster
# All data is synthetic and inline; no services are contacted or changed.
$cpu = @(
    32, 35, 41, 38, 44, 52, 61, 58, 66, 72, 69, 63
    57, 54, 60, 68, 75, 81, 77, 70, 62, 55, 49, 45
)
$memory = @(
    48, 49, 50, 51, 51, 52, 54, 55, 57, 58, 59, 60
    61, 61, 62, 63, 65, 66, 67, 68, 68, 69, 70, 71
)
$samples = for ($i = 0; $i -lt $cpu.Count; $i++) {
    $minutes = $i * 5
    [pscustomobject]@{
        Time   = '{0:D2}:{1:D2}' -f (9 + [int][math]::Floor($minutes / 60)), ($minutes % 60)
        Cpu    = $cpu[$i]
        Memory = $memory[$i]
    }
}

# Layout: construct the widgets shown on screen.
$chart = New-ConsoleChart -Type Line -Unit '%' -Series @(
    [pscustomobject]@{ Key = 'cpu'; Values = $cpu }
    [pscustomobject]@{ Key = 'memory'; Values = $memory }
)
$content = {
    New-ConsoleDataGrid -Key Samples -InputObject $samples -Height 7 -SelectionKey Sample
    New-ConsoleChartView -Key Load -Chart $chart -Labels $samples.Time -SelectionKey Sample
}

# Behaviour: Up/Down picks a sample and the crosshair follows; in the chart, Left/Right picks a
# point and the row follows, + and - zoom, 1 and 2 hide a series; Escape exits.
Show-ConsoleApp -Content $content
C#Program.csView on GitHub
// Explore a load chart linked to the table of samples it was drawn from.
// All data is synthetic and inline; no services are contacted or changed.
using ConsoleMonster.Interactive;
using ConsoleMonster.Layout;
using ConsoleMonster.Widgets;

double[] cpu =
{
    32, 35, 41, 38, 44, 52, 61, 58, 66, 72, 69, 63,
    57, 54, 60, 68, 75, 81, 77, 70, 62, 55, 49, 45
};
double[] memory =
{
    48, 49, 50, 51, 51, 52, 54, 55, 57, 58, 59, 60,
    61, 61, 62, 63, 65, 66, 67, 68, 68, 69, 70, 71
};
string[] times = new string[cpu.Length];
for (int i = 0; i < cpu.Length; i++) { times[i] = $"{9 + (i * 5 / 60):D2}:{i * 5 % 60:D2}"; }

// Layout: construct the widgets shown on screen.
LineChart chart = new LineChart { Unit = "%" };
for (int i = 0; i < cpu.Length; i++) { chart.Add("cpu", cpu[i]); }
for (int i = 0; i < memory.Length; i++) { chart.Add("memory", memory[i]); }
Grid samples = new Grid("Samples").AddColumn("Time").AddColumn("Cpu").AddColumn("Memory");
for (int i = 0; i < cpu.Length; i++) { samples.AddRow(times[i], times[i], cpu[i], memory[i]); }
ChartView load = new ChartView("Load", chart) { SelectionKey = "Sample" };
foreach (string time in times) { load.Labels.Add(time); }
Rows layout = new Rows(
    new DataGrid("Samples", samples) { Height = 7, SelectionKey = "Sample" },
    load);

// Behaviour: Up/Down picks a sample and the crosshair follows; in the chart, Left/Right picks a
// point and the row follows, + and - zoom, 1 and 2 hide a series; Escape exits.
ConsoleApp.Run(layout);
C# fluentProgram.Fluent.csView on GitHub
// Explore a load chart linked to the table of samples it was drawn from.
// All data is synthetic and inline; no services are contacted or changed.
using ConsoleMonster.Interactive;
using ConsoleMonster.Layout;
using ConsoleMonster.Widgets;
using ConsoleMonster;

double[] cpu =
{
    32, 35, 41, 38, 44, 52, 61, 58, 66, 72, 69, 63,
    57, 54, 60, 68, 75, 81, 77, 70, 62, 55, 49, 45
};
double[] memory =
{
    48, 49, 50, 51, 51, 52, 54, 55, 57, 58, 59, 60,
    61, 61, 62, 63, 65, 66, 67, 68, 68, 69, 70, 71
};
string[] times = new string[cpu.Length];
for (int i = 0; i < cpu.Length; i++) { times[i] = $"{9 + (i * 5 / 60):D2}:{i * 5 % 60:D2}"; }

// Layout: construct the widgets shown on screen.
LineChart chart = (LineChart)Ui.Chart().Type(ChartType.Line).Unit("%").Build();
for (int i = 0; i < cpu.Length; i++) { chart.Add("cpu", cpu[i]); }
for (int i = 0; i < memory.Length; i++) { chart.Add("memory", memory[i]); }
Grid samples = new Grid("Samples").AddColumn("Time").AddColumn("Cpu").AddColumn("Memory");
for (int i = 0; i < cpu.Length; i++) { samples.AddRow(times[i], times[i], cpu[i], memory[i]); }
Rows layout = Ui.Rows().Content(c =>
{
    c.DataGrid(grid => grid.Key("Samples").Grid(samples).Height(7).SelectionKey("Sample"));
    c.ChartView(view => view.Key("Load").Chart(chart).Labels(times).SelectionKey("Sample"));
});

// Behaviour: Up/Down picks a sample and the crosshair follows; in the chart, Left/Right picks a
// point and the row follows, + and - zoom, 1 and 2 hide a series; Escape exits.
ConsoleApp.Run(layout);

Run it yourself

Three steps in PowerShell, four in C#. Every command copies with one click.

  1. Install the module

    Once. Windows PowerShell 5.1 or PowerShell 7 on Windows, macOS or Linux.

    Install-Module ConsoleMonster -Scope CurrentUser
  2. Save the program

    Download it, or copy it from above into chart-table.ps1.

  3. Run it

    From the folder you saved it in.

    ./chart-table.ps1
  1. Create a project

    A plain console app; .NET 8 or later.

    dotnet new console -n ChartTable; cd ChartTable
  2. Save the project

    The project selects one C# style at a time and restores ConsoleMonster.

  3. Save both programs

    Replace Program.cs and save Program.Fluent.cs beside it.

  4. Run it

    dotnet run
  1. Create a project

    A plain console app; .NET 8 or later.

    dotnet new console -n ChartTable; cd ChartTable
  2. Save the project

    The project selects one C# style at a time and restores ConsoleMonster.

  3. Save both programs

    Replace Program.cs and save Program.Fluent.cs beside it.

  4. Run it

    dotnet run --property:DemoStyle=Fluent

Or skip the copying. Run the bundled program.

Show-ConsoleDemo chart-table
$source = (Get-ConsoleDemo chart-table).Source
[IO.File]::WriteAllText("$PWD/chart-table.ps1", $source, [Text.UTF8Encoding]::new($true))

Make it yours

Start with these, then read the rest of the file.

  1. Chart your own samples: a build's durations, a service's latency, a disk's free space.

  2. Give the table and the chart the same selection key and keep their rows in the same order.

  3. Label the points with times so the readout says when each value was taken.

More terminal apps

All demos