-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathlab.js
More file actions
117 lines (89 loc) · 4.44 KB
/
lab.js
File metadata and controls
117 lines (89 loc) · 4.44 KB
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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
// these are the very primitive functions for semi-manual analysis of simple
// data structures generated by my random functions and alike
// replace body with minimalistic barChart illustrating the proportions given
const visualize = (data, options={}) => {
// in case it's an object make a nested array of pairs of it
if ( !Array.isArray(data) ) data = Object.entries(data)
// sort if possible, if not - it's fine
try { data = data.sort( (a, b) => a[0] - b[0] ) } catch {}
const { width=1080, namesWidth=80, barMaxWidth=1000, height=700,
barHeight = Math.max(10, height/data.length-1) } = options,
maxNum = Math.max( ...data.map(row => row[1]) ),
unitSize = barMaxWidth / maxNum, // size in pixels per 1 thing
calcWidth = (num) => Math.floor(num * unitSize),
unitColor = 256 / maxNum, // HUE color shift per 1 thing
calcColor = (num) => Math.floor(256 - num * unitColor),
style = `<style>
body>div {
display: grid;
width: ${ width }px;
grid-template-columns: ${ namesWidth }px auto;
gap: 1px;
}
body>div>span:nth-child(odd) {
text-align: right;
padding-right: 5px;
line-height: ${ barHeight }px;
font-weight: bold;
}
body>div>span:nth-child(even) {
height: ${ barHeight }px;
border-radius: 6px;
}
</style>`
const bars = data.reduce( (html, [valueName, number]) =>
html + `<span title=${ number }>${ valueName }</span> <span
title=${ number } style="background:hsl(${ calcColor(number) },74%,45%);
width:${ calcWidth(number) }"></span>`, '')
// I know, it's like a style "on a duct tape" solution, but here it's ok
document.body.innerHTML = style + `<div> ${ bars } </div>`
}
// it's for the quick checking a possible result sets of functions with rnd
const probe = (given, options={}) => {
// it's ready for two presenter-functions: visualise and quickTable
const { presenter=visualize, num=10000 } = options
if (typeof given == 'function') { // in case the function is given...
// if it produces the array - that's what it works on further on
if ( Array.isArray(given()) ) given = given()
// otherwise (it should produce a primitive value) make an array of them
else given = makeArr(num, given) // ... of num length
}
// if an array of values is ready at this point count unique values in it
if ( Array.isArray(given) ) given = countUnique(given)
presenter(given, options) // now the object should be ready to present
}
// I use this to copy columns of data for pasting them into the spreadsheets
const quickTable = (data) => {
// in case it's an object make a nested array of pairs of it
if ( !Array.isArray(data) ) data = Object.entries(data)
// sort if possible, if not - it's fine
try { data = data.sort( (a, b) => a[0] - b[0] ) } catch {}
let trs = data.reduce( (trs, row)=>
trs + `<tr> <th>${ row[0] }</th> <td>${ row[1] }</td> </tr>`, '')
// and of course the body shouldn't be replaced just to show a small table :)
document.body.innerHTML = `<table border=1> ${ trs } </table>`
}
// like the probe function above, just preloaded with the quickTable presenter
const probeTbl = (given, options) =>
probe(given, {...options, presenter: quickTable})
// shorthand for console.table with transformations it may need taken care of
const conTbl = (data) => {
// in case the data is an object
if (!Array.isArray(data) && typeof data == 'object') {
// in case the data is a records object
if (data.headers && data.rows && Object.keys(data).length==2)
conTbl(recordsAsArray(data))
else console.table(data) // in case data is ready for console.table
}
// in case the data is a valid records array
else if (typeof data[0][0] == 'string' && Array.isArray(data[1][0]))
console.table(objectifyRecords(data))
// in case the data is a flat array
else if (Array.isArray(data) && typeof data[0] != 'object')
console.table(data)
// in case the data is a nested rows array without the headers
else {
const headers = Array(data[0].length).fill(0).map((_,i)=>`column${i+1}`)
console.table( objectifyRecords([headers, data]) )
}
}