Skip to content

Instantly share code, notes, and snippets.

@arodbits
Last active Mar 30, 2021
Embed
What would you like to do?
ASCII frequency graph
//sample data
let yAxis = [5,15]
let xAxis = [140, 190]
let dataSet = [
[140,150,15],
[160,170,10],
[170,180,8],
[180,190,5],
]
let yValues = range(yAxis)
let xValues = range([xAxis[0], xAxis[1], dataSet[0][1]-dataSet[0][0]]);
//return an array with values of a given range
// [1,8] -> [1,2,3...,8]
function range([start, end, inc=1]){
let rangeCollector = []
for(let i = start; i<=end; i=i+inc){
rangeCollector.push(i)
}
return rangeCollector;
}
// draw y axis values considering padding
function drawYAxis(yValues){
//in the case:
//100
// 99
//get max value
let maxValue = yValues[yValues.length - 1]
//convert all integers to string
let yValuesAligned = yValues.map(n=>{
return numberToAlignedString(n,(maxValue).toString().length)
})
return yValuesAligned;
}
// @return string
// draw x axis values
function drawXAxis(xValues, mark=" "){
let xValuesSpaced = xValues.reduce((acc,v)=>{
acc = acc.toString()+mark+ v.toString()
return acc;
}, "")
return xValuesSpaced;
}
// draw the point mark for a given interval [start, end]
// @return string with just the mark at the right position
function drawXPoint(xValues, start, end, point="*"){
//mark the point in the xAxis when the value is between start-end
let xValuesSpaced = xValues.reduce((acc,v)=>{
let mark = ""
if(v > start && v <= end){
mark = point;
}
acc = acc.toString()+mark+ convertNumberToSpaces(v).toString()
return acc;
}, "")
return xValuesSpaced;
}
//add leading spaces to number
function numberToAlignedString(number, maxSeparation=0, spaceMark=" "){
while(number.toString().length < maxSeparation){
number = " " + number
}
return number.toString()
}
// convert number values to white spaces
function convertNumberToSpaces(number){
if(!isNaN(number)){
let s = ""
for(let i=0; i<=(number).toString().length; i++){
s = s + " "
}
return s
}
return number
}
// look up the [x] range for a given y
// @return [start, end]
function findXIntervalForY(dataset, y){
let pair = []
dataset.forEach(v=>{
if(v[2] === parseInt(y)){
pair = [v[0], v[1]]
}
})
return pair;
}
let y = drawYAxis(yValues)
let x = drawXAxis(xValues)
//draw grid and points
//iterate over all the y values and draw a point from [x,yn] to [x,y0] to
//represent the frequency of that point
let grid = [];
y.sort((a,b)=>{
if(a-b < 1) return 1
if(a==b) return 0
return -1
}).map(yp=>{
//draw the point corresponding to the [x,y] coordinate
let [start, end] = findXIntervalForY(dataSet,yp)
let xp = drawXPoint(xValues, start, end).split("")
//to repeat the frequency value for a range not explicitly indicated in the dataset, make sure to merge
//the previous line with the new one for the given y point
merge(grid, xp)
//print out
console.log(yp + grid.join(""))
})
function merge(a,b){
b.forEach((v,k)=>{
if(a[k]!==undefined && v === "*"){
a[k] = v
}else if(a[k] === undefined){
a.push(v)
}
})
return a
}
//guarantee perfect alignment between the x and y axis
console.log(convertNumberToSpaces(yValues[yValues.length-1])+x)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment