diff --git a/package.json b/package.json index bc1f2b0..c83f9b6 100644 --- a/package.json +++ b/package.json @@ -3,6 +3,8 @@ "version": "0.1.0", "private": true, "dependencies": { + "bloomer": "^0.6.3", + "bulma": "^0.7.1", "localforage": "^1.7.2", "lodash": "^4.17.10", "namor": "^1.0.1", @@ -11,6 +13,7 @@ "react": "^16.4.1", "react-csv": "^1.0.14", "react-dom": "^16.4.1", + "react-router-dom": "^4.3.1", "react-scripts-ts": "2.16.0", "react-table": "^6.8.6", "react-tabs": "^2.2.2", @@ -31,6 +34,7 @@ "@types/randomcolor": "^0.4.3", "@types/react": "^16.4.1", "@types/react-dom": "^16.0.6", + "@types/react-router-dom": "^4.2.7", "@types/react-table": "^6.7.11", "@types/react-tabs": "^1.0.4", "@types/recharts": "^1.0.23", diff --git a/public/config.json b/public/config.json index 3ec9b28..f8aac38 100644 --- a/public/config.json +++ b/public/config.json @@ -20,5 +20,10 @@ "tabTitle": "Tab 4", "fileName": "data.csv" } + ], + "chartList":[{ + "fileName": "data.csv", + "chartColumn": "status" + } ] } diff --git a/src/App.css b/src/App.css index c5c6e8a..6eeda91 100644 --- a/src/App.css +++ b/src/App.css @@ -22,7 +22,16 @@ font-size: large; } -@keyframes App-logo-spin { - from { transform: rotate(0deg); } - to { transform: rotate(360deg); } +.navbar-item:hover { + background-color: #f0f0f0; + color: #3273dc; +} + +@keyframes App-logo-spin { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } } diff --git a/src/App.tsx b/src/App.tsx index 1ae704f..29863ce 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,12 +1,12 @@ import * as React from 'react'; import './App.css'; -import ServerTabLoader from './ServerTabLoader'; +import AppRoute from './RouteMenu'; class App extends React.Component { public render() { return (
- +
); } diff --git a/src/Chart.tsx b/src/Chart.tsx index ff738a0..0879e12 100644 --- a/src/Chart.tsx +++ b/src/Chart.tsx @@ -1,22 +1,55 @@ import { - PieChart, Pie, ResponsiveContainer, Tooltip + PieChart, Pie, ResponsiveContainer, Tooltip, Cell } from 'recharts'; import * as React from 'react'; +import * as _ from 'lodash'; +import { Container, Title } from 'bloomer'; +const randomColor = require('randomcolor'); +import * as Papa from 'papaparse'; export class Chart extends React.Component { constructor(props: any) { super(props); + this.state = { data: [] }; + const loaded = (results: any) => { + const local = this; + local.setState({ + headers: results.meta.fields, + data: results.data, + }); + } + Papa.parse(this.props.csvFile, { + header: true, + download: true, + skipEmptyLines: true, + dynamicTyping: true, + complete: loaded + }); } public render() { - const data = this.props.data; + const data = this.state.data; + const countMap = _.countBy(data, (o: any) => _.get(o, this.props.chartColumn)) + const chartData = _.map(_.keys(countMap), (k: any) => { + return { + name: this.props.chartColumn + ' ' + k, + value: countMap[k], + } + }) return ( - - - - - - + + Plotting {_.capitalize(this.props.chartColumn)} + + + + { + chartData.map((_0, _1) => ) + } + + + + + ) } } diff --git a/src/ChartLoader.tsx b/src/ChartLoader.tsx new file mode 100644 index 0000000..edeb2c8 --- /dev/null +++ b/src/ChartLoader.tsx @@ -0,0 +1,39 @@ +import * as React from 'react'; +import * as _ from 'lodash'; +import { Columns, Column } from 'bloomer'; +import * as local from 'localforage'; +import { Chart } from './Chart'; + +export default class ChartLoader extends React.Component { + constructor(props: any) { + super(props); + this.state = { + chartList: [] + } + fetch('/config.json') + .then((response) => response.text()) + .then((jsonStr) => { + const jsonObj = JSON.parse(jsonStr); + const chartList = _.get(jsonObj, 'chartList', []); + this.setState({ chartList }); + local.setItem('config', jsonObj).catch((err: any) => { + console.error('error occurred when saving config', err); + }); + }) + .catch((e) => { + console.error('error occurred when loading config', e); + }); + } + + public render() { + return ( + + {this.state.chartList.map((o: any, i: number) => + + + + )} + + ) + } +} diff --git a/src/RouteMenu.tsx b/src/RouteMenu.tsx new file mode 100644 index 0000000..534b39d --- /dev/null +++ b/src/RouteMenu.tsx @@ -0,0 +1,34 @@ +import * as React from 'react'; +import { + BrowserRouter as Router, + Route, + Link +} from 'react-router-dom'; +import { Container, Navbar, NavbarItem, NavbarMenu, Section } from 'bloomer'; +import 'bulma/css/bulma.css'; +import ServerTabLoader from './ServerTabLoader'; +import ChartLoader from './ChartLoader'; + +const navButton = (name:string,link:string) => ( + {name} +); + +const AppRoute = () => ( + +
+ + + + {navButton('Charts','/')} + {navButton('Tables','/tables')} + + + +
+ + +
+
+
+) +export default AppRoute diff --git a/src/ServerTabLoader.tsx b/src/ServerTabLoader.tsx index 3fbc37f..fee3be6 100644 --- a/src/ServerTabLoader.tsx +++ b/src/ServerTabLoader.tsx @@ -2,6 +2,7 @@ import * as React from 'react'; import * as _ from 'lodash'; import ServerTable from './ServerTable'; import { Tabs, TabList, TabPanel, Tab } from 'react-tabs'; +import { Hero, HeroBody } from 'bloomer'; import * as local from 'localforage'; import './Tabs.css'; @@ -56,19 +57,24 @@ export default class ServerTabLoader extends React.Component { public render() { return ( - - - {this.state.tabList.map((o: any, i: number) => - ({o.tabTitle}) - )} - - {this.state.tabList.map((o: any, i: number) => - ( - - - ) - )} - + + + + + {this.state.tabList.map((o: any, i: number) => + ({o.tabTitle}) + )} + + {this.state.tabList.map((o: any, i: number) => + ( + + + ) + )} + + + + ) } } diff --git a/src/ServerTable.tsx b/src/ServerTable.tsx index 2068476..cc3eee5 100644 --- a/src/ServerTable.tsx +++ b/src/ServerTable.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import { Tips } from "./Utils"; import * as _ from 'lodash'; -// import { Chart } from './Chart'; +import { Button } from 'bloomer'; const randomColor = require('randomcolor'); const reactcsv = require('react-csv'); const CSVLink = reactcsv.CSVLink; @@ -56,7 +56,7 @@ export default class ServerTable extends React.Component { } const colorCol = this.props.colorColumn; const colColorMap = this.state.colColorMap; - const rowStyle = (state: any, rowInfo: any, column: any) => { + const rowStyle = (_0: any, rowInfo: any, _1: any) => { if (_.isUndefined(rowInfo) || _.isUndefined(colorCol)) { return {}; } @@ -80,7 +80,7 @@ export default class ServerTable extends React.Component { className="-striped -highlight" getTrProps={rowStyle} style={{ - height: "500px" + height: "75vh" }} > {(state, makeTable, ) => { @@ -89,9 +89,11 @@ export default class ServerTable extends React.Component {
{makeTable()} {/* */} - - Download CSV - +
diff --git a/yarn.lock b/yarn.lock index ae9a868..bf71ae8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -26,6 +26,10 @@ dependencies: "@types/d3-path" "*" +"@types/history@*": + version "4.6.2" + resolved "https://registry.yarnpkg.com/@types/history/-/history-4.6.2.tgz#12cfaba693ba20f114ed5765467ff25fdf67ddb0" + "@types/jest@^23.1.1": version "23.1.1" resolved "https://registry.yarnpkg.com/@types/jest/-/jest-23.1.1.tgz#c54ab1a5f41aa693c0957222dd10414416d0c87b" @@ -59,6 +63,21 @@ "@types/node" "*" "@types/react" "*" +"@types/react-router-dom@^4.2.7": + version "4.2.7" + resolved "https://registry.yarnpkg.com/@types/react-router-dom/-/react-router-dom-4.2.7.tgz#9d36bfe175f916dd8d7b6b0237feed6cce376b4c" + dependencies: + "@types/history" "*" + "@types/react" "*" + "@types/react-router" "*" + +"@types/react-router@*": + version "4.0.27" + resolved "https://registry.yarnpkg.com/@types/react-router/-/react-router-4.0.27.tgz#553f54df7c4b09d6046b0201ce9b91c46b2940e3" + dependencies: + "@types/history" "*" + "@types/react" "*" + "@types/react-table@^6.7.11": version "6.7.11" resolved "https://registry.yarnpkg.com/@types/react-table/-/react-table-6.7.11.tgz#26e85411981054af7dd657ef81e249baa6aee3d5" @@ -1068,6 +1087,13 @@ binary-extensions@^1.0.0: version "1.11.0" resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.11.0.tgz#46aa1751fb6a2f93ee5e689bb1087d4b14c6c205" +bloomer@^0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/bloomer/-/bloomer-0.6.3.tgz#4899cebb1992e934a148df942fbc37ce298e7669" + dependencies: + classnames "^2.2.5" + tslib "^1.7.0" + bluebird@^3.4.7, bluebird@^3.5.1: version "3.5.1" resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.1.tgz#d9551f9de98f1fcda1e683d17ee91a0602ee2eb9" @@ -1262,6 +1288,10 @@ builtin-status-codes@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" +bulma@^0.7.1: + version "0.7.1" + resolved "https://registry.yarnpkg.com/bulma/-/bulma-0.7.1.tgz#73c2e3b2930c90cc272029cbd19918b493fca486" + bytes@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" @@ -3171,6 +3201,16 @@ he@1.1.x: version "1.1.1" resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd" +history@^4.7.2: + version "4.7.2" + resolved "https://registry.yarnpkg.com/history/-/history-4.7.2.tgz#22b5c7f31633c5b8021c7f4a8a954ac139ee8d5b" + dependencies: + invariant "^2.2.1" + loose-envify "^1.2.0" + resolve-pathname "^2.2.0" + value-equal "^0.4.0" + warning "^3.0.0" + hmac-drbg@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" @@ -3179,6 +3219,10 @@ hmac-drbg@^1.0.0: minimalistic-assert "^1.0.0" minimalistic-crypto-utils "^1.0.1" +hoist-non-react-statics@^2.5.0: + version "2.5.5" + resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-2.5.5.tgz#c5903cf409c0dfd908f388e619d86b9c1174cb47" + home-or-tmp@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8" @@ -3428,7 +3472,7 @@ interpret@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.1.0.tgz#7ed1b1410c6a0e0f78cf95d3b8440c63f78b8614" -invariant@^2.2.2: +invariant@^2.2.1, invariant@^2.2.2, invariant@^2.2.4: version "2.2.4" resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" dependencies: @@ -4402,7 +4446,7 @@ longest@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097" -loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.3.1: +loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.2.0, loose-envify@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848" dependencies: @@ -5169,7 +5213,7 @@ path-to-regexp@0.1.7: version "0.1.7" resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" -path-to-regexp@^1.0.1: +path-to-regexp@^1.0.1, path-to-regexp@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-1.7.0.tgz#59fde0f435badacba103a84e9d3bc64e96b9937d" dependencies: @@ -5777,6 +5821,29 @@ react-resize-detector@1.1.0: dependencies: prop-types "^15.5.10" +react-router-dom@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-4.3.1.tgz#4c2619fc24c4fa87c9fd18f4fb4a43fe63fbd5c6" + dependencies: + history "^4.7.2" + invariant "^2.2.4" + loose-envify "^1.3.1" + prop-types "^15.6.1" + react-router "^4.3.1" + warning "^4.0.1" + +react-router@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/react-router/-/react-router-4.3.1.tgz#aada4aef14c809cb2e686b05cee4742234506c4e" + dependencies: + history "^4.7.2" + hoist-non-react-statics "^2.5.0" + invariant "^2.2.4" + loose-envify "^1.3.1" + path-to-regexp "^1.7.0" + prop-types "^15.6.1" + warning "^4.0.1" + react-scripts-ts@2.16.0: version "2.16.0" resolved "https://registry.yarnpkg.com/react-scripts-ts/-/react-scripts-ts-2.16.0.tgz#45f831a12139c3b59d6bb729c1b6ef51e0f22908" @@ -6145,6 +6212,10 @@ resolve-from@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" +resolve-pathname@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/resolve-pathname/-/resolve-pathname-2.2.0.tgz#7e9ae21ed815fd63ab189adeee64dc831eefa879" + resolve-url@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" @@ -6978,7 +7049,7 @@ tsconfig-paths@^3.1.1: strip-bom "^3.0.0" strip-json-comments "^2.0.1" -tslib@^1.8.0, tslib@^1.8.1: +tslib@^1.7.0, tslib@^1.8.0, tslib@^1.8.1: version "1.9.3" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286" @@ -7284,6 +7355,10 @@ validate-npm-package-license@^3.0.1: spdx-correct "^3.0.0" spdx-expression-parse "^3.0.0" +value-equal@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/value-equal/-/value-equal-0.4.0.tgz#c5bdd2f54ee093c04839d71ce2e4758a6890abc7" + vary@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" @@ -7318,6 +7393,18 @@ walker@~1.0.5: dependencies: makeerror "1.0.x" +warning@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/warning/-/warning-3.0.0.tgz#32e5377cb572de4ab04753bdf8821c01ed605b7c" + dependencies: + loose-envify "^1.0.0" + +warning@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/warning/-/warning-4.0.1.tgz#66ce376b7fbfe8a887c22bdf0e7349d73d397745" + dependencies: + loose-envify "^1.0.0" + watch@~0.18.0: version "0.18.0" resolved "https://registry.yarnpkg.com/watch/-/watch-0.18.0.tgz#28095476c6df7c90c963138990c0a5423eb4b986"