3

I am new to react js and I am trying to create a pivot table using React Pivot table. I want to be able to select a data set using a select drop down menu and update the state and re render the full table whenever there is a change in the drop down selection just like the jquery example shown here https://pivottable.js.org/examples/rcsvs.html

It works before I make any selections or changes to the Pivot Table. I am able to toggle between the 2 datasets and the state changes in the Pivot table. But when I select a pivot dimension and use the pivot table, after that point, changing the select menu does not help me change the pivot table's state. Please help.

Here's my code.

import React from 'react';
import PivotTableUI from 'react-pivottable/PivotTableUI';
import 'react-pivottable/pivottable.css';
import TableRenderers from 'react-pivottable/TableRenderers';
import Plot from 'react-plotly.js';
import createPlotlyRenderers from 'react-pivottable/PlotlyRenderers';


// create Plotly renderers via dependency injection
const PlotlyRenderers = createPlotlyRenderers(Plot);



const data1 = [{'Country':'USA','Sales':45000}, 
{'Country':'USA','Sales':50000},{'Country':'CA','Sales':15000}]

const data2 = [{'Product':'Sofa','Sales':5000},{'Product':'Dinner 
Table','Sales':50000},{'Product':'Chair','Sales':15000}]

const dataDic = {'Region':data1,'Products':data2}



class App extends React.Component {


constructor(props) {
  super(props);
  this.state = {selectedOption: 'Region'};
  this.handleChange = this.handleChange.bind(this);
  this.handleSubmit = this.handleSubmit.bind(this);
}

handleChange(event) {
  this.setState({selectedOption: event.target.value});

}


handleSubmit(event) {
  alert('You have selected ' + this.state.selectedOption);
  event.preventDefault();
}


render() { 


    return <div>
              <select defaultValue="Region" onChange={(e)=>   
 this.handleChange(e)}>
                    <option  value="Region">Region</option>
                    <option value="Products">Products</option>
              </select>
              <br/>
              <br/>

              <PivotTableUI
                  data={dataDic[this.state.selectedOption]}
                  onChange={s => this.setState(s)}

           renderers={Object.assign({},TableRenderers)}//,PlotlyRenderers)}
                  {...this.state}
              />

            </div>;
     }
 }



export default App;
Yash Nigam
  • 117
  • 1
  • 8

4 Answers4

1

I found that if I delete the data property from s

<PivotTableUI
  data = {[{}]}
  onChange={ s =>{ 
    delete s.data
    this.setState(s)
  }}
  {...this.state}
/>

This won't overwrite the data in the parent class and will be automatically rendered with updated data

Joe Davis
  • 541
  • 5
  • 10
1

you should add

 renderers={{ ...TableRenderers, ...PlotlyRenderers }}
                            {...state}

to your PivotTableUI, see the full example:


import TableRenderers from 'react-pivottable/TableRenderers';
import PivotTableUI from 'react-pivottable/PivotTableUI';
import Plot from 'react-plotly.js';
import createPlotlyRenderers from 'react-pivottable/PlotlyRenderers';
import 'react-pivottable/pivottable.css';

const PlotlyRenderers = createPlotlyRenderers(Plot);


function DataExploration() {

    const { dashboardData: { data } } = useSelector((state) => state.dashboardData)
    
    const ExpComp = (props) => {
        const [state, setState] = useState(props);
        return (
            <div className="row">
                <div className="col-md-12">
                    {
                        <PivotTableUI
                            style={
                                {
                                    width: "100%",
                                    height: "100%"
                                }
                            }
                            onChange={(s) => setState(s)}
                            renderers={{ ...TableRenderers, ...PlotlyRenderers }}
                            {...state}
                        />

                    }
                </div>
            </div>
        )
    }
    return (

        <ExpComp data={data} />
    )
}

From more details check the doc: https://github.com/plotly/react-pivottable
DINA TAKLIT
  • 7,074
  • 10
  • 69
  • 74
0

Working code sandbox

There were two problems;

  1. s => this.setState(s) in your PivotTable's onChange property. This overrides root state with all the props of your PivotTable. When your page initiated, container's (Grid) state only contains selectedOption:"Region" but after interacting with the PivotTable, container has receives all the props of the PivotTable. Screenshot: State of the Container after receiving props

  2. {...this.state} prop in PivotTableUI component, passes all keys as props in container's state including data.(As seen in the screenshot above). And this overrides data property, data={dataDic[this.state.selectedOption]} After this, changes to selectedOption state does not re-render PivotTableUI

Solution

  1. Change s => this.setState(s) with this.setState({ pivotTableUIConfig: s });

  2. Define a pivotTableUIConfig variable which does not include data property. (Used ES7 Object Rest Operator to Omit data property)

    // Picking all the properties except "data" const { data, ...pivotTableUIConfig } = this.state.pivotTableUIConfig;

  3. Change {...this.state} with {...pivotTableUIConfig}

trkaplan
  • 3,217
  • 2
  • 23
  • 26
0

Encountered the same problem and found a simple fix. The problem is that data prop always gets overwritten by {...state}. Hence we can assign data to state before passing it to PivotTableUI. And the data prop is no longer needed.

const state = {...this.state};
state['data'] = dataDic[this.state.selectedOption];
return (
  <PivotTableUI
      onChange={s => this.setState(s)}
      {...state}
  />
)