Spaces:
Running
Running
| import { useState, useEffect } from 'react' | |
| import { PrimeReactProvider } from 'primereact/api' | |
| import 'primereact/resources/themes/lara-light-cyan/theme.css' | |
| import ModelTable from './components/ModelTable' | |
| import LanguageTable from './components/LanguageTable' | |
| import DatasetTable from './components/DatasetTable' | |
| import WorldMap from './components/WorldMap' | |
| import AutoComplete from './components/AutoComplete' | |
| import LanguagePlot from './components/LanguagePlot' | |
| import SpeakerPlot from './components/SpeakerPlot' | |
| import HistoryPlot from './components/HistoryPlot' | |
| import CostPlot from './components/CostPlot' | |
| import { Carousel } from 'primereact/carousel' | |
| import { Dialog } from 'primereact/dialog' | |
| import { Button } from 'primereact/button' | |
| function App () { | |
| const [data, setData] = useState(null) | |
| const [loading, setLoading] = useState(true) | |
| const [error, setError] = useState(null) | |
| const [selectedLanguages, setSelectedLanguages] = useState([]) | |
| const [dialogVisible, setDialogVisible] = useState(false) | |
| const [aboutVisible, setAboutVisible] = useState(false) | |
| const [contributeVisible, setContributeVisible] = useState(false) | |
| useEffect(() => { | |
| fetch('/api/data', { | |
| method: 'POST', | |
| body: JSON.stringify({ selectedLanguages }) | |
| }) | |
| .then(response => { | |
| if (!response.ok) { | |
| throw new Error('Network response was not ok') | |
| } | |
| return response.json() | |
| }) | |
| .then(jsonData => { | |
| setData(jsonData) | |
| setLoading(false) | |
| }) | |
| .catch(err => { | |
| setError(err.message) | |
| setLoading(false) | |
| }) | |
| }, [selectedLanguages]) | |
| const [windowWidth, setWindowWidth] = useState(window.innerWidth) | |
| const [windowHeight, setWindowHeight] = useState(window.innerHeight) | |
| useEffect(() => { | |
| const handleResize = () => { | |
| setWindowWidth(window.innerWidth) | |
| setWindowHeight(window.innerHeight) | |
| } | |
| window.addEventListener('resize', handleResize) | |
| return () => window.removeEventListener('resize', handleResize) | |
| }, []) | |
| return ( | |
| <PrimeReactProvider> | |
| <div | |
| style={{ | |
| minHeight: '100vh', | |
| display: 'flex', | |
| flexDirection: 'column', | |
| width: '100vw' | |
| }} | |
| > | |
| <div | |
| style={{ | |
| backgroundColor: '#fff3cd', | |
| color: '#856404', | |
| padding: '0.75rem 1.25rem', | |
| marginBottom: '1rem', | |
| border: '1px solid #ffeeba', | |
| borderRadius: '0.25rem', | |
| textAlign: 'center' | |
| }} | |
| > | |
| <strong>Work in Progress:</strong> This dashboard is currently under | |
| active development. Evaluation results are not yet final. | |
| <a | |
| href='https://github.com/datenlabor-bmz/ai-language-monitor' | |
| target='_blank' | |
| rel='noopener noreferrer' | |
| style={{ | |
| textDecoration: 'none', | |
| color: '#856404', | |
| float: 'right', | |
| fontSize: '1.2rem', | |
| fontWeight: 'bold', | |
| padding: '0 0.5rem', | |
| borderRadius: '3px', | |
| backgroundColor: 'rgba(255,255,255,0.3)' | |
| }} | |
| > | |
| <i | |
| className='pi pi-github' | |
| title='View on GitHub' | |
| style={{ marginRight: '0.3rem' }} | |
| /> | |
| GitHub | |
| </a> | |
| </div> | |
| <header | |
| style={{ | |
| display: 'flex', | |
| flexDirection: 'column', | |
| alignItems: 'center', | |
| justifyContent: 'center', | |
| padding: '5vh 5vw', | |
| width: '100%', | |
| maxWidth: '1400px', | |
| margin: '0 auto' | |
| }} | |
| > | |
| <div> | |
| <span | |
| role='img' | |
| aria-label='Globe Emoji' | |
| style={{ fontSize: '40px' }} | |
| > | |
| π | |
| </span> | |
| </div> | |
| <h1 | |
| style={{ | |
| fontSize: '2.5rem', | |
| fontWeight: '600', | |
| margin: '1rem 0 0.5rem 0', | |
| color: '#333', | |
| letterSpacing: '-0.01em' | |
| }} | |
| > | |
| AI Language Proficiency Monitor | |
| </h1> | |
| <p | |
| style={{ | |
| fontSize: '1.1rem', | |
| color: '#666', | |
| margin: '0 0 2.5rem 0', | |
| fontWeight: '400', | |
| maxWidth: '700px', | |
| lineHeight: '1.5' | |
| }} | |
| > | |
| Comprehensive multilingual evaluation results for AI language models | |
| </p> | |
| <div | |
| style={{ | |
| display: 'flex', | |
| gap: '1rem', | |
| marginBottom: '1.5rem', | |
| flexWrap: 'wrap', | |
| justifyContent: 'center' | |
| }} | |
| > | |
| <Button | |
| label='π About this tool' | |
| className='p-button-text' | |
| onClick={() => setAboutVisible(true)} | |
| style={{ | |
| color: '#666', | |
| border: '1px solid #ddd', | |
| padding: '0.5rem 1rem', | |
| borderRadius: '4px', | |
| fontSize: '0.9rem' | |
| }} | |
| /> | |
| <Button | |
| label='π Add your model (soon)' | |
| className='p-button-text' | |
| onClick={() => setContributeVisible(true)} | |
| tooltip='This feature is on our roadmap and will be available soon.' | |
| tooltipOptions={{ position: 'bottom' }} | |
| style={{ | |
| color: '#666', | |
| border: '1px solid #ddd', | |
| padding: '0.5rem 1rem', | |
| borderRadius: '4px', | |
| fontSize: '0.9rem' | |
| }} | |
| /> | |
| </div> | |
| {data && ( | |
| <AutoComplete | |
| languages={data?.language_table} | |
| onComplete={items => setSelectedLanguages(items)} | |
| /> | |
| )} | |
| </header> | |
| <main | |
| style={{ | |
| display: 'flex', | |
| flexDirection: 'column', | |
| gap: '3rem', | |
| width: '100%', | |
| paddingBottom: '5vh', | |
| padding: '1rem 15vw 5vh 15vw' | |
| }} | |
| > | |
| {loading && ( | |
| <div style={{ width: '100%', textAlign: 'center' }}> | |
| <i | |
| className='pi pi-spinner pi-spin' | |
| style={{ fontSize: '4rem' }} | |
| /> | |
| </div> | |
| )} | |
| {error && ( | |
| <div style={{ width: '100%', textAlign: 'center' }}> | |
| <p>Error: {error}</p> | |
| </div> | |
| )} | |
| {data && ( | |
| <> | |
| <ModelTable | |
| data={data.model_table} | |
| selectedLanguages={selectedLanguages} | |
| allLanguages={data.language_table || []} | |
| /> | |
| <LanguageTable | |
| data={data.language_table} | |
| selectedLanguages={selectedLanguages} | |
| setSelectedLanguages={setSelectedLanguages} | |
| totalModels={data.model_table?.length || 0} | |
| /> | |
| <DatasetTable data={data} /> | |
| <div | |
| id='figure' | |
| style={{ | |
| width: '100%', | |
| position: 'relative' | |
| }} | |
| > | |
| <Button | |
| icon='pi pi-external-link' | |
| className='p-button-text p-button-plain' | |
| onClick={() => setDialogVisible(true)} | |
| tooltip='Open in larger view' | |
| style={{ | |
| position: 'absolute', | |
| top: '10px', | |
| right: '10px', | |
| zIndex: 1, | |
| color: '#666' | |
| }} | |
| /> | |
| <Carousel | |
| value={[ | |
| <WorldMap data={data.countries} />, | |
| <LanguagePlot data={data} />, | |
| <SpeakerPlot data={data} />, | |
| <HistoryPlot data={data} />, | |
| <CostPlot data={data} /> | |
| ]} | |
| numScroll={1} | |
| numVisible={1} | |
| itemTemplate={item => item} | |
| circular | |
| style={{ width: '100%', minHeight: '650px' }} | |
| /> | |
| </div> | |
| </> | |
| )} | |
| </main> | |
| {/* About Dialog */} | |
| <Dialog | |
| visible={aboutVisible} | |
| onHide={() => setAboutVisible(false)} | |
| style={{ width: '600px' }} | |
| modal | |
| header='About this tool' | |
| > | |
| <div> | |
| <p> | |
| The <i>AI Language Proficiency Monitor</i> presents comprehensive | |
| multilingual evaluation results of AI language models. | |
| </p> | |
| <h4>Who is this for?</h4> | |
| <ul> | |
| <li> | |
| <b>Practitioners</b> can pick the best model for a given | |
| language. | |
| </li> | |
| <li> | |
| <b>Policymakers and funders</b> can identify and prioritize | |
| neglected languages. | |
| </li> | |
| <li> | |
| <b>Model developers</b> can compete on our{' '} | |
| <i>AI Language Proficiency</i> metric. | |
| </li> | |
| </ul> | |
| <h4>β‘ Live Updates</h4> | |
| <p> | |
| Benchmark results automatically refresh every night and include | |
| the most popular models from{' '} | |
| <a | |
| href='https://openrouter.ai' | |
| target='_blank' | |
| rel='noopener noreferrer' | |
| > | |
| OpenRouter | |
| </a> | |
| , plus community-submitted models. | |
| </p> | |
| <h4>Authors</h4> | |
| <p> | |
| The AI Language Proficiency Monitor is a collaboration between | |
| BMZ's{' '} | |
| <a | |
| href='https://www.bmz-digital.global/en/overview-of-initiatives/the-bmz-data-lab/' | |
| target='_blank' | |
| rel='noopener noreferrer' | |
| > | |
| Data Lab | |
| </a> | |
| , the BMZ-Initiative{' '} | |
| <a | |
| href='https://www.bmz-digital.global/en/overview-of-initiatives/fair-forward/' | |
| target='_blank' | |
| rel='noopener noreferrer' | |
| > | |
| Fair Forward | |
| </a>{' '} | |
| (implemented by GIZ), and the{' '} | |
| <a | |
| href='https://www.dfki.de/en/web/research/research-departments/multilinguality-and-language-technology/ee-team' | |
| target='_blank' | |
| rel='noopener noreferrer' | |
| > | |
| E&E group | |
| </a>{' '} | |
| of DFKI's Multilinguality and Language Technology Lab. | |
| </p> | |
| <h4>π Links</h4> | |
| <p> | |
| <a | |
| href='https://github.com/datenlabor-bmz/ai-language-monitor' | |
| target='_blank' | |
| rel='noopener noreferrer' | |
| style={{ | |
| color: '#666', | |
| textDecoration: 'none', | |
| display: 'inline-flex', | |
| alignItems: 'center', | |
| gap: '0.5rem' | |
| }} | |
| > | |
| <i className='pi pi-github' style={{ fontSize: '1.2rem' }} /> | |
| View source code on GitHub | |
| </a> | |
| </p> | |
| </div> | |
| </Dialog> | |
| {/* Contribute Dialog */} | |
| <Dialog | |
| visible={contributeVisible} | |
| onHide={() => setContributeVisible(false)} | |
| style={{ width: '600px' }} | |
| modal | |
| header='Add your model & Contribute' | |
| > | |
| <div> | |
| <h4>π Submit Your Model</h4> | |
| <p> | |
| Have a custom fine-tuned model you'd like to see on the | |
| leaderboard? | |
| </p> | |
| <p> | |
| <a | |
| href='https://forms.gle/ckvY9pS7XLcHYnaV8' | |
| target='_blank' | |
| rel='noopener noreferrer' | |
| style={{ color: '#28a745', fontWeight: 'bold' }} | |
| > | |
| β Submit your model here | |
| </a> | |
| </p> | |
| <h4>π§ Contribute to Development</h4> | |
| <p> | |
| Help us expand language coverage and add new evaluation tasks: | |
| </p> | |
| <p> | |
| <a | |
| href='https://github.com/datenlabor-bmz/ai-language-monitor/blob/main/CONTRIBUTING.md' | |
| target='_blank' | |
| rel='noopener noreferrer' | |
| style={{ color: '#007bff', fontWeight: 'bold' }} | |
| > | |
| β Contribution guidelines | |
| </a> | |
| </p> | |
| </div> | |
| </Dialog> | |
| {/* Full-screen Dialog for Charts */} | |
| <Dialog | |
| visible={dialogVisible} | |
| onHide={() => setDialogVisible(false)} | |
| style={{ width: '90vw', height: '90vh' }} | |
| maximizable | |
| modal | |
| header={null} | |
| > | |
| {data && ( | |
| <div style={{ width: '100%', height: '100%' }}> | |
| <Carousel | |
| value={[ | |
| <WorldMap | |
| data={data.countries} | |
| width={windowWidth * 0.7} | |
| height={windowHeight * 0.6} | |
| />, | |
| <LanguagePlot | |
| data={data} | |
| width={windowWidth * 0.7} | |
| height={windowHeight * 0.6} | |
| />, | |
| <SpeakerPlot | |
| data={data} | |
| width={windowWidth * 0.7} | |
| height={windowHeight * 0.6} | |
| />, | |
| <HistoryPlot | |
| data={data} | |
| width={windowWidth * 0.7} | |
| height={windowHeight * 0.6} | |
| />, | |
| <CostPlot data={data} /> | |
| ]} | |
| numScroll={1} | |
| numVisible={1} | |
| itemTemplate={item => item} | |
| circular | |
| style={{ width: '100%', height: 'calc(90vh - 120px)' }} | |
| /> | |
| </div> | |
| )} | |
| </Dialog> | |
| </div> | |
| </PrimeReactProvider> | |
| ) | |
| } | |
| export default App | |