Giter Club home page Giter Club logo

Comments (23)

nicolaskruchten avatar nicolaskruchten commented on September 18, 2024 1

I just pushed some new renderers, including an "Exportable TSV" one which should do the trick!

from react-pivottable.

drheinheimer avatar drheinheimer commented on September 18, 2024 1

@podwards In line with my strategy for saving data in #10, you can modify your renderer to accept a function to pass pivotted data back to your main component, which you could then export however you see fit. I need to do this as well, and can share my specific code once I get there.

from react-pivottable.

nicolaskruchten avatar nicolaskruchten commented on September 18, 2024 1

I'm happy to add to the API to make this less "hacky workaround" and more "supported good path" so please let me know what an ideal situation would look like for you and I'll see how close we can get!

from react-pivottable.

fernandocvlopes avatar fernandocvlopes commented on September 18, 2024 1

@nicolaskruchten Congrats for the great component.

I had a necessity to export the pivot table after the user configures it. I found the solution bellow, and maybe it will help others:

` import { PivotData } from 'react-pivottable/Utilities';
const profile = {
rows: [],
cols: [],
vals: [],
aggregator: 'Count'
};
export = () => {
var pivotData = new PivotData(this.state.profile);

var rowKeys = pivotData.getRowKeys();
var colKeys = pivotData.getColKeys();
if (rowKeys.length === 0) {
  rowKeys.push([]);
}
if (colKeys.length === 0) {
  colKeys.push([]);
}

var headerRow = pivotData.props.rows.map(function (r) {
  return r;
});
if (colKeys.length === 1 && colKeys[0].length === 0) {
  headerRow.push(this.state.profile.aggregatorName);
} else {
  colKeys.map(function (c) {
    return headerRow.push(c.join('-'));
  });
}

var result = rowKeys.map(function (r) {
  var row = r.map(function (x) {
    return x;
  });
  colKeys.map(function (c) {
    var v = pivotData.getAggregator(r, c).value();
    row.push(v ? v : '');
  });
  return row;
});

result.unshift(headerRow);

return result.map(function (r) {
  return r.join(',');
}).join('\n');

}`

I simply copied the original code from "TSVExportRenderer" and used it to get the final result.
With that I inserted a button that my users just press and I give him an excel (CSV) file.
Using that function is possible to get the json, CSV, TSV just from the pivot result showed at the screen.

from react-pivottable.

 avatar commented on September 18, 2024 1

@fernandocvlopes - We are trying to achieve this functionality and wanted to know if you were able to successfully do it the way you describe above, is there a repo where we can follow and reproduce this. Thanks in advance!

from react-pivottable.

rahulaggarwalg avatar rahulaggarwalg commented on September 18, 2024 1

Is it possible to save all the selected axis values and other settings (using drag and drop), So next time we can load same formatted graph/table.

from react-pivottable.

nicolaskruchten avatar nicolaskruchten commented on September 18, 2024

This isn't possible at the moment but later this week I can port over the "TSV Export" renderer from the sister project at https://pivottable.js.org/ :)

from react-pivottable.

podwards avatar podwards commented on September 18, 2024

That'd be great!

from react-pivottable.

podwards avatar podwards commented on September 18, 2024

Great! Thanks a lot, I'll check it out.

from react-pivottable.

turnerniles avatar turnerniles commented on September 18, 2024

@rheinheimer please share when you get there!

from react-pivottable.

drheinheimer avatar drheinheimer commented on September 18, 2024

Since PivotTableUI passes props on to the renderers, I've added this as an additional prop: onUpdateContent={this.onUpdateContent}. I then modified my PlotlyRenderer.js as below. However, the way I did it is just so I can plot right away. You could very well call props.onUpdateContent just before rendering, but after the PivotData is created.

<PlotlyComponent
    ....
    onAfterPlot={this.props.onUpdateContent({provider: PLOTLY_PROVIDER, data: [data], layout})}
/>

My onUpdateContent function is very simple:

onUpdateContent(content) {
    this.content = content;
}

This approach works, allowing you to then save content, but is, in fact, fundamentally limited. The main issue with this is that you cannot update your component state from within the renderer, which is called within a React render. This prevents any GUI component other than what's in the PivotTableUI from knowing what's in the PivotTable. I'm trying to figure out a hacky workaround for this.

from react-pivottable.

drheinheimer avatar drheinheimer commented on September 18, 2024

@nicolaskruchten I haven't yet gotten to this, but what I'm thinking is: don't use PivotData in the renderer, but instead have a final rendering component that just reads from props directly (okay, maybe a little necessary manipulation). Then, use the existing onChange to kick off a function to create the PivotData, using the new UI state, with a setState({data: myPivottedData}) at the end. This data would then be passed directly to the renderer. In this way, the pivotted data becomes accessible to other components, and the renderers become just passive consumers of data.

I don't know how this would fit into the API, but I think it should work. The existing renderer(s) would just need to be pulled apart a bit to achieve this.

from react-pivottable.

rit20j avatar rit20j commented on September 18, 2024

@nicolaskruchten Thanks for the amazing react app.

Is it possible to save all the selected axis values and other settings (using drag and drop), So next time we can load same formatted graph.

from react-pivottable.

nicolaskruchten avatar nicolaskruchten commented on September 18, 2024

@rit20j I'm glad you like it! In future please create a new issue instead of adding an unrelated comment to an existing one :)

To answer your question, you can just save all the props that you're passing to the component and that will save the state.

from react-pivottable.

drheinheimer avatar drheinheimer commented on September 18, 2024

@nicolaskruchten I just deleted a previous comment here regarding updating parent state to get pivotted data for export. I've now seen the latest revisions to react-plotly, and it seems the combination of onInitialized and onUpdate work great for this. Thanks for your great work!

from react-pivottable.

JonasWangLilly avatar JonasWangLilly commented on September 18, 2024

Hey I haven't been able to figure out how to export to a CSV and what @fernandocvlopes hasn't been able to work for me. Has anyone else been having the same problem?

from react-pivottable.

rahulaggarwalg avatar rahulaggarwalg commented on September 18, 2024

Hi, I'd like to export the pivot table to CSV or Excel once the user is happy with the arrangement of a table. Do you have any tips for how to do this? I can't see anything built in to do this.

from react-pivottable.

sandheepsebastain avatar sandheepsebastain commented on September 18, 2024

@nicolaskruchten Thank you for an amazing Pivot table app! I have been able to implement it for a lot of different functionalities.
Just so that I can give back to better this app, here is my code for exporting the selected data by using @fernandocvlopes suggestion

`import React from 'react';
import PivotTableUI from 'react-pivottable/PivotTableUI';
import 'react-pivottable/pivottable.css';
import TableRenderers from 'react-pivottable/TableRenderers';
import Plotly from "plotly.js"
import createPlotlyComponent from 'react-plotly.js/factory';
import createPlotlyRenderers from 'react-pivottable/PlotlyRenderers';
import { PivotData } from 'react-pivottable/Utilities';

const Plot = createPlotlyComponent(Plotly);
const PlotlyRenderers = createPlotlyRenderers(Plot);

// see documentation for supported input formats
class ExamplePivot extends React.Component {
constructor(props) {
super(props);
this.state = {pivotTableUIConfig: {}};
}

render() {

    const dataTemp = [['a', 'b'], [1, 2],[3,4]];
    const { data, ...pivotTableUIConfig } = this.state.pivotTableUIConfig;
    const profile = {
        rows: [],
        cols: [],
        vals: [],
        aggregator: 'Count'
        };

        const exportdata = () => {
            if(this.state.pivotTableUIConfig.hasOwnProperty("renderers")){
              var pivotData = new PivotData(this.state.pivotTableUIConfig);
              
              var rowKeys = pivotData.getRowKeys();
              var colKeys = pivotData.getColKeys();
              if (rowKeys.length === 0) {
                rowKeys.push([]);
              }
              if (colKeys.length === 0) {
                colKeys.push([]);
              }
  
              
  
              var headerRow = pivotData.props.rows.map(function (r) {
                return r;
              });
              if (colKeys.length === 1 && colKeys[0].length === 0) {
                headerRow.push(this.state.pivotTableUIConfig.aggregatorName);
              } else {
                colKeys.map(function (c) {
                  return headerRow.push(c.join('-'));
                });
              }
  
              
  
              var result = rowKeys.map(function (r) {
                var row = r.map(function (x) {
                  return x;
                });
                colKeys.map(function (c) {
                  var v = pivotData.getAggregator(r, c).value();
                  row.push(v ? v : '');
                });
                return row;
              });
  
              
  
              result.unshift(headerRow);
              
              var FinalResult= (result.map(function (r) {
                return r.join(',');
              }).join('\n'));
  
              const element = document.createElement("a");
              const file = new Blob([FinalResult], {type: 'text/plain'});
              element.href = URL.createObjectURL(file);
              element.download = "myFile.csv";
              document.body.appendChild(element); // Required for this to work in FireFox
              element.click()
  
              
            }
            else{
              alert("No Selections Made")
            }
          }
    

    return (
      <div>
      <button onClick={exportdata}>Download</button>
      <PivotTableUI
            data={dataTemp}
            aggregatorName="Sum"
            vals={["a"]}
            onChange={s => this.setState({ pivotTableUIConfig: s })}
            renderers={Object.assign({}, TableRenderers, PlotlyRenderers)}
            {...pivotTableUIConfig}
        />
      </div>
    );
}

}

export default ExamplePivot;`

from react-pivottable.

sandheepsebastain avatar sandheepsebastain commented on September 18, 2024

Is it possible to save all the selected axis values and other settings (using drag and drop), So next time we can load same formatted graph/table.

@rahulaggarwalg The pivotTableUIConfig state contains all your saved configurations, which you can save to a json file or to a cookie.
Another option is to refer the documentation for the js version of PivotTable that is saving the configuration to a cookie and modifying that for your react purposes
https://pivottable.js.org/examples/save_restore.html

from react-pivottable.

irfanandratama avatar irfanandratama commented on September 18, 2024

@nicolaskruchten Thank you for an amazing Pivot table app! I have been able to implement it for a lot of different functionalities.
Just so that I can give back to better this app, here is my code for exporting the selected data by using @fernandocvlopes suggestion

`import React from 'react';
import PivotTableUI from 'react-pivottable/PivotTableUI';
import 'react-pivottable/pivottable.css';
import TableRenderers from 'react-pivottable/TableRenderers';
import Plotly from "plotly.js"
import createPlotlyComponent from 'react-plotly.js/factory';
import createPlotlyRenderers from 'react-pivottable/PlotlyRenderers';
import { PivotData } from 'react-pivottable/Utilities';

const Plot = createPlotlyComponent(Plotly);
const PlotlyRenderers = createPlotlyRenderers(Plot);

// see documentation for supported input formats
class ExamplePivot extends React.Component {
constructor(props) {
super(props);
this.state = {pivotTableUIConfig: {}};
}

render() {

    const dataTemp = [['a', 'b'], [1, 2],[3,4]];
    const { data, ...pivotTableUIConfig } = this.state.pivotTableUIConfig;
    const profile = {
        rows: [],
        cols: [],
        vals: [],
        aggregator: 'Count'
        };

        const exportdata = () => {
            if(this.state.pivotTableUIConfig.hasOwnProperty("renderers")){
              var pivotData = new PivotData(this.state.pivotTableUIConfig);
              
              var rowKeys = pivotData.getRowKeys();
              var colKeys = pivotData.getColKeys();
              if (rowKeys.length === 0) {
                rowKeys.push([]);
              }
              if (colKeys.length === 0) {
                colKeys.push([]);
              }
  
              
  
              var headerRow = pivotData.props.rows.map(function (r) {
                return r;
              });
              if (colKeys.length === 1 && colKeys[0].length === 0) {
                headerRow.push(this.state.pivotTableUIConfig.aggregatorName);
              } else {
                colKeys.map(function (c) {
                  return headerRow.push(c.join('-'));
                });
              }
  
              
  
              var result = rowKeys.map(function (r) {
                var row = r.map(function (x) {
                  return x;
                });
                colKeys.map(function (c) {
                  var v = pivotData.getAggregator(r, c).value();
                  row.push(v ? v : '');
                });
                return row;
              });
  
              
  
              result.unshift(headerRow);
              
              var FinalResult= (result.map(function (r) {
                return r.join(',');
              }).join('\n'));
  
              const element = document.createElement("a");
              const file = new Blob([FinalResult], {type: 'text/plain'});
              element.href = URL.createObjectURL(file);
              element.download = "myFile.csv";
              document.body.appendChild(element); // Required for this to work in FireFox
              element.click()
  
              
            }
            else{
              alert("No Selections Made")
            }
          }
    

    return (
      <div>
      <button onClick={exportdata}>Download</button>
      <PivotTableUI
            data={dataTemp}
            aggregatorName="Sum"
            vals={["a"]}
            onChange={s => this.setState({ pivotTableUIConfig: s })}
            renderers={Object.assign({}, TableRenderers, PlotlyRenderers)}
            {...pivotTableUIConfig}
        />
      </div>
    );
}

}

export default ExamplePivot;`

hi @sandheepsebastain , this works great but when we set cols, the ''Totals' column and row is missing
image
image

you can see in react pivot there is Totals column at the right side but there is nothing on csv

from react-pivottable.

Barath-appmocx avatar Barath-appmocx commented on September 18, 2024

I followed the above code @nicolaskruchten i am getting this error in console

Module not found: Error: Can't resolve 'fs' in /node_modules/image-size/lib'

can you anyone suggest me a better solution?

from react-pivottable.

Buddikazz avatar Buddikazz commented on September 18, 2024

@irfanandratama how u get the first initial data withOut onchange setState?? please help

from react-pivottable.

DaleCox avatar DaleCox commented on September 18, 2024

Great app, really appreciate how easy it was to implement.

Here is a CSV export with totals example, building off @fernandocvlopes, @sandheepsebastain and @irfanandratama responses.

Context:
I have setup my react pivottable as outlined by DINA here (Which captures state changes) - https://stackoverflow.com/a/70066758/2212881

My state variable is pvState.

`
import { PivotData } from 'react-pivottable/Utilities';
...
const exportdata = () => {
if (pvState.data) {
const pivotData = new PivotData(pvState);

            const rowKeys = pivotData.getRowKeys();
            const colKeys = pivotData.getColKeys();
            if (rowKeys.length === 0) {
                rowKeys.push([]);
            }
            if (colKeys.length === 0) {
                colKeys.push([]);
            }

            const totalRow = ['Totals'];
            const headerRow = pivotData.props.rows.map(function (r) {
                totalRow.push('');
                return r;
            });

            //remove the last comma so the totals match up
            totalRow.pop();

            if (colKeys.length === 1 && colKeys[0].length === 0) {
                headerRow.push(pivotData.props.aggregatorName);
            } else {
                colKeys.map(function (c) {
                    const totalColAggregator = pivotData.getAggregator([], c).value();
                    totalRow.push(totalColAggregator);
                    return headerRow.push(c.join('-'));
                });

                headerRow.push('Totals');
            }

            const result = rowKeys.map(function (r) {
                let row = r.map(function (rowVal) {
                    if (rowVal && rowVal.length > 0 && rowVal.includes(',')) {
                        return `"${rowVal}"`;
                    } else {
                        return rowVal;
                    }
                });
                colKeys.map(function (c) {
                    let v = pivotData.getAggregator(r, c).value();
                    row.push(v ? v : '');
                });

                const totalRowAggregator = pivotData.getAggregator(r, []).value();
                row.push(totalRowAggregator);
                return row;
            });

            if(totalRow.length > 0){
                totalRow.push(pivotData.allTotal.value())
                result.push(totalRow);
            }

            result.unshift(headerRow);

            const finalResult = result.map(function (r) {
                return r.join(',');
            }).join('\n');

            const element = document.createElement('a');
            const file = new Blob([finalResult], { type: 'text/plain' });
            const object_URL = URL.createObjectURL(file);
            element.href = object_URL;
            element.download = 'myFile.csv';
            document.body.appendChild(element); 
            element.click();
            URL.revokeObjectURL(object_URL);
            element.remove();
        }
        else {
            console.log('No Selections Made');
        }
    }

`

from react-pivottable.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.