import React from 'react'; import PropTypes from 'prop-types'; import { fromPairs, head, keys, pipe, prop, reverse, sortBy, splitEvery, toLower, toPairs, type } from 'ramda'; import SortingDropdown from '../utils/SortingDropdown'; import PaginationDropdown from '../utils/PaginationDropdown'; import { rangeOf } from '../utils/utils'; import { roundTen } from '../utils/helpers/numbers'; import SimplePaginator from '../common/SimplePaginator'; import GraphCard from './GraphCard'; const { max } = Math; const toLowerIfString = (value) => type(value) === 'String' ? toLower(value) : value; const pickValueFromPair = ([ , value ]) => value; export default class SortableBarGraph extends React.Component { static propTypes = { stats: PropTypes.object.isRequired, title: PropTypes.string.isRequired, sortingItems: PropTypes.object.isRequired, extraHeaderContent: PropTypes.func, withPagination: PropTypes.bool, }; state = { orderField: undefined, orderDir: undefined, currentPage: 1, itemsPerPage: Infinity, }; determineStats(stats, sortingItems) { const pairs = toPairs(stats); const sortedPairs = !this.state.orderField ? pairs : sortBy( pipe( prop(this.state.orderField === head(keys(sortingItems)) ? 0 : 1), toLowerIfString ), pairs ); const directionalPairs = !this.state.orderDir || this.state.orderDir === 'ASC' ? sortedPairs : reverse(sortedPairs); if (directionalPairs.length <= this.state.itemsPerPage) { return { currentPageStats: fromPairs(directionalPairs) }; } const pages = splitEvery(this.state.itemsPerPage, directionalPairs); return { currentPageStats: fromPairs(this.determineCurrentPagePairs(pages)), pagination: this.renderPagination(pages.length), max: roundTen(max(...directionalPairs.map(pickValueFromPair))), }; } determineCurrentPagePairs(pages) { const page = pages[this.state.currentPage - 1]; if (this.state.currentPage < pages.length) { return page; } const firstPageLength = pages[0].length; // Using the "hidden" key, the chart will just replace the label by an empty string return [ ...page, ...rangeOf(firstPageLength - page.length, (i) => [ `hidden_${i}`, 0 ]) ]; } renderPagination(pagesCount) { const { currentPage } = this.state; const setCurrentPage = (currentPage) => this.setState({ currentPage }); return ; } render() { const { stats, sortingItems, title, extraHeaderContent, withPagination = true } = this.props; const { currentPageStats, pagination, max } = this.determineStats(stats, sortingItems); const activeCities = keys(currentPageStats); const computeTitle = () => ( {title}
this.setState({ orderField, orderDir, currentPage: 1 })} />
{withPagination && keys(stats).length > 50 && (
this.setState({ itemsPerPage, currentPage: 1 })} />
)} {extraHeaderContent && (
{extraHeaderContent(pagination ? activeCities : undefined)}
)}
); return ; } }