table-and-graph-libs

📈 Console Table and Graph/Plot Libraries

https://github.com/tdulcet/table-and-graph-libs

Science Score: 54.0%

This score indicates how likely this project is to be science-related based on various indicators:

  • CITATION.cff file
    Found CITATION.cff file
  • codemeta.json file
    Found codemeta.json file
  • .zenodo.json file
    Found .zenodo.json file
  • DOI references
  • Academic publication links
  • Committers with academic emails
    1 of 3 committers (33.3%) from academic institutions
  • Institutional organization owner
  • JOSS paper metadata
  • Scientific vocabulary similarity
    Low similarity (11.4%) to scientific vocabulary
Last synced: 7 months ago · JSON representation ·

Repository

📈 Console Table and Graph/Plot Libraries

Basic Info
  • Host: GitHub
  • Owner: tdulcet
  • License: gpl-3.0
  • Language: C++
  • Default Branch: master
  • Homepage:
  • Size: 629 KB
Statistics
  • Stars: 49
  • Watchers: 2
  • Forks: 5
  • Open Issues: 5
  • Releases: 0
Created over 7 years ago · Last pushed 11 months ago
Metadata Files
Readme License Citation

README.md

Actions Status

Table and Graph Libraries

Console Table and Graph/Plot Libraries

Copyright © 2018 Teal Dulcet

These header only libraries use box-drawing, Braille, fraction and other Unicode characters and terminal colors and formatting to output tables and graphs/plots to the console. All the tables and graphs are created with a single (one) function call and they do not require any special data structures.

See the python directory for Python ports of the libraries.

For command-line tools using these respective libraries, see the Tables and Graphs CLI.

❤️ Please visit tealdulcet.com to support these libraries and my other software development.

Table of Contents

Tables

Usage

Requires support for C++17. See the tables.hpp file for full usage information.

Complete versions of all of the examples below and more can be found in the tables.cpp file.

Compile with: * GCC: g++ -std=c++17 -Wall -g -O3 tables.cpp -o tables * Clang: clang++ -std=c++17 -Wall -g -O3 tables.cpp -o tables

Other compilers should work as well, but are not (yet) tested.

Run with: ./tables

Output char array as table

C style char array

```cpp

include "tables.hpp"

using namespace std;

int main() { sizet rows = 5; sizet columns = 5;

char ***array;

// Allocate and set array

tables::options aoptions = {.headerrow = true, .headercolumn = true};

tables::array(rows, columns, array, nullptr, nullptr, aoptions);

// Deallocate array

return 0;

} ```

C++ string array

```cpp

include "tables.hpp"

using namespace std;

int main() { sizet rows = 5; sizet columns = 5;

vector<vector<string>> array(rows, vector<string>(columns));

// Set array

string *headerrow = nullptr;
string *headercolumn = nullptr;

tables::options aoptions = {.headerrow = true, .headercolumn = true};

tables::array(array, headerrow, headercolumn, aoptions);

return 0;

} ```

Table cells can contain Unicode characters and formatted text with ANSI escape sequences, but not newlines and tabs.

Output array as table with separate header row and column

C style char array

```cpp

include "tables.hpp"

using namespace std;

int main() { sizet rows = 4; sizet columns = 4;

const char* headerrow[] = {"Header row/column 1", "Header row 2", "Header row 3", "Header row 4", "Header row 5"};
const char* headercolumn[] = {"Header column 2", "Header column 3", "Header column 4", "Header column 5"};

char ***array;

// Allocate and set array

tables::options aoptions = {.headerrow = true, .headercolumn = true};

tables::array(rows, columns, array, headerrow, headercolumn, aoptions);

// Deallocate array

return 0;

} ```

C++ string array

```cpp

include "tables.hpp"

using namespace std;

int main() { sizet rows = 5; sizet columns = 5;

string headerrow[] = {"Header row/column 1", "Header row 2", "Header row 3", "Header row 4", "Header row 5"};
string headercolumn[] = {"Header column 2", "Header column 3", "Header column 4", "Header column 5"};

vector<vector<string>> array(rows, vector<string>(columns));

// Set array

tables::options aoptions = {.headerrow = true, .headercolumn = true};

tables::array(array, headerrow, headercolumn, aoptions);

return 0;

} ```

Output same as example above.

Output array as table

C style pointer

```cpp

include "tables.hpp"

using namespace std;

int main() { sizet rows = 5; sizet columns = 5;

double **array; // array can be any data type

// Allocate and set array

tables::array(rows, columns, array);

// Deallocate array

return 0;

} ```

C++ array/vector

```cpp

include "tables.hpp"

using namespace std;

int main() { sizet rows = 5; sizet columns = 5;

vector<vector<double>> array(rows, vector<double>(columns)); // array can be any data type

// Set array

tables::array(array);

return 0;

} ```

Output sorted array as table

C style pointer

```cpp

include

include "tables.hpp"

using namespace std;

int dimensions; // Number of columns int sortdimension; // Column to sort by

template bool compare(const T &a, const T &b) { if (a[sortdimension] == b[sortdimension]) for (int i = 0; i < dimensions; ++i) if (sortdimension != i and a[i] != b[i]) return a[i] < b[i];

return a[sortdimension] < b[sortdimension];

}

int main() { sizet rows = 5; sizet columns = 5;

int **array; // array can be any data type

// Allocate and set array

dimensions = columns;
sortdimension = 0;

sort(array, array + rows, compare<int *>);

tables::array(rows, columns, array);

// Deallocate array

return 0;

} ```

C++ array/vector

```cpp

include

include "tables.hpp"

using namespace std;

int sortdimension; // Column to sort by

template bool compare(const T &a, const T &b) { if (a[sortdimension] == b[sortdimension]) for (int i = 0; i < tables::size(a); ++i) if (sortdimension != i and a[i] != b[i]) return a[i] < b[i];

return a[sortdimension] < b[sortdimension];

}

int main() { sizet rows = 5; sizet columns = 5;

vector<vector<int>> array(rows, vector<int>(columns)); // array can be any data type

// Set array

sortdimension = 0;

sort(array.begin(), array.end(), compare<vector<int>>);

tables::array(array);

return 0;

} ```

Output single function as table

C style function pointer

```cpp

include "tables.hpp"

using namespace std;

double afunction(double x) { return x + 1; }

int main() { double xmin = -10; double xmax = 10; double xstep = 0.5;

tables::options aoptions = {.headerrow = true};

tables::function(xmin, xmax, xstep, afunction, aoptions);

return 0;

} ```

C++ lambda function

```cpp

include "tables.hpp"

using namespace std;

int main() { double xmin = -10; double xmax = 10; double xstep = 0.5;

function<double(double)> afunction = [](auto x)
{ return x + 1; };

tables::options aoptions = {.headerrow = true};

tables::function(xmin, xmax, xstep, afunction, aoptions);

return 0;

} ```

Output multiple functions as table

C style function pointer

```cpp

include

include "tables.hpp"

using namespace std;

double function1(double x) { return 2 * x; }

double function2(double x) { return pow(x, 2); }

int main() { double xmin = -10; double xmax = 10; double xstep = 0.5;

size_t numfunctions = 2;

// Function parameter and return value can be any data type, as long as they are the same
function<double(double)> functions[] = {function1, function2};

tables::options aoptions = {.headerrow = true};

tables::functions(xmin, xmax, xstep, numfunctions, functions, aoptions);

return 0;

} ```

C++ lambda function

```cpp

include

include "tables.hpp"

using namespace std;

int main() { double xmin = -10; double xmax = 10; double xstep = 0.5;

size_t numfunctions = 2;

// Function parameter and return value can be any data type, as long as they are the same
function<double(double)> functions[] = {[](auto x)
                                        { return 2 * x; },
                                        [](auto x)
                                        { return pow(x, 2); }};

tables::options aoptions = {.headerrow = true};

tables::functions(xmin, xmax, xstep, numfunctions, functions, aoptions);

return 0;

} ```

Options

Header row

Option: headerrow\ Default value: false

Header rows are bolded, centered and have a border.

Header column

Option: headercolumn\ Default value: false

Header columns are bolded, centered and have a border.

Table border

Option: tableborder\ Default value: true

Cell border

Option: cellborder\ Default value: false

Cell padding

Option: padding\ Default value: 1

Format and Alignment

Option: alignment\ Values:

  • (default)
  • std::ios_base::left
  • std::ios_base::right
  • std::ios_base::internal (integer and floating-point types only)

See ios_base::fmtflags for full available options. Use std::ios_base::boolalpha for bool to alpha.

Title

Option: title\ Default value: nullptr

The title is output at the top of the table. It is word wrapped based on the current width of the terminal, using this solution. Handles newlines, tabs and Unicode characters.

Border style

Option: style\ Values:

  1. style_ASCII: ASCII
  2. style_basic: Basic
  3. style_light: Light (default)
  4. style_heavy: Heavy
  5. style_double: Double
  6. style_arc: Light Arc
  7. style_light_dashed: Light Dashed
  8. style_heavy_dashed: Heavy Dashed

Output stream

Option: ostr\ Values:

  • std::cout (default)
  • std::cerr
  • std::clog

Any other subclass of ostream, including iostream, ofstream and ostringstream

Check size

Option: check\ Default value: true

Check that the width of the table is not greater then the width of the terminal.

Other C++ Console Tables Libraries

  • C++ Text Table (must specify every cell individually in their data structure, limited options, no Unicode support, no header row or column support)
  • Cpp Console Table (must specify every cell individually in their data structure, no Unicode support, no header row or column support)
  • ConsoleTable (requires C++11, must specify entire row at once in their data structure, no header column support)

Graphs/Plots

Usage

Requires support for C++17. See the graphs.hpp file for full usage information.

Complete versions of all of the examples below and more can be found in the graphs.cpp file.

Compile with: * GCC: g++ -std=c++17 -Wall -g -O3 graphs.cpp -o graphs * Clang: clang++ -std=c++17 -Wall -g -O3 graphs.cpp -o graphs

Other compilers should work as well, but are not (yet) tested.

Run with: ./graphs

If height is 0, it will be set to the current height of the terminal (number of rows). If width is 0, it will be set to the current width of the terminal (number of columns).

Output array as histogram

C style pointer

```cpp

include "graphs.hpp"

using namespace std;

int main() { sizet height = 40; sizet width = 80;

long double xmin = -20;
long double xmax = 20;
long double ymin = -20;
long double ymax = 20;

size_t rows = 100;

double *array; // array can be any data type

// Allocate and set array

graphs::histogram(height, width, xmin, xmax, ymin, ymax, rows, array);

// Deallocate array

return 0;

} ```

C++ array/vector

```cpp

include "graphs.hpp"

using namespace std;

int main() { sizet height = 40; sizet width = 80;

long double xmin = -20;
long double xmax = 20;
long double ymin = -20;
long double ymax = 20;

size_t rows = 100;

vector<double> array(rows); // array can be any data type

// Set array

graphs::histogram(height, width, xmin, xmax, ymin, ymax, array);

return 0;

} ```

If xmin and xmax are both 0, they will be set to the respective minimum and maximum values of x in the array. If ymin and ymax are both 0, they will be set to the respective minimum and maximum values of y in the resulting histogram.

Output single array as plot

C style pointer

```cpp

include "graphs.hpp"

using namespace std;

int main() { sizet height = 40; sizet width = 80;

long double xmin = -20;
long double xmax = 20;
long double ymin = -20;
long double ymax = 20;

size_t rows = 10;

double **array; // array can be any data type, but must have exactly two columns

// Allocate and set array

graphs::plot(height, width, xmin, xmax, ymin, ymax, rows, array);

// Deallocate array

return 0;

} ```

C++ array/vector

```cpp

include "graphs.hpp"

using namespace std;

int main() { sizet height = 40; sizet width = 80;

long double xmin = -20;
long double xmax = 20;
long double ymin = -20;
long double ymax = 20;

size_t rows = 10;

vector<vector<double>> array(rows, vector<double>(2)); // array can be any data type, but must have exactly two columns

// Set array

graphs::plot(height, width, xmin, xmax, ymin, ymax, array);

return 0;

} ```

If xmin and xmax are both 0, they will be set to the respective minimum and maximum values of x in the array. If ymin and ymax are both 0, they will be set to the respective minimum and maximum values of y in the array.

Use graphs::plots() to plot multiple arrays, which can be of different sizes.

Output single function as graph

C style function pointer

```cpp

include "graphs.hpp"

using namespace std;

double afunction(double x) { return x + 1; }

int main() { sizet height = 40; sizet width = 80;

long double xmin = -20;
long double xmax = 20;
long double ymin = -20;
long double ymax = 20;

graphs::function(height, width, xmin, xmax, ymin, ymax, afunction);

return 0;

} ```

C++ lambda function

```cpp

include "graphs.hpp"

using namespace std;

int main() { sizet height = 40; sizet width = 80;

long double xmin = -20;
long double xmax = 20;
long double ymin = -20;
long double ymax = 20;

function<double(double)> afunction = [](auto x)
{ return x + 1; };

graphs::function(height, width, xmin, xmax, ymin, ymax, afunction);

return 0;

} ```

Output multiple functions as graph

C style function pointer

```cpp

include "graphs.hpp"

using namespace std;

double function1(double x) { return 2 * x; }

double function2(double x) { return pow(x, 2); }

int main() { sizet height = 40; sizet width = 80;

long double xmin = -20;
long double xmax = 20;
long double ymin = -20;
long double ymax = 20;

size_t numfunctions = 2;

// Function parameter and return value can be any data type, as long as they are the same
function<double(double)> functions[] = {function1, function2};

graphs::functions(height, width, xmin, xmax, ymin, ymax, numfunctions, functions);

return 0;

} ```

C++ lambda function

```cpp

include "graphs.hpp"

using namespace std;

int main() { sizet height = 40; sizet width = 80;

long double xmin = -20;
long double xmax = 20;
long double ymin = -20;
long double ymax = 20;

size_t numfunctions = 2;

// Function parameter and return value can be any data type, as long as they are the same
function<double(double)> functions[] = {[](auto x)
                                        { return 2 * x; },
                                        [](auto x)
                                        { return pow(x, 2); }};

graphs::functions(height, width, xmin, xmax, ymin, ymax, numfunctions, functions);

return 0;

} ```

Options

Border

Option: border\ Default value: false

Axis

Option: axis\ Default value: true

Axis labels

Option: axislabel\ Default value: true

Requires axis to be true.

Axis tick marks

Option: axistick\ Default value: true

Requires axis to be true.

Axis units labels

Option: axisunitslabel\ Default value: true

Requires axis and axistick to be true.

X-axis units format

Option: xunits\ Values:

  1. units_number: Locale number format
  2. units_scale_none: Locale number format with full precision
  3. units_scale_SI: Auto-scale to the SI standard
  4. units_scale_IEC: Auto-scale to the IEC standard
  5. units_scale_IEC_I: Auto-scale to the IEC standard
  6. units_fracts: Locale number format, but convert fractions and mathematical constants to Unicode characters (default)
  7. units_percent: Percentage format
  8. units_date: Locale date format
  9. units_time: Locale time format
  10. units_monetary: Locale monetary/currency format

Formats 2-5 are similar to the respective --to options with the numfmt command from GNU Coreutils, but with more precision.

Y-axis units format

Option: yunits\ Values: Same as above.

Type

Option: type\ Values:

  1. type_braille: Braille (default)
  2. type_block: Block
  3. type_block_quadrant: Block quadrant
  4. type_separated_block_quadrant: Separated block quadrant
  5. type_block_sextant: Block sextant
  6. type_separated_block_sextant: Separated block sextant
  7. type_block_octant: Block octant

The Braille and block octant types have the highest density of 2×4 pixels per character, while the two block sextant types use 2×3, the two block quadrant types use 2×2 and the block type uses 1×1. This option is only used for plots and graphs. Histograms use 1×8 pixels per character.

The block sextant type requires support for Unicode 13.0, while the separated block quadrant, separated block sextant and block octant types require support for Unicode 16.0.

Mark type

Option: mark\ Values:

  1. mark_dot: Dot (default)
  2. mark_plus: Plus
  3. mark_square: Square

The dot mark type uses a single pixel per mark, the plus uses five pixels and the square uses eight pixels. This option is only used for plots and graphs.

Title

Option: title\ Default value: nullptr

The title is output at the top of the graph. It is word wrapped based on the current width of the terminal, using this solution. Handles newlines, tabs and Unicode characters.

Axis/Border style

Option: style\ Values:

  1. style_ASCII: ASCII
  2. style_basic: Basic
  3. style_light: Light (default)
  4. style_heavy: Heavy
  5. style_double: Double
  6. style_arc: Light Arc
  7. style_light_dashed: Light Dashed
  8. style_heavy_dashed: Heavy Dashed

Graph/Plot Color

Option: color\ Values:

  1. color_default: System default
  2. color_black: Black
  3. color_red: Red (default)
  4. color_green: Green
  5. color_yellow: Yellow
  6. color_blue: Blue
  7. color_magenta: Magenta
  8. color_cyan: Cyan
  9. color_white: White
  10. color_gray: Gray
  11. color_bright_red: Bright Red
  12. color_bright_green: Bright Green
  13. color_bright_yellow: Bright Yellow
  14. color_bright_blue: Bright Blue
  15. color_bright_magenta: Bright Magenta
  16. color_bright_cyan: Bright Cyan
  17. color_bright_white: Bright White

See here for examples of the colors.

This option is only used when plotting a single array and when graphing a single function. When plotting multiple arrays or graphing multiple functions, colors 2 - 16 are used inorder. The system default color is used where the plots cross.

Plot

Graph

Output stream

Option: ostr\ Values:

  • std::cout (default)
  • std::cerr
  • std::clog

Any other subclass of ostream, including iostream, ofstream and ostringstream

Check size

Option: check\ Default value: true

Check that the width and height of the graph are not greater then the respective width and height of the terminal.

Other C++ Console Graphs/Plots Libraries

Contributing

Pull requests welcome! Ideas for contributions:

Both: * Add more options * Add options to word wrap and truncate long text in table cells * Add more examples * Improve the performance * Handle newlines and tabs in the tables * Handle formatted text in the table and graph/plot titles * Support more graph/plot colors * Support 256 and 24-bit color * Support combining/blending colors when functions cross * Update the -t, --table options of column command from util-linux to use the Table library * Port to other languages (C, Java, Rust, etc.)

C++: * Add option to center text in table cells * Update the CI to test with more compilers * Support tables with the wchar_t, char16_t and char32_t C data types and the wstring, u16string and u32string C++ data types.

Owner

  • Name: Teal Dulcet
  • Login: tdulcet
  • Kind: user
  • Location: Portland, Oregon

👨‍💻 Computer Scientist, BS, CRTGR, MS @Thunderbird Council member

Citation (CITATION.cff)

cff-version: 1.2.0
title: Console Table and Graph/Plot Libraries
message: >-
  If you use this software, please cite it using the
  metadata from this file.
type: software
authors:
  - given-names: Teal
    family-names: Dulcet
    affiliation: Portland State University
    orcid: 'https://orcid.org/0009-0008-6616-2631'
repository-code: 'https://github.com/tdulcet/Table-and-Graph-Libs'
abstract: >-
  C++ and Python header only libraries that use box-drawing,
  braille, fraction and other Unicode characters and
  terminal colors and formatting to output tables and
  graphs/plots to the console.
license: GPL-3.0

GitHub Events

Total
  • Issues event: 4
  • Watch event: 9
  • Issue comment event: 20
  • Push event: 10
  • Pull request review comment event: 10
  • Pull request review event: 12
  • Pull request event: 4
  • Fork event: 2
Last Year
  • Issues event: 4
  • Watch event: 9
  • Issue comment event: 20
  • Push event: 10
  • Pull request review comment event: 10
  • Pull request review event: 12
  • Pull request event: 4
  • Fork event: 2

Committers

Last synced: 10 months ago

All Time
  • Total Commits: 37
  • Total Committers: 3
  • Avg Commits per committer: 12.333
  • Development Distribution Score (DDS): 0.081
Past Year
  • Commits: 10
  • Committers: 2
  • Avg Commits per committer: 5.0
  • Development Distribution Score (DDS): 0.2
Top Committers
Name Email Commits
Teal Dulcet t****t@p****u 34
Jan Kuhlmann 3****E 2
t-bltg t****g@g****m 1
Committer Domains (Top 20 + Academic)
pdx.edu: 1

Issues and Pull Requests

Last synced: 10 months ago

All Time
  • Total issues: 6
  • Total pull requests: 4
  • Average time to close issues: about 7 hours
  • Average time to close pull requests: about 3 hours
  • Total issue authors: 2
  • Total pull request authors: 2
  • Average comments per issue: 2.5
  • Average comments per pull request: 3.75
  • Merged pull requests: 3
  • Bot issues: 0
  • Bot pull requests: 0
Past Year
  • Issues: 6
  • Pull requests: 3
  • Average time to close issues: about 7 hours
  • Average time to close pull requests: about 4 hours
  • Issue authors: 2
  • Pull request authors: 1
  • Average comments per issue: 2.5
  • Average comments per pull request: 4.0
  • Merged pull requests: 2
  • Bot issues: 0
  • Bot pull requests: 0
Top Authors
Issue Authors
  • M2-TE (4)
  • promistrio (1)
Pull Request Authors
  • M2-TE (4)
  • t-bltg (1)
Top Labels
Issue Labels
enhancement (2) good first issue (2) question (1)
Pull Request Labels

Dependencies

.github/workflows/ci.yml actions
  • actions/checkout v3 composite
  • actions/setup-python v3 composite