Skip to content

Commit 23f182a

Browse files
committed
feat: Dynamically adjust cost scale and ticks based on visible entries
1 parent 119fbc9 commit 23f182a

File tree

1 file changed

+128
-59
lines changed

1 file changed

+128
-59
lines changed

aider/website/_includes/leaderboard_table.js

Lines changed: 128 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ document.addEventListener('DOMContentLoaded', function() {
3434
if (currentMode === 'select') {
3535
updateSelectAllCheckboxState();
3636
}
37+
38+
// Update cost bars and ticks since visible rows may have changed
39+
updateCostBars();
40+
updateCostTicks();
3741
}
3842

3943
function getVisibleMainRows() {
@@ -89,7 +93,6 @@ document.addEventListener('DOMContentLoaded', function() {
8993
// Get the first header cell (for the toggle/checkbox column)
9094
const firstHeaderCell = document.querySelector('table thead th:first-child');
9195

92-
9396
// Show/hide header checkbox based on mode
9497
selectAllCheckbox.style.display = mode === 'select' ? 'inline-block' : 'none';
9598

@@ -193,6 +196,10 @@ document.addEventListener('DOMContentLoaded', function() {
193196

194197
// Update the select-all checkbox state after updating the view
195198
updateSelectAllCheckboxState();
199+
200+
// Update cost bars and ticks since visible/selected rows may have changed
201+
updateCostBars();
202+
updateCostTicks();
196203
}
197204

198205

@@ -209,75 +216,127 @@ document.addEventListener('DOMContentLoaded', function() {
209216
}
210217
});
211218

212-
// Process cost bars
213-
const costBars = document.querySelectorAll('.cost-bar');
214-
const MAX_DISPLAY_COST = 50; // $50 limit for visual display
219+
// Function to calculate the appropriate max display cost based on visible/selected entries
220+
function calculateDisplayMaxCost() {
221+
// Get the appropriate set of rows based on the current mode and selection state
222+
let rowsToConsider;
223+
224+
if (currentMode === 'view' && selectedRows.size > 0) {
225+
// In view mode with selections, only consider selected rows
226+
rowsToConsider = Array.from(allMainRows).filter(row => {
227+
const rowIndex = row.querySelector('.row-selector')?.dataset.rowIndex;
228+
return rowIndex && selectedRows.has(rowIndex) && !row.classList.contains('hidden-by-search');
229+
});
230+
} else {
231+
// In other modes or without selections, consider all visible rows
232+
rowsToConsider = getVisibleMainRows();
233+
}
234+
235+
// Find the maximum cost among the rows to consider
236+
let maxCost = 0;
237+
rowsToConsider.forEach(row => {
238+
const costBar = row.querySelector('.cost-bar');
239+
if (costBar) {
240+
const cost = parseFloat(costBar.dataset.cost || '0');
241+
if (cost > maxCost) maxCost = cost;
242+
}
243+
});
244+
245+
// Cap at 50 if any entries exceed that amount, otherwise use actual max
246+
return maxCost > 50 ? 50 : Math.max(1, maxCost); // Ensure at least 1 to avoid division by zero
247+
}
215248

216-
costBars.forEach(bar => {
217-
const cost = parseFloat(bar.dataset.cost);
218-
const maxCost = parseFloat(bar.dataset.maxCost);
219-
220-
if (cost > 0 && maxCost > 0) {
221-
// Use $50 as the max for display purposes
222-
const displayMaxCost = Math.min(MAX_DISPLAY_COST, maxCost);
223-
// Calculate percentage based on the display max
224-
const percent = Math.min(cost, displayMaxCost) / displayMaxCost * 100;
225-
// Clamp percentage between 0 and 100
226-
bar.style.width = Math.max(0, Math.min(100, percent)) + '%';
249+
// Process cost bars with dynamic scale
250+
function updateCostBars() {
251+
const costBars = document.querySelectorAll('.cost-bar');
252+
const currentMaxDisplayCost = calculateDisplayMaxCost();
253+
254+
// Remove existing special indicators first
255+
document.querySelectorAll('.dark-section, .tear-line').forEach(el => el.remove());
256+
257+
costBars.forEach(bar => {
258+
const cost = parseFloat(bar.dataset.cost);
227259

228-
// Mark bars that exceed the limit
229-
if (cost > MAX_DISPLAY_COST) {
230-
// Create a darker section at the end with diagonal stripes
231-
const darkSection = document.createElement('div');
232-
darkSection.className = 'bar-viz';
233-
darkSection.style.width = '15%'; // From 85% to 100%
234-
darkSection.style.left = '85%';
235-
darkSection.style.backgroundColor = 'rgba(13, 110, 253, 0.6)'; // Darker blue
236-
darkSection.style.borderRight = '1px solid rgba(13, 110, 253, 0.8)';
237-
darkSection.style.zIndex = '1';
238-
// Add diagonal stripes with CSS background
239-
darkSection.style.backgroundImage = 'repeating-linear-gradient(45deg, rgba(255,255,255,0.3), rgba(255,255,255,0.3) 5px, transparent 5px, transparent 10px)';
240-
bar.parentNode.appendChild(darkSection);
260+
if (cost > 0) {
261+
// Calculate percentage based on the dynamic display max
262+
const percent = Math.min(cost, currentMaxDisplayCost) / currentMaxDisplayCost * 100;
263+
// Clamp percentage between 0 and 100
264+
bar.style.width = Math.max(0, Math.min(100, percent)) + '%';
241265

242-
// Add a dashed "tear line" at the transition point
243-
const tearLine = document.createElement('div');
244-
tearLine.style.position = 'absolute';
245-
tearLine.style.left = '85%';
246-
// Center the tear line vertically and make it 1.5x as tall as the bar
247-
tearLine.style.top = '50%';
248-
tearLine.style.transform = 'translateY(-50%)';
249-
tearLine.style.height = '54px'; // 1.5x the bar height (36px)
250-
tearLine.style.width = '2px';
251-
tearLine.style.backgroundColor = 'white';
252-
tearLine.style.borderLeft = '2px dashed rgba(0, 0, 0, 0.3)';
253-
tearLine.style.zIndex = '2'; // Above the bar
254-
bar.parentNode.appendChild(tearLine);
266+
// Mark bars that exceed the limit (only if our display max is capped at 50)
267+
if (currentMaxDisplayCost === 50 && cost > 50) {
268+
// Create a darker section at the end with diagonal stripes
269+
const darkSection = document.createElement('div');
270+
darkSection.className = 'bar-viz dark-section';
271+
darkSection.style.width = '15%'; // From 85% to 100%
272+
darkSection.style.left = '85%';
273+
darkSection.style.backgroundColor = 'rgba(13, 110, 253, 0.6)'; // Darker blue
274+
darkSection.style.borderRight = '1px solid rgba(13, 110, 253, 0.8)';
275+
darkSection.style.zIndex = '1';
276+
// Add diagonal stripes with CSS background
277+
darkSection.style.backgroundImage = 'repeating-linear-gradient(45deg, rgba(255,255,255,0.3), rgba(255,255,255,0.3) 5px, transparent 5px, transparent 10px)';
278+
bar.parentNode.appendChild(darkSection);
279+
280+
// Add a dashed "tear line" at the transition point
281+
const tearLine = document.createElement('div');
282+
tearLine.className = 'tear-line';
283+
tearLine.style.position = 'absolute';
284+
tearLine.style.left = '85%';
285+
// Center the tear line vertically and make it 1.5x as tall as the bar
286+
tearLine.style.top = '50%';
287+
tearLine.style.transform = 'translateY(-50%)';
288+
tearLine.style.height = '54px'; // 1.5x the bar height (36px)
289+
tearLine.style.width = '2px';
290+
tearLine.style.backgroundColor = 'white';
291+
tearLine.style.borderLeft = '2px dashed rgba(0, 0, 0, 0.3)';
292+
tearLine.style.zIndex = '2'; // Above the bar
293+
bar.parentNode.appendChild(tearLine);
294+
}
295+
} else {
296+
// Set width to 0 if cost is 0 or negative
297+
bar.style.width = '0%';
255298
}
256-
} else {
257-
// Set width to 0 if cost is 0 or negative
258-
bar.style.width = '0%';
259-
}
260-
});
299+
});
300+
}
301+
302+
// Call this initially to set up the bars
303+
updateCostBars();
261304

262-
// Calculate and add cost ticks dynamically
263-
const costCells = document.querySelectorAll('.cost-bar-cell');
264-
if (costCells.length > 0) {
265-
const MAX_DISPLAY_COST = 50; // $50 limit for visual display
305+
// Update cost ticks dynamically based on current max display cost
306+
function updateCostTicks() {
307+
const costCells = document.querySelectorAll('.cost-bar-cell');
308+
if (costCells.length === 0) return;
309+
310+
const currentMaxDisplayCost = calculateDisplayMaxCost();
266311

267-
// Generate fixed tick values at $0, $10, $20, $30, $40, $50
268-
const tickValues = [0, 10, 20, 30, 40, 50];
312+
// Remove existing ticks first
313+
document.querySelectorAll('.cost-tick').forEach(tick => tick.remove());
314+
315+
// Generate appropriate tick values based on current max
316+
let tickValues = [];
317+
318+
if (currentMaxDisplayCost === 50) {
319+
// Fixed ticks at $0, $10, $20, $30, $40, $50 when we're at the cap
320+
tickValues = [0, 10, 20, 30, 40, 50];
321+
} else {
322+
// Dynamic ticks based on actual max
323+
const tickCount = 5; // Create 5 segments (6 ticks including 0)
324+
for (let i = 0; i <= tickCount; i++) {
325+
tickValues.push(Math.round((i / tickCount) * currentMaxDisplayCost * 100) / 100);
326+
}
327+
}
269328

270-
// Calculate percentage positions for each tick on the linear scale
329+
// Calculate percentage positions for each tick
271330
const tickPercentages = tickValues.map(tickCost => {
272-
return (tickCost / MAX_DISPLAY_COST) * 100;
331+
return (tickCost / currentMaxDisplayCost) * 100;
273332
});
274-
333+
275334
// Add tick divs to each cost cell
276335
costCells.forEach(cell => {
277336
const costBar = cell.querySelector('.cost-bar');
278337
// Use optional chaining and provide '0' as fallback if costBar or dataset.cost is missing
279338
const cost = parseFloat(costBar?.dataset?.cost || '0');
280-
339+
281340
// Only add ticks if the cost is actually greater than 0
282341
if (cost > 0) {
283342
tickPercentages.forEach((percent, index) => {
@@ -286,15 +345,15 @@ document.addEventListener('DOMContentLoaded', function() {
286345
const tick = document.createElement('div');
287346
tick.className = 'cost-tick';
288347
tick.style.left = `${percent}%`;
289-
290-
// No dollar amount labels
291-
292348
cell.appendChild(tick);
293349
}
294350
});
295351
}
296352
});
297353
}
354+
355+
// Call this initially to set up the ticks
356+
updateCostTicks();
298357

299358

300359
// --- New Event Listeners ---
@@ -340,6 +399,12 @@ document.addEventListener('DOMContentLoaded', function() {
340399
}
341400
// Update select-all checkbox state
342401
updateSelectAllCheckboxState();
402+
403+
// Update cost bars and ticks if in view mode, as selection affects what's shown
404+
if (currentMode === 'view') {
405+
updateCostBars();
406+
updateCostTicks();
407+
}
343408
}
344409
}); // End of tableBody listener
345410

@@ -369,6 +434,10 @@ document.addEventListener('DOMContentLoaded', function() {
369434
});
370435
// After bulk change, ensure the selectAll checkbox state is correct (not indeterminate)
371436
updateSelectAllCheckboxState();
437+
438+
// Update cost bars and ticks after selection changes
439+
updateCostBars();
440+
updateCostTicks();
372441
});
373442

374443
// Listener for search input

0 commit comments

Comments
 (0)