From a7290e49eec08762142703bb483fbf68f0444552 Mon Sep 17 00:00:00 2001 From: Shen Zhang Date: Sat, 25 Oct 2025 17:34:39 -0500 Subject: [PATCH 1/2] Added subtitle to hero section, deleted description. Added affiliation of routers on leaderboard page and leaderboard preview. Changed leaderboard preview text Principled dataset -> diverse dataset Larger text on the dataset composition graph Removed contact us button Removed blue bars New color scheme for top 3, and new icons Two decimal metrics. Larger text on spider and deferral graph More specific information on evaluation metrics Fixed github repo link --- src/components/DatasetCompositionChart.tsx | 19 ++-- src/components/DeferralCurve.tsx | 10 +- src/components/Header.tsx | 3 +- src/components/SpiderChart.css | 6 +- src/components/SpiderChart.tsx | 82 +++++++-------- src/data/mockData.ts | 11 +- src/index.css | 12 +++ src/pages/HomePage.css | 59 +++++++---- src/pages/HomePage.tsx | 21 ++-- src/pages/LeaderboardPage.css | 82 +++++++++++---- src/pages/LeaderboardPage.tsx | 113 +++++++++++++-------- src/types/index.ts | 1 + 12 files changed, 269 insertions(+), 150 deletions(-) diff --git a/src/components/DatasetCompositionChart.tsx b/src/components/DatasetCompositionChart.tsx index a46b678..eef4d0e 100644 --- a/src/components/DatasetCompositionChart.tsx +++ b/src/components/DatasetCompositionChart.tsx @@ -332,7 +332,14 @@ const DatasetCompositionChart: React.FC = () => { const midAngle = (startAngle + endAngle) / 2; const RADIAN = Math.PI / 180; - const radius = CHART_DIMENSIONS.outerRadius + 60; + // Adaptive label radius: farther for sides, closer for top/bottom + const baseOffset = 60; // baseline distance beyond pie edge + const sideBoost = 40; // extra distance for left/right labels + const angleFactor = Math.abs(Math.sin(midAngle * RADIAN)); + // 0 for top/bottom, 1 for sides + + const radius = CHART_DIMENSIONS.outerRadius + baseOffset + sideBoost * angleFactor; + // Use exact center coordinates matching Recharts const centerX = 400; // Exact center of 800x800 viewBox const centerY = 400; // Exact center of 800x800 viewBox @@ -360,10 +367,10 @@ const DatasetCompositionChart: React.FC = () => { return ( { fill="#1f2937" textAnchor="middle" dominantBaseline="central" - fontSize="14" + fontSize="19" fontWeight="700" > {shortName} diff --git a/src/components/DeferralCurve.tsx b/src/components/DeferralCurve.tsx index 3092354..9ab2e52 100644 --- a/src/components/DeferralCurve.tsx +++ b/src/components/DeferralCurve.tsx @@ -238,7 +238,7 @@ const DeferralCurve: React.FC = ({ academicPoints, commercia = ({ academicPoints, commercia @@ -307,7 +307,7 @@ const DeferralCurve: React.FC = ({ academicPoints, commercia @@ -323,7 +323,7 @@ const DeferralCurve: React.FC = ({ academicPoints, commercia = ({ academicPoints, commercia { const [isMenuOpen, setIsMenuOpen] = useState(false); @@ -10,7 +11,7 @@ const Header: React.FC = () => { const navigation = [ { name: 'Home', href: '/', icon: Home }, { name: 'Leaderboard', href: '/leaderboard', icon: Trophy }, - { name: 'GitHub', href: 'https://github.com/RouteWorks', icon: Github, isExternal: true }, + { name: 'GitHub', href: contactInfo.github, icon: Github, isExternal: true }, { name: 'Contact', href: '#contact', icon: Users, isScroll: true }, ]; diff --git a/src/components/SpiderChart.css b/src/components/SpiderChart.css index 0996d79..96b3777 100644 --- a/src/components/SpiderChart.css +++ b/src/components/SpiderChart.css @@ -23,21 +23,21 @@ } .metric-label { - font-size: 0.8rem; + font-size: 1.1rem; font-weight: 600; text-anchor: middle; dominant-baseline: middle; } .metric-score { - font-size: 0.7rem; + font-size: 1rem; font-weight: 500; text-anchor: middle; dominant-baseline: middle; } .grid-label { - font-size: 0.7rem; + font-size: 0.9rem; font-weight: 500; text-anchor: start; dominant-baseline: middle; diff --git a/src/components/SpiderChart.tsx b/src/components/SpiderChart.tsx index a0cf01d..7c4be2c 100644 --- a/src/components/SpiderChart.tsx +++ b/src/components/SpiderChart.tsx @@ -74,36 +74,39 @@ const SpiderChart: React.FC = ({ routers, maxRouters = 5 }) =>
- {/* Grid circles with score labels */} - {[0.2, 0.4, 0.6, 0.8, 1.0].map((scale, index) => { - // Convert visual scale to actual axis values - const actualValue = axisMin + (scale * axisRange); - const score = actualValue.toFixed(1); - - return ( - - - - {score} - - - ); - })} + {/* Grid circles drawn at real 0.1 score increments */} + {Array.from({ length: 11 }, (_, i) => (i * 0.1)) + .filter(v => v >= axisMin && v <= axisMax) + .map((value, index) => { + // Map true axis value -> 0–1 visual radius fraction + const scale = (value - axisMin) / axisRange; + const r = chartRadius * scale; + + return ( + + + + {value.toFixed(1)} + + + ); + })} + {/* Grid lines (axes) */} {metrics.map((metric, index) => { @@ -134,31 +137,16 @@ const SpiderChart: React.FC = ({ routers, maxRouters = 5 }) => {metric.label} - - {metric.key === 'arenaScore' ? 'Arena' : - metric.key === 'costRatioScore' ? 'Cost' : - metric.key === 'optimalAccScore' ? 'Optimal' : - metric.key === 'latencyScore' ? 'Latency' : - 'Robust'} - ); })} diff --git a/src/data/mockData.ts b/src/data/mockData.ts index b14abbd..891c5ef 100644 --- a/src/data/mockData.ts +++ b/src/data/mockData.ts @@ -12,7 +12,7 @@ export const contactInfo: ContactInfo = { ], institution: 'Rice University', email: 'yifan.lu@rice.edu', - github: 'https://github.com/RouteWorks', + github: 'https://github.com/RouteWorks/RouterArena', paper: 'https://www.arxiv.org/abs/2510.00202' }; @@ -30,6 +30,7 @@ export const routers: Router[] = [ name: 'CARROT', type: 'academic', description: 'Cost-aware routing with dual contrastive learning approach', + affiliation: 'UMich', metrics: { arenaScore: 0.85, costRatioScore: 0.92, @@ -47,6 +48,7 @@ export const routers: Router[] = [ name: 'RouterDC', type: 'academic', description: 'Dual contrastive learning-based router with cost optimization', + affiliation: 'SUSTech', metrics: { arenaScore: 0.82, costRatioScore: 0.95, @@ -64,6 +66,7 @@ export const routers: Router[] = [ name: 'GraphRouter', type: 'academic', description: 'Graph neural network-based routing with semantic understanding', + affiliation: 'UIUC', metrics: { arenaScore: 0.80, costRatioScore: 0.88, @@ -81,6 +84,7 @@ export const routers: Router[] = [ name: 'MIRT-BERT', type: 'academic', description: 'Multi-item response theory with BERT embeddings', + affiliation: 'Unknown', metrics: { arenaScore: 0.78, costRatioScore: 0.75, @@ -98,6 +102,7 @@ export const routers: Router[] = [ name: 'NIRT-BERT', type: 'academic', description: 'Neural item response theory with BERT-based routing', + affiliation: 'Unknown', metrics: { arenaScore: 0.76, costRatioScore: 0.70, @@ -115,6 +120,7 @@ export const routers: Router[] = [ name: 'RouteLLM', type: 'academic', description: 'Binary selection between strong and weak models', + affiliation: 'Berkeley', metrics: { arenaScore: 0.74, costRatioScore: 0.85, @@ -132,6 +138,7 @@ export const routers: Router[] = [ name: 'GPT-5', type: 'commercial', description: 'OpenAI\'s internal routing system for GPT model family', + affiliation: 'OpenAI', metrics: { arenaScore: 0.88, costRatioScore: 0.60, @@ -149,6 +156,7 @@ export const routers: Router[] = [ name: 'NotDiamond', type: 'commercial', description: 'Commercial routing service with access to 60+ models', + affiliation: 'NotDiamond', metrics: { arenaScore: 0.82, costRatioScore: 0.65, @@ -166,6 +174,7 @@ export const routers: Router[] = [ name: 'Azure Model Router', type: 'commercial', description: 'Microsoft Azure\'s model routing service', + affiliation: 'Microsoft', metrics: { arenaScore: 0.80, costRatioScore: 0.70, diff --git a/src/index.css b/src/index.css index ec2585e..956ec90 100644 --- a/src/index.css +++ b/src/index.css @@ -1,3 +1,15 @@ +:root { + /* Leaderboard Rank Colors */ + --rank-1-bg: #fbbf24; + --rank-1-text: #0f172a; + --rank-2-bg: #9ca3af; + --rank-2-text: white; + --rank-3-bg: #7e4800; + --rank-3-text: white; + --rank-other-bg: #e5e7eb; + --rank-other-text: #6b7280; +} + body { margin: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', diff --git a/src/pages/HomePage.css b/src/pages/HomePage.css index cfdd4d0..58fd08b 100644 --- a/src/pages/HomePage.css +++ b/src/pages/HomePage.css @@ -20,7 +20,6 @@ padding: 0 1rem; display: grid; grid-template-columns: 1fr 1fr; - gap: 4rem; align-items: center; } @@ -28,9 +27,19 @@ font-size: 3rem; font-weight: 700; line-height: 1.2; + margin-bottom: 1rem; + padding-right: 4rem; + margin-left: 2rem; +} + +.hero-subtitle-short { + font-size: 1.2rem; + line-height: 1.5; margin-bottom: 1.5rem; + color: rgba(255, 255, 255, 0.9); padding-right: 4rem; margin-left: 2rem; + font-weight: 400; } .highlight { @@ -154,11 +163,12 @@ } .hero-right-content { - display: grid; + display: flex; grid-template-columns: 1fr 1fr; gap: 1rem; align-items: start; height: 100%; + float: right; } .hero-cards-container { @@ -219,25 +229,40 @@ transition: all 0.2s ease; } +.rank-item .name { + flex: 1; +} + .rank-item:hover { background: #e9ecef; transform: translateX(4px); } + +.affiliation { + font-size: 0.9rem; + opacity: 1; + font-weight: 500; +} + +.rank-item .affiliation { + color: inherit; +} + .rank-item.rank-1 { - background: #fbbf24; - color: #0f172a; + background: var(--rank-1-bg); + color: var(--rank-1-text); font-weight: 600; } .rank-item.rank-2 { - background: #9ca3af; - color: white; + background: var(--rank-2-bg); + color: var(--rank-2-text); } .rank-item.rank-3 { - background: #f59e0b; - color: white; + background: var(--rank-3-bg); + color: var(--rank-3-text); } .rank { @@ -552,16 +577,22 @@ font-size: 1.1rem; } + + + .authors-grid { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); - gap: 1.5rem; + display: flex; + flex-wrap: wrap; + gap: 1.25rem; /* row/col spacing */ + justify-content: center; /* ✅ centers the last row */ } .author-card { background: #f8f9fa; padding: 1.5rem; border-radius: 8px; + flex: 0 1 240px; /* grow/shrink with a preferred width */ + max-width: 320px; /* prevent over-stretch */ text-align: center; } @@ -688,9 +719,3 @@ grid-template-columns: 1fr; } } - -@media (max-width: 480px) { - .authors-grid { - grid-template-columns: 1fr; - } -} diff --git a/src/pages/HomePage.tsx b/src/pages/HomePage.tsx index 0dfdd0d..72659b8 100644 --- a/src/pages/HomePage.tsx +++ b/src/pages/HomePage.tsx @@ -34,6 +34,9 @@ const HomePage: React.FC = () => { RouterArena: An Open Platform for Comprehensive Comparison of LLM Routers +

+ Diverse dataset, extensive metrics, and live leaderboard +

@@ -43,11 +46,6 @@ const HomePage: React.FC = () => {
-

- The first open platform enabling comprehensive evaluation and comparison of LLM routers - with principled datasets, extensive metrics, and automated leaderboard updates. -

-
@@ -59,6 +57,7 @@ const HomePage: React.FC = () => {
{index + 1} {router.name} + {router.affiliation}
))}
@@ -67,7 +66,7 @@ const HomePage: React.FC = () => {

Want to see your router on the leaderboard?

- Contact us or submit a GitHub issue to evaluate your router on the RouterArena platform + Open a GitHub issue on our RouterArena platform.

Get Started → @@ -91,7 +90,7 @@ const HomePage: React.FC = () => { onClick={() => setActiveTab('dataset')} > - Principled Dataset + Diverse Dataset
-

Principled Dataset

+

Diverse Dataset

{datasetInfo.totalQueries.toLocaleString()} queries across {datasetInfo.domains} domains and {datasetInfo.categories} categories, designed using Dewey Decimal Classification @@ -243,7 +242,7 @@ const HomePage: React.FC = () => {

{/* Team Content */} diff --git a/src/pages/LeaderboardPage.css b/src/pages/LeaderboardPage.css index 1f2e39b..603e8ae 100644 --- a/src/pages/LeaderboardPage.css +++ b/src/pages/LeaderboardPage.css @@ -162,9 +162,13 @@ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); } +:root { + --lb-grid: 60px minmax(140px, 1.4fr) minmax(120px, 1fr) 0.8fr repeat(5, minmax(90px, 1fr)); +} + .leaderboard-header { display: grid; - grid-template-columns: 60px minmax(140px, 1.4fr) 0.8fr repeat(5, minmax(90px, 1fr)) 0.7fr; /* responsive fractions that fit container */ + grid-template-columns: var(--lb-grid); gap: 0.75rem; padding: 1rem 1.5rem; background: #f8fafc; @@ -183,7 +187,7 @@ .leaderboard-row { display: grid; - grid-template-columns: 60px minmax(140px, 1.4fr) 0.8fr repeat(5, minmax(90px, 1fr)) 0.7fr; /* match header */ + grid-template-columns: var(--lb-grid); gap: 0.5rem; padding: 0.5rem 0.75rem; /* shorter rows */ border-bottom: 1px solid #e5e7eb; @@ -222,37 +226,66 @@ .rank-col { display: flex; - justify-content: center; align-items: center; + justify-content: center; + min-width: 60px; } + .rank-badge { - padding: 0.5rem 0.75rem; - border-radius: 20px; - font-size: 0.9rem; + display: flex; + align-items: center; + justify-content: center; + width: 36px; + height: 36px; + border-radius: 50%; + font-size: 18px; /* bigger number text */ font-weight: 700; - text-align: center; - min-width: 40px; + color: #1f2937; +} + +.rank-badge.gold { + background: linear-gradient(135deg, #facc15, #ffd209); + box-shadow: 0 0 10px rgba(180, 134, 9, 0.5); +} + +.rank-badge.silver { + background: linear-gradient(135deg, #d1d5db, #9ca3af); + box-shadow: 0 0 10px rgba(156, 163, 175, 0.4); +} + +.rank-badge.bronze { + background: linear-gradient(135deg, #f59e0b, #b45309); + box-shadow: 0 0 10px rgba(245, 158, 11, 0.4); +} + +.rank-badge.rank-other { + background-color: #e5e7eb; + color: #111827; + font-size: 20px; /* rank numbers larger too */ } + + + .rank-badge.rank-1 { - background: #fbbf24; - color: #0f172a; + background: var(--rank-1-bg); + color: var(--rank-1-text); } .rank-badge.rank-2 { - background: #9ca3af; - color: white; + background: var(--rank-2-bg); + color: var(--rank-2-text); } .rank-badge.rank-3 { - background: #f59e0b; - color: white; + background: var(--rank-3-bg); + color: var(--rank-3-text); } .rank-badge.rank-other { - background: #e5e7eb; - color: #6b7280; + background: var(--rank-other-bg); + color: var(--rank-other-text); } .name-col { @@ -260,6 +293,18 @@ align-items: center; } +.affiliation-col { + display: flex; + align-items: center; + min-width: 120px; +} + +.affiliation { + font-size: 0.9rem; + color: #6b7280; + font-weight: 500; +} + .router-info { display: flex; flex-direction: column; @@ -506,9 +551,12 @@ .leaderboard-container { min-width: 1000px; } + :root { + --lb-grid: 70px 250px 120px 100px repeat(5, 120px); + } + .leaderboard-header, .leaderboard-row { - grid-template-columns: 70px 250px 100px repeat(5, 120px) 90px; gap: 0.75rem; } diff --git a/src/pages/LeaderboardPage.tsx b/src/pages/LeaderboardPage.tsx index 43f7617..5f07957 100644 --- a/src/pages/LeaderboardPage.tsx +++ b/src/pages/LeaderboardPage.tsx @@ -1,5 +1,5 @@ import React, { useState, useMemo } from 'react'; -import { Trophy, Search } from 'lucide-react'; +import { Trophy, Search, Medal} from 'lucide-react'; import { routers } from '../data/mockData'; import SpiderChart from '../components/SpiderChart'; import DeferralCurve from '../components/DeferralCurve'; @@ -54,13 +54,44 @@ const LeaderboardPage: React.FC = () => { return filtered.sort((a, b) => b.metrics[key] - a.metrics[key]); }, [searchTerm, filterType, activeMetric]); - const getRankBadge = (rank: number) => { - if (rank === 1) return 'rank-1'; - if (rank === 2) return 'rank-2'; - if (rank === 3) return 'rank-3'; - return 'rank-other'; + // const getRankBadge = (rank: number) => { + // if (rank === 1) return 'rank-1'; + // if (rank === 2) return 'rank-2'; + // if (rank === 3) return 'rank-3'; + // return 'rank-other'; + // }; + + const renderRankBadge = (rank: number) => { + const baseClass = 'rank-badge'; + switch (rank) { + case 1: + return ( +
+ +
+ ); + case 2: + return ( +
+ +
+ ); + case 3: + return ( +
+ +
+ ); + default: + return ( + + {rank} + + ); + } }; + return (
@@ -129,7 +160,6 @@ const LeaderboardPage: React.FC = () => {
-