forked from kroitor/asciichart
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathasciichart.js
88 lines (73 loc) · 3.62 KB
/
asciichart.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
"use strict";
(function (exports) {
exports.plot = function (series, cfg = undefined) {
var toFixedTrailing = function(x, trailing = 2) {
if (Math.abs(x) > 1) {
var trailing = trailing || 0,
neg = x < 0,
power = Math.pow(10, trailing),
x = Math.round(x * power),
integral = String((neg ? Math.ceil : Math.floor)(x / power)),
fraction = String((neg ? -x : x) % power),
padding = new Array(Math.max(trailing - fraction.length, 0) + 1).join('0');
return trailing ? integral + '.' + padding + fraction : integral;
} else {
var numDigits = x !== 0 ? Math.ceil(Math.log10(Math.abs(x))) : 0;
var rounded = Math.round(x*Math.pow(10,trailing-numDigits))*Math.pow(10,numDigits-trailing);
return rounded.toFixed(Math.max(trailing-numDigits,0));
}
}
let min = series[0]
let max = series[0]
let paddingLength = 0
for (let i = 1; i < series.length; i++) {
min = Math.min (min, series[i])
max = Math.max (max, series[i])
var numChars = String(toFixedTrailing(series[i])).length
paddingLength = numChars > paddingLength ? numChars : paddingLength
}
let range = Math.abs (max - min)
cfg = (typeof cfg !== 'undefined') ? cfg : {}
let offset = (typeof cfg.offset !== 'undefined') ? cfg.offset : 3
let padding = (typeof cfg.padding !== 'undefined') ? cfg.padding : Array(paddingLength).fill(" ")
let height = (typeof cfg.height !== 'undefined') ? cfg.height : range
let ratio = height / range
let min2 = Math.round (min * ratio)
let max2 = Math.round (max * ratio)
let rows = Math.abs (max2 - min2)
let width = series.length + offset
let format = (typeof cfg.format !== 'undefined') ? cfg.format : function (x) {
return (padding + toFixedTrailing(x)).slice (-padding.length)
}
let result = new Array (rows + 1) // empty space
for (let i = 0; i <= rows; i++) {
result[i] = new Array (width)
for (let j = 0; j < width; j++) {
result[i][j] = ' '
}
}
for (let y = min2; y <= max2; ++y) { // axis + labels
let label = format (max - (y - min2) * range / rows, y - min2)
result[y - min2][Math.max (offset - label.length, 0)] = label
result[y - min2][offset - 1] = (y == 0) ? '┼' : '┤'
}
let y0 = Math.round (series[0] * ratio) - min2
result[rows - y0][offset - 1] = '┼' // first value
for (let x = 0; x < series.length - 1; x++) { // plot the line
let y0 = Math.round (series[x + 0] * ratio) - min2
let y1 = Math.round (series[x + 1] * ratio) - min2
if (y0 == y1) {
result[rows - y0][x + offset] = '─'
} else {
result[rows - y1][x + offset] = (y0 > y1) ? '╰' : '╭'
result[rows - y0][x + offset] = (y0 > y1) ? '╮' : '╯'
let from = Math.min (y0, y1)
let to = Math.max (y0, y1)
for (let y = from + 1; y < to; y++) {
result[rows - y][x + offset] = '│'
}
}
}
return result.map (function (x) { return x.join ('') }).join ('\n')
}
}) (typeof exports === 'undefined' ? /* istanbul ignore next */ this['asciichart'] = {} : exports);