mirror of
https://github.com/tdulcet/Table-and-Graph-Libs.git
synced 2025-12-16 00:18:55 +08:00
Compare commits
22 Commits
master
...
3f0442475c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3f0442475c | ||
|
|
afdd9a597b | ||
|
|
e0836b13a3 | ||
|
|
fe16c101cf | ||
|
|
3e665661f3 | ||
|
|
cf7b07a881 | ||
|
|
95b2f7aad0 | ||
|
|
6cfa086a2e | ||
|
|
353b46c2e9 | ||
|
|
ebcbc6978d | ||
|
|
f9ff88c276 | ||
|
|
42e9d73719 | ||
|
|
a1057fe32c | ||
|
|
fc29acf844 | ||
|
|
1d6e7ab716 | ||
|
|
950e3391a8 | ||
|
|
68d18a05cf | ||
|
|
1b67cc6767 | ||
|
|
d57f3c6aad | ||
|
|
316d2105d3 | ||
|
|
366512d614 | ||
|
|
30beea8b75 |
7
.github/workflows/ci.yml
vendored
7
.github/workflows/ci.yml
vendored
@@ -11,9 +11,10 @@ jobs:
|
||||
name: Linux C++
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
continue-on-error: ${{ matrix.cxx == 'clang++' && matrix.os == 'ubuntu-20.04' }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-22.04, ubuntu-24.04]
|
||||
os: [ubuntu-20.04, ubuntu-22.04, ubuntu-24.04]
|
||||
cxx: [g++, clang++]
|
||||
fail-fast: false
|
||||
env:
|
||||
@@ -68,7 +69,7 @@ jobs:
|
||||
python3 -m pip install --upgrade pip
|
||||
python3 -m pip install ruff
|
||||
- name: Script
|
||||
run: ruff check --output-format=github .
|
||||
run: ruff check --output-format=github --target-version py37 --select F,E4,E7,E9,W,I,D,UP,YTT,ANN,S,BLE,B,A,COM819,C4,T10,EM,EXE,ISC,ICN,G,PIE,PYI,Q,RSE,RET,SLF,SLOT,SIM,TID,TC,ARG,PGH,PL,TRY,FLY,PERF,FURB,LOG,RUF --preview --ignore W191,D211,D213,D401,PLR09,PLR1702,PLR2004,FURB101,FURB167,RUF001,RUF002,RUF003,RUF023 .
|
||||
continue-on-error: true
|
||||
|
||||
Python:
|
||||
@@ -82,6 +83,8 @@ jobs:
|
||||
include:
|
||||
- os: ubuntu-22.04
|
||||
python-version: "3.7"
|
||||
- os: ubuntu-20.04
|
||||
python-version: "3.6"
|
||||
fail-fast: false
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright © Teal Dulcet
|
||||
// Teal Dulcet, CS546
|
||||
|
||||
// Compile: g++ -std=gnu++17 -Wall -g -O3 graphs.cpp -o graphs
|
||||
|
||||
|
||||
154
graphs.hpp
154
graphs.hpp
@@ -1,6 +1,9 @@
|
||||
// Copyright © Teal Dulcet
|
||||
// Teal Dulcet, CS546
|
||||
#pragma once
|
||||
#include <bitset>
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
#include <cstring>
|
||||
#include <cmath>
|
||||
@@ -54,7 +57,7 @@ namespace graphs
|
||||
// {" ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " "} // No border
|
||||
};
|
||||
|
||||
enum color_type
|
||||
enum color_type: uint8_t
|
||||
{
|
||||
color_default,
|
||||
color_black,
|
||||
@@ -812,6 +815,153 @@ namespace graphs
|
||||
return 0;
|
||||
}
|
||||
|
||||
// EXPERIMENTAL BEG
|
||||
|
||||
// Using the existing color_type enum for the 4-bit colors (not using std::variant due to its larger size)
|
||||
union Color {
|
||||
color_type col_4; // 4-bit color
|
||||
uint8_t col_8; // 8-bit color
|
||||
struct {
|
||||
uint8_t red;
|
||||
uint8_t green;
|
||||
uint8_t blue;
|
||||
} col_24; // 24-bit true color
|
||||
};
|
||||
enum class ColorBits: uint8_t { e4, e8, e24 };
|
||||
|
||||
// Intermediate fragment representation potentially holding multiple pixels (e.g. 2x4 as braille)
|
||||
// most optimal representation possible with only 4 bytes in size, applicable for all types of characters
|
||||
struct Fragment {
|
||||
Color color;
|
||||
uint8_t data; // stores up to 8 data points or up to 255 values
|
||||
};
|
||||
// store fragments on temporary buffer to pass between draws
|
||||
using Texture = std::vector<Fragment>;
|
||||
struct Axis {
|
||||
long double min = 0;
|
||||
long double max = 0;
|
||||
bool drawn = true;
|
||||
bool labels = true;
|
||||
bool ticks = true;
|
||||
bool units_label = true;
|
||||
units_type units = units_fracts;
|
||||
};
|
||||
struct Options {
|
||||
size_t width = 0; // Width in terminal characters. Set to 0 for automatic size based on terminal.
|
||||
size_t height = 0; // Height in terminal characters. Set to 0 for automatic size based on terminal.
|
||||
|
||||
Axis x = {};
|
||||
Axis y = {};
|
||||
|
||||
type_type character_set = type_braille;
|
||||
plot_type plot = plot_scatter;
|
||||
style_type style = style_light;
|
||||
graph_type graph = graph_dot;
|
||||
|
||||
std::string title;
|
||||
std::ostream &ostr = std::cout;
|
||||
|
||||
ColorBits color_type = ColorBits::e4; // bit depth of color representation
|
||||
bool check = true; // validate sizes for graph draw
|
||||
bool border = false; // draw border around the graph
|
||||
bool draw_immediately = true; // draw graph immediately after creation. otherwise call draw/graph with the returned texture
|
||||
};
|
||||
// intermediate representation of a graph texture for ease of passing around
|
||||
struct Intermediate {
|
||||
// use a graph texture to draw into the terminal
|
||||
inline void draw() {
|
||||
// draw graph for experimental preview purposes only
|
||||
for (size_t y = 0; y < options.height; y++) {
|
||||
for (size_t x = 0; x < options.width; x++) {
|
||||
const size_t index = x + y * options.width;
|
||||
const auto& frag = texture[index];
|
||||
// begin color draw(
|
||||
cout << outputcolor(frag.color.col_4);
|
||||
// draw character
|
||||
switch (options.character_set) {
|
||||
case type_braille:
|
||||
cout << dots[frag.data];
|
||||
break;
|
||||
case type_block_quadrant:
|
||||
cout << blocks_quadrant[frag.data];
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
// reset color (TODO: could be optimized to only reset when color changes)
|
||||
cout << outputcolor(color_type::color_default);
|
||||
}
|
||||
cout << '\n';
|
||||
}
|
||||
}
|
||||
|
||||
Texture texture;
|
||||
const Options options;
|
||||
};
|
||||
|
||||
// plot from single data set, drawn on top of existing graph
|
||||
template <typename T>
|
||||
void plot_experimental(const T &data, Intermediate &intermediate, Color color = {color_red}) {
|
||||
cout << "Experimental plot\n";
|
||||
|
||||
// precalc spans
|
||||
const Options& options = intermediate.options;
|
||||
const long double x_span = options.x.max - options.x.min;
|
||||
const long double y_span = options.y.max - options.y.min;
|
||||
const long double x_span_recip = 1.0 / x_span;
|
||||
const long double y_span_recip = 1.0 / y_span;
|
||||
|
||||
// insert draw plot data into texture
|
||||
for (const auto [x, y]: data) {
|
||||
// check if value is between limits
|
||||
if (x >= options.x.min && x < options.x.max && y >= options.y.min && y < options.y.max) {
|
||||
// calculate terminal character position
|
||||
const long double x_term = ((long double)x - options.x.min) * x_span_recip * (long double)options.width;
|
||||
const long double y_term = ((long double)y - options.y.min) * y_span_recip * (long double)options.height;
|
||||
|
||||
// calculate sub-fragment position (2x4 for braille)
|
||||
const auto [char_width, char_height] = densities[options.character_set];
|
||||
size_t x_sub = (x_term - std::floor(x_term)) * char_width;
|
||||
size_t y_sub = (y_term - std::floor(y_term)) * char_height;
|
||||
// invert y_sub
|
||||
y_sub = char_height - 1 - y_sub;
|
||||
|
||||
// draw Fragment
|
||||
const size_t index = (size_t)x_term + (options.height - 1 - (size_t)y_term) * options.width;
|
||||
intermediate.texture[index].color = color; // TODO: mix color here
|
||||
|
||||
uint8_t value = 0;
|
||||
// TODO: put this in separate function to reuse in other plot funcs
|
||||
switch (options.character_set) {
|
||||
case type_braille:
|
||||
value = dotvalues[x_sub][y_sub];
|
||||
break;
|
||||
case type_block_quadrant:
|
||||
value = 1 << (x_sub + y_sub * char_width);
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
intermediate.texture[index].data |= value;
|
||||
}
|
||||
}
|
||||
|
||||
// draw plot into terminal immediately if requested
|
||||
if (options.draw_immediately) {
|
||||
intermediate.draw();
|
||||
}
|
||||
}
|
||||
// plot from single data set
|
||||
template <typename T>
|
||||
auto plot_experimental(const T &data, const Options &options = {}, Color color = {color_red}) -> Intermediate {
|
||||
cout << "Experimental plot\n";
|
||||
|
||||
// create new intermediate object for texture and options
|
||||
assert(options.width > 0 && options.height > 0); // enforce valid size for now
|
||||
Intermediate intermediate = { Texture(options.width * options.height), options };
|
||||
plot_experimental(data, intermediate, color);
|
||||
return intermediate;
|
||||
}
|
||||
// EXPERIMENTAL END
|
||||
|
||||
template <typename T>
|
||||
int histogram(size_t height, size_t width, long double xmin, long double xmax, long double ymin, long double ymax, const T &aarray, const options &aoptions = {})
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# Copyright © Teal Dulcet
|
||||
# Teal Dulcet, CS546
|
||||
|
||||
# Run: python3 -OO .
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# Copyright © Teal Dulcet
|
||||
# Teal Dulcet, CS546
|
||||
|
||||
import locale
|
||||
import math
|
||||
@@ -77,6 +77,7 @@ class color_types(IntEnum):
|
||||
|
||||
colors = (39, 30, 31, 32, 33, 34, 35, 36, 37, 90, 91, 92, 93, 94, 95, 96, 97)
|
||||
|
||||
# fmt: off
|
||||
dots = (
|
||||
"⠀", "⠁", "⠂", "⠃", "⠄", "⠅", "⠆", "⠇", "⠈", "⠉", "⠊", "⠋", "⠌", "⠍", "⠎",
|
||||
"⠏", "⠐", "⠑", "⠒", "⠓", "⠔", "⠕", "⠖", "⠗", "⠘", "⠙", "⠚", "⠛", "⠜", "⠝",
|
||||
@@ -95,22 +96,23 @@ dots = (
|
||||
"⣒", "⣓", "⣔", "⣕", "⣖", "⣗", "⣘", "⣙", "⣚", "⣛", "⣜", "⣝", "⣞", "⣟", "⣠",
|
||||
"⣡", "⣢", "⣣", "⣤", "⣥", "⣦", "⣧", "⣨", "⣩", "⣪", "⣫", "⣬", "⣭", "⣮", "⣯",
|
||||
"⣰", "⣱", "⣲", "⣳", "⣴", "⣵", "⣶", "⣷", "⣸", "⣹", "⣺", "⣻", "⣼", "⣽", "⣾",
|
||||
"⣿") # fmt: skip
|
||||
"⣿")
|
||||
dotvalues = ((0x1, 0x2, 0x4, 0x40), (0x8, 0x10, 0x20, 0x80))
|
||||
|
||||
blocks = ("\xA0", "█") # fmt: skip
|
||||
blocks = ("\xA0", "█")
|
||||
|
||||
blocks_quadrant = ("\xa0", "▘", "▝", "▀", "▖", "▌", "▞", "▛", "▗", "▚", "▐", "▜", "▄", "▙", "▟", "█")
|
||||
blocks_quadrant = ("\xA0", "▘", "▝", "▀", "▖", "▌", "▞", "▛", "▗", "▚", "▐", "▜", "▄", "▙", "▟", "█")
|
||||
|
||||
separated_blocks_quadrant = ("\xa0", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "")
|
||||
separated_blocks_quadrant = ("\xA0", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "")
|
||||
|
||||
blocks_sextant = ("\xA0", "🬀", "🬁", "🬂", "🬃", "🬄", "🬅", "🬆", "🬇", "🬈", "🬉", "🬊", "🬋", "🬌", "🬍", "🬎", "🬏", "🬐", "🬑", "🬒", "🬓", "▌", "🬔", "🬕", "🬖", "🬗", "🬘", "🬙", "🬚", "🬛", "🬜", "🬝", "🬞", "🬟", "🬠", "🬡", "🬢", "🬣", "🬤", "🬥", "🬦", "🬧", "▐", "🬨", "🬩", "🬪", "🬫", "🬬", "🬭", "🬮", "🬯", "🬰", "🬱", "🬲", "🬳", "🬴", "🬵", "🬶", "🬷", "🬸", "🬹", "🬺", "🬻", "█") # fmt: skip
|
||||
blocks_sextant = ("\xA0", "🬀", "🬁", "🬂", "🬃", "🬄", "🬅", "🬆", "🬇", "🬈", "🬉", "🬊", "🬋", "🬌", "🬍", "🬎", "🬏", "🬐", "🬑", "🬒", "🬓", "▌", "🬔", "🬕", "🬖", "🬗", "🬘", "🬙", "🬚", "🬛", "🬜", "🬝", "🬞", "🬟", "🬠", "🬡", "🬢", "🬣", "🬤", "🬥", "🬦", "🬧", "▐", "🬨", "🬩", "🬪", "🬫", "🬬", "🬭", "🬮", "🬯", "🬰", "🬱", "🬲", "🬳", "🬴", "🬵", "🬶", "🬷", "🬸", "🬹", "🬺", "🬻", "█")
|
||||
|
||||
separated_blocks_sextant = ("\xA0", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "") # fmt: skip
|
||||
separated_blocks_sextant = ("\xA0", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "")
|
||||
|
||||
blocks_octant = ("\xA0", "", "", "🮂", "", "▘", "", "", "", "", "▝", "", "", "", "", "▀", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "🮅", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "▖", "", "", "", "", "▌", "", "", "", "", "▞", "", "", "", "", "▛", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "▗", "", "", "", "", "▚", "", "", "", "", "▐", "", "", "", "", "▜", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "▂", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "▄", "", "", "", "", "▙", "", "", "", "", "▟", "", "▆", "", "", "█") # fmt: skip
|
||||
blocks_octant = ("\xA0", "", "", "🮂", "", "▘", "", "", "", "", "▝", "", "", "", "", "▀", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "🮅", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "▖", "", "", "", "", "▌", "", "", "", "", "▞", "", "", "", "", "▛", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "▗", "", "", "", "", "▚", "", "", "", "", "▐", "", "", "", "", "▜", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "▂", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "▄", "", "", "", "", "▙", "", "", "", "", "▟", "", "▆", "", "", "█")
|
||||
|
||||
bars = ("\xa0", "▁", "▂", "▃", "▄", "▅", "▆", "▇", "█")
|
||||
bars = ("\xA0", "▁", "▂", "▃", "▄", "▅", "▆", "▇", "█")
|
||||
# fmt: on
|
||||
|
||||
|
||||
class type_types(IntEnum):
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
[tool.ruff]
|
||||
line-length = 132 # 88
|
||||
indent-width = 4
|
||||
|
||||
target-version = "py37"
|
||||
|
||||
preview = true
|
||||
|
||||
output-format = "concise"
|
||||
|
||||
[tool.ruff.lint]
|
||||
select = [
|
||||
"F",
|
||||
"E4",
|
||||
"E7",
|
||||
"E9",
|
||||
"W",
|
||||
"I",
|
||||
"D",
|
||||
"UP",
|
||||
"YTT",
|
||||
"ANN",
|
||||
"S",
|
||||
"BLE",
|
||||
"B",
|
||||
"A",
|
||||
"COM819",
|
||||
"C4",
|
||||
"T10",
|
||||
"EM",
|
||||
"EXE",
|
||||
"ISC",
|
||||
"ICN",
|
||||
"G",
|
||||
"PIE",
|
||||
"PYI",
|
||||
"Q",
|
||||
"RSE",
|
||||
"RET",
|
||||
"SLF",
|
||||
"SLOT",
|
||||
"SIM",
|
||||
"TID",
|
||||
"TC",
|
||||
"ARG",
|
||||
"PGH",
|
||||
"PL",
|
||||
"TRY",
|
||||
"FLY",
|
||||
"PERF",
|
||||
"FURB",
|
||||
"LOG",
|
||||
"RUF"
|
||||
]
|
||||
ignore = [
|
||||
"W191",
|
||||
"D211",
|
||||
"D213",
|
||||
"D401",
|
||||
"PLR09",
|
||||
"PLR1702",
|
||||
"PLR2004",
|
||||
"FURB101",
|
||||
"FURB167",
|
||||
"RUF001",
|
||||
"RUF002",
|
||||
"RUF003",
|
||||
"RUF023"
|
||||
]
|
||||
|
||||
[tool.ruff.lint.isort]
|
||||
split-on-trailing-comma = false
|
||||
|
||||
[tool.ruff.format]
|
||||
quote-style = "double"
|
||||
|
||||
indent-style = "tab"
|
||||
|
||||
skip-magic-trailing-comma = true
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# Copyright © Teal Dulcet
|
||||
# Teal Dulcet, CS546
|
||||
|
||||
import locale
|
||||
import re
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright © Teal Dulcet
|
||||
// Teal Dulcet, CS546
|
||||
|
||||
// Compile: g++ -std=gnu++17 -Wall -g -O3 tables.cpp -o tables
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright © Teal Dulcet
|
||||
// Teal Dulcet, CS546
|
||||
#pragma once
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
Reference in New Issue
Block a user