-
Notifications
You must be signed in to change notification settings - Fork 87
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
Two column layout #472
Comments
Hi @pronebird But could you draw an example of the table you want? |
Same as Basically column a is field and column b is value. Then what used to be a column is printed for each entry as row. I am gonna try putting together example when I am back at the keyboard. |
Something like this?
If it is the case, I wonder if you have any ideas what more styles we could add to |
Actually reading the name of the issue use tabled::{
settings::{themes::Layout, Alignment, Style},
Table, Tabled,
};
#[derive(Debug, Tabled)]
struct KV {
key: String,
value: String,
}
impl KV {
fn new(key: &str, value: &str) -> Self {
Self {
key: key.to_string(),
value: value.to_string(),
}
}
}
fn main() {
let data = vec![
KV::new("Hello", "1"),
KV::new("World", "2"),
KV::new("!", "3"),
];
let mut table = Table::new(data);
table
.with(Layout::new(Alignment::left(), false))
.with(Style::modern());
println!("{table}")
}
The same could be achived by |
Meant exactly that. I have a table with way too many columns. There aren’t going to be many entries in it so a vertical layout seems like a better fit. I will elaborate more in the morning as I have a few examples where it could save me some time if it was built in. |
So I have a table with a lot of columns, i.e #[derive(Tabled)]
struct Company<'a> {
#[tabled(rename = "Company")]
name: &'a str,
#[tabled(rename = "Street")]
street: &'a str,
#[tabled(rename = "City")]
city: &'a str,
#[tabled(rename = "ZIP code")]
zip_code: &'a str,
// etc..
} A
The field/value header can be omitted and the inter-record separator can either be:
I realize that I could probably build a |
So I do like your proposition a lot. So there's no out of the box solution yet. If you have some more ideas in this regard please let me know. PS: Yes use tabled::{
builder::Builder,
grid::config::HorizontalLine,
settings::{style::BorderSpanCorrection, Dup, Span, Style, Theme},
Table, Tabled,
};
#[derive(Tabled)]
struct Company<'a> {
#[tabled(rename = "Company", format("{}", self.name.to_uppercase()))]
name: &'a str,
#[tabled(rename = "Street", format("{}", self.street.to_uppercase()))]
street: &'a str,
#[tabled(rename = "City", format("{}", self.city.to_uppercase()))]
city: &'a str,
#[tabled(rename = "ZIP code", format("{}", self.zip_code.to_uppercase()))]
zip_code: &'a str,
}
fn kv_table_build<T>(list: &[T]) -> Table
where
T: Tabled,
{
let mut b = Builder::with_capacity(list.len() * <T as Tabled>::LENGTH, 2);
b.push_record(["Key", "Value"]);
for company in list {
let values = <T as Tabled>::headers()
.into_iter()
.zip(Tabled::fields(&company));
for (k, v) in values {
b.push_record([k, v]);
}
}
b.build()
}
fn kv_table_span<T>(t: &mut Table)
where
T: Tabled,
{
let count_columns = <T as Tabled>::LENGTH;
let length = (t.count_rows() - 1) / count_columns;
for i in 0..length {
let row = 1 + (i * count_columns);
t.with(Dup::new((row, 0), (row, 1)));
t.modify((row, 0), Span::column(2));
}
t.with(Style::modern());
t.with(BorderSpanCorrection);
}
fn kv_table_line_separation<T>(t: &mut Table)
where
T: Tabled,
{
let count_columns = <T as Tabled>::LENGTH;
let length = (t.count_rows() - 1) / count_columns;
let mut theme = Theme::from(Style::modern());
for i in 1..length {
let pos = 1 + (i * count_columns);
theme.insert_horizontal_line(pos, HorizontalLine::full('━', '╋', '┣', '┫'));
}
t.with(theme);
}
fn main() {
let companies = vec![
Company { name: "INTEL CORP", city: "SANTA CLARA", street: "2200 MISSION COLLEGE BLVD, RNB-4-151", zip_code: "95054" },
Company { name: "Apple Inc.", city: "CUPERTINO", street: "ONE APPLE PARK WAY", zip_code: "95014" },
];
let mut table = kv_table_build(&companies);
/* Do for horizontal line change */
// kv_table_line_separation::<Company>(&mut table);
/* Do for panel change */
// kv_table_span::<Company>(&mut table);
println!("{table}")
} Uncomment one of the commented lines and you see what your expect. |
Maybe we could add customisation to the Right now I use let store_rc = Rc::new(store);
let entries = store_rc.all_entries().iter().map(Company::from);
let table = ExtendedTable::new(entries).template(move |index| {
let entry = store_rc
.all_entries()
.iter()
.skip(index)
.take(1)
.next()
.expect("failed to get entry");
entry.name.to_owned()
}); Also it would be great to extend template and pass let entries = store.all_entries().iter().map(Company::from);
let table = ExtendedTable::new(entries).template_with_item(move |index, item /* &Company */| {
item.name.to_owned()
}); I imagine that a derive macro can be added to define the heading of each entry but that's more advanced. I'd be happy to have something simple first. Appreciate the example code above, I'll give it a spin! 💪 Note that uppercase values come from 3rd party system so I am not intentionally uppercasing anything but good to know that the value can be transformed with derive macro. |
Sorry was a little bit busy close #14842 I've added a test but I'd check if it solved it. cc: @fdncred __________________________ **Unrelated** Recently got a pretty good format idea (zhiburt/tabled#472) Just wanna highlight that we could probably experiment with it, if it being a bit elaborated. It's sort of KV table which nushell already has, But it's more for a default table where each row/record being rendered as a KV table. It's not something super nice I guess but maybe it could get some appliance. So yes pointing it out just in case. Like these. ``` ┌──────────────┬───────────────────────────────────────────────┐ │ Field │ Value │ ├──────────────┼───────────────────────────────────────────────┤ │ Company │ INTEL CORP │ ├──────────────┼───────────────────────────────────────────────┤ │ Street │ 2200 MISSION COLLEGE BLVD, RNB-4-151 │ ├──────────────┼───────────────────────────────────────────────┤ │ City │ SANTA CLARA │ ├──────────────┼───────────────────────────────────────────────┤ │ ZIP code │ 95054 │ ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫ │ Company │ Apple Inc. │ ├──────────────┼───────────────────────────────────────────────┤ │ Street │ ONE APPLE PARK WAY │ ├──────────────┼───────────────────────────────────────────────┤ │ City │ CUPERTINO │ ├──────────────┼───────────────────────────────────────────────┤ │ ZIP code │ 95014 │ └──────────────┴───────────────────────────────────────────────┘ ┌──────────────────────────────────────────────────────────────┐ │ INTEL CORP │ ├──────────────┬───────────────────────────────────────────────┤ │ Street │ 2200 MISSION COLLEGE BLVD, RNB-4-151 │ ├──────────────┼───────────────────────────────────────────────┤ │ City │ SANTA CLARA │ ├──────────────┼───────────────────────────────────────────────┤ │ ZIP code │ 95054 │ ├──────────────┴───────────────────────────────────────────────┤ │ Apple Inc. │ ├──────────────┬───────────────────────────────────────────────┤ │ Street │ ONE APPLE PARK WAY │ ├──────────────┼───────────────────────────────────────────────┤ │ City │ CUPERTINO │ ├──────────────┼───────────────────────────────────────────────┤ │ ZIP code │ 95014 │ └──────────────┴───────────────────────────────────────────────┘ ``` PS: Now thinking about it, it's sort of like doing a iteration over rows and building a current KV table, Which is interesting cause we could do it row by row, in which case doing CTRLC would not ruin build but got some data rendered. All though it's a different kind of approach. Just saying.
Hey @pronebird Got a little simplifications for my example: use tabled::{
iter::LayoutIterator,
settings::{style::BorderSpanCorrection, Span, Style},
Table, Tabled,
};
#[derive(Tabled)]
struct Company<'a> {
name: &'a str,
street: &'a str,
city: &'a str,
zip_code: &'a str,
}
fn main() {
let companies = vec![
Company { name: "INTEL CORP", city: "SANTA CLARA", street: "2200 MISSION COLLEGE BLVD, RNB-4-151", zip_code: "95054" },
Company { name: "Apple Inc.", city: "CUPERTINO", street: "ONE APPLE PARK WAY", zip_code: "95014" },
];
let mut table = Table::kv(&companies);
for row in LayoutIterator::kv_batches::<Company>(&table) {
table.modify((row, 1), Span::column(-1));
}
table.with(Style::modern());
table.with(BorderSpanCorrection);
println!("{table}")
} According to your comment about Take care. |
Hi,
is it possible to flip a traditional table with columns at the top and values below into two-column layout similar to psql expanded display but using modern style?
The text was updated successfully, but these errors were encountered: