David Pomerenke
Autonymns and cooler dataset search display
33469f2
raw
history blame
5.95 kB
import { DataTable } from 'primereact/datatable'
import { Column } from 'primereact/column'
import { FilterMatchMode } from 'primereact/api'
import { MultiSelect } from 'primereact/multiselect'
import { useState, useEffect } from 'react'
import { Slider } from 'primereact/slider'
import ScoreField from './ScoreField'
const LanguageTable = ({ data }) => {
const [filters, setFilters] = useState({
language_name: { value: null, matchMode: FilterMatchMode.CONTAINS },
family: { value: null, matchMode: FilterMatchMode.IN },
speakers: { value: null, matchMode: FilterMatchMode.BETWEEN },
})
const table = data.language_table
const families = [...new Set(table.map(item => item.family))].slice(0, 10)
families.push("Other")
const familyRowFilterTemplate = options => {
return (
<MultiSelect
value={options.value}
options={families}
onChange={e => {
options.filterApplyCallback(e.value)
setFilters(prevFilters => ({
...prevFilters,
family: { value: e.value, matchMode: FilterMatchMode.IN }
}))
}}
placeholder='All families'
/>
)
}
const formatPopulation = population => {
if (population === null) {
return ''
} else if (population < 1000) {
return population.toFixed(0) + ''
} else if (population < 10 * 1000) {
return (population / 1000).toFixed(1) + 'K'
} else if (population < 1000 * 1000) {
return (population / 1000).toFixed(0) + 'K'
} else if (population < 10 * 1000 * 1000) {
return (population / 1000 / 1000).toFixed(1) + 'M'
}else if (population < 1000 * 1000 * 1000) {
return (population / 1000 / 1000).toFixed(0) + 'M'
} else {
return (population / 1000 / 1000 / 1000).toFixed(1) + 'B'
}
}
const SliderWithLabel = ({ value, onChange }) => {
const p = 10
const min = 4
const max = 9.3
const start = value === null ? min : Math.log(value[0]) / Math.log(p)
const stop = value === null ? max : Math.log(value[1]) / Math.log(p)
const [_value, _setValue] = useState([start, stop])
useEffect(() => {
const timer = setTimeout(() => {
onChange({
value:
_value[0] <= min + 0.1 && _value[1] >= max - 0.1
? null
: [p ** _value[0], p ** _value[1]]
})
}, 1000)
return () => clearTimeout(timer)
}, [_value, onChange])
return (
<div style={{ minWidth: '20rem' }}>
<div>{formatPopulation(p ** _value[0])}</div>
<div>{formatPopulation(p ** _value[1])}</div>
<Slider
value={_value}
onChange={e => _setValue(e.value)}
placeholder='All sizes'
min={min}
max={max}
step={0.01}
range
style={{ marginTop: '5rem' }}
/>
</div>
)
}
const speakerFilterTemplate = options => {
return (
<SliderWithLabel
value={options.value}
onChange={e => {
options.filterApplyCallback(e.value)
setFilters(prevFilters => ({
...prevFilters,
speakers: { value: e.value, matchMode: FilterMatchMode.BETWEEN }
}))
}}
/>
)
}
const speakerBodyTemplate = rowData => {
const populationStr = formatPopulation(rowData.speakers)
return <div style={{ textAlign: 'center' }}>{populationStr}</div>
}
const languageBodyTemplate = rowData => {
return <div>
<div style={{ fontWeight: 'bold' }}>{rowData.autonym}</div>
<div style={{ fontSize: '0.8rem', color: 'gray' }}>{rowData.language_name}</div>
</div>
}
const scoreBodyTemplate = (field, options = {}) => {
const { minScore = 0, maxScore = 1 } = options
return rowData => {
const score = rowData[field]
return ScoreField(score, minScore, maxScore)
}
}
return (
<DataTable
value={table}
header={<>Languages</>}
sortField='speakers'
removableSort
filters={filters}
filterDisplay='menu'
scrollable
scrollHeight='600px'
id='language-table'
>
<Column
field='language_name'
header='Language'
body={languageBodyTemplate}
style={{ minWidth: '5rem' }}
frozen
/>
<Column
field='speakers'
header={<i className='pi pi-users' title='Speakers' />}
body={speakerBodyTemplate}
filter
filterElement={speakerFilterTemplate}
showFilterMatchModes={false}
sortable
style={{ minWidth: '5rem' }}
/>
<Column
field='family'
header='Family'
filter
showFilterMatchModes={false}
filterElement={familyRowFilterTemplate}
style={{ minWidth: '10rem' }}
/>
<Column
field='average'
header='Average'
sortable
body={scoreBodyTemplate('average', { minScore: 0.2, maxScore: 0.5 })}
style={{ minWidth: '5rem', maxWidth: '10rem' }}
/>
<Column
field='translation_chrf'
header='Translation'
sortable
body={scoreBodyTemplate('translation_chrf', {
minScore: 0.3,
maxScore: 0.6
})}
style={{ minWidth: '5rem', maxWidth: '10rem' }}
/>
<Column
field='classification_accuracy'
header='Classification'
sortable
body={scoreBodyTemplate('classification_accuracy', {
minScore: 0.3,
maxScore: 0.7
})}
style={{ minWidth: '5rem', maxWidth: '10rem' }}
/>
<Column
field='language_modeling_chrf'
header='Language Modeling'
sortable
body={scoreBodyTemplate('language_modeling_chrf', {
minScore: 0.8,
maxScore: 1
})}
style={{ minWidth: '5rem', maxWidth: '10rem' }}
/>
</DataTable>
)
}
export default LanguageTable