Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3,811 changes: 2,870 additions & 941 deletions package-lock.json

Large diffs are not rendered by default.

6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,23 @@
"@testing-library/jest-dom": "^6.9.1",
"@testing-library/react": "^16.3.0",
"@testing-library/user-event": "^13.5.0",
"katex": "^0.16.25",
"lucide-react": "^0.263.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-katex": "^3.1.0",
"react-router-dom": "^6.8.1",
"react-scripts": "5.0.1",
"recharts": "^2.8.0",
"web-vitals": "^2.1.4"
},
"devDependencies": {
"@types/node": "^16.18.0",
"@types/react": "^18.2.0",
"@types/react-dom": "^18.2.0",
"@types/react-katex": "^3.0.4",
"gh-pages": "^6.3.0",
"html-webpack-plugin": "^4.5.2",
"react-scripts": "^5.0.1",
"typescript": "^4.9.5"
},
"scripts": {
Expand Down
2 changes: 2 additions & 0 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@ import Header from './components/Header';
import HomePage from './pages/HomePage';
import LeaderboardPage from './pages/LeaderboardPage';
import SubmitPromptPage from './pages/SubmitPromptPage';
import GoogleAnalytics from './components/GoogleAnalytics';

const App: React.FC = () => {
return (
<Router>
<div className="App">
<GoogleAnalytics />
<Header />
<main className="main-content">
<Routes>
Expand Down
41 changes: 41 additions & 0 deletions src/components/GoogleAnalytics.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { useEffect } from 'react';
import { useLocation } from 'react-router-dom';

const GA_MEASUREMENT_ID = 'G-CFZYZLHP5X';

const GoogleAnalytics: React.FC = () => {
const location = useLocation();

useEffect(() => {
// Load Google Analytics script
const script1 = document.createElement('script');
script1.async = true;
script1.src = `https://www.googletagmanager.com/gtag/js?id=${GA_MEASUREMENT_ID}`;
document.head.appendChild(script1);

// Initialize dataLayer and gtag function
window.dataLayer = window.dataLayer || [];
function gtag(...args: any[]) {
window.dataLayer.push(args);
}
window.gtag = gtag;

gtag('js', new Date());
gtag('config', GA_MEASUREMENT_ID, {
page_path: window.location.pathname,
});
}, []);

useEffect(() => {
// Track page view on route change
if (window.gtag) {
window.gtag('config', GA_MEASUREMENT_ID, {
page_path: location.pathname + location.search,
});
}
}, [location]);

return null;
};

export default GoogleAnalytics;
30 changes: 21 additions & 9 deletions src/components/SpiderChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,14 @@ const SpiderChart: React.FC<SpiderChartProps> = ({ routers, maxRouters = 5 }) =>
.sort((a, b) => a.metrics.overallRank - b.metrics.overallRank)
.slice(0, maxRouters);

// Define the 5 metrics and their corresponding data keys
// Define the 6 metrics and their corresponding data keys
const metrics = [
{ key: 'arenaScore', label: 'Arena', color: '#3b82f6' },
{ key: 'costRatioScore', label: 'Cost', color: '#10b981' },
{ key: 'optimalAccScore', label: 'Optimal', color: '#f59e0b' },
{ key: 'latencyScore', label: 'Latency', color: '#ef4444' },
{ key: 'robustnessScore', label: 'Robust', color: '#8b5cf6' }
{ key: 'optimalSelectionScore', label: 'Opt. Select', color: '#10b981' },
{ key: 'optimalCostScore', label: 'Opt. Cost', color: '#f59e0b' },
{ key: 'optimalAccScore', label: 'Opt. Acc', color: '#ef4444' },
{ key: 'latencyScore', label: 'Latency', color: '#8b5cf6' },
{ key: 'robustnessScore', label: 'Robust', color: '#ec4899' }
] as const;

// Router colors for the chart
Expand All @@ -45,16 +46,25 @@ const SpiderChart: React.FC<SpiderChartProps> = ({ routers, maxRouters = 5 }) =>
// Generate path for a router's performance line
const getRouterPath = (router: Router, radius: number) => {
const points = metrics.map((metric, index) => {
const value = router.metrics[metric.key];
const value = router.metrics[metric.key as keyof typeof router.metrics];
// Handle null values by using 0 (will be at center)
if (value === null) {
const angle = (index * 2 * Math.PI) / metrics.length - Math.PI / 2;
const x = centerX + Math.cos(angle) * 0;
const y = centerY + Math.sin(angle) * 0;
return `${index === 0 ? 'M' : 'L'} ${x} ${y}`;
}
const pos = getMetricPosition(index, value, radius);
return `${index === 0 ? 'M' : 'L'} ${pos.x} ${pos.y}`;
});
return points.join(' ') + ' Z';
};

// Calculate adaptive axis scaling to show more variation
// Filter out null values
const allValues = topRouters.flatMap(router =>
metrics.map(metric => router.metrics[metric.key])
metrics.map(metric => router.metrics[metric.key as keyof typeof router.metrics])
.filter((val): val is number => val !== null)
);
const minValue = Math.min(...allValues);
const maxValue = Math.max(...allValues);
Expand All @@ -75,7 +85,7 @@ const SpiderChart: React.FC<SpiderChartProps> = ({ routers, maxRouters = 5 }) =>
<div className="spider-chart">
<svg width="450" height="450" viewBox="0 0 450 450">
{/* Grid circles drawn at real 0.1 score increments */}
{Array.from({ length: 11 }, (_, i) => (i * 0.1))
{Array.from({ length: 11 }, (_, i) => (i * 0.2))
.filter(v => v >= axisMin && v <= axisMax)
.map((value, index) => {
// Map true axis value -> 0–1 visual radius fraction
Expand Down Expand Up @@ -174,7 +184,9 @@ const SpiderChart: React.FC<SpiderChartProps> = ({ routers, maxRouters = 5 }) =>
/>
{/* Data points */}
{metrics.map((metric, metricIndex) => {
const value = router.metrics[metric.key];
const value = router.metrics[metric.key as keyof typeof router.metrics];
// Skip rendering if value is null
if (value === null) return null;
const pos = getMetricPosition(metricIndex, value, chartRadius);

return (
Expand Down
Loading