react-pivottable is a React-based pivot table library with drag'n'drop
functionality. It is a React port of the jQuery-based
PivotTable.js by the same author.
react-pivottable is part of Plotly's React Component Suite for building data visualization Web apps and products.
react-pivottable's function is to enable data exploration and analysis by
summarizing a data set into table or Plotly.js
chart with a true 2-d drag'n'drop UI, very similar to the one found in older
versions of Microsoft Excel.
A live demo can be found here.
Installation is via NPM and has a peer dependency on React:
npm install --save react-pivottable react react-dom
Basic usage is as follows. Note that PivotTableUI is a "dumb component" that
maintains essentially no state of its own.
importReactfrom'react';importReactDOMfrom'react-dom';importPivotTableUIfrom'react-pivottable/PivotTableUI';import'react-pivottable/pivottable.css';// see documentation for supported input formatsconstdata=[['attribute','attribute2'],['value1','value2']];classAppextendsReact.Component{constructor(props){super(props);this.state=props;}render(){return(<PivotTableUIdata={data}onChange={s=>this.setState(s)}{...this.state}/>);}}ReactDOM.render(<App/>,document.body);The Plotly react-plotly.js component can be passed in via dependency
injection. It has a peer dependency on plotly.js.
Important: If you build your project using webpack, you'll have to follow
these instructions
in order to successfully bundle plotly.js. See below for how to avoid having
to bundle plotly.js.
npm install --save react-pivottable react-plotly.js plotly.js react react-dom
To add the Plotly renderers to your app, you can use the following pattern:
importReactfrom'react';importPivotTableUIfrom'react-pivottable/PivotTableUI';import'react-pivottable/pivottable.css';importTableRenderersfrom'react-pivottable/TableRenderers';importPlotfrom'react-plotly.js';importcreatePlotlyRenderersfrom'react-pivottable/PlotlyRenderers';// create Plotly renderers via dependency injectionconstPlotlyRenderers=createPlotlyRenderers(Plot);// see documentation for supported input formatsconstdata=[['attribute','attribute2'],['value1','value2']];classAppextendsReact.Component{constructor(props){super(props);this.state=props;}render(){return(<PivotTableUIdata={data}onChange={s=>this.setState(s)}renderers={Object.assign({},TableRenderers,PlotlyRenderers)}{...this.state}/>);}}ReactDOM.render(<App/>,document.body);If you would rather not install and bundle plotly.js but rather get it into
your app via something like <script> tag, you can ignore react-plotly.js'
peer-dependcy warning and handle the dependency injection like this:
importReactfrom'react';importPivotTableUIfrom'react-pivottable/PivotTableUI';import'react-pivottable/pivottable.css';importTableRenderersfrom'react-pivottable/TableRenderers';importcreatePlotlyComponentfrom'react-plotly.js/factory';importcreatePlotlyRenderersfrom'react-pivottable/PlotlyRenderers';// create Plotly React component via dependency injectionconstPlot=createPlotlyComponent(window.Plotly);// create Plotly renderers via dependency injectionconstPlotlyRenderers=createPlotlyRenderers(Plot);// see documentation for supported input formatsconstdata=[['attribute','attribute2'],['value1','value2']];classAppextendsReact.Component{constructor(props){super(props);this.state=props;}render(){return(<PivotTableUIdata={data}onChange={s=>this.setState(s)}renderers={Object.assign({},TableRenderers,PlotlyRenderers)}{...this.state}/>);}}ReactDOM.render(<App/>,document.body);<PivotTableUI {...props} /><PivotTable {...props} /><Renderer {...props} />PivotData(props)
The interactive component provided by react-pivottable is PivotTableUI, but
output rendering is delegated to the non-interactive PivotTable component,
which accepts a subset of its properties. PivotTable can be invoked directly
and is useful for outputting non-interactive saved snapshots of PivotTableUI
configurations. PivotTable in turn delegates to a specific renderer component,
such as the default TableRenderer, which accepts a subset of the same
properties. Finally, most renderers will create non-React PivotData object to
handle the actual computations, which also accepts a subset of the same props as
the rest of the stack.
Here is a table of the properties accepted by this stack, including an indication of which layer consumes each, from the bottom up:
| Layer | Key & Type | Default Value | Description |
|---|---|---|---|
PivotData | datasee below for formats | (none, required) | data to be summarized |
PivotData | rowsarray of strings | [] | attribute names to prepopulate in row area |
PivotData | colsarray of strings | [] | attribute names to prepopulate in cols area |
PivotData | valsarray of strings | [] | attribute names used as arguments to aggregator (gets passed to aggregator generating function) |
PivotData | aggregatorsobject of functions | aggregators from Utilites | dictionary of generators for aggregation functions in dropdown (see original PivotTable.js documentation) |
PivotData | aggregatorNamestring | first key in aggregators | key to aggregators object specifying the aggregator to use for computations |
PivotData | valueFilterobject of arrays of strings | {} | object whose keys are attribute names and values are objects of attribute value-boolean pairs which denote records to include or exclude from computation and rendering; used to prepopulate the filter menus that appear on double-click |
PivotData | sortersobject or function | {} | accessed or called with an attribute name and can return a function which can be used as an argument to array.sort for output purposes. If no function is returned, the default sorting mechanism is a built-in "natural sort" implementation. Useful for sorting attributes like month names, see original PivotTable.js example 1 and original PivotTable.js example 2. |
PivotData | rowOrderstring | "key_a_to_z" | the order in which row data is provided to the renderer, must be one of "key_a_to_z", "value_a_to_z", "value_z_to_a", ordering by value orders by row total |
PivotData | colOrderstring | "key_a_to_z" | the order in which column data is provided to the renderer, must be one of "key_a_to_z", "value_a_to_z", "value_z_to_a", ordering by value orders by column total |
PivotData | derivedAttributesobject of functions | {} | defines derived attributes (see original PivotTable.js documentation) |
Renderer | <any> | (none, optional) | Renderers may accept any additional properties |
PivotTable | renderersobject of functions | TableRenderers | dictionary of renderer components |
PivotTable | rendererNamestring | first key in renderers | key to renderers object specifying the renderer to use |
PivotTableUI | onChangefunction | (none, required) | function called every time anything changes in the UI, with the new value of the properties needed to render the new state. This function must be hooked into a state-management system in order for the "dumb" PivotTableUI component to work. |
PivotTableUI | hiddenAttributesarray of strings | [] | contains attribute names to omit from the UI |
PivotTableUI | hiddenFromAggregatorsarray of strings | [] | contains attribute names to omit from the aggregator arguments dropdowns |
PivotTableUI | hiddenFromDragDroparray of strings | [] | contains attribute names to omit from the drag'n'drop portion of the UI |
PivotTableUI | menuLimitinteger | 500 | maximum number of values to list in the double-click menu |
PivotTableUI | unusedOrientationCutoffinteger | 85 | If the attributes' names' combined length in characters exceeds this value then the unused attributes area will be shown vertically to the left of the UI instead of horizontally above it. 0 therefore means 'always vertical', and Infinity means 'always horizontal'. |
One object per record, the object's keys are the attribute names.
Note: missing attributes or attributes with a value of null are treated as
if the value was the string "null".
constdata=[{attr1: 'value1_attr1',attr2: 'value1_attr2',//...},{attr1: 'value2_attr1',attr2: 'value2_attr2',//...},//...];One sub-array per record, the first sub-array contains the attribute names. If
subsequent sub-arrays are shorter than the first one, the trailing values are
treated as if they contained the string value "null". If subsequent sub-arrays
are longer than the first one, excess values are ignored. This format is
compatible with the output of CSV parsing libraries like PapaParse.
constdata=[['attr1','attr2'],['value1_attr1','value1_attr2'],['value2_attr1','value2_attr2'],//...];The function will be called with a callback that takes an object as a parameter.
Note: missing attributes or attributes with a value of null are treated as
if the value was the string "null".
constdata=function(callback){callback({"attr1": "value1_attr1","attr2": "value1_attr2",//...});callback({"attr1": "value2_attr1","attr2": "value2_attr2",//...};//...};
