{"id":17720367,"url":"https://github.com/piotrmurach/tty-sparkline","last_synced_at":"2025-04-13T19:04:26.972Z","repository":{"id":59158180,"uuid":"364927588","full_name":"piotrmurach/tty-sparkline","owner":"piotrmurach","description":"Sparkline charts for terminal applications.","archived":false,"fork":false,"pushed_at":"2024-04-20T16:48:55.000Z","size":74,"stargazers_count":29,"open_issues_count":0,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-09-20T04:38:01.217Z","etag":null,"topics":["console","ruby","sparkline","sparkline-graphs","terminal","terminal-charts","tty"],"latest_commit_sha":null,"homepage":"https://ttytoolkit.org","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/piotrmurach.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE.txt","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"piotrmurach"}},"created_at":"2021-05-06T13:53:05.000Z","updated_at":"2024-05-25T21:23:56.000Z","dependencies_parsed_at":"2024-02-29T00:29:19.928Z","dependency_job_id":"dc220a5a-2718-4787-b885-02cd9facefa0","html_url":"https://github.com/piotrmurach/tty-sparkline","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/piotrmurach%2Ftty-sparkline","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/piotrmurach%2Ftty-sparkline/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/piotrmurach%2Ftty-sparkline/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/piotrmurach%2Ftty-sparkline/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/piotrmurach","download_url":"https://codeload.github.com/piotrmurach/tty-sparkline/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245819691,"owners_count":20677703,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["console","ruby","sparkline","sparkline-graphs","terminal","terminal-charts","tty"],"created_at":"2024-10-25T15:26:44.683Z","updated_at":"2025-03-29T11:30:51.197Z","avatar_url":"https://github.com/piotrmurach.png","language":"Ruby","funding_links":["https://github.com/sponsors/piotrmurach"],"categories":["Ruby"],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n  \u003ca href=\"https://ttytoolkit.org\"\u003e\u003cimg width=\"130\" src=\"https://github.com/piotrmurach/tty/raw/master/images/tty.png\" alt=\"TTY Toolkit logo\" /\u003e\u003c/a\u003e\n\u003c/div\u003e\n\n# TTY::Sparkline\n\n[![Gem Version](https://badge.fury.io/rb/tty-sparkline.svg)][gem]\n[![Actions CI](https://github.com/piotrmurach/tty-sparkline/actions/workflows/ci.yml/badge.svg)][gh_actions_ci]\n[![Build status](https://ci.appveyor.com/api/projects/status/3pk69ulk2fs330ja?svg=true)][appveyor]\n[![Maintainability](https://api.codeclimate.com/v1/badges/aade5679e021d0ca5b55/maintainability)][codeclimate]\n[![Coverage Status](https://coveralls.io/repos/github/piotrmurach/tty-sparkline/badge.svg)][coverage]\n\n[gem]: https://badge.fury.io/rb/tty-sparkline\n[gh_actions_ci]: https://github.com/piotrmurach/tty-sparkline/actions/workflows/ci.yml\n[appveyor]: https://ci.appveyor.com/project/piotrmurach/tty-sparkline\n[codeclimate]: https://codeclimate.com/github/piotrmurach/tty-sparkline/maintainability\n[coverage]: https://coveralls.io/github/piotrmurach/tty-sparkline\n\n\u003e Sparkline charts for terminal applications.\n\n**TTY::Sparkline** provides sparkline drawing component for [TTY](https://github.com/piotrmurach/tty) toolkit.\n\n![tty-sparkline](https://github.com/piotrmurach/tty-sparkline/raw/master/assets/tty-sparkline.png)\n\n## Installation\n\nAdd this line to your application's Gemfile:\n\n```ruby\ngem \"tty-sparkline\"\n```\n\nAnd then execute:\n\n    $ bundle install\n\nOr install it yourself as:\n\n    $ gem install tty-sparkline\n\n## Contents\n\n* [1. Usage](#1-usage)\n* [2. Interface](#2-interface)\n  * [2.1 new](#21-new)\n  * [2.2 append](#22-append)\n  * [2.3 render](#23-render)\n* [3. Configuration](#3-configuration)\n  * [3.1 :top](#31-top)\n  * [3.2 :left](#32-left)\n  * [3.3 :height](#33-height)\n  * [3.4 :width](#34-width)\n  * [3.5 :min](#35-min)\n  * [3.6 :max](#36-max)\n  * [3.7 :bars](#37-bars)\n  * [3.8 :buffer_size](#38-buffer_size)\n  * [3.9 :non_numeric](#39-non_numeric)\n\n## 1. Usage\n\nTo display a sparkline chart, first, create an instance with some data:\n\n```ruby\nsparkline = TTY::Sparkline.new(1..8)\n```\n\nThen invoke `render` to generate the chart:\n\n```ruby\nsparkline.render\n# =\u003e \"▁▂▃▄▅▆▇█\"\n```\n\nTo display the sparkline in the terminal, print it like so:\n\n```ruby\nprint sparkline.render\n```\n\nThis will result in the following output:\n\n```\n▁▂▃▄▅▆▇█\n```\n\nA sparkline can be positioned anywhere within the terminal screen using [:top](#31-top) and [:left](#32-left) keywords:\n\n```ruby\nsparkline = TTY::Sparkline.new(1..8, top: 10, left: 50)\n```\n\nA sparkline can have custom size given by the [:height](#33-height) and [:width](#34-width) keywords:\n\n```ruby\nsparkline = TTY::Sparkline.new(1..8, height: 5, width: 100)\n```\n\nTo restrict data values use [:min](#35-min) and [:max](#36-max):\n\n```ruby\nsparkline = TTY::Sparkline.new(1..8, min: 0, max: 5)\n```\n\n## 2. Interface\n\n### 2.1 new\n\nTo render a new sparkline chart, first, create an instance:\n\n```ruby\nsparkline = TTY::Sparkline.new\n```\n\nIf you have a static set of data items you can provide them during initialisation with the `:data` keyword that accepts both `Array` and `Range` types:\n\n```ruby\nsparkline = TTY::Sparkline.new(1..8)\nsparkline = TTY::Sparkline.new([1, 2, 3, 4, 5, 6, 7, 8])\n```\n\nHowever, if you don't know data upfront you can [append](#22-append) it after instantiation:\n\n```ruby\nsparkline \u003c\u003c 1 \u003c\u003c 2 \u003c\u003c 3 \u003c\u003c 4\n```\n\n### 2.2 append\n\nAfter a sparkline is created, you can further add more data items using the `push` method:\n\n```ruby\nsparkline.push(1).push(2)\nsparkline.push(3, 4)\n```\n\nThe `push` is also aliased as `append` and `\u003c\u003c` operator:\n\n```ruby\nsparkline.append(5).append(6)\nsparkline \u003c\u003c 7 \u003c\u003c 8\n```\n\nThen calling `render` will result in the following:\n\n```ruby\nsparkline.render\n# =\u003e \"▁▂▃▄▅▆▇█\"\n````\n\nThis method is particularly useful if you intend to stream data. When streaming it's advisable to specify the maximum [width](#34-width) and position that the chart is going to span:\n\n```ruby\nsparkline = TTY::Sparkline.new(left: 0, top: 0, width: 50)\n````\n\nAnd then you can stream data, for example, from some service like so:\n\n```ruby\nloop do\n  # fetch next value(s) from another service etc.\n\n  sparkline \u003c\u003c value      # send value(s) to the chart\n  print sparkline.render  # render the chart out to the console\nend\n```\n\n### 2.3 render\n\nOnce you have a sparkline instance with some data:\n\n```ruby\nsparkline = TTY::Sparkline.new(1..8)\n```\n\nTo show the sparkline chart use the `render` method like so:\n\n```ruby\nsparkline.render\n# =\u003e \"▁▂▃▄▅▆▇█\"\n```\n\nTo display the chart in the terminal, you need to print it:\n\n```ruby\nprint sparkline.render\n```\n\nThis will result in the following output:\n\n```\n▁▂▃▄▅▆▇█\n```\n\nThe render method also accepts a block that provides access to the current value, bar character, column and row.\n\nFor example, to insert a space between each bar, we could do the following:\n\n```ruby\nsparkline.render do |val, bar, col, row|\n  col == 7 ? bar : \"#{bar} \"\nend\n```\n\nThat would result in:\n\n```ruby\n# =\u003e \"▁ ▂ ▃ ▄ ▅ ▆ ▇ █\"\n```\n\nThe block form is useful for applying colours, for example, to mark the lowest or the highest value.\n\nFor instance, you can use [pastel](https://github.com/piotrmurach/pastel) to colour the maximum cyan, minimum red and all the other bars green:\n\n\n```ruby\npastel = Pastel.new\n\nsparkline.render do |val, bar, col, row|\n  if val == 8\n    pastel.cyan(bar)\n  elsif val == 1\n    pastel.red(bar)\n  else\n    pastel.green(bar)\n  end\nend\n```\n\n## 3. Configuration\n\n### 3.1 `:top`\n\nBy default, a sparkline will not be positioned. To position it against the top of the terminal screen use `:top` keyword. For example, to place a sparkline 10 lines down from the top of the screen do:\n\n```ruby\nTTY::Sparkline.new(top: 10)\n```\n\nAdd [:left](#32-left) to position against the left of the terminal screen.\n\nTo dynamically position a sparkline within a terminal window consider using [tty-screen](https://github.com/piotrmurach/tty-screen) for gathering screen size. For example, to centre align against the vertical axis do:\n\n```ruby\nTTY::Sparkline.new(top: TTY::Screen.height / 2)\n```\n\n### 3.2 `:left`\n\nBy default, a sparkline will not be positioned. To position it against the left side of the terminal screen use `:left` keyword. For example, to place a sparkline `50` columns away from the left side of the terminal window do:\n\n```ruby\nTTY::Sparkline.new(left: 50)\n```\n\nAdd [:top](#31-top) to position against the top of the terminal screen.\n\nTo dynamically position a sparkline within a terminal window consider using [tty-screen](https://github.com/piotrmurach/tty-screen) for gathering screen size. For example, to centre align against horizontal axis do:\n\n```ruby\nTTY::Sparkline.new(left: TTY::Screen.width / 2)\n```\n\n### 3.3 `:height`\n\nBy default, a sparkline will be rendered within a single terminal line. To change a chart to span more than one line use `:height` keyword. For example to display a sparkline on `3` lines do:\n\n```ruby\nTTY::Sparkline.new(1..8, height: 3)\n```\n\nThen rendering the sparkline in the console:\n\n```ruby\nprint sparkline.render\n````\n\nWe would get the following output:\n\n```\n      ▃▆\n   ▂▅███\n▁▄▇█████\n```\n\n### 3.4 `:width`\n\nBy default, a sparkline will be rendered in as many terminal columns as there are data items. To restrict the chart to a limited number of columns use the `:width` keyword. For example, to display a sparkline up to a maximum of `5` columns do:\n\n```ruby\nTTY::Sparkline.new(1..8, width: 5)\n```\n\nThen by rendering the sparkline in the console:\n\n```ruby\nprint sparkline.render\n```\n\nWe would generate the following limited output:\n\n```\n▄▅▆▇█\n```\n\nThis option can be combined with the [:height](#33-height):\n\n```ruby\nTTY::Sparkline.new(1..8, height: 3, width: 5)\n```\n\nThe result of rendering the above sparkline would be as follows:\n\n```\n   ▃▆\n▂▅███\n█████\n```\n\n### 3.5 `:min`\n\nBy default, the minimum value will be calculated from the entire data set. For example, given the following data:\n\n```ruby\nsparkline = TTY::Sparkline.new([100, 75, 100, 50, 80])\n```\n\nWhen displayed in the console, you will see the following:\n\n```\n█▄█▁▅\n```\n\nYou will notice that the value of `50` looks like it's almost zero. This is because the sparkline automatically scales bars against the minimum value to make the differences between values more visible.\n\nTo change this, you can provide a custom minimum value using the `:min` keyword:\n\n```ruby\nsparkline = TTY::Sparkline.new([100, 75, 100, 50, 80], min: 0)\n```\n\nThis time the display will show `50` as a more prominent value at the cost of making the difference between other values less striking:\n\n```\n█▆█▄▆\n```\n\n### 3.6 `:max`\n\nBy default, the maximum value will be calculated from the entire data set. For example, given the following data:\n\n```ruby\nsparkline = TTY::Sparkline.new([100, 75, 300, 50, 80])\n```\n\nWhen displayed in the console, you will see the following:\n\n```\n▂▁█▁▁\n```\n\nYou will notice that the value of `300` makes all the remaining numbers look like insignificant zeros. This is because the sparkline automatically scales bars against the maximum value to make the differences between values more prominent.\n\nTo change this, you can provide a custom maximum value using the `:max` keyword:\n\n```ruby\nsparkline = TTY::Sparkline.new([100, 75, 300, 50, 80], max: 100)\n```\n\nThis time the display will limit values and reduce `300` to the height of `100` making all the remaining values more visible.\n\n```\n█▄█▁▅\n```\n\n### 3.7 `:bars`\n\nThere are eight bar types used to display values in a sparkline chart. These can be changed with the `:bars` keyword to a different set of characters:\n\n```ruby\nsparkline = TTY::Sparkline.new(1..8, bars: %w[_ - = ^])\n```\n\nThen rendering the chart will output:\n\n```ruby\nsparkline.render\n# =\u003e \"___--==^\"\n```\n\n### 3.8 `:buffer_size`\n\nBy default, the amount of data values that can be [appended](#22-append) to a sparkline is limited to `16K`. This helps to keep the memory size down when streaming data. You can change it with the `:buffer_size` keyword.\n\nFor example, to keep the last 5 data values do:\n\n```ruby\nsparkline = TTY::Sparkline.new(buffer_size: 5, min: 0)\n```\n\nThen exceeding the number of values:\n\n```ruby\nsparkline.push(1, 2, 3, 4, 5, 6, 7, 8)\n```\n\nWill cause the render to truncate the output:\n\n```ruby\nsparkline.render\n# =\u003e \"▄▅▆▇█\"\n````\n\n### 3.9 `:non_numeric`\n\nTo instruct a sparkline on how to deal with non-numeric data use the `:non_numeric` keyword.\n\nBelow are the possible values:\n\n* `:empty` - shows empty spaces (default)\n* `:ignore` - skips displaying anything\n* `:minimum` - shows the smallest bar\n\nGiven data with some non-numeric values like `\"foo\"`, `nil` and `\"\"`:\n\n```ruby\ndata = [1, 2, \"foo\", 4, nil, 6, \"\", 8]\n```\n\nWhen you don't specify the `:non_numeric` keyword, it will be set to `:empty` by default:\n\n```ruby\nsparkline = TTY::Sparkline.new(data)\n```\n\nThis will then display any non-numeric values as empty spaces:\n\n```ruby\nsparkline.render\n# =\u003e \"▁▂ ▄ ▆ █\"\n```\n\nIf you want to ignore displaying any non-numeric values use `:ignore`:\n\n```ruby\nsparkline = TTY::Sparkline.new(data, non_numeric: :ignore)\n```\n\nWhen rendered, this will result in:\n\n```ruby\nsparkline.render\n# =\u003e \"▁▂▄▆█\"\n````\n\nYou can also convert any non-numeric values to the smallest bar with `:minimum`:\n\n```ruby\nsparkline = TTY::Sparkline.new(data, non_numeric: :minimum)\n```\n\nThis will render the following:\n\n```ruby\nsparkline.render\n# =\u003e \"▁▂▁▄▁▆▁█\"\n```\n\n## Development\n\nAfter checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.\n\nTo install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).\n\n## Contributing\n\nBug reports and pull requests are welcome on GitHub at https://github.com/piotrmurach/tty-sparkline. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/piotrmurach/tty-sparkline/blob/master/CODE_OF_CONDUCT.md).\n\n## License\n\nThe gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).\n\n## Code of Conduct\n\nEveryone interacting in the TTY::Sparkline project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/piotrmurach/tty-sparkline/blob/master/CODE_OF_CONDUCT.md).\n\n## Copyright\n\nCopyright (c) 2021 Piotr Murach. See LICENSE for further details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpiotrmurach%2Ftty-sparkline","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpiotrmurach%2Ftty-sparkline","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpiotrmurach%2Ftty-sparkline/lists"}