.
This commit is contained in:
156
text_graph.html
156
text_graph.html
@@ -18,7 +18,7 @@
|
||||
padding: 20px;
|
||||
border: 2px solid #00ff00;
|
||||
border-radius: 5px;
|
||||
overflow-x: auto;
|
||||
overflow: hidden;
|
||||
white-space: pre;
|
||||
font-size: 8px;
|
||||
line-height: 1.0;
|
||||
@@ -103,7 +103,25 @@
|
||||
Chart Height:
|
||||
<input type="number" id="chart-height" value="20" min="10" max="50" step="5" style="width: 60px;">
|
||||
</label>
|
||||
<label style="margin-left: 15px;">
|
||||
<input type="checkbox" id="use-bin-mode" checked onchange="toggleBinMode()">
|
||||
Time Bin Mode
|
||||
</label>
|
||||
<label style="margin-left: 15px;">
|
||||
Bin Duration (s):
|
||||
<input type="number" id="bin-duration" value="4" min="0.1" max="300" step="0.1" style="width: 60px;">
|
||||
</label>
|
||||
<label style="margin-left: 15px;">
|
||||
X-Axis Format:
|
||||
<select id="x-axis-format" style="width: 100px;">
|
||||
<option value="elapsed">Elapsed</option>
|
||||
<option value="bins">Bin Numbers</option>
|
||||
<option value="timestamps">Timestamps</option>
|
||||
<option value="ranges">Time Ranges</option>
|
||||
</select>
|
||||
</label>
|
||||
<button onclick="applySettings()" style="margin-left: 15px; padding: 5px 15px;">Apply Settings</button>
|
||||
<button onclick="rotateBin()" id="rotate-bin-btn" style="margin-left: 10px; padding: 5px 15px; display: none;">Rotate Bin</button>
|
||||
</div>
|
||||
|
||||
<div id="info">
|
||||
@@ -115,9 +133,10 @@
|
||||
<div id="chart-container"></div>
|
||||
|
||||
<div id="chart-info">
|
||||
<div><strong>Legend:</strong> Each X represents a count unit</div>
|
||||
<div><strong>Legend:</strong> <span id="legend-text">Each X represents a count of events</span></div>
|
||||
<div><strong>Values:</strong> <span id="values">--</span></div>
|
||||
<div><strong>Max value:</strong> <span id="max-value">--</span>, <strong>Scale:</strong> <span id="scale">--</span></div>
|
||||
<div id="bin-info" style="display: none;"><strong>Current Bin:</strong> <span id="current-bin">--</span>, <strong>Time Remaining:</strong> <span id="time-remaining">--</span>s</div>
|
||||
</div>
|
||||
|
||||
<!-- Include the ASCII Bar Chart library -->
|
||||
@@ -132,7 +151,10 @@
|
||||
title: 'Real-Time Data Visualization',
|
||||
xAxisLabel: 'Time (seconds)',
|
||||
yAxisLabel: 'Count',
|
||||
autoFitWidth: true // Automatically adjust font size to fit container width
|
||||
autoFitWidth: true, // Automatically adjust font size to fit container width
|
||||
useBinMode: true, // Start in time bin mode
|
||||
binDuration: 4000, // 4 seconds
|
||||
xAxisLabelFormat: 'elapsed'
|
||||
});
|
||||
|
||||
// Initial render
|
||||
@@ -163,12 +185,21 @@
|
||||
// Add some randomness around the base value (±3)
|
||||
const variation = Math.floor(Math.random() * 7) - 3;
|
||||
const value = this.baseValue + variation;
|
||||
|
||||
|
||||
// Increase the base value slightly for next time (0.5 to 1.5 increase)
|
||||
this.baseValue += 0.5 + Math.random();
|
||||
|
||||
|
||||
return Math.max(1, Math.round(value));
|
||||
}
|
||||
|
||||
generateRandomInterval() {
|
||||
// Generate random interval based on update interval setting
|
||||
// Random between 10% and 200% of the base update interval
|
||||
const baseInterval = parseInt(document.getElementById('update-interval').value);
|
||||
const minInterval = Math.max(50, baseInterval * 0.1); // Minimum 50ms
|
||||
const maxInterval = baseInterval * 2; // Maximum 2x the base interval
|
||||
return Math.floor(Math.random() * (maxInterval - minInterval)) + minInterval;
|
||||
}
|
||||
|
||||
updateCountdown() {
|
||||
if (!this.isRunning || !this.nextUpdateTime) {
|
||||
@@ -183,46 +214,60 @@
|
||||
|
||||
start() {
|
||||
if (this.isRunning) return;
|
||||
|
||||
|
||||
this.isRunning = true;
|
||||
document.getElementById('status').textContent = 'Running';
|
||||
|
||||
|
||||
// Add first data point immediately
|
||||
chart.addValue(this.generateValue());
|
||||
|
||||
// Set up interval for subsequent updates
|
||||
this.nextUpdateTime = Date.now() + this.updateInterval;
|
||||
this.intervalId = setInterval(() => {
|
||||
chart.addValue(this.generateValue());
|
||||
this.nextUpdateTime = Date.now() + this.updateInterval;
|
||||
}, this.updateInterval);
|
||||
|
||||
// Update countdown every second
|
||||
|
||||
// Set up interval for subsequent updates with random timing
|
||||
this.scheduleNextUpdate();
|
||||
this.countdownId = setInterval(() => {
|
||||
this.updateCountdown();
|
||||
}, 1000);
|
||||
|
||||
|
||||
this.updateCountdown();
|
||||
}
|
||||
|
||||
scheduleNextUpdate() {
|
||||
if (!this.isRunning) return;
|
||||
|
||||
const randomInterval = this.generateRandomInterval();
|
||||
this.nextUpdateTime = Date.now() + randomInterval;
|
||||
|
||||
this.intervalId = setTimeout(() => {
|
||||
if (this.isRunning) {
|
||||
chart.addValue(this.generateValue());
|
||||
this.scheduleNextUpdate();
|
||||
}
|
||||
}, randomInterval);
|
||||
}
|
||||
|
||||
stop() {
|
||||
if (!this.isRunning) return;
|
||||
|
||||
|
||||
this.isRunning = false;
|
||||
document.getElementById('status').textContent = 'Stopped';
|
||||
|
||||
|
||||
if (this.intervalId) {
|
||||
clearInterval(this.intervalId);
|
||||
clearTimeout(this.intervalId);
|
||||
this.intervalId = null;
|
||||
}
|
||||
|
||||
|
||||
if (this.countdownId) {
|
||||
clearInterval(this.countdownId);
|
||||
this.countdownId = null;
|
||||
}
|
||||
|
||||
|
||||
this.nextUpdateTime = null;
|
||||
this.updateCountdown();
|
||||
|
||||
// Stop bin rotation timer when stopping data generation
|
||||
if (chart.binCheckInterval) {
|
||||
clearInterval(chart.binCheckInterval);
|
||||
chart.binCheckInterval = null;
|
||||
}
|
||||
}
|
||||
|
||||
reset() {
|
||||
@@ -235,18 +280,48 @@
|
||||
// Create data generator for testing
|
||||
let dataGenerator = new DataGenerator(1000);
|
||||
|
||||
// Function to toggle bin mode
|
||||
function toggleBinMode() {
|
||||
const useBinMode = document.getElementById('use-bin-mode').checked;
|
||||
const binDurationInput = document.getElementById('bin-duration');
|
||||
const xAxisFormatSelect = document.getElementById('x-axis-format');
|
||||
const rotateBinBtn = document.getElementById('rotate-bin-btn');
|
||||
const binInfo = document.getElementById('bin-info');
|
||||
const legendText = document.getElementById('legend-text');
|
||||
|
||||
if (useBinMode) {
|
||||
rotateBinBtn.style.display = 'inline-block';
|
||||
binInfo.style.display = 'block';
|
||||
legendText.textContent = 'Each X represents a count of events. O marks the active bin.';
|
||||
} else {
|
||||
rotateBinBtn.style.display = 'none';
|
||||
binInfo.style.display = 'none';
|
||||
legendText.textContent = 'Each X represents a count of events';
|
||||
}
|
||||
}
|
||||
|
||||
// Function to manually rotate bin
|
||||
function rotateBin() {
|
||||
if (chart && chart.useBinMode) {
|
||||
chart.rotateBin();
|
||||
}
|
||||
}
|
||||
|
||||
// Function to apply settings
|
||||
function applySettings() {
|
||||
const wasRunning = dataGenerator.isRunning;
|
||||
|
||||
|
||||
// Stop current generator
|
||||
dataGenerator.stop();
|
||||
|
||||
|
||||
// Get new settings
|
||||
const updateInterval = parseInt(document.getElementById('update-interval').value);
|
||||
const maxColumns = parseInt(document.getElementById('max-columns').value);
|
||||
const chartHeight = parseInt(document.getElementById('chart-height').value);
|
||||
|
||||
const useBinMode = document.getElementById('use-bin-mode').checked;
|
||||
const binDuration = parseFloat(document.getElementById('bin-duration').value) * 1000; // Convert to milliseconds
|
||||
const xAxisLabelFormat = document.getElementById('x-axis-format').value;
|
||||
|
||||
// Recreate chart with new settings
|
||||
chart = new ASCIIBarChart('chart-container', {
|
||||
maxHeight: chartHeight,
|
||||
@@ -254,20 +329,43 @@
|
||||
title: 'Real-Time Data Visualization',
|
||||
xAxisLabel: 'Time (seconds)',
|
||||
yAxisLabel: 'Count',
|
||||
autoFitWidth: true
|
||||
autoFitWidth: true,
|
||||
useBinMode: useBinMode,
|
||||
binDuration: binDuration,
|
||||
xAxisLabelFormat: xAxisLabelFormat
|
||||
});
|
||||
|
||||
|
||||
// Force font size adjustment for new settings
|
||||
chart.fontSizeAdjusted = false;
|
||||
chart.render();
|
||||
chart.updateInfo();
|
||||
|
||||
|
||||
// Recreate data generator with new interval
|
||||
dataGenerator = new DataGenerator(updateInterval);
|
||||
|
||||
|
||||
// Restart if it was running
|
||||
if (wasRunning) {
|
||||
dataGenerator.start();
|
||||
} else {
|
||||
// If not restarting, make sure bin timer is also stopped
|
||||
if (chart.binCheckInterval) {
|
||||
clearInterval(chart.binCheckInterval);
|
||||
chart.binCheckInterval = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update bin info display
|
||||
setInterval(() => {
|
||||
if (chart && chart.useBinMode && chart.bins.length > 0) {
|
||||
const currentBin = chart.currentBinIndex + 1;
|
||||
const timeRemaining = chart.binStartTime ?
|
||||
Math.max(0, Math.ceil((chart.binStartTime + chart.binDuration - Date.now()) / 1000)) : 0;
|
||||
|
||||
document.getElementById('current-bin').textContent = currentBin;
|
||||
document.getElementById('time-remaining').textContent = timeRemaining;
|
||||
}
|
||||
}, 1000);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user