From 795b278feb1b6e0c0121bd496d521de834f6b7f3 Mon Sep 17 00:00:00 2001 From: masukomi Date: Sun, 1 Jan 2023 15:59:37 -0500 Subject: [PATCH] initial commit - unfinished time to walk the dogs --- .github/workflows/test.yml | 32 +++ .gitignore | 2 + Changes | 4 + LICENSE | 201 ++++++++++++++++++ META6.json | 27 +++ README.md | 29 +++ dist.ini | 9 + lib/CLI/Graphing/VerticalBarChart.rakumod | 59 +++++ .../Graphing/VerticalBarChart/Graph.rakumod | 6 + .../Graphing/VerticalBarChart/Legend.rakumod | 97 +++++++++ t/01-basic.rakutest | 6 + 11 files changed, 472 insertions(+) create mode 100644 .github/workflows/test.yml create mode 100644 .gitignore create mode 100644 Changes create mode 100644 LICENSE create mode 100644 META6.json create mode 100644 README.md create mode 100644 dist.ini create mode 100644 lib/CLI/Graphing/VerticalBarChart.rakumod create mode 100644 lib/CLI/Graphing/VerticalBarChart/Graph.rakumod create mode 100644 lib/CLI/Graphing/VerticalBarChart/Legend.rakumod create mode 100644 t/01-basic.rakutest diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..c8d3740 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,32 @@ +name: test + +on: + push: + branches: + - '*' + tags-ignore: + - '*' + pull_request: + +jobs: + raku: + strategy: + matrix: + os: + - ubuntu-latest + - macos-latest + - windows-latest + raku-version: + - 'latest' + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v3 + - uses: Raku/setup-raku@v1 + with: + raku-version: ${{ matrix.raku-version }} + - name: Install Dependencies + run: zef install --/test --test-depends --deps-only . + - name: Install App::Prove6 + run: zef install --/test App::Prove6 + - name: Run Tests + run: prove6 -I. t diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c874da9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.precomp/ +/CLI-Graphing-VerticalBarChart-* diff --git a/Changes b/Changes new file mode 100644 index 0000000..8bfec27 --- /dev/null +++ b/Changes @@ -0,0 +1,4 @@ +Revision history for CLI-Graphing-VerticalBarChart + +{{$NEXT}} + - Initial version diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..32efefc --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + The Artistic License 2.0 + + Copyright (c) 2000-2006, The Perl Foundation. + + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +Preamble + +This license establishes the terms under which a given free software +Package may be copied, modified, distributed, and/or redistributed. +The intent is that the Copyright Holder maintains some artistic +control over the development of that Package while still keeping the +Package available as open source and free software. + +You are always permitted to make arrangements wholly outside of this +license directly with the Copyright Holder of a given Package. If the +terms of this license do not permit the full use that you propose to +make of the Package, you should contact the Copyright Holder and seek +a different licensing arrangement. + +Definitions + + "Copyright Holder" means the individual(s) or organization(s) + named in the copyright notice for the entire Package. + + "Contributor" means any party that has contributed code or other + material to the Package, in accordance with the Copyright Holder's + procedures. + + "You" and "your" means any person who would like to copy, + distribute, or modify the Package. + + "Package" means the collection of files distributed by the + Copyright Holder, and derivatives of that collection and/or of + those files. A given Package may consist of either the Standard + Version, or a Modified Version. + + "Distribute" means providing a copy of the Package or making it + accessible to anyone else, or in the case of a company or + organization, to others outside of your company or organization. + + "Distributor Fee" means any fee that you charge for Distributing + this Package or providing support for this Package to another + party. It does not mean licensing fees. + + "Standard Version" refers to the Package if it has not been + modified, or has been modified only in ways explicitly requested + by the Copyright Holder. + + "Modified Version" means the Package, if it has been changed, and + such changes were not explicitly requested by the Copyright + Holder. + + "Original License" means this Artistic License as Distributed with + the Standard Version of the Package, in its current version or as + it may be modified by The Perl Foundation in the future. + + "Source" form means the source code, documentation source, and + configuration files for the Package. + + "Compiled" form means the compiled bytecode, object code, binary, + or any other form resulting from mechanical transformation or + translation of the Source form. + + +Permission for Use and Modification Without Distribution + +(1) You are permitted to use the Standard Version and create and use +Modified Versions for any purpose without restriction, provided that +you do not Distribute the Modified Version. + + +Permissions for Redistribution of the Standard Version + +(2) You may Distribute verbatim copies of the Source form of the +Standard Version of this Package in any medium without restriction, +either gratis or for a Distributor Fee, provided that you duplicate +all of the original copyright notices and associated disclaimers. At +your discretion, such verbatim copies may or may not include a +Compiled form of the Package. + +(3) You may apply any bug fixes, portability changes, and other +modifications made available from the Copyright Holder. The resulting +Package will still be considered the Standard Version, and as such +will be subject to the Original License. + + +Distribution of Modified Versions of the Package as Source + +(4) You may Distribute your Modified Version as Source (either gratis +or for a Distributor Fee, and with or without a Compiled form of the +Modified Version) provided that you clearly document how it differs +from the Standard Version, including, but not limited to, documenting +any non-standard features, executables, or modules, and provided that +you do at least ONE of the following: + + (a) make the Modified Version available to the Copyright Holder + of the Standard Version, under the Original License, so that the + Copyright Holder may include your modifications in the Standard + Version. + + (b) ensure that installation of your Modified Version does not + prevent the user installing or running the Standard Version. In + addition, the Modified Version must bear a name that is different + from the name of the Standard Version. + + (c) allow anyone who receives a copy of the Modified Version to + make the Source form of the Modified Version available to others + under + + (i) the Original License or + + (ii) a license that permits the licensee to freely copy, + modify and redistribute the Modified Version using the same + licensing terms that apply to the copy that the licensee + received, and requires that the Source form of the Modified + Version, and of any works derived from it, be made freely + available in that license fees are prohibited but Distributor + Fees are allowed. + + +Distribution of Compiled Forms of the Standard Version +or Modified Versions without the Source + +(5) You may Distribute Compiled forms of the Standard Version without +the Source, provided that you include complete instructions on how to +get the Source of the Standard Version. Such instructions must be +valid at the time of your distribution. If these instructions, at any +time while you are carrying out such distribution, become invalid, you +must provide new instructions on demand or cease further distribution. +If you provide valid instructions or cease distribution within thirty +days after you become aware that the instructions are invalid, then +you do not forfeit any of your rights under this license. + +(6) You may Distribute a Modified Version in Compiled form without +the Source, provided that you comply with Section 4 with respect to +the Source of the Modified Version. + + +Aggregating or Linking the Package + +(7) You may aggregate the Package (either the Standard Version or +Modified Version) with other packages and Distribute the resulting +aggregation provided that you do not charge a licensing fee for the +Package. Distributor Fees are permitted, and licensing fees for other +components in the aggregation are permitted. The terms of this license +apply to the use and Distribution of the Standard or Modified Versions +as included in the aggregation. + +(8) You are permitted to link Modified and Standard Versions with +other works, to embed the Package in a larger work of your own, or to +build stand-alone binary or bytecode versions of applications that +include the Package, and Distribute the result without restriction, +provided the result does not expose a direct interface to the Package. + + +Items That are Not Considered Part of a Modified Version + +(9) Works (including, but not limited to, modules and scripts) that +merely extend or make use of the Package, do not, by themselves, cause +the Package to be a Modified Version. In addition, such works are not +considered parts of the Package itself, and are not subject to the +terms of this license. + + +General Provisions + +(10) Any use, modification, and distribution of the Standard or +Modified Versions is governed by this Artistic License. By using, +modifying or distributing the Package, you accept this license. Do not +use, modify, or distribute the Package, if you do not accept this +license. + +(11) If your Modified Version has been derived from a Modified +Version made by someone other than you, you are nevertheless required +to ensure that your Modified Version complies with the requirements of +this license. + +(12) This license does not grant you the right to use any trademark, +service mark, tradename, or logo of the Copyright Holder. + +(13) This license includes the non-exclusive, worldwide, +free-of-charge patent license to make, have made, use, offer to sell, +sell, import and otherwise transfer the Package with respect to any +patent claims licensable by the Copyright Holder that are necessarily +infringed by the Package. If you institute patent litigation +(including a cross-claim or counterclaim) against any party alleging +that the Package constitutes direct or contributory patent +infringement, then this Artistic License to you shall terminate on the +date that such litigation is filed. + +(14) Disclaimer of Warranty: +THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS +IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES. THE IMPLIED +WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR +NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY YOUR LOCAL +LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR CONTRIBUTOR WILL +BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/META6.json b/META6.json new file mode 100644 index 0000000..83fad00 --- /dev/null +++ b/META6.json @@ -0,0 +1,27 @@ +{ + "auth": "zef:masukomi", + "authors": [ + "" + ], + "build-depends": [ + ], + "depends": [ + "Listicles", + "Text::Wrap:ver<0.0.3+>" + ], + "description": "blah blah blah", + "license": "Artistic-2.0", + "name": "CLI::Graphing::VerticalBarChart", + "perl": "6.d", + "provides": { + "CLI::Graphing::VerticalBarChart": "lib/CLI/Graphing/VerticalBarChart.rakumod" + }, + "resources": [ + ], + "source-url": "", + "tags": [ + ], + "test-depends": [ + ], + "version": "0.0.1" +} diff --git a/README.md b/README.md new file mode 100644 index 0000000..ba1b047 --- /dev/null +++ b/README.md @@ -0,0 +1,29 @@ +NAME +==== + +CLI::Graphing::VerticalBarChart - blah blah blah + +SYNOPSIS +======== + +```raku +use CLI::Graphing::VerticalBarChart; +``` + +DESCRIPTION +=========== + +CLI::Graphing::VerticalBarChart is ... + +AUTHOR +====== + + <> + +COPYRIGHT AND LICENSE +===================== + +Copyright 2023 + +This library is free software; you can redistribute it and/or modify it under the Artistic License 2.0. + diff --git a/dist.ini b/dist.ini new file mode 100644 index 0000000..aa90df0 --- /dev/null +++ b/dist.ini @@ -0,0 +1,9 @@ +name = CLI-Graphing-VerticalBarChart + +[ReadmeFromPod] +filename = lib/CLI/Graphing/VerticalBarChart.rakumod + +[UploadToZef] + +[Badges] +provider = github-actions/test.yml diff --git a/lib/CLI/Graphing/VerticalBarChart.rakumod b/lib/CLI/Graphing/VerticalBarChart.rakumod new file mode 100644 index 0000000..235bb2c --- /dev/null +++ b/lib/CLI/Graphing/VerticalBarChart.rakumod @@ -0,0 +1,59 @@ +use Listicles; + +unit module CLI::Graphing::VerticalBarChart; + +constant KEY_CHARS is export = ('a'..'z').Array.append: ('A'..'Z').Array; + +our sub calculate-max-key-chars(Array $data, Array $key_chars) returns Int is export { + return ($data.elems / $key_chars.elems) + 1 +} + +our sub get-key-chars(Array $custom_chars?) returns Array { + if $custom_chars and ! $custom_chars.is-empty { + $custom_chars; + } else { + KEY_CHARS; + } +} + +our sub generate-key-for-index(Int $index, Int $max_key_chars, Array $key_chars) returns Str is export { + my $multiplier = ($index / $key_chars.elems) + 1; + my $lc_index = $index - ($multiplier * $key_chars.elems); + my $key = ($key_chars[$lc_index] * $multiplier); + if $key.chars < $max_key_chars { + my $key_padding_size = $max_key_chars - $key.chars; + $key ~= " " x $key_padding_size; + } + return $key; +} + + +=begin pod + +=head1 NAME + +CLI::Graphing::VerticalBarChart - blah blah blah + +=head1 SYNOPSIS + +=begin code :lang + +use CLI::Graphing::VerticalBarChart; + +=end code + +=head1 DESCRIPTION + +CLI::Graphing::VerticalBarChart is ... + +=head1 AUTHOR + + <> + +=head1 COPYRIGHT AND LICENSE + +Copyright 2023 + +This library is free software; you can redistribute it and/or modify it under the Artistic License 2.0. + +=end pod diff --git a/lib/CLI/Graphing/VerticalBarChart/Graph.rakumod b/lib/CLI/Graphing/VerticalBarChart/Graph.rakumod new file mode 100644 index 0000000..d6dfbc8 --- /dev/null +++ b/lib/CLI/Graphing/VerticalBarChart/Graph.rakumod @@ -0,0 +1,6 @@ +unit class CLI::Graphing::VerticalBarChart::Graph { + use CLI::Graphing::VerticalBarChart; + + + +} diff --git a/lib/CLI/Graphing/VerticalBarChart/Legend.rakumod b/lib/CLI/Graphing/VerticalBarChart/Legend.rakumod new file mode 100644 index 0000000..00ac6f0 --- /dev/null +++ b/lib/CLI/Graphing/VerticalBarChart/Legend.rakumod @@ -0,0 +1,97 @@ +unit class CLI::Graphing::VerticalBarChart::Legend { + use CLI::Graphing::VerticalBarChart; + use Text::Wrap; + + has $.data; + has $.labels; + has $.key_chars; + has $.max_width; + + method generate() returns String { + return "" if $!data.elems == 0; + + my $max_key_chars = calculate-max-key-chars($!data, + CLI::Graphing::VerticalBarChart::KEY_CHARS); + my $left_cols_size = 2 + $max_key_chars + 2; + # ^^ that's "| " + max_key_chars + ": " + + my $right_cols_size = 2; + # ^^ that's " |" + + my Str @rows_without_edges = []; + my $max_text_width = $!max_width - $left_cols_size - $right_cols_size; + for 0..($!data.elems - 1) -> $index { + #pair.key = index, pair.value = datum + my $key = generate-key-for-index(0, $max_key_chars, CLI::Graphing::VerticalBarChart::KEY_CHARS); + @rows_without_edges.push: generate-legend-row($!labels[$index], + $key, + $!max_width, + $max_key_chars); + } + my $max_legend_width = @rows_without_edges.map({.chars}).max; + $max_legend_width = $max_width - 4 if $max_legend_width + 4 < $max_width; + + my Str @response = []; + @response.push: generate-top-horizontal-edge($max_legend_width + 4); + @response.push: "\n"; + my @rows_without_edges = pad-rows-to-width(@rows_without_edges, $max_legend_width); + for @rows_without_edges -> $row { + @response.push: "│ "; + @response.push: $row; + @response.push: " │"; + } + @response.push: generate-bottom-horizontal-edge($max_legend_width + 4); + return @response.join; + } + + method pad-rows-to-width(Array $rows, Int $largest_legend_size) returns Array { + my Str @new_rows = []; + for $rows -> $row { + if $row.chars < $largest_legend_size { + @new_rows.push: $row ~ (" " x ($largest_legend_size - $row.chars)); + } else { + @new_rows.push: $row; + } + } + return @new_rows; + } + + method generate-bottom-horizontal-edge(Int $max_width) returns Str { + "└" ~ ("─" x ($max_width - 2) ) ~ "┘" + } + + method generate-top-horizontal-edge(Int $max_width) returns Str { + "┌" ~ ("─" x ($max_width - 2) ) ~ "┐" + } + + method generate-legend-row(Str $legend, + Str $key, + Int $max_width, + Int $max_key_chars) returns Array { + my $max_text_width = $max_width - 6 - $max_key_chars; + my Str @legend = []; + @legend.push: $key; + if $key.chars < $max_key_chars { + @legend.push: (' ' x ($max_key_chars - $key.size)); + } + @legend.push: ': '; + my @legend_lines = wrap-text($legend, + width => $max_text_width, + hard-wrap => False #Undecided about this... + ).lines; + if @legend_lines.elems == 1 { + @legend.push: @legend_lines.head; + } else { + for @legend_lines.pairs -> $pair { + #$pair.key == index, $pair.value = text + @legend.push: ( ' ' x ($max_key_chars + 2) ) if $pair.key > 0; + @legend.push: $pair.value; + @legend.push: "\n" if $pair.key != @legend_lines.elems - 1; + } + } + + return @legend_lines; + } + + +} # end class diff --git a/t/01-basic.rakutest b/t/01-basic.rakutest new file mode 100644 index 0000000..7ceb7e0 --- /dev/null +++ b/t/01-basic.rakutest @@ -0,0 +1,6 @@ +use Test; +use CLI::Graphing::VerticalBarChart; + +pass "replace me"; + +done-testing;