feat: Teach Table to render top grouping headers
πWhat is this pr about?
Partially fix #472.
Reuses the internal rendering mechanism to leverage existing features and benefit from existing test coverage.
Implementation favored a design which is as less invasive as possible with regards to the current code.
Pending topics:
- [ ] Adding documentation to console-table-printer/console-table-docu
Potential future features:
- Support coloring grouped headers (cannot be easily done in the scope of that PR)
- Allow true dynamic resizing (cf. test
should cope with very long group names)
π Changes
Added
- [x] New Table option:
groupedColumnsHeaders
πΌ Screenshots
const table = new Table({
groupedColumnsHeaders: [
{ name: 'G1', width: 9 }
]});
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β G1 β
ββββββ¬βββββ¬βββββ¬ββββββββββ¬βββββ¬βββββ¬βββββ¬βββββ¬ββββββββββ€
β A β B β C β D β E β F β G β H β I β
ββββββΌβββββΌβββββΌββββββββββΌβββββΌβββββΌβββββΌβββββΌββββββββββ€
β A1 β B1 β C1 β D1 β E1 β F1 β G1 β H1 β I 00001 β
β A2 β B2 β C2 β D 00002 β E2 β F2 β G2 β H2 β I2 β
ββββββ΄βββββ΄βββββ΄ββββββββββ΄βββββ΄βββββ΄βββββ΄βββββ΄ββββββββββ
---
const table = new Table({
groupedColumnsHeaders: [
{ name: 'G1', width: 2 },
{ name: 'G2', width: 2 },
{ name: 'G3', width: 5 },
]});
βββββββββββ¬βββββββββββββββ¬ββββββββββββββββββββββββββββββ
β G1 β G2 β G3 β
ββββββ¬βββββΌβββββ¬ββββββββββΌβββββ¬βββββ¬βββββ¬βββββ¬ββββββββββ€
β A β B β C β D β E β F β G β H β I β
ββββββΌβββββΌβββββΌββββββββββΌβββββΌβββββΌβββββΌβββββΌββββββββββ€
β A1 β B1 β C1 β D1 β E1 β F1 β G1 β H1 β I 00001 β
β A2 β B2 β C2 β D 00002 β E2 β F2 β G2 β H2 β I2 β
ββββββ΄βββββ΄βββββ΄ββββββββββ΄βββββ΄βββββ΄βββββ΄βββββ΄ββββββββββ
---
const table = new Table({
groupedColumnsHeaders: [
{ kind: 'PLACEHOLDER', width: 1 },
{ name: 'G1', width: 2 },
{ name: 'G2', width: 2 },
{ name: 'G3', width: 4 },
]});
βββββββββββ¬βββββββββββββββ¬βββββββββββββββββββββββββ
β G1 β G2 β G3 β
ββββββΌβββββ¬βββββΌββββββββββ¬βββββΌβββββ¬βββββ¬βββββ¬ββββββββββ€
β A β B β C β D β E β F β G β H β I β
ββββββΌβββββΌβββββΌββββββββββΌβββββΌβββββΌβββββΌβββββΌββββββββββ€
β A1 β B1 β C1 β D1 β E1 β F1 β G1 β H1 β I 00001 β
β A2 β B2 β C2 β D 00002 β E2 β F2 β G2 β H2 β I2 β
ββββββ΄βββββ΄βββββ΄ββββββββββ΄βββββ΄βββββ΄βββββ΄βββββ΄ββββββββββ
---
const table = new Table({
groupedColumnsHeaders: [
{ name: 'G1', width: 2 },
{ name: 'G2', width: 2 },
{ name: 'G3', width: 4 },
]});
βββββββββββ¬βββββββββββββββ¬ββββββββββββββββββββ
β G1 β G2 β G3 β
ββββββ¬βββββΌβββββ¬ββββββββββΌβββββ¬βββββ¬βββββ¬βββββΌββββββββββ
β A β B β C β D β E β F β G β H β I β
ββββββΌβββββΌβββββΌββββββββββΌβββββΌβββββΌβββββΌβββββΌββββββββββ€
β A1 β B1 β C1 β D1 β E1 β F1 β G1 β H1 β I 00001 β
β A2 β B2 β C2 β D 00002 β E2 β F2 β G2 β H2 β I2 β
ββββββ΄βββββ΄βββββ΄ββββββββββ΄βββββ΄βββββ΄βββββ΄βββββ΄ββββββββββ
---
const table = new Table({
groupedColumnsHeaders: [
{ name: 'G1', width: 2 },
{ name: 'G2', width: 2 },
{ kind: 'PLACEHOLDER', width: 1 },
{ name: 'G3', width: 4 },
]});
βββββββββββ¬βββββββββββββββ ββββββββββββββββββββββββββ
β G1 β G2 β β G3 β
ββββββ¬βββββΌβββββ¬ββββββββββΌβββββΌβββββ¬βββββ¬βββββ¬ββββββββββ€
β A β B β C β D β E β F β G β H β I β
ββββββΌβββββΌβββββΌββββββββββΌβββββΌβββββΌβββββΌβββββΌββββββββββ€
β A1 β B1 β C1 β D1 β E1 β F1 β G1 β H1 β I 00001 β
β A2 β B2 β C2 β D 00002 β E2 β F2 β G2 β H2 β I2 β
ββββββ΄βββββ΄βββββ΄ββββββββββ΄βββββ΄βββββ΄βββββ΄βββββ΄ββββββββββ
---
const table = new Table({
groupedColumnsHeaders: [
{ kind: 'PLACEHOLDER', width: 1 },
{ name: 'G1', width: 2 },
{ kind: 'PLACEHOLDER', width: 1 },
{ name: 'G2', width: 2 },
{ name: 'G3', width: 2 },
]});
βββββββββββ βββββββββββ¬ββββββββββ
β G1 β β G2 β G3 β
ββββββΌβββββ¬βββββΌββββββββββΌβββββ¬βββββΌβββββ¬βββββΌββββββββββ
β A β B β C β D β E β F β G β H β I β
ββββββΌβββββΌβββββΌββββββββββΌβββββΌβββββΌβββββΌβββββΌββββββββββ€
β A1 β B1 β C1 β D1 β E1 β F1 β G1 β H1 β I 00001 β
β A2 β B2 β C2 β D 00002 β E2 β F2 β G2 β H2 β I2 β
ββββββ΄βββββ΄βββββ΄ββββββββββ΄βββββ΄βββββ΄βββββ΄βββββ΄ββββββββββ
---
const table = new Table({
groupedColumnsHeaders: [
{ kind: 'PLACEHOLDER', width: 5 },
{ name: 'G1', width: 2 },
]});
βββββββββββ
β G1 β
ββββββ¬βββββ¬βββββ¬ββββββββββ¬βββββΌβββββ¬βββββΌβββββ¬ββββββββββ
β A β B β C β D β E β F β G β H β I β
ββββββΌβββββΌβββββΌββββββββββΌβββββΌβββββΌβββββΌβββββΌββββββββββ€
β A1 β B1 β C1 β D1 β E1 β F1 β G1 β H1 β I 00001 β
β A2 β B2 β C2 β D 00002 β E2 β F2 β G2 β H2 β I2 β
ββββββ΄βββββ΄βββββ΄ββββββββββ΄βββββ΄βββββ΄βββββ΄βββββ΄ββββββββββ
---
const table = new Table({
groupedColumnsHeaders: [
{ kind: 'PLACEHOLDER', width: 7 },
{ name: 'VERY LONG GROUP NAME', width: 2 },
]});
ββββββββββββββββ
β VERY LONG β
ββββββ¬βββββ¬βββββ¬ββββββββββ¬βββββ¬βββββ¬βββββΌβββββ¬ββββββββββ€
β A β B β C β D β E β F β G β H β I β
ββββββΌβββββΌβββββΌββββββββββΌβββββΌβββββΌβββββΌβββββΌββββββββββ€
β A1 β B1 β C1 β D1 β E1 β F1 β G1 β H1 β I 00001 β
β A2 β B2 β C2 β D 00002 β E2 β F2 β G2 β H2 β I2 β
ββββββ΄βββββ΄βββββ΄ββββββββββ΄βββββ΄βββββ΄βββββ΄βββββ΄ββββββββββ
---
const table = new Table({
groupedColumnsHeaders: [
{ name: 'LEFT', alignment: 'left', width: 2 },
{ name: 'RIGHT', alignment: 'right', width: 2 },
]});
βββββββββββ¬βββββββββββββββ
β LEFT β RIGHT β
ββββββ¬βββββΌβββββ¬ββββββββββΌβββββ¬βββββ¬βββββ¬βββββ¬ββββββββββ
β A β B β C β D β E β F β G β H β I β
ββββββΌβββββΌβββββΌββββββββββΌβββββΌβββββΌβββββΌβββββΌββββββββββ€
β A1 β B1 β C1 β D1 β E1 β F1 β G1 β H1 β I 00001 β
β A2 β B2 β C2 β D 00002 β E2 β F2 β G2 β H2 β I2 β
ββββββ΄βββββ΄βββββ΄ββββββββββ΄βββββ΄βββββ΄βββββ΄βββββ΄ββββββββββ
Codecov Report
:x: Patch coverage is 96.96970% with 5 lines in your changes missing coverage. Please review.
| Files with missing lines | Patch % | Lines |
|---|---|---|
| src/internalTable/grouped-column-headers.ts | 96.75% | 1 Missing and 4 partials :warning: |
:loudspeaker: Thoughts on this report? Let us know!
@ayonious Thoughts?
I will take some time to review this. Maybe around a week. But the feature looks good.
I would also suggest to add more tests like test/features/groupedColumnHeaders
I would also suggest to add more tests like test/features/groupedColumnHeaders
@ayonious Will do.
Although I'm not sure what is the proper balance between what's expected to live under test/features/groupedColumnHeaders/render.tests vs test/render.tests.
Will push something and let you decide ;-)
Will push something and let you decide ;-)
Done.
Moved everything under test/features/ and added one global rendering test in test/render.tests.ts
@ayonious rebased
Im thinking about some special cases
- with calculated columns
- With columns that are far from each other but belongs to same parent column
- group of groups
And with this solution, column headers need to be in same order as the other columns, means columns actually have to have a strict serial.
So although this is a nice partial solution its complication makes it hard for me to allow this in the package.
If there is something simpler and more effective I can take a look. Lets first maybe brainstorm and see if we can come up with something simpler.
Lets first maybe brainstorm and see if we can come up with something simpler.
That's the simplest I've been able to come with. How would you approach it?
Instead of grouping serially with widths, I think its more correct grouping them with the ids.
groupedColumnsHeaders: [{
childIds: 'col1', 'col2'
id: 'title1'
title: 'Title1'
}]
@ayonious Thanks for the feedback. Let me see what I can come up with.
@ayonious Thanks for the feedback. Let me see what I can come up with.
@ayonious Here's a new version exposing a column name based aggregation definition.
Thoughts?
Note: In order to make your review easier, I've pushed my changes in a fixup commit.
my changes in a fixup commit
@ayonious Thoughts?
@ayonious Here's a new version exposing a column name based aggregation definition.
@ayonious Have you had the time to take a look at the proposal yet?
@ayonious Kind bump?