Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
183 changes: 183 additions & 0 deletions examples/advanced.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
var babar = require('../lib/babar');

function section(title) {
var w = 72;
var inner = title.length + 2;
var pad = Math.max(0, Math.floor((w - inner) / 2));
var right = Math.max(0, w - inner - pad);
var line = '─'.repeat(pad) + ' ' + title + ' ' + '─'.repeat(right);
console.log('\n' + line);
}

// ─────────────────────────────────────────────────────────────────────────────
section('1. just above the floor — bar cap sitting exactly at the grid bottom');
// All values cluster just above minY so the bars are 1–2 rows tall max.
// Tests that partial blocks render correctly at very low heights.
var barelyAbove = [];
for (var i = 0; i < 40; i++) {
barelyAbove.push([i, 100 + Math.sin(i * 0.4) * 0.9]);
}
console.log(babar(barelyAbove, {
caption: 'sin wave compressed near floor (minY=99, maxY=103)',
color: 'magenta',
grid: 'grey',
width: 72,
height: 12,
minY: 99,
maxY: 103,
yFractions: 2,
}));

// ─────────────────────────────────────────────────────────────────────────────
section('2. just below the ceiling — bar cap touching the top row');
// Values crowd the top, testing that ▇/█ at the topmost row don't overflow.
var nearCeiling = [];
for (var i = 0; i < 40; i++) {
nearCeiling.push([i, 99 + Math.cos(i * 0.3) * 0.95]);
}
console.log(babar(nearCeiling, {
caption: 'cos wave compressed near ceiling (minY=97, maxY=101)',
color: 'cyan',
grid: 'grey',
width: 72,
height: 12,
minY: 97,
maxY: 101,
yFractions: 2,
}));

// ─────────────────────────────────────────────────────────────────────────────
section('3. single point — minimum viable dataset');
console.log(babar([[0, 42]], {
caption: 'single point',
color: 'yellow',
grid: 'grey',
width: 30,
height: 6,
}));

// ─────────────────────────────────────────────────────────────────────────────
section('4. all identical Y — flat chart (diff = 0)');
console.log(babar([[0,7],[1,7],[2,7],[3,7],[4,7],[5,7]], {
caption: 'all values = 7',
color: 'green',
grid: 'grey',
width: 40,
height: 8,
}));

// ─────────────────────────────────────────────────────────────────────────────
section('5. single unique X with many Y values — diffX = 0');
console.log(babar([[5,1],[5,3],[5,7],[5,2],[5,9]], {
caption: 'all points at x=5 (avg=4.4)',
color: 'blue',
grid: 'grey',
width: 30,
height: 8,
}));

// ─────────────────────────────────────────────────────────────────────────────
section('6. negative Y range — bars below zero');
var negPts = [];
for (var i = 0; i < 30; i++) {
negPts.push([i, Math.sin(i * 0.5) * 50]);
}
console.log(babar(negPts, {
caption: 'sin wave from -50 to +50',
color: 'red',
grid: 'grey',
width: 72,
height: 14,
yFractions: 1,
}));

// ─────────────────────────────────────────────────────────────────────────────
section('7. very sparse data — 3 points over wide x range with many empty buckets');
console.log(babar([[0, 10], [50, 90], [100, 40]], {
caption: '3 points → empty buckets interpolate from neighbours',
color: 'yellow',
grid: 'grey',
width: 72,
height: 10,
}));

// ─────────────────────────────────────────────────────────────────────────────
section('8. dense data — many points per bucket (averaging)');
var densePts = [];
for (var i = 0; i < 2000; i++) {
var x = Math.floor(i / 20); // 100 unique x values
var noise = (Math.random() - 0.5) * 30;
densePts.push([x, Math.sin(x * 0.2) * 40 + 50 + noise]);
}
console.log(babar(densePts, {
caption: '2000 points → 100 buckets averaged (sin + noise)',
color: 'cyan',
grid: 'grey',
width: 72,
height: 14,
yFractions: 0,
}));

// ─────────────────────────────────────────────────────────────────────────────
section('9. tiny terminal — minimum size');
console.log(babar([[0,1],[1,3],[2,2]], {
caption: 'tiny',
color: 'green',
grid: 'grey',
width: 16,
height: 5,
}));

// ─────────────────────────────────────────────────────────────────────────────
section('10. exponential growth — tests label width with large numbers');
var expPts = [];
for (var i = 0; i < 20; i++) {
expPts.push([i, Math.pow(2, i)]);
}
console.log(babar(expPts, {
caption: '2^x from 1 to 524288',
color: 'magenta',
grid: 'grey',
width: 72,
height: 14,
yFractions: 0,
}));

// ─────────────────────────────────────────────────────────────────────────────
section('11. clipped window — maxY cuts off spikes');
var spiky = [[0,5],[1,5],[2,5],[3,999],[4,5],[5,5],[6,999],[7,5],[8,5]];
console.log(babar(spiky, {
caption: 'spikes at x=3 and x=6 clipped by maxY=10',
color: 'red',
grid: 'grey',
width: 72,
height: 10,
maxY: 10,
yFractions: 0,
}));

// ─────────────────────────────────────────────────────────────────────────────
section('12. sub-row precision showcase — staircase through all 8 block levels');
// Build a staircase so each bar cap falls exactly at k/8 fractions
var stairPts = [];
for (var i = 0; i < 9; i++) {
stairPts.push([i, i / 8]); // 0/8, 1/8, 2/8 … 8/8
}
console.log(babar(stairPts, {
caption: 'staircase: each bar cap at k/8 — shows ▁▂▃▄▅▆▇█',
color: 'cyan',
grid: 'grey',
width: 72,
height: 10,
yFractions: 3,
}));

// ─────────────────────────────────────────────────────────────────────────────
section('13. ascii fallback — same staircase without color');
console.log(babar(stairPts, {
caption: 'staircase in ascii mode',
color: 'ascii',
width: 72,
height: 10,
yFractions: 3,
}));
161 changes: 161 additions & 0 deletions examples/features.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
var babar = require('../lib/babar');

function section(title) {
var w = 72;
var inner = title.length + 2;
var pad = Math.max(0, Math.floor((w - inner) / 2));
var right = Math.max(0, w - inner - pad);
console.log('\n' + '─'.repeat(pad) + ' ' + title + ' ' + '─'.repeat(right));
}

// ─────────────────────────────────────────────────────────────────────────────
section('1. aggregation: avg (default) vs sum vs count');

var requestLog = [];
for (var i = 0; i < 10; i++) {
for (var j = 0; j < Math.floor(Math.random() * 5 + 1); j++) {
requestLog.push([i, Math.random() * 200 + 50]); // response times
}
}

console.log(babar(requestLog, {
caption: 'avg response time per second',
color: 'cyan', grid: 'grey', width: 72, height: 10,
aggregation: 'avg', yFractions: 0,
}));
console.log(babar(requestLog, {
caption: 'total response time (sum)',
color: 'magenta', grid: 'grey', width: 72, height: 10,
aggregation: 'sum', yFractions: 0,
}));
console.log(babar(requestLog, {
caption: 'request count per second',
color: 'green', grid: 'grey', width: 72, height: 8,
aggregation: 'count', yFractions: 0,
}));

// ─────────────────────────────────────────────────────────────────────────────
section('2. aggregation: min / max — shows spread');

var noisyPts = [];
for (var i = 0; i < 12; i++) {
for (var j = 0; j < 8; j++) {
noisyPts.push([i, 50 + Math.sin(i * 0.5) * 30 + (Math.random() - 0.5) * 40]);
}
}
console.log(babar(noisyPts, {
caption: 'worst case (max) latency per bucket',
color: 'red', grid: 'grey', width: 72, height: 10,
aggregation: 'max', yFractions: 0,
}));
console.log(babar(noisyPts, {
caption: 'best case (min) latency per bucket',
color: 'green', grid: 'grey', width: 72, height: 10,
aggregation: 'min', yFractions: 0,
}));

// ─────────────────────────────────────────────────────────────────────────────
section('3. yScale: log — exponential data readable at a glance');

var expPts = [];
for (var i = 1; i <= 20; i++) expPts.push([i, Math.pow(2, i)]);

console.log(babar(expPts, {
caption: '2^x linear scale — everything looks flat except the last bar',
color: 'yellow', grid: 'grey', width: 72, height: 12,
yScale: 'linear', yFractions: 0,
}));
console.log(babar(expPts, {
caption: '2^x log scale — growth is visible across all values',
color: 'cyan', grid: 'grey', width: 72, height: 12,
yScale: 'log', yFractions: 0,
}));

// ─────────────────────────────────────────────────────────────────────────────
section('4. refY — reference / threshold line');

var latency = [
[0,45],[1,62],[2,38],[3,91],[4,110],[5,78],[6,55],[7,130],[8,48],[9,72],
];
console.log(babar(latency, {
caption: 'p99 latency (ms) — SLA threshold at 80ms',
color: 'cyan', grid: 'grey', width: 72, height: 12,
refY: 80, yFractions: 0,
}));

// refY with log scale
console.log(babar(expPts, {
caption: '2^x log scale with refY=1000',
color: 'magenta', grid: 'grey', width: 72, height: 12,
yScale: 'log', yFractions: 0, refY: 1000,
}));

// ─────────────────────────────────────────────────────────────────────────────
section('5. categorical X — named buckets (vertical)');

var monthlyRevenue = [
['Jan', 12400], ['Feb', 9800], ['Mar', 15600], ['Apr', 18200],
['May', 21000], ['Jun', 19500], ['Jul', 17800], ['Aug', 22400],
['Sep', 20100], ['Oct', 24600], ['Nov', 28900], ['Dec', 31200],
];
console.log(babar(monthlyRevenue, {
caption: 'monthly revenue ($)',
color: 'green', grid: 'grey', width: 72, height: 14,
yFractions: 0,
}));

// categorical with aggregation on duplicate labels
var surveyResults = [
['Strongly agree', 34], ['Agree', 28], ['Neutral', 15],
['Disagree', 12], ['Strongly disagree', 8],
// second survey round, same categories
['Strongly agree', 40], ['Agree', 31], ['Neutral', 11],
['Disagree', 9], ['Strongly disagree', 5],
];
console.log(babar(surveyResults, {
caption: 'survey results (avg of 2 rounds)',
color: 'blue', grid: 'grey', width: 72, height: 12,
aggregation: 'avg', yFractions: 0,
}));

// ─────────────────────────────────────────────────────────────────────────────
section('6. categorical X — horizontal direction');

console.log(babar(monthlyRevenue, {
caption: 'monthly revenue — horizontal',
color: 'green', grid: 'grey', width: 72,
direction: 'horizontal', yFractions: 0,
}));

console.log(babar(surveyResults, {
caption: 'survey results — horizontal, avg aggregation',
color: 'cyan', grid: 'grey', width: 72,
direction: 'horizontal', aggregation: 'avg', yFractions: 1,
}));

// ─────────────────────────────────────────────────────────────────────────────
section('7. numeric horizontal — time series turned sideways');

var cpuLoad = [];
for (var i = 0; i < 30; i++) {
cpuLoad.push([i, 20 + Math.sin(i * 0.4) * 15 + Math.random() * 10]);
}
console.log(babar(cpuLoad, {
caption: 'CPU load % over 30s (horizontal)',
color: 'yellow', grid: 'grey', width: 72, height: 20,
direction: 'horizontal', yFractions: 1, refY: 30,
}));

// ─────────────────────────────────────────────────────────────────────────────
section('8. combining features: log + refY + categorical + horizontal');

var diskUsage = [
['/', 45000], ['/home', 320000], ['/var', 8500],
['/tmp', 120], ['/boot', 980], ['/srv', 62000],
];
console.log(babar(diskUsage, {
caption: 'disk usage (MB) — log scale, 10000 MB threshold',
color: 'red', grid: 'grey', width: 72,
direction: 'horizontal', yScale: 'log',
refY: 10000, yFractions: 0,
}));
2 changes: 1 addition & 1 deletion examples/simple.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ console.log(babar([
], {
width: 80,
grid: 'blue',
height: 10,
height: 11,
color: 'yellow',
maxY: 100
}));
Loading