Skip to content
glyphcss

ASCII bar charts: categories, groups, and intervals

glyphChartBar(data, channels?, options?) defaults to vertical bars. The following sales-channel counts are illustrative.

                         Orders by sales channel                        
                                                                        
orders                                                                  
                                                                        
   │      ░░░                                                           
50 ┤      ░░░                                                           
   │   ▃▃▃░░░                                                           
40 ┤   ███░░░        ░░░                                                
   │   ███░░░     ▆▆▆░░░                               ░░░              
30 ┤   ███░░░     ███░░░        ░░░                 ███░░░        ░░░   
   │   ███░░░     ███░░░     ▆▆▆░░░         ░░░     ███░░░     ▃▃▃░░░   
20 ┤   ███░░░     ███░░░     ███░░░      ▅▅▅░░░     ███░░░     ███░░░   
   │   ███░░░     ███░░░     ███░░░      ███░░░     ███░░░     ███░░░   
10 ┤   ███░░░     ███░░░     ███░░░      ███░░░     ███░░░     ███░░░   
   │   ███░░░     ███░░░     ███░░░      ███░░░     ███░░░     ███░░░   
 0 └─────┬──────────┬──────────┬───────────┬──────────┬──────────┬──────
      Search     Direct      Email      Social     Partner      Ads     
             █  April                             ░  May                
Code
import { renderGlyphChart } from "@glyphcss/charts";

const { text } = renderGlyphChart({
  marks: [
    {
      type: "bar",
      data: [
        {
          channel: "Search",
          orders: 42,
          month: "April"
        },
        {
          channel: "Direct",
          orders: 34,
          month: "April"
        },
        {
          channel: "Email",
          orders: 24,
          month: "April"
        },
        {
          channel: "Social",
          orders: 18,
          month: "April"
        },
        {
          channel: "Partner",
          orders: 30,
          month: "April"
        },
        {
          channel: "Ads",
          orders: 22,
          month: "April"
        },
        {
          channel: "Search",
          orders: 55,
          month: "May"
        },
        {
          channel: "Direct",
          orders: 38,
          month: "May"
        },
        {
          channel: "Email",
          orders: 32,
          month: "May"
        },
        {
          channel: "Social",
          orders: 26,
          month: "May"
        },
        {
          channel: "Partner",
          orders: 36,
          month: "May"
        },
        {
          channel: "Ads",
          orders: 28,
          month: "May"
        }
      ],
      channels: {
        x: "channel",
        y: "orders",
        fill: "month"
      }
    }
  ],
  scales: {
    x: {
      type: "band"
    }
  },
  title: "Orders by sales channel"
}, {
  target: "chat",
  width: 72,
  height: 18
});
console.log(text);

Horizontal bars swap the channel roles: x is the numeric value and y is the category. Use a band y scale.

channel                                                     
                                                            
 Email ┤ ██████████████████████                             
       │                                                    
Direct ┤ ██████████████████████████████████                 
       │                                                    
Search ┤ ███████████████████████████████████████████████████
       └┬───────────┬───────────┬───────────┬────────────┬──
        0          10          20          30           40  
Code
import { renderGlyphChart } from "@glyphcss/charts";

const { text } = renderGlyphChart({
  marks: [
    {
      type: "bar",
      data: [
        {
          channel: "Search",
          orders: 42
        },
        {
          channel: "Direct",
          orders: 28
        },
        {
          channel: "Email",
          orders: 18
        }
      ],
      channels: {
        x: "orders",
        y: "channel"
      },
      options: {
        orientation: "horizontal"
      }
    }
  ],
  scales: {
    y: {
      type: "band"
    }
  },
  legend: false
}, {
  target: "chat",
  width: 60,
  height: 9
});
console.log(text);
import { glyphChartBar, renderGlyphChart } from "@glyphcss/charts";
const mark = glyphChartBar([
{ channel: "Search", orders: 42 },
{ channel: "Direct", orders: 28 },
{ channel: "Email", orders: 18 },
], { x: "orders", y: "channel" }, { orientation: "horizontal" });
const result = renderGlyphChart({ marks: [mark], scales: { y: { type: "band" } } }, { target: "chat" });

Bind fill to a category for grouped series. For stacked vertical bars set transform: { kind: "stack" } on the mark. Narrow grouped bands can overlap; check series-dodge-degraded in render notes.

Use x0 for the start and x for the end of a horizontal interval. These bars do not require a zero baseline. Horizontal bars take materialized rows and reject transforms.

task                                                        
                                                            
 Ship ┤                                            █████████
      │                                                     
 Test ┤                           █████████████████         
      │                                                     
Build ┤ ██████████████████████████                          
      └┬────────┬───────┬────────┬────────┬───────┬────────┬
       1        2       3        4        5       6        7
Code
import { renderGlyphChart } from "@glyphcss/charts";

const { text } = renderGlyphChart({
  marks: [
    {
      type: "bar",
      data: [
        {
          task: "Build",
          start: 1,
          end: 4
        },
        {
          task: "Test",
          start: 4,
          end: 6
        },
        {
          task: "Ship",
          start: 6,
          end: 7
        }
      ],
      channels: {
        x0: "start",
        x: "end",
        y: "task"
      },
      options: {
        orientation: "horizontal"
      }
    }
  ],
  scales: {
    y: {
      type: "band"
    }
  },
  legend: false
}, {
  target: "chat",
  width: 60,
  height: 9
});
console.log(text);

Intervals narrower than one cell become event dots and report bar-interval-collapsed. Use Mermaid Gantt for calendar dates and dependencies.