Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

5 min example (similar to ConsoleTable library's example) #24

Closed
nikoudel opened this issue Feb 14, 2019 · 2 comments
Closed

5 min example (similar to ConsoleTable library's example) #24

nikoudel opened this issue Feb 14, 2019 · 2 comments
Assignees

Comments

@nikoudel
Copy link

I needed to get a nice table fast but CsConsoleFormat appeared too complicated. It would help a lot if there was a simple fully working and copy-pastable example to start with, right on the front page. Something like this:

using ConsoleTables;
					
public class Color
{
	public string Name { get; set; }
	public string Code { get; set; }
}

public class Program
{
	public static void Main()
	{
		var colors = new[] {
			new Color { Name = "Blue", Code = "#0000FF" },
			new Color { Name = "Yellow", Code = "#FFFF00" },
			new Color { Name = "Cyan", Code = "#00FFFF" }};
		
		var table = new ConsoleTable(
			"Name",
			"Code");
		
		foreach (var color in colors)
		{
			table.AddRow(color.Name, color.Code);
		}

		table.Write();
	}
}

And the result of the program, of course:

 -------------------- 
 | Name   | Code    |
 -------------------- 
 | Blue   | #0000FF |
 -------------------- 
 | Yellow | #FFFF00 |
 -------------------- 
 | Cyan   | #00FFFF |
 -------------------- 

 Count: 3
@Athari
Copy link
Owner

Athari commented Feb 14, 2019

@nikoudel The "simple fully working and copy-pastable example to start with, right on the front page" exists exactly there under the title "C# (like LINQ to XML)". Yes, it includes setting colors, alignment and borders, but you can just remove what you don't need. In your case, the code would look like this:

var colors = new[] {
    new { Name = "Blue", Code = "#0000FF" },
    new { Name = "Yellow", Code = "#FFFF00" },
    new { Name = "Cyan", Code = "#00FFFF" },
};
var doc = new Document(
    "HTML Colors",
    new Grid {
        Columns = { -1, -1 }, // -1 means GridLength.Auto - size column to content
        Children = {
            new Cell("Name"),
            new Cell("Code"),
            colors.Select(c => new [] {
                new Cell(c.Name),
                new Cell(c.Code),
            })
        }
    }
);
ConsoleRenderer.RenderDocument(doc);

This code would produce this output:

HTML Colors
╔══════╤═══════╗
║Name  │Code   ║
╟──────┼───────╢
║Blue  │#0000FF║
╟──────┼───────╢
║Yellow│#FFFF00║
╟──────┼───────╢
║Cyan  │#00FFFF║
╚══════╧═══════╝

It's more verbose than ConsoleTable library, but it's impossible to construct facades that would work for every case as there're too many options, so everyone would need something different. Normally, if you want many tables with various formatting in your console application, the best approach is probably to separate views from models, like it's done in GUI apps. So you would have a method like this:

public static Document RenderHtmlColors((string name, string code)[] colors) => new Document(
    "HTML Colors",
    new Grid {
        Columns = { -1, -1 },
        Children = {
            new Cell("Name"),
            new Cell("Code"),
            colors.Select(c => new[] {
                new Cell(c.name),
                new Cell(c.code),
            })
        }
    }
);

and would call it from the main code:

var colors = new[] {
    (name: "Blue", code: "#0000FF"),
    (name: "Yellow", code: "#FFFF00"),
    (name: "Cyan", code: "#00FFFF"),
};
ConsoleRenderer.RenderDocument(RenderHtmlColors(colors));

Alternatively, you can write a facade which outputs the tables you want with less code. A starting point would look like this:

public class ConsoleTable
{
    public string Title { get; set; }
    public IEnumerable<string> ColumnNames { get; set; }
    public IEnumerable<string> Cells { get; set; }

    public void Render()
    {
        var doc = new Document(
            Title,
            new Grid {
                Columns = { ColumnNames.Select(c => -1) },
                Children = {
                    ColumnNames.Select(c => new Cell(c)),
                    Cells.Select(c => new Cell(c)),
                }
            }
        );
        ConsoleRenderer.RenderDocument(doc);
    }
}

You can then use it like this:

var table = new ConsoleTable {
    Title = "HTML Colors",
    ColumnNames = new[] { "Name", "Code" },
    Cells = colors.SelectMany(c => new[] { c.name, c.code }).ToList()
};
table.Render();

(If you're confused by what happens with IEnumerable inside IEnumerable and how it works, please check out System.Xml.Linq documentation as the logic of collapsing enumerables is the same as in LINQ to XML.)

Even something as trivial as this is superior to ConsoleTable library already, for example, it properly handles multi-line cells.

You can easily expand this code to suit your needs. For example, instead of specifying column headers and and cell contens explicitly, you can use expressions and reflection. Overall, you write the facades that you need and then use them.

P.S. I understand that the library may look too complicated, as it burrows concepts from unrelated technologies (WPF, HTML, LINQ to XML), but I hope this clears up things a bit. If you have more questions, feel free to ask.

@Athari Athari self-assigned this Feb 14, 2019
@Athari Athari added the type:support Support label Feb 14, 2019
@Athari Athari changed the title 5 min example 5 min example (similar to ConsoleTable library's example) Feb 14, 2019
@nikoudel
Copy link
Author

I get it now, thank you!

It was just missing a bit of context (the Order.OrderItems thing). Now it seems obvious when I have the whole model in mind but the first sight was a bit confusing.

@Athari Athari closed this as completed Feb 14, 2019
@Athari Athari added the resolved:done Done label Feb 14, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants