Fix baseline values
Browse files- static/index.html +40 -7
static/index.html
CHANGED
|
@@ -1276,10 +1276,11 @@ function parseLeaderboardMd(md) {
|
|
| 1276 |
const cells = t.split('|').map(c => c.trim()).filter((_, i, arr) => i > 0 && i < arr.length - 1);
|
| 1277 |
if (cells.length >= 5) {
|
| 1278 |
const score = parseInt(cells[0], 10);
|
| 1279 |
-
const
|
| 1280 |
-
const
|
| 1281 |
-
const
|
| 1282 |
-
|
|
|
|
| 1283 |
if (date && !date.endsWith('Z') && !date.includes('+')) date += 'Z';
|
| 1284 |
if (!isNaN(score) && agent && date) entries.push({ score, optimizer, agent, run, date });
|
| 1285 |
}
|
|
@@ -1605,6 +1606,8 @@ const NON_BEST_COLOR = '#9ca3af';
|
|
| 1605 |
const NON_BEST_LABEL_BG = 'rgba(107,114,128,0.08)';
|
| 1606 |
const NON_BEST_LABEL_BORDER = 'rgba(107,114,128,0.2)';
|
| 1607 |
const NON_BEST_LABEL_TEXT = '#6b7280';
|
|
|
|
|
|
|
| 1608 |
const GRID_COLOR = 'rgba(0,0,0,0.05)';
|
| 1609 |
|
| 1610 |
function renderChart(entries) {
|
|
@@ -1615,6 +1618,8 @@ function renderChart(entries) {
|
|
| 1615 |
sorted.forEach(e => { e.isRecord = e.score < runningBest; if (e.isRecord) runningBest = e.score; });
|
| 1616 |
const bestEntries = sorted.filter(e => e.isRecord);
|
| 1617 |
const nonBestEntries = sorted.filter(e => !e.isRecord);
|
|
|
|
|
|
|
| 1618 |
|
| 1619 |
const allDates = sorted.map(e => new Date(e.date).getTime());
|
| 1620 |
const minDate = Math.min(...allDates);
|
|
@@ -1630,6 +1635,10 @@ function renderChart(entries) {
|
|
| 1630 |
}
|
| 1631 |
const bestScatter = bestEntries.map(e => ({ x: new Date(e.date).getTime(), y: e.score, agent: e.agent }));
|
| 1632 |
const nonBestData = nonBestEntries.map(e => ({ x: new Date(e.date).getTime(), y: e.score, agent: e.agent }));
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1633 |
|
| 1634 |
const allScores = sorted.map(e => e.score);
|
| 1635 |
const minScore = Math.min(...allScores);
|
|
@@ -1639,7 +1648,7 @@ function renderChart(entries) {
|
|
| 1639 |
const bestLabels = {
|
| 1640 |
id: 'bestLabels',
|
| 1641 |
afterDatasetsDraw(c) {
|
| 1642 |
-
const meta = c.getDatasetMeta(
|
| 1643 |
if (!meta?.data) return;
|
| 1644 |
const ctx2 = c.ctx;
|
| 1645 |
ctx2.save();
|
|
@@ -1668,7 +1677,7 @@ function renderChart(entries) {
|
|
| 1668 |
const nonBestLabels = {
|
| 1669 |
id: 'nonBestLabels',
|
| 1670 |
afterDatasetsDraw(c) {
|
| 1671 |
-
const meta = c.getDatasetMeta(
|
| 1672 |
if (!meta?.data) return;
|
| 1673 |
const ctx2 = c.ctx;
|
| 1674 |
ctx2.save();
|
|
@@ -1694,12 +1703,36 @@ function renderChart(entries) {
|
|
| 1694 |
ctx2.restore();
|
| 1695 |
}
|
| 1696 |
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1697 |
|
| 1698 |
const ctx = document.getElementById('evolutionChart').getContext('2d');
|
| 1699 |
chart = new Chart(ctx, {
|
| 1700 |
type: 'line',
|
| 1701 |
data: {
|
| 1702 |
datasets: [
|
|
|
|
| 1703 |
{ label: 'Running Best', data: bestLineData, borderColor: HF_ORANGE, backgroundColor: HF_ORANGE_DIM, borderWidth: 2.5, stepped: 'after', fill: true, pointRadius: 0, pointHoverRadius: 0, tension: 0, order: 2 },
|
| 1704 |
{ label: 'Records', data: bestScatter, type: 'scatter', backgroundColor: HF_ORANGE, borderColor: '#fff', borderWidth: 2, pointRadius: 7, pointHoverRadius: 9, pointStyle: 'circle', order: 1 },
|
| 1705 |
{ label: 'Non-Records', data: nonBestData, type: 'scatter', backgroundColor: NON_BEST_COLOR, borderColor: '#fff', borderWidth: 1.5, pointRadius: 5, pointHoverRadius: 7, pointStyle: 'circle', order: 0 },
|
|
@@ -1749,7 +1782,7 @@ function renderChart(entries) {
|
|
| 1749 |
},
|
| 1750 |
interaction: { mode: 'nearest', intersect: true },
|
| 1751 |
},
|
| 1752 |
-
plugins: [bestLabels, nonBestLabels],
|
| 1753 |
});
|
| 1754 |
}
|
| 1755 |
|
|
|
|
| 1276 |
const cells = t.split('|').map(c => c.trim()).filter((_, i, arr) => i > 0 && i < arr.length - 1);
|
| 1277 |
if (cells.length >= 5) {
|
| 1278 |
const score = parseInt(cells[0], 10);
|
| 1279 |
+
const hasValLossColumn = cells.length >= 7;
|
| 1280 |
+
const optimizer = hasValLossColumn ? cells[2] : cells[1];
|
| 1281 |
+
const agent = hasValLossColumn ? cells[3] : cells[2];
|
| 1282 |
+
const run = hasValLossColumn ? cells[4] : cells[3];
|
| 1283 |
+
let date = hasValLossColumn ? cells[5] : cells[4];
|
| 1284 |
if (date && !date.endsWith('Z') && !date.includes('+')) date += 'Z';
|
| 1285 |
if (!isNaN(score) && agent && date) entries.push({ score, optimizer, agent, run, date });
|
| 1286 |
}
|
|
|
|
| 1606 |
const NON_BEST_LABEL_BG = 'rgba(107,114,128,0.08)';
|
| 1607 |
const NON_BEST_LABEL_BORDER = 'rgba(107,114,128,0.2)';
|
| 1608 |
const NON_BEST_LABEL_TEXT = '#6b7280';
|
| 1609 |
+
const BASELINE_GUIDE_COLOR = 'rgba(75,85,99,0.75)';
|
| 1610 |
+
const BASELINE_GUIDE_BG = 'rgba(249,250,251,0.92)';
|
| 1611 |
const GRID_COLOR = 'rgba(0,0,0,0.05)';
|
| 1612 |
|
| 1613 |
function renderChart(entries) {
|
|
|
|
| 1618 |
sorted.forEach(e => { e.isRecord = e.score < runningBest; if (e.isRecord) runningBest = e.score; });
|
| 1619 |
const bestEntries = sorted.filter(e => e.isRecord);
|
| 1620 |
const nonBestEntries = sorted.filter(e => !e.isRecord);
|
| 1621 |
+
const baselineScores = sorted.filter(e => e.agent === 'baseline').map(e => e.score);
|
| 1622 |
+
const baselineScore = baselineScores.length ? Math.min(...baselineScores) : null;
|
| 1623 |
|
| 1624 |
const allDates = sorted.map(e => new Date(e.date).getTime());
|
| 1625 |
const minDate = Math.min(...allDates);
|
|
|
|
| 1635 |
}
|
| 1636 |
const bestScatter = bestEntries.map(e => ({ x: new Date(e.date).getTime(), y: e.score, agent: e.agent }));
|
| 1637 |
const nonBestData = nonBestEntries.map(e => ({ x: new Date(e.date).getTime(), y: e.score, agent: e.agent }));
|
| 1638 |
+
const baselineGuideData = baselineScore === null ? [] : [
|
| 1639 |
+
{ x: minDate - datePadding, y: baselineScore, agent: 'Baseline' },
|
| 1640 |
+
{ x: extendedEnd, y: baselineScore, agent: 'Baseline' },
|
| 1641 |
+
];
|
| 1642 |
|
| 1643 |
const allScores = sorted.map(e => e.score);
|
| 1644 |
const minScore = Math.min(...allScores);
|
|
|
|
| 1648 |
const bestLabels = {
|
| 1649 |
id: 'bestLabels',
|
| 1650 |
afterDatasetsDraw(c) {
|
| 1651 |
+
const meta = c.getDatasetMeta(2);
|
| 1652 |
if (!meta?.data) return;
|
| 1653 |
const ctx2 = c.ctx;
|
| 1654 |
ctx2.save();
|
|
|
|
| 1677 |
const nonBestLabels = {
|
| 1678 |
id: 'nonBestLabels',
|
| 1679 |
afterDatasetsDraw(c) {
|
| 1680 |
+
const meta = c.getDatasetMeta(3);
|
| 1681 |
if (!meta?.data) return;
|
| 1682 |
const ctx2 = c.ctx;
|
| 1683 |
ctx2.save();
|
|
|
|
| 1703 |
ctx2.restore();
|
| 1704 |
}
|
| 1705 |
};
|
| 1706 |
+
const baselineGuideLabel = {
|
| 1707 |
+
id: 'baselineGuideLabel',
|
| 1708 |
+
afterDatasetsDraw(c) {
|
| 1709 |
+
if (baselineScore === null) return;
|
| 1710 |
+
const { ctx: ctx2, chartArea: a, scales } = c;
|
| 1711 |
+
const y = scales.y.getPixelForValue(baselineScore);
|
| 1712 |
+
if (y < a.top || y > a.bottom) return;
|
| 1713 |
+
const label = `Baseline ${baselineScore.toLocaleString()} steps`;
|
| 1714 |
+
ctx2.save();
|
| 1715 |
+
ctx2.font = '600 10px "JetBrains Mono", monospace';
|
| 1716 |
+
const px = 7, boxH = 20, tw = ctx2.measureText(label).width, boxW = tw + px * 2;
|
| 1717 |
+
const lx = Math.max(a.left + 4, a.right - boxW - 4);
|
| 1718 |
+
const ly = Math.max(a.top + 4, Math.min(y - boxH - 6, a.bottom - boxH - 4));
|
| 1719 |
+
ctx2.fillStyle = BASELINE_GUIDE_BG;
|
| 1720 |
+
ctx2.strokeStyle = BASELINE_GUIDE_COLOR;
|
| 1721 |
+
ctx2.lineWidth = 1;
|
| 1722 |
+
ctx2.beginPath(); ctx2.roundRect(lx, ly, boxW, boxH, 5); ctx2.fill(); ctx2.stroke();
|
| 1723 |
+
ctx2.fillStyle = BASELINE_GUIDE_COLOR;
|
| 1724 |
+
ctx2.textBaseline = 'middle';
|
| 1725 |
+
ctx2.fillText(label, lx + px, ly + boxH / 2);
|
| 1726 |
+
ctx2.restore();
|
| 1727 |
+
}
|
| 1728 |
+
};
|
| 1729 |
|
| 1730 |
const ctx = document.getElementById('evolutionChart').getContext('2d');
|
| 1731 |
chart = new Chart(ctx, {
|
| 1732 |
type: 'line',
|
| 1733 |
data: {
|
| 1734 |
datasets: [
|
| 1735 |
+
{ label: 'Baseline', data: baselineGuideData, borderColor: BASELINE_GUIDE_COLOR, borderWidth: 1.5, borderDash: [5, 5], pointRadius: 0, pointHoverRadius: 0, fill: false, tension: 0, order: 3 },
|
| 1736 |
{ label: 'Running Best', data: bestLineData, borderColor: HF_ORANGE, backgroundColor: HF_ORANGE_DIM, borderWidth: 2.5, stepped: 'after', fill: true, pointRadius: 0, pointHoverRadius: 0, tension: 0, order: 2 },
|
| 1737 |
{ label: 'Records', data: bestScatter, type: 'scatter', backgroundColor: HF_ORANGE, borderColor: '#fff', borderWidth: 2, pointRadius: 7, pointHoverRadius: 9, pointStyle: 'circle', order: 1 },
|
| 1738 |
{ label: 'Non-Records', data: nonBestData, type: 'scatter', backgroundColor: NON_BEST_COLOR, borderColor: '#fff', borderWidth: 1.5, pointRadius: 5, pointHoverRadius: 7, pointStyle: 'circle', order: 0 },
|
|
|
|
| 1782 |
},
|
| 1783 |
interaction: { mode: 'nearest', intersect: true },
|
| 1784 |
},
|
| 1785 |
+
plugins: [bestLabels, nonBestLabels, baselineGuideLabel],
|
| 1786 |
});
|
| 1787 |
}
|
| 1788 |
|