simple-ascii-chart-cli 1.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.
package/README.md ADDED
@@ -0,0 +1,1074 @@
1
+ # Simple ascii chart
2
+
3
+ ![NPM License](https://img.shields.io/npm/l/simple-ascii-chart)
4
+ ![NPM Version](https://img.shields.io/npm/v/simple-ascii-chart)
5
+ ![npm package minimized gzipped size (select exports)](https://img.shields.io/bundlejs/size/simple-ascii-chart)
6
+ ![Codecov](https://img.shields.io/codecov/c/github/gtktsc/ascii-chart)
7
+
8
+ **Simple ASCII Chart** is a TypeScript package that allows you to create ASCII charts in your terminal. It operates on two-dimensional input data, supports multiple series, custom colors, and formatters to make your data visualization clear and customizable.
9
+
10
+ [Interactive demo.](https://simple-ascii-chart.vercel.app/)
11
+
12
+ With colored multiline:
13
+
14
+ ![Example chart](https://user-images.githubusercontent.com/17948218/183446543-9a88e655-d83b-40f4-b7af-ffd8540380d2.png)
15
+
16
+ With colored area:
17
+
18
+ ![Views per iteration](https://user-images.githubusercontent.com/17948218/183447293-4feac74f-b3d1-4e26-a8c1-02d793d3e81b.png)
19
+
20
+ With axis:
21
+
22
+ ![Example chart with center position](https://user-images.githubusercontent.com/17948218/183447523-a0604d0c-eb22-451a-91c8-fb56eff039a7.png)
23
+
24
+ ## Usage
25
+
26
+ Package can be imported via yarn (or npm):
27
+
28
+ ```bash
29
+ yarn add simple-ascii-chart
30
+ ```
31
+
32
+ And used like:
33
+
34
+ ```typescript
35
+ import plot from 'simple-ascii-chart';
36
+
37
+ const graph = plot(input, settings);
38
+ ```
39
+
40
+ ## Playground
41
+
42
+ Alternatively, you can create a graph interactively in the [playground](https://simple-ascii-chart.vercel.app/).
43
+
44
+ ## API Endpoint
45
+
46
+ You can also use the API endpoint to generate charts by sending a POST request with your input data:
47
+
48
+ ```bash
49
+ curl -d input='[[1,2],[2,3],[3,4]]' -G https://simple-ascii-chart.vercel.app/api
50
+ ```
51
+
52
+ or as a URL parameter:
53
+
54
+ ```bash
55
+ https://simple-ascii-chart.vercel.app/api?input=[[1,2],[2,3],[3,4]]&settings={%22width%22:50}
56
+ ```
57
+
58
+ ## How to use it
59
+
60
+ When dependency is imported to project:
61
+
62
+ ```typescript
63
+ import plot from 'simple-ascii-chart';
64
+
65
+ console.log(
66
+ plot(
67
+ [
68
+ [1, 1],
69
+ [2, 4],
70
+ [3, 4],
71
+ [4, 2],
72
+ [5, -1],
73
+ [6, 3],
74
+ [7, -1],
75
+ [8, 9],
76
+ ],
77
+ { title: 'Important data', width: 20, height: 8 },
78
+ ),
79
+ );
80
+ ```
81
+
82
+ And 🎉, chart appears in your terminal:
83
+
84
+ ```bash
85
+ Important data
86
+
87
+ 9┤ ┏━
88
+ │ ┃
89
+ │ ┃
90
+ 4┤ ┏━━━━┓ ┃
91
+ 3┤ ┃ ┃ ┏━┓ ┃
92
+ 2┤ ┃ ┗━━┓ ┃ ┃ ┃
93
+ 1┤━━┛ ┃ ┃ ┃ ┃
94
+ -1┤ ┗━━┛ ┗━━┛
95
+ └┬──┬─┬──┬──┬──┬─┬──┬▶
96
+ 1 2 3 4 5 6 7 8
97
+ ```
98
+
99
+ ## Input
100
+
101
+ Input has to be a two dimensional array or array of arrays for series:
102
+
103
+ ```typescript
104
+ Point = [x: number, y: number];
105
+ SingleLine = Point[];
106
+ MultiLine = SingleLine[];
107
+
108
+ Input = SingleLine | MultiLine;
109
+ ```
110
+
111
+ Therefore input for a single series is:
112
+
113
+ ```typescript
114
+ const input = [
115
+ [1, 1],
116
+ [2, 4],
117
+ [3, 40],
118
+ ];
119
+ ```
120
+
121
+ Or for multi-series:
122
+
123
+ ```typescript
124
+ const input = [
125
+ [
126
+ [0, 18],
127
+ [1, 1],
128
+ [2, 3],
129
+ ],
130
+ [
131
+ [4, 1],
132
+ [5, 0],
133
+ [6, 1],
134
+ ],
135
+ ];
136
+ ```
137
+
138
+ ## Settings
139
+
140
+ Plot can be adjusted with a second parameter `settings`.
141
+
142
+ ### color
143
+
144
+ Changes graph color. Possible values are:
145
+
146
+ ```typescript
147
+ color?:
148
+ | 'ansiRed'
149
+ | 'ansiGreen'
150
+ | 'ansiBlack'
151
+ | 'ansiYellow'
152
+ | 'ansiBlue'
153
+ | 'ansiMagenta'
154
+ | 'ansiCyan'
155
+ | 'ansiWhite'
156
+ ```
157
+
158
+ Can be used to distinguish series like:
159
+
160
+ ```typescript
161
+ color: ['ansiGreen', 'ansiRed'];
162
+ ```
163
+
164
+ ### width
165
+
166
+ Changes default width of the graph, can be used to scale up/down values:
167
+
168
+ ```typescript
169
+ width?: number
170
+ ```
171
+
172
+ ### height
173
+
174
+ Changes default height of the graph, can be used to scale up/down values:
175
+
176
+ ```typescript
177
+ height?: number
178
+ ```
179
+
180
+ ### axisCenter
181
+
182
+ Changes center of the axis, by default it's placed in the bottom-left:
183
+
184
+ ```typescript
185
+ axisCenter?: [x:number, y:number]
186
+ ```
187
+
188
+ ### formatter
189
+
190
+ Transforms axis label:
191
+
192
+ ```typescript
193
+ formatter?: Formatter
194
+ ```
195
+
196
+ Where
197
+
198
+ ```typescript
199
+ type FormatterHelpers = {
200
+ axis: 'x' | 'y';
201
+ xRange: number[];
202
+ yRange: number[];
203
+ };
204
+
205
+ type Formatter = (number: number, helpers: FormatterHelpers) => number | string;
206
+ ```
207
+
208
+ Default formatter is:
209
+
210
+ ```typescript
211
+ defaultFormatter: Formatter = (value, { xRange, yRange }) => {
212
+ // Cut off small values
213
+ if (Math.abs(xRange[0]) < 1000 || Math.abs(yRange[0]) < 1000) {
214
+ return Number(value.toFixed(3));
215
+ }
216
+ // Adds XYZk to cut off large values
217
+ if (Math.abs(value) > 1000) return `${value / 1000}k`;
218
+ return value;
219
+ };
220
+ ```
221
+
222
+ ### lineFormatter
223
+
224
+ Transforms line, allows to format graph style. Callback takes arguments:
225
+
226
+ ```typescript
227
+ LineFormatterArgs = {
228
+ x: number;
229
+ y: number;
230
+ plotX: number;
231
+ plotY: number;
232
+ input: SingleLine;
233
+ index: number;
234
+ };
235
+ ```
236
+
237
+ `plotX` and `plotY` is coordinate of a point scaled to the plot. Callback has to return:
238
+
239
+ ```typescript
240
+ CustomSymbol = { x: number; y: number; symbol: string };
241
+ ```
242
+
243
+ where `x` and `y` is also plot coordinate, `symbol` is char to be displayed. If an array is returned, more points can be placed on the graph.
244
+
245
+ ```typescript
246
+ lineFormatter?: (args: LineFormatterArgs) => CustomSymbol | CustomSymbol[];
247
+ ```
248
+
249
+ Check examples section for real world usage.
250
+
251
+ ### title
252
+
253
+ Adds title above the graph:
254
+
255
+ ```typescript
256
+ title?: string;
257
+ ```
258
+
259
+ ### xLabel
260
+
261
+ Adds label to the x axis:
262
+
263
+ ```typescript
264
+ xLabe
265
+ l?: string;
266
+ ```
267
+
268
+ ### yLabel
269
+
270
+ Adds label to the y axis:
271
+
272
+ ```typescript
273
+ yLabel?: string;
274
+ ```
275
+
276
+ ### thresholds
277
+
278
+ Adds thresholds to plot:
279
+
280
+ ```typescript
281
+ thresholds?: {
282
+ x?: number;
283
+ y?: number;
284
+ color?: Color;
285
+ }[];
286
+ ```
287
+
288
+ ### fillArea
289
+
290
+ Some graphs look better presented as a area, not lines. In order to use area chart, pass fillArea prop:
291
+
292
+ ```typescript
293
+ fillArea?: boolean;
294
+ ```
295
+
296
+ ### hideXAxis
297
+
298
+ Hide X axis:
299
+
300
+ ```typescript
301
+ hideXAxis? boolean;
302
+ ```
303
+
304
+ ### hideYAxis
305
+
306
+ Hide Y axis:
307
+
308
+ ```typescript
309
+ hideYAxis? boolean;
310
+ ```
311
+
312
+ ### symbols
313
+
314
+ Overrides default symbols. Three independent sections are: `empty` - background, `axis` - symbols used to draw axis, `chart` - symbols used to draw graph.
315
+
316
+ ```typescript
317
+ symbols: {
318
+ background: ' ',
319
+ border: undefined,
320
+ empty: ' ',
321
+ axis: {
322
+ n: '▲',
323
+ ns: '│',
324
+ y: '┤',
325
+ nse: '└',
326
+ x: '┬',
327
+ we: '─',
328
+ e: '▶',
329
+ },
330
+ chart: {
331
+ we: '━',
332
+ wns: '┓',
333
+ ns: '┃',
334
+ nse: '┗',
335
+ wsn: '┛',
336
+ sne: '┏',
337
+ area: '█'
338
+ }
339
+ ```
340
+
341
+ ## Summary
342
+
343
+ ```typescript
344
+ Settings = {
345
+ color?: Color | Color[];
346
+ width?: number;
347
+ height?: number;
348
+ axisCenter?: [number, number];
349
+ formatter?: (number:number) => number;
350
+ lineFormatter?: (args: LineFormatterArgs) => CustomSymbol | CustomSymbol[];
351
+ hideXAxis?: boolean;
352
+ legend?: { position?: 'left' | 'right' | 'top' | 'bottom'; series: string | string[] };
353
+ title?: string;
354
+ xLabel?: string;
355
+ yLabel?: string;
356
+ fillArea?: boolean;
357
+ hideYAxis?: boolean;
358
+ thresholds?: {
359
+ x?: number;
360
+ y?: number;
361
+ color?: Color;
362
+ }[];
363
+ symbols?: {
364
+ background?: ' ',
365
+ border?: undefined,
366
+ empty?: ' ',
367
+ axis?: {
368
+ n: '▲',
369
+ ns: '│',
370
+ y: '┤',
371
+ nse: '└',
372
+ x: '┬',
373
+ we: '─',
374
+ e: '▶',
375
+ },
376
+ chart?: {
377
+ we: '━',
378
+ wns: '┓',
379
+ ns: '┃',
380
+ nse: '┗',
381
+ wsn: '┛',
382
+ sne: '┏',
383
+ area: '█',
384
+ }
385
+ }
386
+ };
387
+ ```
388
+
389
+ ## Examples
390
+
391
+ ### Simple plot
392
+
393
+ Input:
394
+
395
+ ```typescript
396
+ plot(
397
+ [
398
+ [1, 1],
399
+ [2, 4],
400
+ [3, 4],
401
+ [4, 2],
402
+ [5, -1],
403
+ ],
404
+ { width: 9, height: 6 },
405
+ );
406
+ ```
407
+
408
+ Output:
409
+
410
+ ```bash
411
+
412
+
413
+ 4┤ ┏━━━┓
414
+ │ ┃ ┃
415
+ 2┤ ┃ ┗━┓
416
+ 1┤━┛ ┃
417
+ │ ┃
418
+ -1┤ ┗━
419
+ └┬─┬─┬─┬─┬▶
420
+ 1 2 3 4 5
421
+ ```
422
+
423
+ ### Plot with title and defined size
424
+
425
+ Input:
426
+
427
+ ```typescript
428
+ plot(
429
+ [
430
+ [1, 1],
431
+ [2, 4],
432
+ [3, 4],
433
+ [4, 2],
434
+ [5, -1],
435
+ [6, 3],
436
+ [7, -1],
437
+ [8, 9],
438
+ ],
439
+ { title: 'Important data', width: 20, height: 8 },
440
+ );
441
+ ```
442
+
443
+ Output:
444
+
445
+ ```bash
446
+ Important data
447
+
448
+ 9┤ ┏━
449
+ │ ┃
450
+ │ ┃
451
+ 4┤ ┏━━━━┓ ┃
452
+ 3┤ ┃ ┃ ┏━┓ ┃
453
+ 2┤ ┃ ┗━━┓ ┃ ┃ ┃
454
+ 1┤━━┛ ┃ ┃ ┃ ┃
455
+ -1┤ ┗━━┛ ┗━━┛
456
+ └┬──┬─┬──┬──┬──┬─┬──┬▶
457
+ 1 2 3 4 5 6 7 8
458
+ ```
459
+
460
+ ### Plot with axis labels
461
+
462
+ Input:
463
+
464
+ ```typescript
465
+ plot(
466
+ [
467
+ [1, 1],
468
+ [2, 4],
469
+ [3, 4],
470
+ [4, 2],
471
+ [5, -1],
472
+ [6, 3],
473
+ [7, -1],
474
+ [8, 9],
475
+ ],
476
+ { xLabel: 'x', yLabel: 'y', width: 20, height: 8 },
477
+ );
478
+ ```
479
+
480
+ Output:
481
+
482
+ ```bash
483
+
484
+ 9┤ ┏━
485
+ │ ┃
486
+ │ ┃
487
+ 4┤ ┏━━━━┓ ┃
488
+ 3┤ ┃ ┃ ┏━┓ ┃
489
+ y 2┤ ┃ ┗━━┓ ┃ ┃ ┃
490
+ 1┤━━┛ ┃ ┃ ┃ ┃
491
+ -1┤ ┗━━┛ ┗━━┛
492
+ └┬──┬─┬──┬──┬──┬─┬──┬▶
493
+ 1 2 3 4 5 6 7 8
494
+ x
495
+ ```
496
+
497
+ ### Plot with colors
498
+
499
+ Input:
500
+
501
+ ```typescript
502
+ plot(
503
+ [
504
+ [
505
+ [1, 1],
506
+ [2, 2],
507
+ [3, 4],
508
+ [4, 6],
509
+ ],
510
+ [
511
+ [5, 4],
512
+ [6, 1],
513
+ [7, 2],
514
+ [8, 3],
515
+ ],
516
+ ],
517
+ {
518
+ width: 20,
519
+ fillArea: true,
520
+ color: ['ansiGreen', 'ansiBlue'],
521
+ legend: { position: 'bottom', series: ['first', 'second'] },
522
+ },
523
+ );
524
+ ```
525
+
526
+ Output:
527
+
528
+ ```bash
529
+
530
+ 6┤ ██
531
+ │ ██
532
+ 4┤ █████ ███
533
+ 3┤ █████ ███ ██
534
+ 2┤ ███████ ███ █████
535
+ 1┤█████████ █████████
536
+ └┬──┬─┬──┬──┬──┬─┬──┬▶
537
+ 1 2 3 4 5 6 7 8
538
+ █ first
539
+ █ second
540
+
541
+ ```
542
+
543
+ ### Plot with borders
544
+
545
+ Input:
546
+
547
+ ```typescript
548
+ plot(
549
+ [
550
+ [1, 1],
551
+ [2, 4],
552
+ [3, 4],
553
+ [4, 2],
554
+ [5, -1],
555
+ [6, 3],
556
+ [7, -1],
557
+ [8, 9],
558
+ ],
559
+ { symbols: { border: '█' }, xLabel: 'x', yLabel: 'y', width: 20, height: 8 },
560
+ );
561
+ ```
562
+
563
+ Output:
564
+
565
+ ```bash
566
+ ███████████████████████████
567
+ █ ▲ █
568
+ █ 9┤ ┏━ █
569
+ █ │ ┃ █
570
+ █ │ ┃ █
571
+ █ 4┤ ┏━━━━┓ ┃ █
572
+ █ 3┤ ┃ ┃ ┏━┓ ┃ █
573
+ █y 2┤ ┃ ┗━━┓ ┃ ┃ ┃ █
574
+ █ 1┤━━┛ ┃ ┃ ┃ ┃ █
575
+ █ -1┤ ┗━━┛ ┗━━┛ █
576
+ █ └┬──┬─┬──┬──┬──┬─┬──┬▶█
577
+ █ 1 2 3 4 5 6 7 8 █
578
+ █ x █
579
+ ███████████████████████████
580
+ ```
581
+
582
+ ### Plot with filled area
583
+
584
+ Input:
585
+
586
+ ```typescript
587
+ plot(
588
+ [
589
+ [
590
+ [1, 1],
591
+ [2, 2],
592
+ [3, 4],
593
+ [4, 6],
594
+ ],
595
+ [
596
+ [1, 4],
597
+ [2, 1],
598
+ [3, 2],
599
+ [4, 3],
600
+ ],
601
+ ],
602
+ {
603
+ fillArea: true,
604
+ color: ['ansiGreen', 'ansiBlue'],
605
+ },
606
+ );
607
+ ```
608
+
609
+ Output:
610
+
611
+ ```bash
612
+
613
+ 6┤ ██
614
+ │ ██
615
+ 4┤████
616
+ 3┤████
617
+ 2┤████
618
+ 1┤████
619
+ └┬┬┬┬▶
620
+ 1234
621
+ ```
622
+
623
+ ### Scaled up plot
624
+
625
+ Input:
626
+
627
+ ```typescript
628
+ plot(
629
+ [
630
+ [1, 1],
631
+ [2, 4],
632
+ [3, 40],
633
+ [4, 2],
634
+ [5, -1],
635
+ [6, 3],
636
+ [7, -1],
637
+ [8, -1],
638
+ [9, 9],
639
+ [10, 9],
640
+ ],
641
+ { width: 40, height: 10 },
642
+ );
643
+ ```
644
+
645
+ Output:
646
+
647
+ ```bash
648
+
649
+ 40┤ ┏━━━┓
650
+ │ ┃ ┃
651
+ │ ┃ ┃
652
+ │ ┃ ┃
653
+ │ ┃ ┃
654
+ │ ┃ ┃
655
+ │ ┃ ┃
656
+ 9┤ ┃ ┃ ┏━━━━━
657
+ 3┤ ┏━━━━┛ ┗━━━┓ ┏━━━┓ ┃
658
+ -1┤━━━┛ ┗━━━━┛ ┗━━━━━━━━┛
659
+ └┬───┬────┬───┬───┬────┬───┬───┬────┬───┬▶
660
+ 1 2 3 4 5 6 7 8 9 10
661
+ ```
662
+
663
+ ### Add thresholds
664
+
665
+ Input:
666
+
667
+ ```typescript
668
+ plot(
669
+ [
670
+ [1, 1],
671
+ [2, 4],
672
+ [3, 4],
673
+ [4, 2],
674
+ [5, -1],
675
+ [6, 3],
676
+ [7, -1],
677
+ [8, 9],
678
+ ],
679
+ {
680
+ width: 40,
681
+ thresholds: [
682
+ {
683
+ y: 5,
684
+ x: 5,
685
+ },
686
+ {
687
+ x: 2,
688
+ },
689
+ ],
690
+ },
691
+ );
692
+ ```
693
+
694
+ Output:
695
+
696
+ ```bash
697
+ ▲ ┃ ┃
698
+ 9┤ ┃ ┃ ┏━
699
+ │ ┃ ┃ ┃
700
+ │ ┃ ┃ ┃
701
+ │━━━━━┃━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
702
+ │ ┃ ┃ ┃
703
+ 4┤ ┃━━━━━━━━━━┓ ┃ ┃
704
+ 3┤ ┃ ┃ ┃ ┏━━━━┓ ┃
705
+ 2┤ ┃ ┗━━━━┃ ┃ ┃ ┃
706
+ 1┤━━━━━┃ ┃ ┃ ┃ ┃
707
+ │ ┃ ┃ ┃ ┃ ┃
708
+ -1┤ ┃ ┃━━━━━┛ ┗━━━━━┛
709
+ └┬─────┬────┬─────┬────┬─────┬────┬─────┬▶
710
+ 1 2 3 4 5 6 7 8
711
+ ```
712
+
713
+ ### Multi-series plot
714
+
715
+ Input:
716
+
717
+ ```typescript
718
+ plot(
719
+ [
720
+ [
721
+ [0, 18],
722
+ [1, 1],
723
+ [2, 3],
724
+ [3, 11],
725
+ [4, 5],
726
+ [5, 16],
727
+ [6, 17],
728
+ [7, 14],
729
+ [8, 7],
730
+ [9, 4],
731
+ ],
732
+ [
733
+ [0, 0],
734
+ [1, 1],
735
+ [2, 1],
736
+ [3, 1],
737
+ [4, 1],
738
+ [5, 0],
739
+ [6, 1],
740
+ [7, 0],
741
+ [8, 1],
742
+ [9, 0],
743
+ ],
744
+ ],
745
+ { width: 40, height: 10, color: ['ansiBlue', 'ansiGreen'] },
746
+ );
747
+ ```
748
+
749
+ Output:
750
+
751
+ ```bash
752
+
753
+ 17┤━━━━┓ ┏━━━━┓
754
+ 16┤ ┃ ┏━━━━━┛ ┃
755
+ 14┤ ┃ ┃ ┗━━━━━┓
756
+ 11┤ ┃ ┏━━━━━┓ ┃ ┃
757
+ │ ┃ ┃ ┃ ┃ ┃
758
+ 7┤ ┃ ┃ ┃ ┃ ┗━━━━┓
759
+ 5┤ ┃ ┃ ┗━━━━┛ ┃
760
+ 4┤ ┃ ┏━━━━┛ ┗━
761
+ 1┤ ┏━━━━━━━━━━━━━━━━━━━━━┓ ┏━━━━┓ ┏━━━━┓
762
+ 0┤━━━━┛ ┗━━━━━┛ ┗━━━━━┛ ┗━
763
+ └┬────┬─────┬────┬─────┬────┬─────┬────┬─────┬────┬▶
764
+ 0 1 2 3 4 5 6 7 8 9
765
+ ```
766
+
767
+ ### Plot with formatting applied
768
+
769
+ Input:
770
+
771
+ ```typescript
772
+ plot(
773
+ [
774
+ [
775
+ [0, -10],
776
+ [1, 0.001],
777
+ [2, 10],
778
+ [3, 200],
779
+ [4, 10000],
780
+ [5, 2000000],
781
+ [6, 50000000],
782
+ ],
783
+ ],
784
+ {
785
+ width: 30,
786
+ height: 20,
787
+ formatter: (n: number, { axis }: FormatterHelpers) => {
788
+ const labels = ['A', 'B', 'C', 'D', 'E', 'F', 'G'];
789
+ if (axis === 'y') return n;
790
+ return labels[n] || 'X';
791
+ },
792
+ },
793
+ );
794
+ ```
795
+
796
+ Output:
797
+
798
+ ```bash
799
+
800
+ 50000000┤ ┏━
801
+ │ ┃
802
+ │ ┃
803
+ │ ┃
804
+ │ ┃
805
+ │ ┃
806
+ │ ┃
807
+ │ ┃
808
+ │ ┃
809
+ │ ┃
810
+ │ ┃
811
+ │ ┃
812
+ │ ┃
813
+ │ ┃
814
+ │ ┃
815
+ │ ┃
816
+ │ ┃
817
+ │ ┃
818
+ 2000000┤ ┏━━━━┛
819
+ -10┤━━━━━━━━━━━━━━━━━━━━━━━┛
820
+ └┬────┬────┬────┬───┬────┬────┬▶
821
+ A B C D E F G
822
+ ```
823
+
824
+ ### Plot with axis center
825
+
826
+ Input:
827
+
828
+ ```typescript
829
+ plot(
830
+ [
831
+ [
832
+ [-8, -8],
833
+ [-4, -4],
834
+ [-3, -3],
835
+ [-2, -2],
836
+ [-1, -1],
837
+ [0, 0],
838
+ [2, 2],
839
+ [3, 3],
840
+ [4, 4],
841
+ [8, 8],
842
+ ],
843
+ ],
844
+ { width: 60, height: 20, axisCenter: [0, 0] },
845
+ );
846
+ ```
847
+
848
+ Output:
849
+
850
+ ```bash
851
+
852
+ 8┤ ┏━
853
+ │ ┃
854
+ │ ┃
855
+ │ ┃
856
+ │ ┃
857
+ 4┤ ┏━━━━━━━━━━━━━━┛
858
+ 3┤ ┏━━┛
859
+ 2┤ ┏━━━┛
860
+ │ ┃
861
+ ┬──────────────┬──┬───┬───┬───0│─────────┬──┬──────────────┬─▶
862
+ -8 -4 -3 -2 -1 0│ 2 3 4 8
863
+ ┏━━-1┤
864
+ ┏━━━┛ -2┤
865
+ ┏━━━┛ -3┤
866
+ ┏━━┛ -4┤
867
+ ┃ │
868
+ ┃ │
869
+ ┃ │
870
+ ┃ │
871
+ ━━━━━━━━━━━━━━┛ -8┤
872
+
873
+ ```
874
+
875
+ ## Plot with custom symbols
876
+
877
+ Input:
878
+
879
+ ```typescript
880
+ plot(
881
+ [
882
+ [1, 2],
883
+ [2, 0],
884
+ [3, 5],
885
+ [4, 2],
886
+ [5, -2],
887
+ [6, 3],
888
+ ],
889
+ {
890
+ symbols: {
891
+ empty: 'x',
892
+ empty: '-',
893
+ axis: {
894
+ n: 'A',
895
+ ns: 'i',
896
+ y: 't',
897
+ nse: 'o',
898
+ x: 'j',
899
+ we: 'm',
900
+ e: 'B',
901
+ },
902
+ chart: {
903
+ we: '1',
904
+ wns: '2',
905
+ ns: '3',
906
+ nse: '4',
907
+ wsn: '5',
908
+ sne: '6',
909
+ },
910
+ },
911
+ width: 40,
912
+ height: 10,
913
+ },
914
+ );
915
+ ```
916
+
917
+ Output:
918
+
919
+ ```bash
920
+ xxA-----------------------------------------
921
+ x5t---------------61111112------------------
922
+ xxi---------------3------3------------------
923
+ xxi---------------3------3------------------
924
+ x3t---------------3------3---------------61-
925
+ x2t11111112-------3------411111112-------3--
926
+ xxi-------3-------3--------------3-------3--
927
+ x0t-------411111115--------------3-------3--
928
+ xxi------------------------------3-------3--
929
+ xxi------------------------------3-------3--
930
+ -2t------------------------------411111115--
931
+ xxojmmmmmmmjmmmmmmmjmmmmmmjmmmmmmmjmmmmmmmjB
932
+ xxx1xxxxxxx2xxxxxxx3xxxxxx4xxxxxxx5xxxxxxx6x
933
+ ```
934
+
935
+ ### Plot without axis
936
+
937
+ Input:
938
+
939
+ ```typescript
940
+ plot(
941
+ [
942
+ [-5, 2],
943
+ [2, -3],
944
+ [13, 0.1],
945
+ [4, 2],
946
+ [5, -2],
947
+ [6, 12],
948
+ ],
949
+ {
950
+ width: 40,
951
+ height: 10,
952
+ hideYAxis: true,
953
+ hideXAxis: true,
954
+ },
955
+ );
956
+ ```
957
+
958
+ Output:
959
+
960
+ ```bash
961
+ ┏━━━━━━━━━━━━━━┓
962
+ ┃ ┃
963
+ ┃ ┃
964
+ ┃ ┃
965
+ ┃ ┃
966
+ ┃ ┃
967
+ ━━━━━━━━━━━━━━┓ ┏━┓ ┃ ┃
968
+ ┃ ┃ ┃ ┃ ┗━
969
+ ┃ ┃ ┗━┛
970
+ ┗━━━━┛
971
+ ```
972
+
973
+ ### Plot with with large numbers
974
+
975
+ Input:
976
+
977
+ ```typescript
978
+ plot(
979
+ [
980
+ [-9000, 2000],
981
+ [-8000, -3000],
982
+ [-2000, -2000],
983
+ [2000, 2000],
984
+ [3000, 1500],
985
+ [4000, 5000],
986
+ [10000, 1400],
987
+ [11000, 20000],
988
+ [12000, 30000],
989
+ ],
990
+ {
991
+ width: 60,
992
+ height: 20,
993
+ },
994
+ );
995
+ ```
996
+
997
+ Output:
998
+
999
+ ```bash
1000
+
1001
+ 30k┤ ┏━
1002
+ │ ┃
1003
+ │ ┃
1004
+ │ ┃
1005
+ │ ┃
1006
+ │ ┃
1007
+ 20k┤ ┏━━┛
1008
+ │ ┃
1009
+ │ ┃
1010
+ │ ┃
1011
+ │ ┃
1012
+ │ ┃
1013
+ │ ┃
1014
+ │ ┃
1015
+ 5k┤ ┏━━━━━━━━━━━━━━━┓ ┃
1016
+ │ ┃ ┃ ┃
1017
+ 1.4k┤━━┓ ┏━━━━━┛ ┗━━┛
1018
+ │ ┃ ┃
1019
+ -2k┤ ┃ ┏━━━━━━━━━━┛
1020
+ -3k┤ ┗━━━━━━━━━━━━━━━━┛
1021
+ └┬──┬────────────────┬──────────┬──┬──┬───────────────┬──┬──┬▶
1022
+ -8k 2k 4k 11k
1023
+ -9k -2k 3k 10k 12k
1024
+ ```
1025
+
1026
+ ### Plot with custom line format
1027
+
1028
+ Input:
1029
+
1030
+ ```typescript
1031
+ plot(
1032
+ [
1033
+ [1, 0],
1034
+ [2, 20],
1035
+ [3, 29],
1036
+ [4, 10],
1037
+ [5, 3],
1038
+ [6, 40],
1039
+ [7, 0],
1040
+ [8, 20],
1041
+ ],
1042
+ {
1043
+ height: 10,
1044
+ width: 30,
1045
+ lineFormatter: ({ y, plotX, plotY, input, index }) => {
1046
+ const output = [{ x: plotX, y: plotY, symbol: '█' }];
1047
+
1048
+ if (input[index - 1]?.[1] < y) {
1049
+ return [...output, { x: plotX, y: plotY - 1, symbol: '▲' }];
1050
+ }
1051
+
1052
+ return [...output, { x: plotX, y: plotY + 1, symbol: '▼' }];
1053
+ },
1054
+ },
1055
+ );
1056
+ ```
1057
+
1058
+ Output:
1059
+
1060
+ ```bash
1061
+ ▲ ▲
1062
+ 40┤ █
1063
+ │ ▲
1064
+ 29┤ █
1065
+ │ ▲ ▲
1066
+ 20┤ █ █
1067
+
1068
+
1069
+ 10┤ █
1070
+ 3┤ ▼ █
1071
+ 0┤█ ▼ █
1072
+ └┬───┬───┬───┬────┬───┬───┬───┬▶
1073
+ 1 2 3 4 5 6 7 8
1074
+ ```