UNPKG

@krowdy-ui/views

Version:

React components that implement Google's Material Design.

130 lines (124 loc) 3.82 kB
import React from 'react'; import PropTypes from 'prop-types'; import clsx from 'clsx'; import { makeStyles } from '@krowdy-ui/core'; import Column from './Column'; import Price from './Price'; import Count from './Count'; const groupByObject = function (array, prices, keyGetter = x => x) { return array.reduce((resultObject, x) => { const match = keyGetter(x); const price = prices.find((price, index) => match >= price && match <= prices[index + 1]); if (price) { resultObject[price] = resultObject[price] || []; resultObject[price].push(x); } return resultObject; }, {}); }; // let interval = 8 // let emptyPrices = new Array(interval) const Histogram = ({ multiplier = 1, candidates = [] }) => { const max = candidates.reduce((r, { salary }) => Math.max(r, salary), 1); const min = candidates.reduce((r, { salary }) => Math.min(r, salary), Infinity); const interval = (max - min) / multiplier; let emptyPrices = new Array(multiplier + 1).fill(min); const rawPrices = Array.from(emptyPrices, (value, index) => value + interval * index); const prices = [0, ...rawPrices]; const classes = useStyles({ max }); const rawData = groupByObject(candidates, rawPrices, ({ salary }) => salary); const keys = Object.keys(rawData); const maxCandidates = [...keys].sort((a, b) => rawData[b].length - rawData[a].length)[0]; const maxCandidatesSize = rawData[maxCandidates] ? rawData[maxCandidates].length : 0; const columnPrices = prices.slice(0, prices.length - 1); const pricePercent = 100 / prices.length; return /*#__PURE__*/React.createElement("div", { className: classes.root }, /*#__PURE__*/React.createElement("div", { className: clsx(classes.column, classes.countCandidates) }, new Array(maxCandidatesSize).fill(maxCandidatesSize).map((count, index) => /*#__PURE__*/React.createElement(Count, { count: count, index: index, key: index }))), /*#__PURE__*/React.createElement("div", { className: clsx(classes.column, classes.container) }, /*#__PURE__*/React.createElement("div", { className: clsx(classes.containerHistogram, classes.row) }, columnPrices.map((key, index) => /*#__PURE__*/React.createElement(Column, { candidates: rawData[key] || [], divider: columnPrices.length, index: index, key: index, max: max, maxCandidates: maxCandidatesSize, pricePercent: pricePercent }))), /*#__PURE__*/React.createElement("div", { className: clsx(classes.row, classes.prices) }, prices.map((price, index) => /*#__PURE__*/React.createElement(Price, { index: index, key: index, price: price, pricePercent: pricePercent }))))); }; process.env.NODE_ENV !== "production" ? Histogram.propTypes = { candidates: PropTypes.arrayOf(PropTypes.shape({ firstName: PropTypes.string, lastName: PropTypes.string, photo: PropTypes.string, salary: PropTypes.number, selected: PropTypes.bool })), multiplier: PropTypes.number } : void 0; const useStyles = makeStyles(theme => ({ column: { display: 'flex', flexDirection: 'column' }, container: { height: '100%', minHeight: 150, width: '100%' }, containerHistogram: { borderBottom: `1px solid ${theme.palette.grey[600]}`, display: 'flex', flexDirection: 'row', height: 'inherit', width: 'inherit' }, countCandidates: { alignItems: 'center' }, price: { color: theme.palette.grey[600] }, prices: { position: 'relative' }, root: { display: 'flex', height: 'calc(100% - 32px)', marginTop: theme.spacing(1), paddingBottom: theme.spacing(1), paddingRight: theme.spacing(1) }, row: { display: 'flex', flexDirection: 'row' } }), { name: 'Histogram' }); export default Histogram;