Skip to content

Commit f1122fc

Browse files
initial support for aggregators
1 parent ac8c540 commit f1122fc

File tree

2 files changed

+45
-16
lines changed

2 files changed

+45
-16
lines changed

src/PivotTableUI.js

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import React from 'react';
22
import PropTypes from 'prop-types';
33
import update from 'immutability-helper';
4-
import {PivotData} from './Utilities';
4+
import {PivotData, aggregators} from './Utilities';
55
import DnDCell from './DnDCell';
66
import TableRenderer from './TableRenderer';
77
import './pivottable.css';
@@ -44,13 +44,20 @@ class PivotTableUI extends React.Component {
4444
this.attrValues = attrValues;
4545
}
4646

47-
onChange(command) { this.props.onChange(update(this.props, command)); }
47+
sendPropUpdate(command) {
48+
this.props.onChange(update(this.props, command));
49+
}
50+
51+
updateProps(key) {
52+
return value => this.sendPropUpdate({[key]: {$set: value}});
53+
}
4854

4955
render() {
56+
const numValsAllowed = aggregators[this.props.aggregatorName]([])().numInputs || 0;
5057
return (
5158
<table className="pvtUi"><tbody>
5259
<tr>
53-
<td>(renderers)</td>
60+
<td><select><option>Table</option></select></td>
5461
<DnDCell
5562
items={Object.keys(this.attrValues)
5663
.filter(e => !this.props.rows.includes(e) && !this.props.cols.includes(e))}
@@ -59,20 +66,40 @@ class PivotTableUI extends React.Component {
5966
/>
6067
</tr>
6168
<tr>
62-
<td>(aggregators)</td>
69+
<td className="pvtVals">
70+
<select value={this.props.aggregatorName}
71+
onChange={({target: {value}}) => this.updateProps('aggregatorName')(value)}
72+
>
73+
{Object.keys(aggregators).map(n => <option key={`agg${n}`} value={n}>{n}</option>)}
74+
</select>
75+
{(numValsAllowed > 0) && <br />}
76+
{new Array(numValsAllowed).fill().map((n, i) =>
77+
<select value={this.props.vals[i]} key={`val${i}`}
78+
onChange={({target: {value}}) =>
79+
this.sendPropUpdate({vals: {$splice: [[i, 1, value]]}})}
80+
>
81+
<option key={`none${i}`} value=""></option>
82+
{Object.keys(this.attrValues).map((v, j) =>
83+
<option key={`${i}-${j}`} value={v}>{v}</option>)}
84+
</select>
85+
)}
86+
</td>
6387
<DnDCell
6488
items={this.props.cols} classes="pvtAxisContainer pvtHorizList pvtCols"
65-
onChange={newCols => this.onChange({cols: {$set: newCols}})}
89+
onChange={this.updateProps('cols')}
6690
/>
6791
</tr>
6892
<tr>
6993
<DnDCell
7094
items={this.props.rows} classes="pvtAxisContainer pvtVertList pvtRows"
71-
onChange={newRows => this.onChange({rows: {$set: newRows}})}
95+
onChange={this.updateProps('rows')}
7296
/>
7397
<td>
7498
<TableRenderer pivotData={new PivotData(
75-
update(this.props, {data: {$set: this.materializedInput}}))}
99+
update(this.props, {
100+
data: {$set: this.materializedInput},
101+
aggregator: {$set: aggregators[this.props.aggregatorName](this.props.vals)}
102+
}))}
76103
/>
77104
</td>
78105
</tr>
@@ -83,14 +110,16 @@ class PivotTableUI extends React.Component {
83110
}
84111

85112
PivotTableUI.defaultProps = {
86-
rows: [], cols: []
113+
rows: [], cols: [], vals: [], aggregatorName: 'Count'
87114
};
88115

89116
PivotTableUI.propTypes = {
90117
data: PropTypes.oneOfType([PropTypes.array, PropTypes.object, PropTypes.func]).isRequired,
91118
onChange: PropTypes.func.isRequired,
119+
aggregatorName: PropTypes.string,
92120
cols: PropTypes.arrayOf(PropTypes.string),
93-
rows: PropTypes.arrayOf(PropTypes.string)
121+
rows: PropTypes.arrayOf(PropTypes.string),
122+
vals: PropTypes.arrayOf(PropTypes.string)
94123
};
95124

96125

src/Utilities.js

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ const aggregatorTemplates = {
147147
},
148148
value() { return fn(this.uniq); },
149149
format: formatter,
150-
numInputs: (attr !== null) ? 0 : 1
150+
numInputs: (typeof attr !== 'undefined') ? 0 : 1
151151
};
152152
};
153153
};
@@ -163,7 +163,7 @@ const aggregatorTemplates = {
163163
},
164164
value() { return this.sum; },
165165
format: formatter,
166-
numInputs: (attr !== null) ? 0 : 1
166+
numInputs: (typeof attr !== 'undefined') ? 0 : 1
167167
};
168168
};
169169
};
@@ -174,7 +174,7 @@ const aggregatorTemplates = {
174174
return function(data) {
175175
return {
176176
val: null,
177-
sorter: getSort(data.sorters, attr),
177+
sorter: getSort(typeof data !== 'undefined' ? data.sorters : null, attr),
178178
push(record) {
179179
let x = record[attr];
180180
if (['min', 'max'].includes(mode)) {
@@ -190,7 +190,7 @@ const aggregatorTemplates = {
190190
},
191191
value() { return this.val; },
192192
format(x) { if (isNaN(x)) { return x; } return formatter(x); },
193-
numInputs: (attr !== null) ? 0 : 1
193+
numInputs: (typeof attr !== 'undefined') ? 0 : 1
194194
};
195195
};
196196
};
@@ -212,7 +212,7 @@ const aggregatorTemplates = {
212212
return (this.vals[Math.floor(i)] + this.vals[Math.ceil(i)]) / 2.0;
213213
},
214214
format: formatter,
215-
numInputs: (attr !== null) ? 0 : 1
215+
numInputs: (typeof attr !== 'undefined') ? 0 : 1
216216
};
217217
};
218218
};
@@ -246,7 +246,7 @@ const aggregatorTemplates = {
246246
}
247247
},
248248
format: formatter,
249-
numInputs: (attr !== null) ? 0 : 1
249+
numInputs: (typeof attr !== 'undefined') ? 0 : 1
250250
};
251251
};
252252
};
@@ -264,7 +264,7 @@ const aggregatorTemplates = {
264264
},
265265
value() { return this.sumNum / this.sumDenom; },
266266
format: formatter,
267-
numInputs: (num !== null) && (denom !== null) ? 0 : 2
267+
numInputs: (typeof num !== 'undefined') && (typeof denom !== 'undefined') ? 0 : 2
268268
};
269269
};
270270
};

0 commit comments

Comments
 (0)