now download csv saves the filtered data
parent
e45fb70b8b
commit
a2af511bf5
|
|
@ -3,6 +3,7 @@
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"lodash": "^4.17.10",
|
||||||
"namor": "^1.0.1",
|
"namor": "^1.0.1",
|
||||||
"papaparse": "^4.5.0",
|
"papaparse": "^4.5.0",
|
||||||
"react": "^16.4.1",
|
"react": "^16.4.1",
|
||||||
|
|
@ -21,6 +22,7 @@
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/jest": "^23.1.1",
|
"@types/jest": "^23.1.1",
|
||||||
|
"@types/lodash": "^4.14.110",
|
||||||
"@types/node": "^10.3.4",
|
"@types/node": "^10.3.4",
|
||||||
"@types/papaparse": "^4.5.0",
|
"@types/papaparse": "^4.5.0",
|
||||||
"@types/react": "^16.4.1",
|
"@types/react": "^16.4.1",
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
import { LineChart, XAxis, Tooltip, CartesianGrid, Line } from 'recharts';
|
import {
|
||||||
|
PieChart, Pie, ResponsiveContainer, Tooltip
|
||||||
|
} from 'recharts';
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -7,28 +9,14 @@ export class Chart extends React.Component<any, any> {
|
||||||
super(props);
|
super(props);
|
||||||
}
|
}
|
||||||
public render() {
|
public render() {
|
||||||
const data = [
|
const data = this.props.data;
|
||||||
{ name: 'Page A', uv: 4000, pv: 2400, amt: 2400 },
|
|
||||||
{ name: 'Page B', uv: 3000, pv: 1398, amt: 2210 },
|
|
||||||
{ name: 'Page C', uv: 2000, pv: 9800, amt: 2290 },
|
|
||||||
{ name: 'Page D', uv: 2780, pv: 3908, amt: 2000 },
|
|
||||||
{ name: 'Page E', uv: 1890, pv: 4800, amt: 2181 },
|
|
||||||
{ name: 'Page F', uv: 2390, pv: 3800, amt: 2500 },
|
|
||||||
{ name: 'Page G', uv: 3490, pv: 4300, amt: 2100 },
|
|
||||||
];
|
|
||||||
return (
|
return (
|
||||||
<LineChart
|
<ResponsiveContainer width="100%" height={800}>
|
||||||
width={400}
|
<PieChart>
|
||||||
height={400}
|
<Pie data={data} dataKey="age" cx={500} cy={200} outerRadius={80} fill="#82ca9d" />
|
||||||
data={data}
|
|
||||||
margin={{ top: 5, right: 20, left: 10, bottom: 5 }}
|
|
||||||
>
|
|
||||||
<XAxis dataKey="name" />
|
|
||||||
<Tooltip />
|
<Tooltip />
|
||||||
<CartesianGrid stroke="#f5f5f5" />
|
</PieChart>
|
||||||
<Line type="monotone" dataKey="uv" stroke="#ff7300" yAxisId={0} />
|
</ResponsiveContainer>
|
||||||
<Line type="monotone" dataKey="pv" stroke="#387908" yAxisId={1} />
|
|
||||||
</LineChart>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,39 @@ import 'react-tabs/style/react-tabs.css';
|
||||||
import { Tab, Tabs, TabList, TabPanel } from 'react-tabs';
|
import { Tab, Tabs, TabList, TabPanel } from 'react-tabs';
|
||||||
import { ServerTable } from './ServerTable';
|
import { ServerTable } from './ServerTable';
|
||||||
import { Chart } from './Chart';
|
import { Chart } from './Chart';
|
||||||
|
import * as Papa from 'papaparse';
|
||||||
|
|
||||||
export default class ServerAnalytics extends React.Component {
|
export default class ServerAnalytics extends React.Component<any, any> {
|
||||||
|
constructor(props: any) {
|
||||||
|
super(props);
|
||||||
|
this.state = {
|
||||||
|
filteredData: [],
|
||||||
|
headers: [],
|
||||||
|
data: []
|
||||||
|
}
|
||||||
|
const loaded = (results: any) => {
|
||||||
|
const localstate = this;
|
||||||
|
localstate.setState({
|
||||||
|
headers: results.meta.fields,
|
||||||
|
data: results.data
|
||||||
|
});
|
||||||
|
}
|
||||||
|
Papa.parse('/data.csv', {
|
||||||
|
header: true,
|
||||||
|
download: true,
|
||||||
|
skipEmptyLines: true,
|
||||||
|
dynamicTyping: true,
|
||||||
|
complete: loaded
|
||||||
|
});
|
||||||
|
}
|
||||||
public render() {
|
public render() {
|
||||||
|
const setData = (filteredData: any) => {
|
||||||
|
this.setState({
|
||||||
|
filteredData
|
||||||
|
});
|
||||||
|
};
|
||||||
|
const data = this.state.data;
|
||||||
|
const headers = this.state.headers;
|
||||||
return (
|
return (
|
||||||
<div className="App">
|
<div className="App">
|
||||||
<Tabs>
|
<Tabs>
|
||||||
|
|
@ -16,10 +46,10 @@ export default class ServerAnalytics extends React.Component {
|
||||||
<Tab>Charts</Tab>
|
<Tab>Charts</Tab>
|
||||||
</TabList>
|
</TabList>
|
||||||
<TabPanel>
|
<TabPanel>
|
||||||
<ServerTable csvPath='/data.csv'/>
|
<ServerTable {...{ setData, data, headers }} />
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
<TabPanel>
|
<TabPanel>
|
||||||
<Chart />
|
<Chart data={this.state.filteredData} />
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { Tips } from "./Utils";
|
import { Tips } from "./Utils";
|
||||||
import * as Papa from 'papaparse';
|
import * as _ from 'lodash';
|
||||||
const reactcsv = require('react-csv');
|
const reactcsv = require('react-csv');
|
||||||
const CSVLink = reactcsv.CSVLink;
|
const CSVLink = reactcsv.CSVLink;
|
||||||
|
|
||||||
|
|
@ -9,42 +9,29 @@ import ReactTable from 'react-table';
|
||||||
import "react-table/react-table.css";
|
import "react-table/react-table.css";
|
||||||
|
|
||||||
export class ServerTable extends React.Component<any, any> {
|
export class ServerTable extends React.Component<any, any> {
|
||||||
|
private lastFiltered: any[] = []
|
||||||
constructor(props: any) {
|
constructor(props: any) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
|
||||||
headers: [],
|
|
||||||
data: []
|
|
||||||
};
|
|
||||||
const loaded = (results: any) => {
|
|
||||||
const localstate = this;
|
|
||||||
localstate.setState({
|
|
||||||
headers: results.meta.fields,
|
|
||||||
data: results.data
|
|
||||||
});
|
|
||||||
}
|
|
||||||
Papa.parse(this.props.csvPath, {
|
|
||||||
header: true,
|
|
||||||
download: true,
|
|
||||||
skipEmptyLines: true,
|
|
||||||
complete: loaded
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public render() {
|
public render() {
|
||||||
const { data, headers } = this.state;
|
const data = this.props.data;
|
||||||
|
const headers = this.props.headers;
|
||||||
const filterPart = (filter: any, row: any) =>
|
const filterPart = (filter: any, row: any) =>
|
||||||
row[filter.id].startsWith(filter.value) ||
|
String(row[filter.id]).startsWith(filter.value) ||
|
||||||
row[filter.id].endsWith(filter.value)
|
String(row[filter.id]).endsWith(filter.value)
|
||||||
const headerGen = (headerName: string) => {
|
const headerGen = (headerName: string) => {
|
||||||
const title = headerName.replace(/([A-Z])/g, ' $1').replace(/^./, (str:string) => str.toUpperCase());
|
const title = headerName
|
||||||
|
.replace(/([A-Z])/g, ' $1')
|
||||||
|
.replace(/^./, (str: string) => str.toUpperCase());
|
||||||
return {
|
return {
|
||||||
Header: title,
|
Header: title,
|
||||||
accessor: headerName
|
accessor: headerName
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
debugger;
|
||||||
const headerCols = headers.map(headerGen);
|
const headerCols = headers.map(headerGen);
|
||||||
return (
|
return (
|
||||||
<div>
|
|
||||||
<ReactTable
|
<ReactTable
|
||||||
data={data}
|
data={data}
|
||||||
filterable={true}
|
filterable={true}
|
||||||
|
|
@ -55,14 +42,29 @@ export class ServerTable extends React.Component<any, any> {
|
||||||
style={{
|
style={{
|
||||||
height: "450px"
|
height: "450px"
|
||||||
}}
|
}}
|
||||||
/>
|
>
|
||||||
|
{(state, makeTable,) => {
|
||||||
|
this.lastFiltered = state.sortedData.map((o: any) => _.pick(o, headers));
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
{makeTable()}
|
||||||
|
<CSVLink data={this.lastFiltered} filename={"data.csv"}>
|
||||||
|
Click here to download CSV file
|
||||||
|
</CSVLink>
|
||||||
<br />
|
<br />
|
||||||
<CSVLink data={data} filename={"data.csv"}>Click here to download CSV file</CSVLink>
|
|
||||||
<Tips />
|
<Tips />
|
||||||
</div>
|
</div>
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
</ReactTable>
|
||||||
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public componentWillUnmount() {
|
||||||
|
this.props.setData(this.lastFiltered);
|
||||||
|
}
|
||||||
|
|
||||||
public loaded(results: any) {
|
public loaded(results: any) {
|
||||||
this.setState({
|
this.setState({
|
||||||
headers: results.meta.fields,
|
headers: results.meta.fields,
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,10 @@
|
||||||
version "23.1.1"
|
version "23.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/@types/jest/-/jest-23.1.1.tgz#c54ab1a5f41aa693c0957222dd10414416d0c87b"
|
resolved "https://registry.yarnpkg.com/@types/jest/-/jest-23.1.1.tgz#c54ab1a5f41aa693c0957222dd10414416d0c87b"
|
||||||
|
|
||||||
|
"@types/lodash@^4.14.110":
|
||||||
|
version "4.14.110"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.110.tgz#fb07498f84152947f30ea09d89207ca07123461e"
|
||||||
|
|
||||||
"@types/node@*", "@types/node@^10.3.4":
|
"@types/node@*", "@types/node@^10.3.4":
|
||||||
version "10.3.4"
|
version "10.3.4"
|
||||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.3.4.tgz#c74e8aec19e555df44609b8057311052a2c84d9e"
|
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.3.4.tgz#c74e8aec19e555df44609b8057311052a2c84d9e"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue