simple-ascii-chart
v4.2.0
Published
Simple ascii chart generator
Downloads
739
Maintainers
Readme
Simple ASCII Chart
Simple ASCII Chart is a TypeScript package for creating customizable ASCII charts in the terminal. It supports two-dimensional data, multiple series, custom colors, and formatters, making it a versatile solution for terminal-based data visualization.
Playground and documentation NPM
Installation
Install the package using yarn
(or npm
):
yarn add simple-ascii-chart
Usage
import plot from 'simple-ascii-chart';
const graph = plot(input, settings);
CLI
Playground
Create charts interactively in the playground.
API Endpoint
Generate charts via the API by sending a POST request with your input data:
curl -d input='[[1,2],[2,3],[3,4]]' -G https://simple-ascii-chart.vercel.app/api
Or pass it as a URL parameter:
https://simple-ascii-chart.vercel.app/api?input=[[1,2],[2,3],[3,4]]&settings={%22width%22:50}
Input Format
Input data should be a two-dimensional array of points or an array of arrays for multiple series:
type Point = [x: number, y: number];
type MaybePoint = Point | undefined | [number | undefined, number | undefined];
type SingleLine = Point[];
type MultiLine = SingleLine[];
type Input = SingleLine | MultiLine;
For a single series, use:
const input = [
[1, 1],
[2, 4],
[3, 40],
];
For multiple series, use:
const input = [
[
[0, 18],
[1, 1],
[2, 3],
],
[
[4, 1],
[5, 0],
[6, 1],
],
];
Detailed Input Parameters
Point
: A single point with x and y coordinates, represented as[x, y]
.MaybePoint
: Allows partial or undefined values within a point, accommodating incomplete data.SingleLine
: A series of connected points representing a single line.MultiLine
: A collection ofSingleLine
arrays for multiple data series.
Configuration (Settings)
Customize the plot
function with a variety of settings:
Available Settings
| Option | Description |
|------------------|---------------------------------------------------------------------------------------------------------------|
| color
| Colors for the graph. Options include 'ansiRed'
, 'ansiGreen'
, etc. Multiple colors are accepted for series. |
| width
| Sets the graph width. |
| height
| Sets the graph height. |
| axisCenter
| Specifies the center of the axis as [x, y]
, with default as bottom-left. |
| formatter
| A function to format axis labels, offering custom display styles. |
| lineFormatter
| Function to define custom styles for each line. |
| title
| Title of the chart, displayed above the graph. |
| xLabel
| Label for the x-axis. |
| yLabel
| Label for the y-axis. |
| thresholds
| Defines threshold lines or points with optional colors at specific x or y coordinates. |
| fillArea
| Fills the area under each line, suitable for area charts. |
| barChart
| Draws bar chart. |
| horizontalBarChart
| Draws horizontal bar chart. |
| hideXAxis
| Hides the x-axis. |
| hideYAxis
| Hides the y-axis. |
| symbols
| Symbols for customizing the chart’s appearance, including axis, background, and chart symbols. |
| legend
| Configuration for a legend, showing series names and position options (left
, right
, top
, bottom
). |
| debugMode
| Enables debug mode (default = false
). |
Advanced Settings
| Setting | Description |
|----------------------|-----------------------------------------------------------------------------------------------------------|
| yRange
| Specifies the y-axis range as [min, max]
. |
| showTickLabel
| Enables tick labels on the axis, improving readability for larger plots. |
| legend
| Configures legend display with position and series names, such as { position: 'top', series: ['Series 1', 'Series 2'] }
. |
| ColorGetter
| A function for dynamic color assignment based on series or coordinates. |
| axisCenter
| Sets a custom origin point for the chart, shifting the chart layout to focus around a particular point. |
| lineFormatter
| Customize each line using the format lineFormatter: (args: LineFormatterArgs) => CustomSymbol | CustomSymbol[]
. |
| formatterHelpers
| Provides helpers such as axis type and range for detailed formatting of axis labels. |
Symbols
Overrides default symbols. Three independent sections are: empty
- background, axis
- symbols used to draw axis, chart
- symbols used to draw graph.
symbols: {
background: ' ',
border: undefined,
empty: ' ',
axis: {
n: '▲',
ns: '│',
y: '┤',
nse: '└',
x: '┬',
we: '─',
e: '▶',
},
chart: {
we: '━',
wns: '┓',
ns: '┃',
nse: '┗',
wsn: '┛',
sne: '┏',
area: '█'
}
}
Summary
Settings = {
color?: Colors; // Colors for the plot lines or areas
width?: number; // Width of the plot
height?: number; // Height of the plot
yRange?: [number, number]; // Range of y-axis values
showTickLabel?: boolean; // Option to show tick labels on the axis
hideXAxis?: boolean; // Option to hide the x-axis
hideYAxis?: boolean; // Option to hide the y-axis
title?: string; // Title of the plot
xLabel?: string; // Label for the x-axis
yLabel?: string; // Label for the y-axis
thresholds?: Threshold[]; // Array of threshold lines or points
fillArea?: boolean; // Option to fill the area under lines
legend?: Legend; // Legend settings
axisCenter?: MaybePoint; // Center point for axes alignment
formatter?: Formatter; // Custom formatter for axis values
lineFormatter?: (args: LineFormatterArgs) => CustomSymbol | CustomSymbol[]; // Custom line formatter
symbols?: Symbols; // Custom symbols for chart elements
};
Examples
Simple Plot
Input:
plot(
[
[1, 1],
[2, 4],
[3, 4],
[4, 2],
[5, -1],
],
{ width: 9, height: 6 },
);
Expected Output:
▲
4┤ ┏━━━┓
│ ┃ ┃
2┤ ┃ ┗━┓
1┤━┛ ┃
│ ┃
-1┤ ┗━
└┬─┬─┬─┬─┬▶
1 2 3 4 5
Plot with Title and Custom Size
Input:
plot(
[
[1, 1],
[2, 4],
[3, 4],
[4, 2],
[5, -1],
[6, 3],
[7, -1],
[8, 9],
],
{ title: 'Important data', width: 20, height: 8 },
);
Expected Output:
Important data
▲
9┤ ┏━
│ ┃
│ ┃
4┤ ┏━━━━┓ ┃
3┤ ┃ ┃ ┏━┓ ┃
2┤ ┃ ┗━━┓ ┃ ┃ ┃
1┤━━┛ ┃ ┃ ┃ ┃
-1┤ ┗━━┛ ┗━━┛
└┬──┬─┬──┬──┬──┬─┬──┬▶
1 2 3 4 5 6 7 8
Plot with Axis Labels
Input:
plot(
[
[1, 1],
[2, 4],
[3, 4],
[4, 2],
[5, -1],
[6, 3],
[7, -1],
[8, 9],
],
{ xLabel: 'x', yLabel: 'y', width: 20, height: 8 },
);
Expected Output:
▲
9┤ ┏━
│ ┃
│ ┃
4┤ ┏━━━━┓ ┃
3┤ ┃ ┃ ┏━┓ ┃
y 2┤ ┃ ┗━━┓ ┃ ┃ ┃
1┤━━┛ ┃ ┃ ┃ ┃
-1┤ ┗━━┛ ┗━━┛
└┬──┬─┬──┬──┬──┬─┬──┬▶
1 2 3 4 5 6 7 8
x
Plot with colors
Input:
plot(
[
[
[1, 1],
[2, 2],
[3, 4],
[4, 6],
],
[
[5, 4],
[6, 1],
[7, 2],
[8, 3],
],
],
{
width: 20,
fillArea: true,
color: ['ansiGreen', 'ansiBlue'],
legend: { position: 'bottom', series: ['first', 'second'] },
},
);
Expected Output:
▲
6┤ ██
│ ██
4┤ █████ ███
3┤ █████ ███ ██
2┤ ███████ ███ █████
1┤█████████ █████████
└┬──┬─┬──┬──┬──┬─┬──┬▶
1 2 3 4 5 6 7 8
█ first
█ second
Plot with borders
Input:
plot(
[
[1, 1],
[2, 4],
[3, 4],
[4, 2],
[5, -1],
[6, 3],
[7, -1],
[8, 9],
],
{ symbols: { border: '█' }, xLabel: 'x', yLabel: 'y', width: 20, height: 8 },
);
Expected Output:
███████████████████████████
█ ▲ █
█ 9┤ ┏━ █
█ │ ┃ █
█ │ ┃ █
█ 4┤ ┏━━━━┓ ┃ █
█ 3┤ ┃ ┃ ┏━┓ ┃ █
█y 2┤ ┃ ┗━━┓ ┃ ┃ ┃ █
█ 1┤━━┛ ┃ ┃ ┃ ┃ █
█ -1┤ ┗━━┛ ┗━━┛ █
█ └┬──┬─┬──┬──┬──┬─┬──┬▶█
█ 1 2 3 4 5 6 7 8 █
█ x █
███████████████████████████
Plot with filled area
Input:
plot(
[
[
[1, 1],
[2, 2],
[3, 4],
[4, 6],
],
[
[1, 4],
[2, 1],
[3, 2],
[4, 3],
],
],
{
fillArea: true,
color: ['ansiGreen', 'ansiBlue'],
},
);
Expected Output:
▲
6┤ ██
│ ██
4┤████
3┤████
2┤████
1┤████
└┬┬┬┬▶
1234
Scaled up plot
Input:
plot(
[
[1, 1],
[2, 4],
[3, 40],
[4, 2],
[5, -1],
[6, 3],
[7, -1],
[8, -1],
[9, 9],
[10, 9],
],
{ width: 40, height: 10 },
);
Expected Output:
▲
40┤ ┏━━━┓
│ ┃ ┃
│ ┃ ┃
│ ┃ ┃
│ ┃ ┃
│ ┃ ┃
│ ┃ ┃
9┤ ┃ ┃ ┏━━━━━
3┤ ┏━━━━┛ ┗━━━┓ ┏━━━┓ ┃
-1┤━━━┛ ┗━━━━┛ ┗━━━━━━━━┛
└┬───┬────┬───┬───┬────┬───┬───┬────┬───┬▶
1 2 3 4 5 6 7 8 9 10
Add thresholds
Input:
plot(
[
[1, 1],
[2, 4],
[3, 4],
[4, 2],
[5, -1],
[6, 3],
[7, -1],
[8, 9],
],
{
width: 40,
thresholds: [
{
y: 5,
x: 5,
},
{
x: 2,
},
],
},
);
Expected Output:
▲ ┃ ┃
9┤ ┃ ┃ ┏━
│ ┃ ┃ ┃
│ ┃ ┃ ┃
│━━━━━┃━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
│ ┃ ┃ ┃
4┤ ┃━━━━━━━━━━┓ ┃ ┃
3┤ ┃ ┃ ┃ ┏━━━━┓ ┃
2┤ ┃ ┗━━━━┃ ┃ ┃ ┃
1┤━━━━━┃ ┃ ┃ ┃ ┃
│ ┃ ┃ ┃ ┃ ┃
-1┤ ┃ ┃━━━━━┛ ┗━━━━━┛
└┬─────┬────┬─────┬────┬─────┬────┬─────┬▶
1 2 3 4 5 6 7 8
Multi-series plot
Input:
plot(
[
[
[0, 18],
[1, 1],
[2, 3],
[3, 11],
[4, 5],
[5, 16],
[6, 17],
[7, 14],
[8, 7],
[9, 4],
],
[
[0, 0],
[1, 1],
[2, 1],
[3, 1],
[4, 1],
[5, 0],
[6, 1],
[7, 0],
[8, 1],
[9, 0],
],
],
{ width: 40, height: 10, color: ['ansiBlue', 'ansiGreen'] },
);
Expected Output:
▲
17┤━━━━┓ ┏━━━━┓
16┤ ┃ ┏━━━━━┛ ┃
14┤ ┃ ┃ ┗━━━━━┓
11┤ ┃ ┏━━━━━┓ ┃ ┃
│ ┃ ┃ ┃ ┃ ┃
7┤ ┃ ┃ ┃ ┃ ┗━━━━┓
5┤ ┃ ┃ ┗━━━━┛ ┃
4┤ ┃ ┏━━━━┛ ┗━
1┤ ┏━━━━━━━━━━━━━━━━━━━━━┓ ┏━━━━┓ ┏━━━━┓
0┤━━━━┛ ┗━━━━━┛ ┗━━━━━┛ ┗━
└┬────┬─────┬────┬─────┬────┬─────┬────┬─────┬────┬▶
0 1 2 3 4 5 6 7 8 9
Plot with formatting applied
Input:
plot(
[
[
[0, -10],
[1, 0.001],
[2, 10],
[3, 200],
[4, 10000],
[5, 2000000],
[6, 50000000],
],
],
{
width: 30,
height: 20,
formatter: (n: number, { axis }: FormatterHelpers) => {
const labels = ['A', 'B', 'C', 'D', 'E', 'F', 'G'];
if (axis === 'y') return n;
return labels[n] || 'X';
},
},
);
Expected Output:
▲
50000000┤ ┏━
│ ┃
│ ┃
│ ┃
│ ┃
│ ┃
│ ┃
│ ┃
│ ┃
│ ┃
│ ┃
│ ┃
│ ┃
│ ┃
│ ┃
│ ┃
│ ┃
│ ┃
2000000┤ ┏━━━━┛
-10┤━━━━━━━━━━━━━━━━━━━━━━━┛
└┬────┬────┬────┬───┬────┬────┬▶
A B C D E F G
Plot with axis center
Input:
plot(
[
[
[-8, -8],
[-4, -4],
[-3, -3],
[-2, -2],
[-1, -1],
[0, 0],
[2, 2],
[3, 3],
[4, 4],
[8, 8],
],
],
{ width: 60, height: 20, axisCenter: [0, 0] },
);
Expected Output:
▲
8┤ ┏━
│ ┃
│ ┃
│ ┃
│ ┃
4┤ ┏━━━━━━━━━━━━━━┛
3┤ ┏━━┛
2┤ ┏━━━┛
│ ┃
┬──────────────┬──┬───┬───┬───0│─────────┬──┬──────────────┬─▶
-8 -4 -3 -2 -1 0│ 2 3 4 8
┏━━-1┤
┏━━━┛ -2┤
┏━━━┛ -3┤
┏━━┛ -4┤
┃ │
┃ │
┃ │
┃ │
━━━━━━━━━━━━━━┛ -8┤
│
Plot with custom symbols
Input:
plot(
[
[1, 2],
[2, 0],
[3, 5],
[4, 2],
[5, -2],
[6, 3],
],
{
symbols: {
empty: 'x',
empty: '-',
axis: {
n: 'A',
ns: 'i',
y: 't',
nse: 'o',
x: 'j',
we: 'm',
e: 'B',
},
chart: {
we: '1',
wns: '2',
ns: '3',
nse: '4',
wsn: '5',
sne: '6',
},
},
width: 40,
height: 10,
},
);
Expected Output:
xxA-----------------------------------------
x5t---------------61111112------------------
xxi---------------3------3------------------
xxi---------------3------3------------------
x3t---------------3------3---------------61-
x2t11111112-------3------411111112-------3--
xxi-------3-------3--------------3-------3--
x0t-------411111115--------------3-------3--
xxi------------------------------3-------3--
xxi------------------------------3-------3--
-2t------------------------------411111115--
xxojmmmmmmmjmmmmmmmjmmmmmmjmmmmmmmjmmmmmmmjB
xxx1xxxxxxx2xxxxxxx3xxxxxx4xxxxxxx5xxxxxxx6x
Plot without axis
Input:
plot(
[
[-5, 2],
[2, -3],
[13, 0.1],
[4, 2],
[5, -2],
[6, 12],
],
{
width: 40,
height: 10,
hideYAxis: true,
hideXAxis: true,
},
);
Expected Output:
┏━━━━━━━━━━━━━━┓
┃ ┃
┃ ┃
┃ ┃
┃ ┃
┃ ┃
━━━━━━━━━━━━━━┓ ┏━┓ ┃ ┃
┃ ┃ ┃ ┃ ┗━
┃ ┃ ┗━┛
┗━━━━┛
Plot with with large numbers
Input:
plot(
[
[-9000, 2000],
[-8000, -3000],
[-2000, -2000],
[2000, 2000],
[3000, 1500],
[4000, 5000],
[10000, 1400],
[11000, 20000],
[12000, 30000],
],
{
width: 60,
height: 20,
},
);
Expected Output:
▲
30k┤ ┏━
│ ┃
│ ┃
│ ┃
│ ┃
│ ┃
20k┤ ┏━━┛
│ ┃
│ ┃
│ ┃
│ ┃
│ ┃
│ ┃
│ ┃
5k┤ ┏━━━━━━━━━━━━━━━┓ ┃
│ ┃ ┃ ┃
1.4k┤━━┓ ┏━━━━━┛ ┗━━┛
│ ┃ ┃
-2k┤ ┃ ┏━━━━━━━━━━┛
-3k┤ ┗━━━━━━━━━━━━━━━━┛
└┬──┬────────────────┬──────────┬──┬──┬───────────────┬──┬──┬▶
-8k 2k 4k 11k
-9k -2k 3k 10k 12k
Plot with custom line format
Input:
plot(
[
[1, 0],
[2, 20],
[3, 29],
[4, 10],
[5, 3],
[6, 40],
[7, 0],
[8, 20],
],
{
height: 10,
width: 30,
lineFormatter: ({ y, plotX, plotY, input, index }) => {
const output = [{ x: plotX, y: plotY, symbol: '█' }];
if (input[index - 1]?.[1] < y) {
return [...output, { x: plotX, y: plotY - 1, symbol: '▲' }];
}
return [...output, { x: plotX, y: plotY + 1, symbol: '▼' }];
},
},
);
Expected Output:
▲ ▲
40┤ █
│ ▲
29┤ █
│ ▲ ▲
20┤ █ █
│
│
10┤ █
3┤ ▼ █
0┤█ ▼ █
└┬───┬───┬───┬────┬───┬───┬───┬▶
1 2 3 4 5 6 7 8
Bar chart
Input:
plot(
[
[0, 3],
[1, 2],
[2, 3],
[3, 4],
[4, -2],
[5, -5],
[6, 2],
[7, 0],
],
{
title: 'bar chart with axis',
barChart: true,
showTickLabel: true,
width: 40,
axisCenter: [0, 0],
},
);
Expected Output:
bar chart with axis
▲ █
4┤ █ █
3┤ █ █ █ █
2┤ █ █ █ █
1┤ █ █ █ █ █
0┤─────┬────┬─────┬────┬─────┬────┬─────┬─▶
-1┤ 1 2 3 4 5 6 7
-2┤ █
-3┤ █
-4┤ █
-5┤
│
Bar chart
Input:
plot(
[
[0, 3],
[1, 2],
[2, 3],
[3, 4],
[4, -2],
[5, -5],
[6, 2],
[7, 0],
],
{
horizontalBarChart: true,
showTickLabel: true,
width: 40,
height: 20,
axisCenter: [3, 1],
},
);
Expected Output:
▲
4┤
│
████████████████3┤
│
██████████2┤████████████████
│
┬─────┬────┬────1┤────┬─────┬────┬─────┬─▶
0 1 2 3 4 5 6 7
0┤██████████████████████
│
-1┤
│
-2┤
│█████
-3┤
│
-4┤
│
│
-5┤███████████
│