feat: Limit cost bar to $50, mark bars exceeding, add tick labels

This commit is contained in:
Paul Gauthier (aider) 2025-04-13 13:35:47 -07:00
parent fd94f1a5f9
commit f65e6a3bb1
2 changed files with 78 additions and 37 deletions

View file

@ -199,15 +199,28 @@ document.addEventListener('DOMContentLoaded', function() {
// Process cost bars
const costBars = document.querySelectorAll('.cost-bar');
const MAX_DISPLAY_COST = 50; // $50 limit for visual display
costBars.forEach(bar => {
const cost = parseFloat(bar.dataset.cost);
const maxCost = parseFloat(bar.dataset.maxCost);
if (cost > 0 && maxCost > 0) {
// Calculate percentage directly (linear scale)
const percent = (cost / maxCost) * 100;
// Use $50 as the max for display purposes
const displayMaxCost = Math.min(MAX_DISPLAY_COST, maxCost);
// Calculate percentage based on the display max
const percent = Math.min(cost, displayMaxCost) / displayMaxCost * 100;
// Clamp percentage between 0 and 100
bar.style.width = Math.max(0, Math.min(100, percent)) + '%';
// Mark bars that exceed the limit
if (cost > MAX_DISPLAY_COST) {
bar.classList.add('cost-exceeded');
// Add a marker at the end of the bar
const marker = document.createElement('div');
marker.className = 'cost-exceeded-marker';
bar.parentNode.appendChild(marker);
}
} else {
// Set width to 0 if cost is 0 or negative
bar.style.width = '0%';
@ -217,43 +230,45 @@ document.addEventListener('DOMContentLoaded', function() {
// Calculate and add cost ticks dynamically
const costCells = document.querySelectorAll('.cost-bar-cell');
if (costCells.length > 0) {
// Find the max cost from the first available cost bar's data attribute
const firstCostBar = document.querySelector('.cost-bar');
const maxCost = parseFloat(firstCostBar?.dataset.maxCost || '1'); // Use 1 as fallback
const MAX_DISPLAY_COST = 50; // $50 limit for visual display
// Generate fixed tick values at $0, $10, $20, $30, $40, $50
const tickValues = [0, 10, 20, 30, 40, 50];
// Calculate percentage positions for each tick on the linear scale
const tickPercentages = tickValues.map(tickCost => {
return (tickCost / MAX_DISPLAY_COST) * 100;
});
if (maxCost > 0) {
const tickValues = [];
// Generate ticks at regular intervals (every 20% of max cost)
tickValues.push(0); // Add tick at base (0 position)
for (let i = 1; i <= 5; i++) {
tickValues.push((maxCost * i) / 5);
}
// Add tick divs to each cost cell
costCells.forEach(cell => {
const costBar = cell.querySelector('.cost-bar');
// Use optional chaining and provide '0' as fallback if costBar or dataset.cost is missing
const cost = parseFloat(costBar?.dataset?.cost || '0');
// Calculate percentage positions for each tick on the linear scale
const tickPercentages = tickValues.map(tickCost => {
return (tickCost / maxCost) * 100;
});
// Add tick divs to each cost cell
costCells.forEach(cell => {
const costBar = cell.querySelector('.cost-bar');
// Use optional chaining and provide '0' as fallback if costBar or dataset.cost is missing
const cost = parseFloat(costBar?.dataset?.cost || '0');
// Only add ticks if the cost is actually greater than 0
if (cost > 0) {
tickPercentages.forEach(percent => {
// Ensure percentage is within valid range
if (percent >= 0 && percent <= 100) {
const tick = document.createElement('div');
tick.className = 'cost-tick';
tick.style.left = `${percent}%`;
cell.appendChild(tick);
// Only add ticks if the cost is actually greater than 0
if (cost > 0) {
tickPercentages.forEach((percent, index) => {
// Ensure percentage is within valid range
if (percent >= 0 && percent <= 100) {
const tick = document.createElement('div');
tick.className = 'cost-tick';
tick.style.left = `${percent}%`;
// Add dollar amount labels to the ticks
if (index % 2 === 0) { // Only label every other tick to avoid crowding
const label = document.createElement('div');
label.className = 'cost-tick-label';
label.textContent = '$' + tickValues[index];
label.style.left = `${percent}%`;
cell.appendChild(label);
}
});
}
});
}
cell.appendChild(tick);
}
});
}
});
}

View file

@ -34,7 +34,7 @@ human intervention.
</th> <!-- Header checkbox added here -->
<th style="padding: 8px; text-align: left;">Model</th>
<th style="padding: 8px; text-align: center; width: 25%">Percent correct</th>
<th style="padding: 8px; text-align: center; width: 25%">Cost</th>
<th style="padding: 8px; text-align: center; width: 25%">Cost (max $50)</th>
<th style="padding: 8px; text-align: left;" class="col-command">Command</th>
<th style="padding: 8px; text-align: center; width: 10%" class="col-conform">Correct edit format</th>
<th style="padding: 8px; text-align: left; width: 10%" class="col-edit-format">Edit Format</th>
@ -171,6 +171,32 @@ human intervention.
background-color: rgba(170, 170, 170, 0.5);
z-index: 2; /* Above the bar but below the text */
}
.cost-tick-label {
position: absolute;
top: 50%;
transform: translateY(20px);
font-size: 10px;
color: #666;
z-index: 2;
text-align: center;
margin-left: -10px;
}
.cost-exceeded {
background-color: rgba(220, 53, 69, 0.3) !important; /* Red background for exceeded cost */
border-right: 1px solid rgba(220, 53, 69, 0.5) !important;
}
.cost-exceeded-marker {
position: absolute;
right: 0;
top: 50%;
transform: translateY(-50%);
width: 0;
height: 0;
border-top: 6px solid transparent;
border-bottom: 6px solid transparent;
border-left: 6px solid rgba(220, 53, 69, 0.8);
z-index: 3;
}
.bar-viz {
position: absolute;
left: 0;