Skip to content

Commit

Permalink
ability to create cross tables
Browse files Browse the repository at this point in the history
i.e. tables with headers in both the first row and first column
  • Loading branch information
sonnym committed Jul 27, 2012
1 parent da91634 commit 5c18988
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 14 deletions.
17 changes: 17 additions & 0 deletions README.md
Expand Up @@ -54,6 +54,23 @@ table.push(
, { 'Another key': 'Another value' }
);

console.log(table.toString());
```
### Cross Tables
Cross tables are very similar to vertical tables, with two key differences:

1. They require a `head` setting when instantiated that has an empty string as the first header
2. The individual rows take the general form of { "Header": ["Row", "Values"] }

```javascript
var Table = require('cli-table');
var table = new Table({ head: ["", "Top Header 1", "Top Header 2"] });

table.push(
{ 'Left Header 1': ['Value Row 1 Col 1', 'Value Row 1 Col 2'] }
, { 'Left Header 2': ['Value Row 2 Col 1', 'Value Row 2 Col 2'] }
);

console.log(table.toString());
```

Expand Down
6 changes: 6 additions & 0 deletions examples/revs.js
Expand Up @@ -51,3 +51,9 @@ vertical_table.push({ "Some Key": "Some Value"},
);

console.log(vertical_table.toString());

/* cross */
var cross_table = new Table({ head: ["", "Header #1", "Header #2"] });
cross_table.push({ "Header #3": ["Value 1", "Value 2"] },
{ "Header #4": ["Value 3", "Value 4"] });
console.log(cross_table.toString());
51 changes: 37 additions & 14 deletions lib/cli-table/index.js
Expand Up @@ -89,16 +89,23 @@ Table.prototype.toString = function (){

if (!colWidths.length){
this.slice(0).concat([head]).forEach(function(cells){
if (cells.length) {
cells.forEach(function(cell, i){
colWidths[i] = Math.max(colWidths[i] || 0, get_width(cell) || 0);
});
// horizontal (arrays)
if (typeof cells === 'object' && cells.length) {
extractColumnWidths(cells);

// vertical (objects)
} else {
var header_cell = Object.keys(cells)[0]
, value_cell = cells[header_cell];

colWidths[0] = Math.max(colWidths[0] || 0, get_width(header_cell) || 0);
colWidths[1] = Math.max(colWidths[1] || 0, get_width(value_cell) || 0);

// cross (objects w/ array values)
if (typeof value_cell === 'object' && value_cell.length) {
extractColumnWidths(value_cell, 1);
} else {
colWidths[1] = Math.max(colWidths[1] || 0, get_width(value_cell) || 0);
}
}
});
};
Expand All @@ -108,6 +115,13 @@ Table.prototype.toString = function (){
return a + b
})) + colWidths.length + 1;

function extractColumnWidths(arr, offset) {
var offset = offset || 0;
arr.forEach(function(cell, i){
colWidths[i + offset] = Math.max(colWidths[i + offset] || 0, get_width(cell) || 0);
});
};

function get_width(obj) {
return width = typeof obj == 'object' && obj.width != undefined
? obj.width
Expand Down Expand Up @@ -140,6 +154,16 @@ Table.prototype.toString = function (){
ret += "\n";
};

function arrayToCells(arr, start_column) {
var ret = "", start_column = start_column || 0;

arr.forEach(function(cell, i){
ret += string(cell, start_column + i);
ret += chars.right;
});
return ret;
};

// renders a string, by padding it or truncating it
function string (str, index){
var str = String(typeof str == 'object' && str.text ? str.text : str)
Expand Down Expand Up @@ -194,18 +218,15 @@ Table.prototype.toString = function (){
}
}

// empty row
if (cells.hasOwnProperty("length") && !cells.length)
return

// horizontal
if (cells.hasOwnProperty("length")) {
ret += chars.left;
ret += chars.left + arrayToCells(cells) + "\n";

cells.forEach(function(cell, i){
ret += string(cell, i);
ret += chars.right;
});

ret += "\n";
// vertical
} else if (typeof cells === 'object') {
var key = Object.keys(cells)[0]
, value = cells[key];
Expand All @@ -216,8 +237,10 @@ Table.prototype.toString = function (){
});
}

ret += chars.left + string(key, 0) + chars.right +
string(value, 1) + chars.right + "\n"
// if value is not String, assume Array for cross table
var row = (typeof value === 'string') ? string(value, 1) + chars.right : arrayToCells(value, 1);

ret += chars.left + string(key, 0) + chars.right + row + "\n";
}
});

Expand Down
21 changes: 21 additions & 0 deletions test/index.test.js
Expand Up @@ -65,6 +65,27 @@ module.exports = {
, '└─────────┴──────────────────────┘'
];

table.toString().should.eql(expected.join("\n"));
},

'test cross table output': function() {
var table = new Table({ head: ["", "Header 1", "Header 2"], style: {} }); // clear styles to prevent color output

table.push(
{"Header 3": ['v0.1', 'Testing something cool'] }
, {"Header 4": ['v0.1', 'Testing something cool'] }
);

var expected = [
'┌────────┬────────┬──────────────────────┐'
, '│ │Header 1│Header 2 │'
, '├────────┼────────┼──────────────────────┤'
, '│Header 3│v0.1 │Testing something cool│'
, '├────────┼────────┼──────────────────────┤'
, '│Header 4│v0.1 │Testing something cool│'
, '└────────┴────────┴──────────────────────┘'
];

table.toString().should.eql(expected.join("\n"));
}
};

0 comments on commit 5c18988

Please sign in to comment.