diff --git a/text_graph.html b/text_graph.html
index bdf39f5..75badd5 100644
--- a/text_graph.html
+++ b/text_graph.html
@@ -322,6 +322,12 @@
const binDuration = parseFloat(document.getElementById('bin-duration').value) * 1000; // Convert to milliseconds
const xAxisLabelFormat = document.getElementById('x-axis-format').value;
+ // Stop any existing bin rotation timer before recreating chart
+ if (chart && chart.binCheckInterval) {
+ clearInterval(chart.binCheckInterval);
+ chart.binCheckInterval = null;
+ }
+
// Recreate chart with new settings
chart = new ASCIIBarChart('chart-container', {
maxHeight: chartHeight,
diff --git a/text_graph.js b/text_graph.js
index a0d4315..ea36504 100644
--- a/text_graph.js
+++ b/text_graph.js
@@ -112,7 +112,8 @@ class ASCIIBarChart {
const yAxisPadding = this.yAxisLabel ? 2 : 0;
const yAxisNumbers = 3; // Width of Y-axis numbers
const separator = 1; // The '|' character
- const dataWidth = dataLength * 2; // Each column is 2 characters wide
+ // const dataWidth = dataLength * 2; // Each column is 2 characters wide // TEMP: commented for no-space test
+ const dataWidth = dataLength; // Each column is 1 character wide // TEMP: adjusted for no-space columns
const padding = 1; // Extra padding
const totalWidth = yAxisPadding + yAxisNumbers + separator + dataWidth + padding;
@@ -140,8 +141,9 @@ class ASCIIBarChart {
// Calculate optimal font size
// For monospace fonts, character width is approximately 0.6 * font size
- const charWidthRatio = 0.6;
- const padding = 40; // Account for container padding
+ // Use a slightly smaller ratio to fit more content
+ const charWidthRatio = 0.7;
+ const padding = 30; // Reduce padding to fit more content
const availableWidth = containerWidth - padding;
const optimalFontSize = Math.floor((availableWidth / chartWidth) / charWidthRatio);
@@ -174,11 +176,21 @@ class ASCIIBarChart {
this.container.textContent = 'No data yet. Click Start to begin.';
return;
}
- // Only render the most recent bins up to maxDataPoints
- // Reverse the order so the most recent (active) bin is on the left
+ // Always create a fixed-length array filled with 0s, then overlay actual bin data
+ dataToRender = new Array(this.maxDataPoints).fill(0);
+
+ // Overlay actual bin data (most recent bins, reversed for left-to-right display)
const startIndex = Math.max(0, this.bins.length - this.maxDataPoints);
const recentBins = this.bins.slice(startIndex);
- dataToRender = recentBins.reverse().map(bin => bin.count); // Reverse so active bin is first (leftmost)
+
+ // Reverse the bins so most recent is on the left, and overlay onto the fixed array
+ recentBins.reverse().forEach((bin, index) => {
+ if (index < this.maxDataPoints) {
+ dataToRender[index] = bin.count;
+ }
+ });
+
+ console.log('render() dataToRender:', dataToRender, 'bins length:', this.bins.length);
maxValue = Math.max(...dataToRender);
minValue = Math.min(...dataToRender);
valueRange = maxValue - minValue;
@@ -208,7 +220,8 @@ class ASCIIBarChart {
// Add title if provided (centered)
if (this.title) {
- const chartWidth = 4 + this.maxDataPoints * 2; // Y-axis numbers + data columns
+ // const chartWidth = 4 + this.maxDataPoints * 2; // Y-axis numbers + data columns // TEMP: commented for no-space test
+ const chartWidth = 4 + this.maxDataPoints; // Y-axis numbers + data columns // TEMP: adjusted for no-space columns
const titlePadding = Math.floor((chartWidth - this.title.length) / 2);
output += yAxisPadding + ' '.repeat(Math.max(0, titlePadding)) + this.title + '\n\n';
}
@@ -242,9 +255,11 @@ class ASCIIBarChart {
const scaledHeight = Math.ceil(count / scaleFactor);
if (scaledHeight >= row) {
- line += ' X';
+ // line += ' X'; // TEMP: commented out space between columns
+ line += 'X'; // TEMP: no space between columns
} else {
- line += ' ';
+ // line += ' '; // TEMP: commented out space between columns
+ line += ' '; // TEMP: single space for empty columns
}
}
@@ -252,33 +267,57 @@ class ASCIIBarChart {
}
// Draw X-axis
- output += yAxisPadding + ' +' + '-'.repeat(this.maxDataPoints * 2) + '\n';
+ // output += yAxisPadding + ' +' + '-'.repeat(this.maxDataPoints * 2) + '\n'; // TEMP: commented out for no-space test
+ output += yAxisPadding + ' +' + '-'.repeat(this.maxDataPoints) + '\n'; // TEMP: back to original length
// Draw X-axis labels based on mode and format
- let xAxisLabels = yAxisPadding + ' ';
+ let xAxisLabels = yAxisPadding + ' '; // Initial padding to align with X-axis
+ let labels = [];
for (let i = 0; i < this.maxDataPoints; i++) {
if (i % 5 === 0) {
let label = '';
if (this.useBinMode) {
// For bin mode, show labels for all possible positions
// i=0 is leftmost (most recent), i=maxDataPoints-1 is rightmost (oldest)
- const elapsedSec = i * Math.floor(this.binDuration / 1000);
- label = String(elapsedSec).padStart(2, ' ') + 's';
+ const elapsedSec = (i * this.binDuration) / 1000;
+ // Format with appropriate precision for sub-second bins
+ if (this.binDuration < 1000) {
+ // Show decimal seconds for sub-second bins
+ label = elapsedSec.toFixed(1) + 's';
+ } else {
+ // Show whole seconds for 1+ second bins
+ label = ' ' + String(Math.round(elapsedSec)) + 's';
+ }
} else {
// For legacy mode, show data point numbers
const startIndex = Math.max(1, this.totalDataPoints - this.maxDataPoints + 1);
- label = String(startIndex + i).padStart(2, ' ');
+ label = String(startIndex + i).padStart(3, ' ');
}
- xAxisLabels += label;
- } else {
- xAxisLabels += ' ';
+ labels.push({ position: i, text: label });
}
}
+
+ // Position all labels
+ let currentPosition = yAxisPadding.length + 3; // Start after initial padding
+ for (const labelInfo of labels) {
+ const spacesBefore = Math.max(0, labelInfo.position - currentPosition);
+ xAxisLabels += ' '.repeat(spacesBefore) + labelInfo.text;
+ currentPosition = labelInfo.position + labelInfo.text.length;
+ }
+
+ // Ensure the label line extends to match the X-axis dash line length
+ // The dash line is this.maxDataPoints characters long, starting after " +"
+ const dashLineLength = this.maxDataPoints;
+ const minLabelLineLength = yAxisPadding.length + 4 + dashLineLength; // 4 for " "
+ if (xAxisLabels.length < minLabelLineLength) {
+ xAxisLabels += ' '.repeat(minLabelLineLength - xAxisLabels.length);
+ }
output += xAxisLabels + '\n';
// Add X-axis label if provided
if (this.xAxisLabel) {
- const labelPadding = Math.floor((this.maxDataPoints * 2 - this.xAxisLabel.length) / 2);
+ // const labelPadding = Math.floor((this.maxDataPoints * 2 - this.xAxisLabel.length) / 2); // TEMP: commented for no-space test
+ const labelPadding = Math.floor((this.maxDataPoints - this.xAxisLabel.length) / 2); // TEMP: adjusted for no-space columns
output += '\n' + yAxisPadding + ' ' + ' '.repeat(Math.max(0, labelPadding)) + this.xAxisLabel + '\n';
}