Commit a0fa5698 by ryan

rename reducer to statsCalculator

parent 29695077
...@@ -3,45 +3,45 @@ import React, { PureComponent } from 'react'; ...@@ -3,45 +3,45 @@ import React, { PureComponent } from 'react';
import { storiesOf } from '@storybook/react'; import { storiesOf } from '@storybook/react';
import { action } from '@storybook/addon-actions'; import { action } from '@storybook/addon-actions';
import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; import { withCenteredStory } from '../../utils/storybook/withCenteredStory';
import { TableReducePicker } from './TableReducePicker'; import { StatsPicker } from './StatsPicker';
import { text, boolean } from '@storybook/addon-knobs'; import { text, boolean } from '@storybook/addon-knobs';
interface State { interface State {
reducers: string[]; stats: string[];
} }
export class WrapperWithState extends PureComponent<any, State> { export class WrapperWithState extends PureComponent<any, State> {
constructor(props: any) { constructor(props: any) {
super(props); super(props);
this.state = { this.state = {
reducers: this.toReducersArray(props.initialReducers), stats: this.toStatsArray(props.initialReducers),
}; };
} }
toReducersArray = (txt: string): string[] => { toStatsArray = (txt: string): string[] => {
return txt.split(',').map(v => v.trim()); return txt.split(',').map(v => v.trim());
}; };
componentDidUpdate(prevProps: any) { componentDidUpdate(prevProps: any) {
const { initialReducers } = this.props; const { initialReducers } = this.props;
if (initialReducers !== prevProps.initialReducers) { if (initialReducers !== prevProps.initialReducers) {
this.setState({ reducers: this.toReducersArray(initialReducers) }); this.setState({ stats: this.toStatsArray(initialReducers) });
} }
} }
render() { render() {
const { placeholder, defaultReducer, allowMultiple } = this.props; const { placeholder, defaultStat, allowMultiple } = this.props;
const { reducers } = this.state; const { stats } = this.state;
return ( return (
<TableReducePicker <StatsPicker
placeholder={placeholder} placeholder={placeholder}
defaultReducer={defaultReducer} defaultStat={defaultStat}
allowMultiple={allowMultiple} allowMultiple={allowMultiple}
reducers={reducers} stats={stats}
onChange={(reducers: string[]) => { onChange={(stats: string[]) => {
action('Picked:')(reducers); action('Picked:')(stats);
this.setState({ reducers }); this.setState({ stats });
}} }}
/> />
); );
...@@ -52,16 +52,16 @@ const story = storiesOf('UI/TableReducePicker', module); ...@@ -52,16 +52,16 @@ const story = storiesOf('UI/TableReducePicker', module);
story.addDecorator(withCenteredStory); story.addDecorator(withCenteredStory);
story.add('picker', () => { story.add('picker', () => {
const placeholder = text('Placeholder Text', ''); const placeholder = text('Placeholder Text', '');
const defaultReducer = text('Default Reducer', ''); const defaultStat = text('Default Stat', '');
const allowMultiple = boolean('Allow Multiple', false); const allowMultiple = boolean('Allow Multiple', false);
const initialReducers = text('Initial Reducers', ''); const initialStats = text('Initial Stats', '');
return ( return (
<div> <div>
<WrapperWithState <WrapperWithState
placeholder={placeholder} placeholder={placeholder}
defaultReducer={defaultReducer} defaultStat={defaultStat}
allowMultiple={allowMultiple} allowMultiple={allowMultiple}
initialReducers={initialReducers} initialStats={initialStats}
/> />
</div> </div>
); );
......
...@@ -4,19 +4,19 @@ import isArray from 'lodash/isArray'; ...@@ -4,19 +4,19 @@ import isArray from 'lodash/isArray';
import { Select } from '../index'; import { Select } from '../index';
import { getTableReducers } from '../../utils/tableReducer'; import { getStatsCalculators } from '../../utils/statsCalculator';
import { SelectOptionItem } from '../Select/Select'; import { SelectOptionItem } from '../Select/Select';
interface Props { interface Props {
placeholder?: string; placeholder?: string;
onChange: (reducers: string[]) => void; onChange: (stats: string[]) => void;
reducers: string[]; stats: string[];
width?: number; width?: number;
allowMultiple?: boolean; allowMultiple?: boolean;
defaultReducer?: string; defaultStat?: string;
} }
export class TableReducePicker extends PureComponent<Props> { export class StatsPicker extends PureComponent<Props> {
static defaultProps = { static defaultProps = {
width: 12, width: 12,
allowMultiple: false, allowMultiple: false,
...@@ -31,25 +31,25 @@ export class TableReducePicker extends PureComponent<Props> { ...@@ -31,25 +31,25 @@ export class TableReducePicker extends PureComponent<Props> {
} }
checkInput = () => { checkInput = () => {
const { reducers, allowMultiple, defaultReducer, onChange } = this.props; const { stats, allowMultiple, defaultStat, onChange } = this.props;
// Check that the selected reducers are all real // Check that the selected reducers are all real
const notFound: string[] = []; const notFound: string[] = [];
const current = getTableReducers(reducers, notFound); const current = getStatsCalculators(stats, notFound);
if (notFound.length > 0) { if (notFound.length > 0) {
console.warn('Unknown reducers', notFound, reducers); console.warn('Unknown reducers', notFound, stats);
onChange(current.map(reducer => reducer.value)); onChange(current.map(reducer => reducer.value));
} }
// Make sure there is only one // Make sure there is only one
if (!allowMultiple && reducers.length > 1) { if (!allowMultiple && stats.length > 1) {
console.warn('Removing extra reducers', reducers); console.warn('Removing extra stat', stats);
onChange([reducers[0]]); onChange([stats[0]]);
} }
// Set the reducer from callback // Set the reducer from callback
if (defaultReducer && reducers.length < 1) { if (defaultStat && stats.length < 1) {
onChange([defaultReducer]); onChange([defaultStat]);
} }
}; };
...@@ -63,17 +63,17 @@ export class TableReducePicker extends PureComponent<Props> { ...@@ -63,17 +63,17 @@ export class TableReducePicker extends PureComponent<Props> {
}; };
render() { render() {
const { width, reducers, allowMultiple, defaultReducer, placeholder } = this.props; const { width, stats, allowMultiple, defaultStat, placeholder } = this.props;
const current = getTableReducers(reducers); const current = getStatsCalculators(stats);
return ( return (
<Select <Select
width={width} width={width}
value={current} value={current}
isClearable={!defaultReducer} isClearable={!defaultStat}
isMulti={allowMultiple} isMulti={allowMultiple}
isSearchable={true} isSearchable={true}
options={getTableReducers()} options={getStatsCalculators()}
placeholder={placeholder} placeholder={placeholder}
onChange={this.onSelectionChange} onChange={this.onSelectionChange}
/> />
......
import { parseCSV } from './processTableData';
import { getStatsCalculators, StatID, calculateStats } from './statsCalculator';
describe('Stats Calculators', () => {
const basicTable = parseCSV('a,b,c\n10,20,30\n20,30,40');
it('should load all standard stats', () => {
const names = [
StatID.sum,
StatID.max,
StatID.min,
StatID.logmin,
StatID.mean,
StatID.last,
StatID.first,
StatID.count,
StatID.range,
StatID.diff,
StatID.step,
StatID.delta,
// StatID.allIsZero,
// StatID.allIsNull,
];
const notFound: string[] = [];
const stats = getStatsCalculators(names, notFound);
stats.forEach((stat, index) => {
expect(stat ? stat.value : '<missing>').toEqual(names[index]);
});
expect(notFound.length).toBe(0);
});
it('should fail to load unknown stats', () => {
const names = ['not a stat', StatID.max, StatID.min, 'also not a stat'];
const notFound: string[] = [];
const stats = getStatsCalculators(names, notFound);
expect(stats.length).toBe(2);
expect(notFound.length).toBe(2);
});
it('should calculate stats', () => {
const stats = calculateStats({
data: basicTable,
columnIndex: 0,
stats: ['first', 'last', 'mean'],
});
// First
expect(stats.first).toEqual(10);
// Last
expect(stats.last).toEqual(20);
// Mean
expect(stats.mean).toEqual(15);
});
it('should support a single stat also', () => {
const stats = calculateStats({
data: basicTable,
columnIndex: 0,
stats: ['first', 'last', 'mean'],
});
// First
expect(stats.first).toEqual(10);
// Last
expect(stats.last).toEqual(20);
// Mean
expect(stats.mean).toEqual(15);
});
});
import { parseCSV } from './processTableData';
import { reduceTableData, getTableReducers, TableReducerID } from './tableReducer';
describe('Table Reducer', () => {
const basicTable = parseCSV('a,b,c\n10,20,30\n20,30,40');
it('should load all standard stats', () => {
const names = [
TableReducerID.sum,
TableReducerID.max,
TableReducerID.min,
TableReducerID.logmin,
TableReducerID.mean,
TableReducerID.last,
TableReducerID.first,
TableReducerID.count,
TableReducerID.range,
TableReducerID.diff,
TableReducerID.step,
TableReducerID.delta,
// TableReducerID.allIsZero,
// TableReducerID.allIsNull,
];
const notFound: string[] = [];
const reducers = getTableReducers(names, notFound);
reducers.forEach((reducer, index) => {
expect(reducer ? reducer.value : '<missing>').toEqual(names[index]);
});
expect(notFound.length).toBe(0);
});
it('should fail to load unknown reducers', () => {
const names = ['not a reducer', TableReducerID.max, TableReducerID.min, 'also not a reducer'];
const notFound: string[] = [];
const reducers = getTableReducers(names, notFound);
expect(reducers.length).toBe(2);
expect(notFound.length).toBe(2);
});
it('should calculate stats', () => {
const reduced = reduceTableData(basicTable, {
columnIndexes: [0, 1],
stats: ['first', 'last', 'mean'],
});
expect(reduced.length).toBe(3);
// First
expect(reduced[0].rows[0]).toEqual([10, 20]);
// Last
expect(reduced[1].rows[0]).toEqual([20, 30]);
// Mean
expect(reduced[2].rows[0]).toEqual([15, 25]);
});
it('should support a single stat also', () => {
// First
let reduced = reduceTableData(basicTable, {
columnIndexes: [0, 1],
stats: ['first'],
});
expect(reduced.length).toBe(1);
expect(reduced[0].rows[0]).toEqual([10, 20]);
// Last
reduced = reduceTableData(basicTable, {
columnIndexes: [0, 1],
stats: ['last'],
});
expect(reduced.length).toBe(1);
expect(reduced[0].rows[0]).toEqual([20, 30]);
// Mean
reduced = reduceTableData(basicTable, {
columnIndexes: [0, 1],
stats: ['mean'],
});
expect(reduced.length).toBe(1);
expect(reduced[0].rows[0]).toEqual([15, 25]);
});
});
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment