Build terminal dashboards using ascii/ansi art and javascript

Overview

blessed-contrib

Build dashboards (or any other application) using ascii/ansi art and javascript.

Friendly to terminals, ssh and developers. Extends blessed with custom drawille and other widgets.

You should also check WOPR: a markup for creating terminal reports, presentations and infographics.

Contributors:

Yaron Naveh (@YaronNaveh) Chris (@xcezzz) Miguel Valadas (@mvaladas)

Demo (full size):

term

term

(source code)

Running the demo

git clone https://github.com/yaronn/blessed-contrib.git
cd blessed-contrib
npm install
node ./examples/dashboard.js

Works on Linux, OS X and Windows. For Windows follow the pre requisites.

Installation (to build custom projects)

npm install blessed blessed-contrib

Usage

You can use any of the default widgets of blessed (texts, lists and etc) or the widgets added in blessed-contrib (described below). A layout is optional but useful for dashboards. The widgets in blessed-contrib follow the same usage pattern:

   var blessed = require('blessed')
     , contrib = require('blessed-contrib')
     , screen = blessed.screen()
     , line = contrib.line(
         { style:
           { line: "yellow"
           , text: "green"
           , baseline: "black"}
         , xLabelPadding: 3
         , xPadding: 5
         , label: 'Title'})
     , data = {
         x: ['t1', 't2', 't3', 't4'],
         y: [5, 1, 7, 5]
      }
   screen.append(line) //must append before setting data
   line.setData([data])

   screen.key(['escape', 'q', 'C-c'], function(ch, key) {
     return process.exit(0);
   });

   screen.render()

See below for a complete list of widgets.

Widgets

Line Chart

Bar Chart

Stacked Bar Chart

Map

Gauge

Stacked Gauge

Donut

LCD Display

Rolling Log

Picture

Sparkline

Table

Tree

Markdown

Line Chart

line

   var line = contrib.line(
         { style:
           { line: "yellow"
           , text: "green"
           , baseline: "black"}
         , xLabelPadding: 3
         , xPadding: 5
         , showLegend: true
         , wholeNumbersOnly: false //true=do not show fraction in y axis
         , label: 'Title'})
   var series1 = {
         title: 'apples',
         x: ['t1', 't2', 't3', 't4'],
         y: [5, 1, 7, 5]
      }
   var series2 = {
         title: 'oranges',
         x: ['t1', 't2', 't3', 't4'],
         y: [2, 1, 4, 8]
      }
   screen.append(line) //must append before setting data
   line.setData([series1, series2])

Examples: simple line chart, multiple lines, 256 colors

Bar Chart

bar

    var bar = contrib.bar(
       { label: 'Server Utilization (%)'
       , barWidth: 4
       , barSpacing: 6
       , xOffset: 0
       , maxHeight: 9})
    screen.append(bar) //must append before setting data
    bar.setData(
       { titles: ['bar1', 'bar2']
       , data: [5, 10]})

Stacked Bar Chart

stacked-bar

    bar = contrib.stackedBar(
       { label: 'Server Utilization (%)'
       , barWidth: 4
       , barSpacing: 6
       , xOffset: 0
       //, maxValue: 15
       , height: "40%"
       , width: "50%"
       , barBgColor: [ 'red', 'blue', 'green' ]})
    screen.append(bar)
    bar.setData(
       { barCategory: ['Q1', 'Q2', 'Q3', 'Q4']
       , stackedCategory: ['US', 'EU', 'AP']
       , data:
          [ [ 7, 7, 5]
          , [8, 2, 0]
          , [0, 0, 0]
          , [2, 3, 2] ]
       })

Map

map

   var map = contrib.map({label: 'World Map'})
   map.addMarker({"lon" : "-79.0000", "lat" : "37.5000", color: "red", char: "X" })

Gauge

gauge

   var gauge = contrib.gauge({label: 'Progress', stroke: 'green', fill: 'white'})
   gauge.setPercent(25)

Stacked Gauge

stackedgauge

Either specify each stacked portion with a percent and stroke...

   var gauge = contrib.gauge({label: 'Stacked '})
   gauge.setStack([{percent: 30, stroke: 'green'}, {percent: 30, stroke: 'magenta'}, {percent: 40, stroke: 'cyan'}])

Or, you can just supply an array of numbers and random colors will be chosen.

   var gauge = contrib.gauge({label: 'Stacked Progress'})
   gauge.setStack([30,30,40])

Donut

donut

   var donut = contrib.donut({
	label: 'Test',
	radius: 8,
	arcWidth: 3,
	remainColor: 'black',
	yPadding: 2,
	data: [
	  {percent: 80, label: 'web1', color: 'green'}
	]
  });

Data passed in uses percent and label to draw the donut graph. Color is optional and defaults to green.

   donut.setData([
   	{percent: 87, label: 'rcp','color': 'green'},
	{percent: 43, label: 'rcp','color': 'cyan'},
   ]);

Updating the donut is as easy as passing in an array to setData using the same array format as in the constructor. Pass in as many objects to the array of data as you want, they will automatically resize and try to fit. However, please note that you will still be restricted to actual screen space.

You can also hardcode a specific numeric into the donut's core display instead of the percentage by passing an percentAltNumber property to the data, such as:

   var donut = contrib.donut({
	label: 'Test',
	radius: 8,
	arcWidth: 3,
	remainColor: 'black',
	yPadding: 2,
	data: [
	  {percentAltNumber: 50, percent: 80, label: 'web1', color: 'green'}
	]
  });

See an example of this in one of the donuts settings on ./examples/donut.js.

LCD Display

lcd

   var lcd = contrib.lcd(
     { segmentWidth: 0.06 // how wide are the segments in % so 50% = 0.5
     , segmentInterval: 0.11 // spacing between the segments in % so 50% = 0.550% = 0.5
     , strokeWidth: 0.11 // spacing between the segments in % so 50% = 0.5
     , elements: 4 // how many elements in the display. or how many characters can be displayed.
     , display: 321 // what should be displayed before first call to setDisplay
     , elementSpacing: 4 // spacing between each element
     , elementPadding: 2 // how far away from the edges to put the elements
     , color: 'white' // color for the segments
     , label: 'Storage Remaining'})
	lcd.setDisplay(23 + 'G'); // will display "23G"
	lcd.setOptions({}) // adjust options at runtime

Please see the examples/lcd.js for an example. The example provides keybindings to adjust the segmentWidth and segmentInterval and strokeWidth in real-time so that you can see how they manipulate the look and feel.

Rolling Log

log

   var log = contrib.log(
      { fg: "green"
      , selectedFg: "green"
      , label: 'Server Log'})
   log.log("new log line")

Picture

(Also check the new blessed image implementation which has several benefits over this one.)

log

    var pic = contrib.picture(
       { file: './flower.png'
       , cols: 25
       , onReady: ready})
    function ready() {screen.render()}

note: only png images are supported

Sparkline

spark

   var spark = contrib.sparkline(
     { label: 'Throughput (bits/sec)'
     , tags: true
     , style: { fg: 'blue' }})

   sparkline.setData(
   [ 'Sparkline1', 'Sparkline2'],
   [ [10, 20, 30, 20]
   , [40, 10, 40, 50]])

Table

table

   var table = contrib.table(
     { keys: true
     , fg: 'white'
     , selectedFg: 'white'
     , selectedBg: 'blue'
     , interactive: true
     , label: 'Active Processes'
     , width: '30%'
     , height: '30%'
     , border: {type: "line", fg: "cyan"}
     , columnSpacing: 10 //in chars
     , columnWidth: [16, 12, 12] /*in chars*/ })

   //allow control the table with the keyboard
   table.focus()

   table.setData(
   { headers: ['col1', 'col2', 'col3']
   , data:
      [ [1, 2, 3]
      , [4, 5, 6] ]})

Tree

table

   var tree = contrib.tree({fg: 'green'})

   //allow control the table with the keyboard
   tree.focus()

   tree.on('select',function(node){
     if (node.myCustomProperty){
       console.log(node.myCustomProperty);
     }
     console.log(node.name);
   }

   // you can specify a name property at root level to display root
   tree.setData(
   { extended: true
   , children:
     {
       'Fruit':
       { children:
         { 'Banana': {}
         , 'Apple': {}
         , 'Cherry': {}
         , 'Exotics': {
             children:
             { 'Mango': {}
             , 'Papaya': {}
             , 'Kiwi': { name: 'Kiwi (not the bird!)', myCustomProperty: "hairy fruit" }
             }}
         , 'Pear': {}}}
     , 'Vegetables':
       { children:
         { 'Peas': {}
         , 'Lettuce': {}
         , 'Pepper': {}}}}})

Options

  • keys : Key to expand nodes. Default : ['enter','default']
  • extended : Should nodes be extended/generated by default? Be careful with this setting when using a callback function. Default : false
  • template :
    • extend : Suffix "icon" for closed node. Default : '[+]'
    • retract : Suffix "icon" for opened node. Default : '[-]'
    • lines : Show lines in tree. Default : true

Nodes

Every node is a hash and it can have custom properties that can be used in "select" event callback. However, there are several special keys :

  • name
    • Type : string
    • Desc : Node name
    • If the node isn't the root and you don't specify the name, will be set to hash key
    • Example : { name: 'Fruit'}
  • children
    • Type : hash or function(node){ return children }
    • Desc : Node children.
    • The function must return a hash that could have been used as children property
    • If you use a function, the result will be stored in node.childrenContent and children
    • Example :
      • Hash : {'Fruit':{ name: 'Fruit', children:{ 'Banana': {}, 'Cherry': {}}}}
      • Function : see examples/explorer.js
  • childrenContent
    • Type : hash
    • Desc : Children content for internal usage DO NOT MODIFY
    • If node.children is a hash, node.children===node.childrenContent
    • If node.children is a function, it's used to store the node.children() result
    • You can read this property, but you should never write it.
    • Usually this will be used to check if(node.childrenContent) in your node.children function to generate children only once
  • extended
    • Type : boolean
    • Desc : Determine if this node is extended
    • No effect when the node have no child
    • Default value for each node will be treeInstance.options.extended if the node extended option is not set
    • Example : {'Fruit':{ name: 'Fruit', extended: true, children:{ 'Banana': {}, 'Cherry': {}}}}

Markdown

table

   var markdown = contrib.markdown()
   markdown.setMarkdown('# Hello \n blessed-contrib renders markdown using `marked-terminal`')

Colors

You can use 256 colors (source):

  function randomColor() {
    return [Math.random() * 255,Math.random()*255, Math.random()*255]
  }

  line = contrib.line(
  {
    ...
    , style: { line: randomColor(), text: randomColor(), baseline: randomColor() }
  })

Layouts

Grid

Carousel

Grid

A grid layout can auto position your elements in a grid layout. When using a grid, you should not create the widgets, rather specify to the grid which widget to create and with which params. Each widget can span multiple rows and columns.

   var screen = blessed.screen()

   var grid = new contrib.grid({rows: 12, cols: 12, screen: screen})

   //grid.set(row, col, rowSpan, colSpan, obj, opts)
   var map = grid.set(0, 0, 4, 4, contrib.map, {label: 'World Map'})
   var box = grid.set(4, 4, 4, 4, blessed.box, {content: 'My Box'})

   screen.render()

Carousel

A carousel layout switches between different views based on time or keyboard activity. One use case is an office dashboard with rotating views:

    var blessed = require('blessed')
      , contrib = require('./')
      , screen = blessed.screen()

    function page1(screen) {
       var map = contrib.map()
       screen.append(map)
    }

    function page2(screen) {
      var line = contrib.line(
       { width: 80
       , height: 30
       , left: 15
       , top: 12
       , xPadding: 5
       , label: 'Title'
       })

      var data = [ { title: 'us-east',
                 x: ['t1', 't2', 't3', 't4'],
                 y: [0, 0.0695652173913043, 0.11304347826087, 2],
                 style: {
                  line: 'red'
                 }
               }
            ]

      screen.append(line)
      line.setData(data)
    }

    screen.key(['escape', 'q', 'C-c'], function(ch, key) {
      return process.exit(0);
    });

    var carousel = new contrib.carousel( [page1, page2]
                                       , { screen: screen
                                         , interval: 3000 //how often to switch views (set 0 to never swicth automatically)
                                         , controlKeys: true  //should right and left keyboard arrows control view rotation
                                         })
    carousel.start()

Samples

Terminal Dashboard

term

Running the sample

git clone https://github.com/yaronn/blessed-contrib.git
cd blessed-contrib
npm install
node ./examples/dashboard.js

Installation (for a custom dashboard)

npm install blessed
npm install blessed-contrib

A simple dashboard

   var blessed = require('blessed')
     , contrib = require('blessed-contrib')
     , screen = blessed.screen()
     , grid = new contrib.grid({rows: 1, cols: 2, screen: screen})

   var line = grid.set(0, 0, 1, 1, contrib.line,
     { style:
       { line: "yellow"
       , text: "green"
       , baseline: "black"}
     , xLabelPadding: 3
     , xPadding: 5
     , label: 'Stocks'})

   var map = grid.set(0, 1, 1, 1, contrib.map, {label: 'Servers Location'})

   var lineData = {
      x: ['t1', 't2', 't3', 't4'],
      y: [5, 1, 7, 5]
   }

   line.setData([lineData])

   screen.key(['escape', 'q', 'C-c'], function(ch, key) {
     return process.exit(0);
   });

   screen.render()

Rich dashboard

See source code

Troubleshooting

If you see questions marks or some (or all) missign characters try running with these env vars to fix encoding / terminal:

    $> LANG=en_US.utf8 TERM=xterm-256color node your-code.js 

License

This library is under the MIT License

More Information

Created by Yaron Naveh (twitter, blog)

Comments
  • Cannot use 256 colors in donuts widget.

    Cannot use 256 colors in donuts widget.

    As far as I can tell, you can only use 8 colors when drawing with drawille.

    I can try and contribute to the repo so it supports 256 colors, but I cannot find the github repo for drawille-canvas-blessed-contrib.

    If you tell me I can have a look and get more colors out of the canvas.

    Cheers.

    opened by mvaladas 15
  • TypeError: Cannot read property 'width' of null

    TypeError: Cannot read property 'width' of null

    Hi. When i try to create ListTable in grid, application crashing with that error. ba0bxljc14r7my

    var accountList = mainGrid.set(1, 16, 6, 9, blessed.ListTable, {
        label: "Loaded Acounts",
        keys: true,
        fg: "white",
        selectedFg: "white",
        selectedBg: "blue",
        interactive: true,
        border: {type: "line", fg: "cyan"},
        scrollable: true
    });
    
    accountList.setData({
        headers: ["Login", "Password"],
        data: [["asdasd", "asdasd"], ["asdd", "asda"]]
    });
    

    How fix that problem? Maybe i do something wrong?

    opened by evsign 13
  • Lines with callbacks

    Lines with callbacks

    What do you think about modifying the syntax of a line to take an optional callback and interval values?The callback would be function() --> [labels_arr, values_arr]. This would be wrapped in a function to call it and use the return value to call setData. This wrapper would be setImmediate and setInterval.

    opened by flatiron32 10
  • Fix line chart y-axis decimal logic

    Fix line chart y-axis decimal logic

    Overview

    Currently, the formatYLabel function only incorporates the maxY option when calculating if decimal places should be shown for y-axis labels. This works fine for most cases, but presents a problem if both minY and maxY options are present.

    For example: If minY = 100 and maxY = 101, it is impossible for the y-axis labels to show decimals (100.25, 100.50, etc). It will always just round to the nearest whole number, which in this case, would be undesirable.

    This PR, updates the logic so that the example above works as expected (i.e. shows decimals for y-axis labels) without breaking existing functionality.

    Changes

    • Added logic to the formatYLabel function to incorporate the minY option when calculating fixed decimal places.
    bug 
    opened by larsonjj 8
  • Releasing an updated npm package version

    Releasing an updated npm package version

    @yaronn thanks for inviting me to the project ❤️

    can you also invite me to the npmjs project at https://www.npmjs.com/package/blessed-contrib with publish access so I can release new versions with the updates we added to the github repo?

    My npmjs user is lirantal

    opened by lirantal 6
  • About encoding problems

    About encoding problems

    Hi,

    Thanks for the great work, but it seems to have some encoding problems, when I set the table label to:

    table = contrib.table({
            label : '你好',
        })
    

    It just didn't display as it should be, any ideas? Thanks.

    opened by hustcer 6
  • For lines xPadding should be dynamic based on maxY

    For lines xPadding should be dynamic based on maxY

    If I have Y values greater than 4 chars wide, I have to manually override the padding to get the values to appear correctly. I should be able to set the y values and let blessed-contrib do the work for me.

    opened by flatiron32 6
  • Upgrade picture-tube to v1.0.0

    Upgrade picture-tube to v1.0.0

    To fix the future charm memory leak bug, which will cause the contrib.picture.setImage got the follow error after be called multiple times(after 11 times):

    (node:20914) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 ^C listeners added. Use emitter.setMaxListeners() to increase limit
    MaxListenersExceededWarning
    Possible EventEmitter memory leak detected. 11 ^C listeners added. Use emitter.setMaxListeners() to increase limit
    MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 ^C listeners added. Use emitter.setMaxListeners() to increase limit
        at _addListener (events.js:281:19)
        at Charm.addListener [(events.js:298:10)](url)
        at Charm.once (events.js:342:8)
        at module.exports (/home/zixia/git/node-facenet/node_modules/picture-tube/node_modules/charm/index.js:45:11)
        at module.exports (/home/zixia/git/node-facenet/node_modules/picture-tube/index.js:13:13)
        at Picture.setImage (/home/zixia/git/node-facenet/node_modules/blessed-contrib/lib/widget/picture.js:31:14)
        at Promise (/home/zixia/git/node-facenet/bin/manager.contrib.ts:222:13)
        at Promise (<anonymous>)
        at /home/zixia/git/node-facenet/bin/manager.contrib.ts:221:10
        at Generator.next (<anonymous>)
    

    See:

    1. https://github.com/substack/node-charm/issues/34
    2. https://github.com/substack/picture-tube/pull/11
    opened by huan 5
  • zoom in to see the difference between big numbers in line chart

    zoom in to see the difference between big numbers in line chart

    Hi,

    it would be nice to have an auto zoom option.

    I have numbers betweeen 2000 and 2050 and I can not see any difference between them in the line chart. Even if I set the minY option to 2000 I have a maxY value of 2760 and a horizontal line near the beaseline.

    I suggest to provide to new option: autoZoom: { enabled: true, paddingBottom: 10, // minY is set to the min value of the provided numbers - 10 paddingTop: 10 // maxY is set to the max value of the provided numbers - 10 }

    Is this a good idea or do you have a better one to solve my problem. Maybe I missed an option.

    Regards, Simon

    opened by SimonMonecke 5
  • License?

    License?

    Noticed there is no license on this -- any plans for what direction you might take there?

    As it stands it's ambiguous if one could even use it for private stuff.

    opened by brycebaril 5
  • Broken dependency

    Broken dependency "marked-terminal" + "marked" when using `strict-peer-dependencies`

    After installing in a downstream package, I just now started receiving a peer dependency error:

    blessed-contrib: [email protected] requires a peer of marked@^1.0.0 || ^2.0.0 but version 0.7.0 was installed.
    

    package.json:

    https://github.com/yaronn/blessed-contrib/blob/master/package.json#L35

    causal upstream commit:

    https://github.com/mikaelbr/marked-terminal/commit/abba40b6d0150c591ca92a6ec70c5c0103c41a4a#diff-7ae45ad102eab3b6d7e7896acd08c427a9b25b346470d7bc6507b6481575d519

    The marked-terminal requires a peer dependency of "marked": "^1.x.x || ^2.x.x", whereas blessed-contrib is only installing "marked": "^0.x.x"

    image

    Not a problem if not using strict-peer-dependencies but for projects that require this (for whatever reason) it makes it FAIL instead of WARN which blocks installation of fastify-cli.

    image

    opened by prescience-data 4
  • Crashes with error in terminal

    Crashes with error in terminal

    I'm running this on the lastest release of Ubuntu, and when I type node ./examples/dashboard.js I get the following error with a program termination.

    internal/modules/cjs/loader.js:818 throw err; ^

    Error: Cannot find module 'node:process' Require stack:

    • /home/aknight2015/Programs/blessed-contrib/node_modules/marked-terminal/index.cjs
    • /home/aknight2015/Programs/blessed-contrib/lib/widget/markdown.js
    • /home/aknight2015/Programs/blessed-contrib/index.js
    • /home/aknight2015/Programs/blessed-contrib/examples/dashboard.js at Function.Module._resolveFilename (internal/modules/cjs/loader.js:815:15) at Function.Module._load (internal/modules/cjs/loader.js:667:27) at Module.require (internal/modules/cjs/loader.js:887:19) at require (internal/modules/cjs/helpers.js:74:18) at Object. (/home/aknight2015/Programs/blessed-contrib/node_modules/marked-terminal/index.cjs:3:17) at Module._compile (internal/modules/cjs/loader.js:999:30) at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10) at Module.load (internal/modules/cjs/loader.js:863:32) at Function.Module._load (internal/modules/cjs/loader.js:708:14) at Module.require (internal/modules/cjs/loader.js:887:19) { code: 'MODULE_NOT_FOUND', requireStack: [ '/home/aknight2015/Programs/blessed-contrib/node_modules/marked-terminal/index.cjs', '/home/aknight2015/Programs/blessed-contrib/lib/widget/markdown.js', '/home/aknight2015/Programs/blessed-contrib/index.js', '/home/aknight2015/Programs/blessed-contrib/examples/dashboard.js' ] }
    opened by aknight2015 0
  • Does Blessed Contrib Support HyperLinks?

    Does Blessed Contrib Support HyperLinks?

    I'm looking to render some markdown with terminal hyperlinks in blessed. I'm wondering if the markdown module in blessed-contrib allows the addition of terminal hyperlinks...

    opened by zach-is-my-name 0
  • [Bug] Property 'setData' in type 'BarElement' is not assignable to the same property in base type 'CanvasElement<BarData>'.

    [Bug] Property 'setData' in type 'BarElement' is not assignable to the same property in base type 'CanvasElement'.

    Fresh install of blessed and blessed-contrib.

    Typescript v4.6.3

    Duplicate of #208, which was closed by original poster without clear justification.

    The error presents itself with my original tsconfig.json:

    {
      "compilerOptions": {
        "target": "es2015",
        "module": "commonjs",
        "outDir": "./dist",
        "noImplicitAny": true,
        "sourceMap": true,
        "esModuleInterop": true,
        "resolveJsonModule": true
      },
      "include": [
        "./src/main.ts"
      ],
      "exclude": [
        "node_modules",
        "dist"
      ]
    }
    

    Per #208, their new tsconfig set compilerOptions.skipLibCheck to true - this does not fix the issue, but hides it by not type checking the type declaration. Adding the flag allows it to compile; however, the types are still incorrect.

    The full error I get:

    node_modules/blessed-contrib/index.d.ts:134:13 - error TS2416: Property 'setData' in type 'BarElement' is not assignable to the same property in base type 'CanvasElement<BarData>'.
      Type '(data: BarData) => void' is not assignable to type '{ (data: BarData): void; (titles: string[], data: BarData): void; }'.
        Types of parameters 'data' and 'titles' are incompatible.
          Type 'string[]' has no properties in common with type 'BarData'.
    
    134             setData(data: BarData): void;
                    ~~~~~~~
    
    node_modules/blessed-contrib/index.d.ts:277:13 - error TS2416: Property 'setData' in type 'GaugeElement' is not assignable to the same property in base type 'CanvasElement<any>'.
      Type '{ (percent: number[]): void; (percent: number): void; }' is not assignable to type '{ (data: any): void; (titles: string[], data: any): void; }'.
        Types of parameters 'percent' and 'titles' are incompatible.
          Type 'string[]' is not assignable to type 'number[]'.
            Type 'string' is not assignable to type 'number'.
    
    277             setData(percent: number[]): void;
                    ~~~~~~~
    
    node_modules/blessed-contrib/index.d.ts:278:13 - error TS2416: Property 'setData' in type 'GaugeElement' is not assignable to the same property in base type 'CanvasElement<any>'.
      Type '{ (percent: number[]): void; (percent: number): void; }' is not assignable to type '{ (data: any): void; (titles: string[], data: any): void; }'.
    
    278             setData(percent: number): void;
                    ~~~~~~~
    

    Seems to have been introduced in 4.8.21 via #206, which adds the parameter overload for CanvasElement.setData to accept non-generic string titles which introduces the type compatibility.

    Removing the overloaded function signature seems to resolve the errors without skipping type checks in the tsconfig. Perhaps instead fo changing the generic type, the SparklineElement class could implement a custom setData signature as a special case?

    opened by EagleLizard 0
  • [Feature Request] Grid as element

    [Feature Request] Grid as element

    I guess the title explains it all.

    I really was exited to see that this contribution of blessed has a grid. Then i was kinda disappointed to see it's not actually an element/widget and that it was global and didn't was re scalable. Having a additional grid element would be really useful.

    opened by QTPah 0
  • FreeMono font will not work for Windows 10 consoles

    FreeMono font will not work for Windows 10 consoles

    Therefore, it appears this no longer works with Windows 10, at least.

    The font will not appear in the Windows console prompt. There are some fonts that will never display despite being correctly added to the registry. FreeMono is one of them that will not work with Windows 10.

    opened by astralis 1
Owner
Yaron Naveh
Yaron Naveh
A more compact and intuitive ASCII table in your terminal: an alternative to "man 7 ascii" and "ascii"

asciit A more compact and intuitive ASCII table in your terminal: an alternative to man 7 ascii and ascii. Colored numbers and letters are much more e

Qichen Liu 刘启辰 5 Nov 16, 2023
Build terminal user interfaces and dashboards using Rust

tui-rs tui-rs is a Rust library to build rich terminal user interfaces and dashboards. It is heavily inspired by the Javascript library blessed-contri

Florian Dehau 9.3k Jan 4, 2023
A CLI utility installed as "ansi" to quickly get ANSI escape sequences. Supports the most basic ones, like colors and styles as bold or italic.

'ansi' - a CLI utility to quickly get ANSI escape codes This Rust project called ansi-escape-sequences-cli provides an executable called ansi which ca

Philipp Schuster 5 Jul 28, 2022
Backend service to build customer facing dashboards 10x faster. Written in Rust.

Frolic is an open source backend service (written in Rust) to build customer facing dashboards 10x faster. You can directly connect your database to t

Frolic 82 Aug 7, 2023
Advanced image to ascii art fully created with rust 🦀 🚀

RASCII image to ascii art fully created with rust ?? ?? multiple language character lists -> ✔️ creatable custom char list -> ✔️ pixel art creaton ->

KoBruh 16 Dec 16, 2022
A simple CLI tool to convert the images to ASCII art with rust 🦀💙

aarty: A simple CLI tool to convert images to ASCII art with Rust ?? More screenshots Original image Original image Original image Original image Orig

Anas Elgarhy 26 Feb 13, 2023
API Client to Generate AI ASCII Art 🦾🧠

Charisma Charisma serves a purpose of being a bridge between Dall-e mini. It's used to generate ASCII Art directly from your terminal. It uses Craiyon

camel_case 3 Jul 23, 2023
A CLI tool that converts images to ASCII art.

Rust ASCII Art Converter This Rust tool converts images into ASCII art. It takes an image file as input, resizes it according to specified width and h

TheD24 133 Dec 3, 2023
Rust library for ANSI terminal colours and styles (bold, underline)

rust-ansi-term This is a library for controlling colours and formatting, such as red bold text or blue underlined text, on ANSI terminals. View the Ru

Benjamin Sago 407 Jan 2, 2023
A dead simple ANSI terminal color painting library for Rust.

yansi A dead simple ANSI terminal color painting library for Rust. use yansi::Paint; print!("{} light, {} light!", Paint::green("Green"), Paint::red(

Sergio Benitez 169 Dec 25, 2022
Terminal text styling via ANSI escape sequences.

Iridescent Features iridescent is a library for styling terminal text easily. It supports basic ANSI sequences, Xterm-256 colors, and RGB. You can ope

Rob 2 Oct 20, 2022
100% stream-based O(n) syntax highlighter for ANSI terminal

Lex-highlighter 100% stream-based $\mathcal O(n)$ syntax highlighter for ANSI terminal Warning This is proof-of-concept implementation and WON't be co

Abiria 10 Nov 17, 2023
rusty-donut - ASCII raymarching inside a terminal

ASCII raymarching inside a terminal

drip 14 Feb 9, 2022
ADPlay (ASCII-Drip Play): Pics on your terminal

ADPlay ADPlay (ASCII-Drip play): Graphic content on your terminal (works better on pixel arts) Build Build bin and install dependencies: cargo build -

Sofiane H. Djerbi 26 Oct 7, 2022
Rust library to convert RGB 24-bit colors into ANSI 256 (8-bit) color codes with zero dependencies and at compile-time.

rgb2ansi256 rgb2ansi256 is a small Rust library to convert RGB 24-bit colors into ANSI 256 (8-bit) color codes with zero dependencies and const fn. Th

Linda_pp 7 Nov 17, 2022
Rust crate to enable ANSI escape code support on Windows.

enable-ansi-support: Enable ANSI escape code support on Windows 10 About This crate provides one function, enable_ansi_support, which allows ANSI esca

Rain 9 Nov 18, 2022
convert images to ansi or irc, with a bunch of post-processing filters

img2irc (0.2.0) img2irc is a utility which converts images to halfblock irc/ansi art, with a lot of post-processing filters halfblock means that each

null 6 Apr 4, 2023
Tiny Rust library to draw pretty line graphs using ascii characters.

rasciigraph Tiny Rust library to draw pretty line graphs using ascii characters. Usage Add this to your Cargo.toml [dependencies] rasciigraph = "0.1.1

Orhan Balci 54 Jan 6, 2023
A Rust library for drawing grid-based user interfaces using ASCII characters.

grux A library for drawing grid-based user interfaces using ASCII characters. // Provides a uniform interface for drawing to a 2D grid. use grux::Grid

Matan Lurey 4 Jan 10, 2023