.
This commit is contained in:
@@ -322,6 +322,12 @@
|
|||||||
const binDuration = parseFloat(document.getElementById('bin-duration').value) * 1000; // Convert to milliseconds
|
const binDuration = parseFloat(document.getElementById('bin-duration').value) * 1000; // Convert to milliseconds
|
||||||
const xAxisLabelFormat = document.getElementById('x-axis-format').value;
|
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
|
// Recreate chart with new settings
|
||||||
chart = new ASCIIBarChart('chart-container', {
|
chart = new ASCIIBarChart('chart-container', {
|
||||||
maxHeight: chartHeight,
|
maxHeight: chartHeight,
|
||||||
|
|||||||
@@ -112,7 +112,8 @@ class ASCIIBarChart {
|
|||||||
const yAxisPadding = this.yAxisLabel ? 2 : 0;
|
const yAxisPadding = this.yAxisLabel ? 2 : 0;
|
||||||
const yAxisNumbers = 3; // Width of Y-axis numbers
|
const yAxisNumbers = 3; // Width of Y-axis numbers
|
||||||
const separator = 1; // The '|' character
|
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 padding = 1; // Extra padding
|
||||||
|
|
||||||
const totalWidth = yAxisPadding + yAxisNumbers + separator + dataWidth + padding;
|
const totalWidth = yAxisPadding + yAxisNumbers + separator + dataWidth + padding;
|
||||||
@@ -140,8 +141,9 @@ class ASCIIBarChart {
|
|||||||
|
|
||||||
// Calculate optimal font size
|
// Calculate optimal font size
|
||||||
// For monospace fonts, character width is approximately 0.6 * font size
|
// For monospace fonts, character width is approximately 0.6 * font size
|
||||||
const charWidthRatio = 0.6;
|
// Use a slightly smaller ratio to fit more content
|
||||||
const padding = 40; // Account for container padding
|
const charWidthRatio = 0.7;
|
||||||
|
const padding = 30; // Reduce padding to fit more content
|
||||||
const availableWidth = containerWidth - padding;
|
const availableWidth = containerWidth - padding;
|
||||||
const optimalFontSize = Math.floor((availableWidth / chartWidth) / charWidthRatio);
|
const optimalFontSize = Math.floor((availableWidth / chartWidth) / charWidthRatio);
|
||||||
|
|
||||||
@@ -174,11 +176,21 @@ class ASCIIBarChart {
|
|||||||
this.container.textContent = 'No data yet. Click Start to begin.';
|
this.container.textContent = 'No data yet. Click Start to begin.';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Only render the most recent bins up to maxDataPoints
|
// Always create a fixed-length array filled with 0s, then overlay actual bin data
|
||||||
// Reverse the order so the most recent (active) bin is on the left
|
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 startIndex = Math.max(0, this.bins.length - this.maxDataPoints);
|
||||||
const recentBins = this.bins.slice(startIndex);
|
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);
|
maxValue = Math.max(...dataToRender);
|
||||||
minValue = Math.min(...dataToRender);
|
minValue = Math.min(...dataToRender);
|
||||||
valueRange = maxValue - minValue;
|
valueRange = maxValue - minValue;
|
||||||
@@ -208,7 +220,8 @@ class ASCIIBarChart {
|
|||||||
|
|
||||||
// Add title if provided (centered)
|
// Add title if provided (centered)
|
||||||
if (this.title) {
|
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);
|
const titlePadding = Math.floor((chartWidth - this.title.length) / 2);
|
||||||
output += yAxisPadding + ' '.repeat(Math.max(0, titlePadding)) + this.title + '\n\n';
|
output += yAxisPadding + ' '.repeat(Math.max(0, titlePadding)) + this.title + '\n\n';
|
||||||
}
|
}
|
||||||
@@ -242,9 +255,11 @@ class ASCIIBarChart {
|
|||||||
const scaledHeight = Math.ceil(count / scaleFactor);
|
const scaledHeight = Math.ceil(count / scaleFactor);
|
||||||
|
|
||||||
if (scaledHeight >= row) {
|
if (scaledHeight >= row) {
|
||||||
line += ' X';
|
// line += ' X'; // TEMP: commented out space between columns
|
||||||
|
line += 'X'; // TEMP: no space between columns
|
||||||
} else {
|
} 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
|
// 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
|
// 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++) {
|
for (let i = 0; i < this.maxDataPoints; i++) {
|
||||||
if (i % 5 === 0) {
|
if (i % 5 === 0) {
|
||||||
let label = '';
|
let label = '';
|
||||||
if (this.useBinMode) {
|
if (this.useBinMode) {
|
||||||
// For bin mode, show labels for all possible positions
|
// For bin mode, show labels for all possible positions
|
||||||
// i=0 is leftmost (most recent), i=maxDataPoints-1 is rightmost (oldest)
|
// i=0 is leftmost (most recent), i=maxDataPoints-1 is rightmost (oldest)
|
||||||
const elapsedSec = i * Math.floor(this.binDuration / 1000);
|
const elapsedSec = (i * this.binDuration) / 1000;
|
||||||
label = String(elapsedSec).padStart(2, ' ') + 's';
|
// 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 {
|
} else {
|
||||||
// For legacy mode, show data point numbers
|
// For legacy mode, show data point numbers
|
||||||
const startIndex = Math.max(1, this.totalDataPoints - this.maxDataPoints + 1);
|
const startIndex = Math.max(1, this.totalDataPoints - this.maxDataPoints + 1);
|
||||||
label = String(startIndex + i).padStart(2, ' ');
|
label = String(startIndex + i).padStart(3, ' ');
|
||||||
}
|
}
|
||||||
xAxisLabels += label;
|
labels.push({ position: i, text: label });
|
||||||
} else {
|
|
||||||
xAxisLabels += ' ';
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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';
|
output += xAxisLabels + '\n';
|
||||||
|
|
||||||
// Add X-axis label if provided
|
// Add X-axis label if provided
|
||||||
if (this.xAxisLabel) {
|
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';
|
output += '\n' + yAxisPadding + ' ' + ' '.repeat(Math.max(0, labelPadding)) + this.xAxisLabel + '\n';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user