graphina 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/Gemfile +5 -0
- data/LICENSE +8 -0
- data/README.md +128 -0
- data/Rakefile +41 -0
- data/VERSION +1 -0
- data/bin/graphina +67 -0
- data/graphina.gemspec +30 -0
- data/lib/graphina/graph/display/cell.rb +48 -0
- data/lib/graphina/graph/display.rb +494 -0
- data/lib/graphina/graph/formatters.rb +111 -0
- data/lib/graphina/graph.rb +459 -0
- data/lib/graphina/version.rb +8 -0
- data/lib/graphina.rb +4 -0
- metadata +127 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 81e19cd89c158ccc817c1f9100ddd3b6d61e2b9b30b16cec62b5a59390d9bf62
|
|
4
|
+
data.tar.gz: 567f7d0ddb56e0de0b3393eb9361d17f64c4fc68f468034a83b34a29c0d1f69a
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 5f7b448e74eea737afd046b14286bcb14ef1a7b4aa7ff7123082ebb5593144fcfa71db6dff0aad8dacbe5351bd4b06c827befc8f7f031e93ab43fe9c93119051
|
|
7
|
+
data.tar.gz: 76d20ada5fb7d8e00f2317c51e21d25dedd31e74893d50d6601e9539239836d75296d390e745664dcf7c439360e98cb86c1ac93e376c9d09798eda504a17afd1
|
data/Gemfile
ADDED
data/LICENSE
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
Copyright Florian Frank
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
4
|
+
|
|
5
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
6
|
+
|
|
7
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
8
|
+
|
data/README.md
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# Graphina 📊📈
|
|
2
|
+
|
|
3
|
+
## Description
|
|
4
|
+
|
|
5
|
+
A Ruby gem for creating terminal-based data visualizations with real-time
|
|
6
|
+
graphical displays using Unicode characters and ANSI styling 🎨📊
|
|
7
|
+
|
|
8
|
+
## Documentation
|
|
9
|
+
|
|
10
|
+
Complete API documentation is available at: [GitHub.io](https://flori.github.io/graphina/)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
## Features
|
|
14
|
+
|
|
15
|
+
- **Real-time Data Visualization**: Create dynamic, continuously updating
|
|
16
|
+
graphs in terminal environments
|
|
17
|
+
- **Unicode Graphics**: Utilize Unicode block characters for high-resolution
|
|
18
|
+
terminal graphics (2px vertical resolution)
|
|
19
|
+
- **ANSI Color Support**: Full color management with 256-color and true-color
|
|
20
|
+
(24-bit) support
|
|
21
|
+
- **Multiple Display Modes**: Single and double resolution modes for different
|
|
22
|
+
terminal capabilities
|
|
23
|
+
- **Flexible Data Sources**: Support for custom data providers via Proc objects
|
|
24
|
+
- **Multiple Formatting Options**: Built-in formatters for bytes, hertz,
|
|
25
|
+
celsius, and percentage values
|
|
26
|
+
- **Efficient Rendering**: Delta-based updates to minimize terminal I/O
|
|
27
|
+
overhead
|
|
28
|
+
- **Signal Handling**: Graceful shutdown and terminal resize handling
|
|
29
|
+
- **String-based Color Derivation**: Automatically derive consistent colors
|
|
30
|
+
from titles and labels
|
|
31
|
+
|
|
32
|
+
## Installation
|
|
33
|
+
|
|
34
|
+
Add this gem to your Gemfile:
|
|
35
|
+
|
|
36
|
+
```ruby
|
|
37
|
+
gem 'graphina'
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
And install it using Bundler:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
bundle install
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Or install the gem directly:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
gem install graphina
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Usage
|
|
53
|
+
|
|
54
|
+
### 1. Basic Usage with Random Data
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
# Simple usage with random data
|
|
58
|
+
graphina
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### 2. Custom Title and Text Colors
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
# Custom title with specific colors
|
|
65
|
+
graphina -t "CPU Usage (faked)" -f blue -b black
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### 3. More complex CPU Usage Monitoring example
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
# Monitor CPU usage in real-time
|
|
72
|
+
graphina -t 'CPU Usage' -n 1 -F as_percent -e "top -l 1 -n 0 | grep 'CPU usage' | awk '{print \$3+\$5}' | sed 's/%//'"
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### 4. Custom Data Source
|
|
76
|
+
|
|
77
|
+
```ruby
|
|
78
|
+
# Using the library directly in Ruby code
|
|
79
|
+
require 'graphina'
|
|
80
|
+
|
|
81
|
+
graph = Graphina::Graph.new(
|
|
82
|
+
title: 'CPU Usage',
|
|
83
|
+
value: ->(i) { rand(100) },
|
|
84
|
+
format_value: :as_percent,
|
|
85
|
+
sleep: 1,
|
|
86
|
+
color: 33
|
|
87
|
+
)
|
|
88
|
+
graph.start
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### 5. Custom Command with External Data
|
|
92
|
+
|
|
93
|
+
```ruby
|
|
94
|
+
# Using external command for data
|
|
95
|
+
graph = Graphina::Graph.new(
|
|
96
|
+
title: 'Temperature',
|
|
97
|
+
value: ->(i) { `sensors | grep 'Tctl' | awk '{print \$2}'`.to_f },
|
|
98
|
+
format_value: :as_celsius,
|
|
99
|
+
sleep: 2
|
|
100
|
+
)
|
|
101
|
+
graph.start
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## Command Line Options
|
|
105
|
+
|
|
106
|
+
```
|
|
107
|
+
Usage: graphina [OPTIONS]
|
|
108
|
+
|
|
109
|
+
OPTIONS are
|
|
110
|
+
|
|
111
|
+
-t TITLE Title for the graph (default: 'Data')
|
|
112
|
+
-n SECONDS Update interval in seconds (default: 5)
|
|
113
|
+
-r MODE Resolution mode (:single or :double, default: :double)
|
|
114
|
+
-f COLOR Foreground color (default: :white)
|
|
115
|
+
-b COLOR Background color (default: :black)
|
|
116
|
+
-c COLOR Primary color (default: derived from title)
|
|
117
|
+
-C COLOR Secondary color (default: derived from primary)
|
|
118
|
+
-F FORMAT Format function (:as_bytes, :as_hertz, :as_celsius, :as_percent, :as_default, default: :as_default)
|
|
119
|
+
-h this help
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## Author
|
|
123
|
+
|
|
124
|
+
[Florian Frank](mailto:flori@ping.de) 🧑💻
|
|
125
|
+
|
|
126
|
+
## License
|
|
127
|
+
|
|
128
|
+
[MIT License](./LICENSE) 📄
|
data/Rakefile
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# vim: set filetype=ruby et sw=2 ts=2:
|
|
2
|
+
|
|
3
|
+
require 'gem_hadar'
|
|
4
|
+
|
|
5
|
+
GemHadar do
|
|
6
|
+
name 'graphina'
|
|
7
|
+
module_type :module
|
|
8
|
+
author 'Florian Frank'
|
|
9
|
+
email 'flori@ping.de'
|
|
10
|
+
homepage "https://github.com/flori/#{name}"
|
|
11
|
+
summary <<~EOT
|
|
12
|
+
Gem for creating terminal-based data visualizations with real-time
|
|
13
|
+
graphical displays using Unicode characters and ANSI styling.
|
|
14
|
+
EOT
|
|
15
|
+
description <<~EOT
|
|
16
|
+
Gem that provides terminal-based data visualization capabilities, enabling
|
|
17
|
+
developers to create dynamic, real-time graphical displays of numerical data
|
|
18
|
+
directly within terminal environments using Unicode characters and ANSI
|
|
19
|
+
styling.
|
|
20
|
+
EOT
|
|
21
|
+
test_dir 'spec'
|
|
22
|
+
ignore '.*.sw[pon]', 'pkg', 'Gemfile.lock', '.AppleDouble', '.bundle',
|
|
23
|
+
'.yardoc', 'tags', 'doc'
|
|
24
|
+
package_ignore '.gitignore', '.contexts', '.github'
|
|
25
|
+
|
|
26
|
+
readme 'README.md'
|
|
27
|
+
|
|
28
|
+
github_workflows(
|
|
29
|
+
'static.yml' => {}
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
required_ruby_version '>= 3.1'
|
|
33
|
+
|
|
34
|
+
executables << 'graphina'
|
|
35
|
+
|
|
36
|
+
dependency 'tins', '~> 1.45'
|
|
37
|
+
dependency 'term-ansicolor', '~> 1.11'
|
|
38
|
+
development_dependency 'debug', '~> 1.0'
|
|
39
|
+
|
|
40
|
+
licenses << 'MIT'
|
|
41
|
+
end
|
data/VERSION
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
0.0.0
|
data/bin/graphina
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require 'graphina'
|
|
4
|
+
require 'term/ansicolor'
|
|
5
|
+
include Tins::GO
|
|
6
|
+
require 'shellwords'
|
|
7
|
+
|
|
8
|
+
def usage
|
|
9
|
+
puts <<~EOT
|
|
10
|
+
Usage: #{File.basename($0)} [OPTIONS]
|
|
11
|
+
|
|
12
|
+
OPTIONS are
|
|
13
|
+
|
|
14
|
+
-t TITLE Title for the graph (default: 'Data')
|
|
15
|
+
-n SECONDS Update interval in seconds (default: 5)
|
|
16
|
+
-r MODE Resolution mode (:single or :double, default: :double)
|
|
17
|
+
-f COLOR Foreground color (default: :white)
|
|
18
|
+
-b COLOR Background color (default: :black)
|
|
19
|
+
-c COLOR Primary color (default: derived from title)
|
|
20
|
+
-C COLOR Secondary color (default: derived from primary)
|
|
21
|
+
-F FORMAT Format function (:as_bytes, :as_hertz, :as_celsius, :as_percent, :as_default, default: :as_default)
|
|
22
|
+
-h this help
|
|
23
|
+
|
|
24
|
+
Examples:
|
|
25
|
+
|
|
26
|
+
graphina # Basic usage with random data
|
|
27
|
+
graphina -t "CPU Usage" # Custom title
|
|
28
|
+
graphina -t "Memory" -f blue -b black # Custom colors
|
|
29
|
+
graphina -t "Network" -r single -n 2 # Single resolution, 2 second updates
|
|
30
|
+
# Full example
|
|
31
|
+
graphina -t 'CPU Usage' -n 1 -F as_percent -e "top -l 1 -n 0 | grep 'CPU usage' | awk '{print \\$3+\\$5}' | sed 's/%//'"
|
|
32
|
+
|
|
33
|
+
EOT
|
|
34
|
+
0
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
$opts = go 't:n:r:f:b:c:C:F:e:h', defaults: {
|
|
38
|
+
?t => 'Data',
|
|
39
|
+
?n => 5,
|
|
40
|
+
?r => :double,
|
|
41
|
+
?f => :white,
|
|
42
|
+
?b => :black,
|
|
43
|
+
?F => :as_default,
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
$opts[?h] and exit usage
|
|
47
|
+
|
|
48
|
+
sleep_duration = [ 0.01, $opts[?n].to_f ].max
|
|
49
|
+
format_value = $opts[?F].to_sym
|
|
50
|
+
value = if $opts[?e]
|
|
51
|
+
-> _ { `#{$opts[?e]}`.to_f }
|
|
52
|
+
else
|
|
53
|
+
-> _ { rand(100) }
|
|
54
|
+
end
|
|
55
|
+
graph = Graphina::Graph.new(
|
|
56
|
+
title: $opts[?t],
|
|
57
|
+
sleep: sleep_duration,
|
|
58
|
+
value:,
|
|
59
|
+
true_coloring: ENV['COLORTERM'] =~ /\A(truecolor|24bit)\z/,
|
|
60
|
+
color: $opts[?c],
|
|
61
|
+
color_secondary: $opts[?C],
|
|
62
|
+
foreground_color: $opts[?f],
|
|
63
|
+
background_color: $opts[?b],
|
|
64
|
+
resolution: $opts[?r],
|
|
65
|
+
format_value:
|
|
66
|
+
)
|
|
67
|
+
graph.start
|
data/graphina.gemspec
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
# stub: graphina 0.0.0 ruby lib
|
|
3
|
+
|
|
4
|
+
Gem::Specification.new do |s|
|
|
5
|
+
s.name = "graphina".freeze
|
|
6
|
+
s.version = "0.0.0".freeze
|
|
7
|
+
|
|
8
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
|
|
9
|
+
s.require_paths = ["lib".freeze]
|
|
10
|
+
s.authors = ["Florian Frank".freeze]
|
|
11
|
+
s.date = "1980-01-02"
|
|
12
|
+
s.description = "Gem that provides terminal-based data visualization capabilities, enabling\ndevelopers to create dynamic, real-time graphical displays of numerical data\ndirectly within terminal environments using Unicode characters and ANSI\nstyling.\n".freeze
|
|
13
|
+
s.email = "flori@ping.de".freeze
|
|
14
|
+
s.executables = ["graphina".freeze]
|
|
15
|
+
s.extra_rdoc_files = ["README.md".freeze, "lib/graphina.rb".freeze, "lib/graphina/graph.rb".freeze, "lib/graphina/graph/display.rb".freeze, "lib/graphina/graph/display/cell.rb".freeze, "lib/graphina/graph/formatters.rb".freeze, "lib/graphina/version.rb".freeze]
|
|
16
|
+
s.files = ["Gemfile".freeze, "LICENSE".freeze, "README.md".freeze, "Rakefile".freeze, "VERSION".freeze, "bin/graphina".freeze, "graphina.gemspec".freeze, "lib/graphina.rb".freeze, "lib/graphina/graph.rb".freeze, "lib/graphina/graph/display.rb".freeze, "lib/graphina/graph/display/cell.rb".freeze, "lib/graphina/graph/formatters.rb".freeze, "lib/graphina/version.rb".freeze]
|
|
17
|
+
s.homepage = "https://github.com/flori/graphina".freeze
|
|
18
|
+
s.licenses = ["MIT".freeze]
|
|
19
|
+
s.rdoc_options = ["--title".freeze, "Graphina - Gem for creating terminal-based data visualizations with real-time\ngraphical displays using Unicode characters and ANSI styling.\n".freeze, "--main".freeze, "README.md".freeze]
|
|
20
|
+
s.required_ruby_version = Gem::Requirement.new(">= 3.1".freeze)
|
|
21
|
+
s.rubygems_version = "3.7.2".freeze
|
|
22
|
+
s.summary = "Gem for creating terminal-based data visualizations with real-time graphical displays using Unicode characters and ANSI styling.".freeze
|
|
23
|
+
|
|
24
|
+
s.specification_version = 4
|
|
25
|
+
|
|
26
|
+
s.add_development_dependency(%q<gem_hadar>.freeze, ["~> 2.8".freeze])
|
|
27
|
+
s.add_development_dependency(%q<debug>.freeze, ["~> 1.0".freeze])
|
|
28
|
+
s.add_runtime_dependency(%q<tins>.freeze, ["~> 1.45".freeze])
|
|
29
|
+
s.add_runtime_dependency(%q<term-ansicolor>.freeze, ["~> 1.11".freeze])
|
|
30
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
class Graphina::Graph::Display
|
|
2
|
+
# A cell representation for terminal display with character, color,
|
|
3
|
+
# background color, and styling attributes
|
|
4
|
+
#
|
|
5
|
+
# The Cell class encapsulates the properties of a single character cell in
|
|
6
|
+
# a terminal display, including its visual characteristics such as the
|
|
7
|
+
# displayed character, text color, background color, and styling
|
|
8
|
+
# attributes. It provides methods to compare cells and convert them to
|
|
9
|
+
# their string representation with ANSI escape codes for terminal
|
|
10
|
+
# rendering.
|
|
11
|
+
class Cell < Struct.new(:char, :color, :on_color, :styles)
|
|
12
|
+
# The == method compares two Cell objects for equality by their internal
|
|
13
|
+
# array representation
|
|
14
|
+
#
|
|
15
|
+
# This method checks if the current Cell instance is equal to another
|
|
16
|
+
# Cell instance by comparing their underlying array representations
|
|
17
|
+
# returned by to_a
|
|
18
|
+
#
|
|
19
|
+
# @param other [ Graphina::Graph::Display::Cell ] the other Cell object to
|
|
20
|
+
# compare against
|
|
21
|
+
#
|
|
22
|
+
# @return [ Boolean ] true if both cells have identical char, color,
|
|
23
|
+
# on_color, and styles values, false otherwise
|
|
24
|
+
def ==(other)
|
|
25
|
+
to_a == other.to_a
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# The to_s method converts a Cell object into its string representation
|
|
29
|
+
# with ANSI styling
|
|
30
|
+
#
|
|
31
|
+
# This method constructs a formatted string that includes the cell's
|
|
32
|
+
# character along with its color, background color, and text style
|
|
33
|
+
# attributes using ANSI escape sequences. The resulting string is
|
|
34
|
+
# suitable for display in terminal environments that support ANSI colors.
|
|
35
|
+
#
|
|
36
|
+
# @return [ String ] a formatted string containing the cell's visual
|
|
37
|
+
# representation with appropriate ANSI styling codes for terminal
|
|
38
|
+
# rendering
|
|
39
|
+
def to_s
|
|
40
|
+
result = +''
|
|
41
|
+
result << ANSI.color(color)
|
|
42
|
+
result << ANSI.on_color(on_color)
|
|
43
|
+
styles.each { |s| result << ANSI.send(s) }
|
|
44
|
+
result << char
|
|
45
|
+
result << ANSI.reset
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|