知乎css
我的博客node
Githubreact
Demogit
Repogithub
附上web
先上兩張照片吧express
由於公司使用的 react
+antd
+ts
, 雖然antd
前兩天搞了個聖誕驚嚇,可是毋庸置疑,這個組件庫作的確實很好啊,我不怕被噴,辯證一分爲二,不能由於別人犯一點的錯誤,就否定人家吧,廢話很少說,仍是講本文的主題吧
首先先安裝create-react-app
npm
npm i -g create-react-app create-react-app Charts --scripts-version=react-scripts-ts-antd
而後安裝react-route-dom和recharts
json
yarn add react-route-dom or npm i react-route-dom --save npm i recharts --save
由於TS
檢查較爲嚴格,因此,我對TS
有一些我本身須要rules
的配置tslint.js
後端
{ "extends": ["tslint:recommended", "tslint-react", "tslint-config-prettier"], "linterOptions": { "exclude": [ "config/**/*.js", "node_modules/**/*.ts", "coverage/lcov-report/*.js" ] }, "rules": { "no-string-throw": true, "no-unused-expression": false, "no-unused-variable": false, "no-use-before-declare": false, "no-duplicate-variable": false, "curly": true, "class-name": true, "triple-equals": [true, "allow-null-check"], "comment-format": [false, "check-space"], "eofline": true, "forin": false, "indent": [true, "spaces", 2], "label-position": true, "max-line-length": [true, 150], "member-access": false, "no-arg": true, "no-bitwise": false, "no-console": [true, "debug", "info", "time", "timeEnd", "trace" ], "no-construct": true, "no-debugger": true, "no-empty": false, "no-eval": true, "no-inferrable-types": true, "no-shadowed-variable": false, "no-string-literal": false, "no-switch-case-fall-through": false, "no-trailing-whitespace": true, "no-var-keyword": false, "object-literal-sort-keys": false, "one-line": [true, "check-open-brace", "check-catch", "check-else" ], "radix": false, "typedef-whitespace": [true, { "call-signature": "nospace", "index-signature": "nospace", "parameter": "nospace", "property-declaration": "nospace", "variable-declaration": "nospace" }], "variable-name": [true, "ban-keywords"], "whitespace": [true, "check-branch", "check-decl", "check-type", "check-preblock" ], "ordered-imports": false, "jsx-no-lambda": false, "interface-name": [true, "never-prefix"], "prefer-const": false } }
React-Route 4.x
提供給咱們使用的都是以組件形式存在的。咱們使用的時候就像咱們之前使用組件那樣使用就好了,詳見React-Route官方文檔。
菜單欄,我以爲往後可能還會增長其餘的Charts
,因此我將菜單經過配置文件來控制,增長複用性。
SideMenu.tsx
import React, { Component } from 'react'; import { Link } from 'react-router-dom'; import classnames from 'classnames'; import moment from 'moment'; import './index.scss'; import { menus } from './menus'; import { Layout, Menu, Icon } from 'antd'; import Timer from 'src/components/Timer/Timer'; const { Header, Footer, Sider, Content } = Layout; const { SubMenu } = Menu; interface SideMenuProps { children?: any; } export default class SideMenu extends Component<SideMenuProps, any> { public state = { collapsed: false, selectedKeys: [menus[0].key], }; public toggle = () => { this.setState({ collapsed: !this.state.collapsed }); }; render() { const { collapsed, selectedKeys, } = this.state return ( <Layout className="side-menu"> <Sider trigger={null} collapsible={true} collapsed={collapsed}> <div className="logo"> <img src={require('src/common/images/logo.png')} /> <a href="https://github.com/Rain120/charts" target="_blank"> <span className={classnames("title")}><Icon type="github" /></span> </a> <a href="https://www.zhihu.com/people/yan-yang-nian-hua-120/activities" target="_blank"> <span className={classnames("title")}><Icon type="zhihu" /></span> </a> </div> <Menu theme="dark" mode="inline" defaultSelectedKeys={selectedKeys}> { menus && menus.map(menu => ( menu.children ? ( <SubMenu key={menu.key} title={<span><Icon type={menu.icon} /><span>{menu.text}</span></span>}> { menu.children.map(item => ( <Menu.Item key={item.key}> <Link to={item.path}>{item.text}</Link> </Menu.Item> )) } </SubMenu> ) : ( <Menu.Item key={menu.key}> <Link to={menu.path} style={{ overflow: 'hidden' }}><Icon type={menu.icon} />{menu.text}</Link> </Menu.Item> ) )) } </Menu> </Sider> <Layout className="r-content"> <Header> <Icon className="trigger" type={collapsed ? 'menu-unfold' : 'menu-fold'} onClick={this.toggle} /> <Timer timerStyle="timer" /> </Header> <Content style={{ margin: '1rem', padding: '1rem', background: '#fff', minHeight: '25rem', }}> {this.props.children} </Content> <Footer style={{ textAlign: 'center' }}> ©{moment().format('YYYY')} Created by Rainy </Footer> </Layout> </Layout> ); } }
Menu.ts
/* * @Author: Rainy * @Github: https://github.com/Rain120 * @Date: 2018-12-30 15:43:12 * @LastEditTime: 2018-12-31 13:28:04 */ export const menus = [ { key: 'menu-0', icon: 'bar-chart', text: 'Charts Demo Show', path: '/', }, { key: 'menu-1', icon: 'dashboard', text: 'ReCharts', children: [ { key: '1', text: 'Charts Drawer', path: '/charts/charts-drawer' }, ] } ] as any;
獲取Excel
的數據是經過使用大佬的xlsx
插件來實現的,詳見XLSX官網。
npm i xlsx -S
由於此次項目沒有後端,因此其實咱們對Excel
文件的解析是在upload
以前完成的
public beforeUpload = (file: any, fileList: any) => { var rABS = true; const f = fileList[0]; var reader = new FileReader(); reader.onload = (e: any) => { let data: any = e.target.result; if (!rABS) { data = new Uint8Array(data); } var workbook = XLSX.read(data, { type: rABS ? 'binary' : 'array' }); // more sheet workbook.SheetNames.map(item => { var worksheet = workbook.Sheets[item]; var jsonArr = XLSX.utils.sheet_to_json(worksheet, { header: 1 }); this.handleImpotedJson(jsonArr); }) }; if (rABS) { reader.readAsBinaryString(f); } else { reader.readAsArrayBuffer(f); } return false; }
upload config
const props = { accept: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', name: 'file', headers: { authorization: 'authorization-text', }, multiple: false, action: '', beforeUpload: (file, fileList) => this.beforeUpload(file, fileList), onChange(info) { const status = info.file.status; if (status !== 'uploading') { console.log(info.file, info.fileList); } if (status === 'done') { message.success(`${info.file.name} file uploaded successfully.`); } else if (status === 'error') { message.error(`${info.file.name} file upload failed.`); } }, };
Charts
組件
由於使用的Charts
比較多,因此使用recharts
提供的組件ResponsiveContainer
爲了使得這些Charts
不夠縮放的影響。可是當前作的這些Charts
大部分都是相同的結構,因此相同的部分應該抽離出來。
由於其餘的Charts
都差很少,這裏我只說一下LineCharts
import React, { Component } from 'react'; import WrapperCharts from './WrapperCharts'; import './index.scss'; import { Line, Legend, Tooltip, XAxis, YAxis, CartesianGrid, LineChart, Label, } from "recharts"; export const COLOR_LISTS = ['#8884d8', '#cf6868', '#3fb549', '#a6d41f', '#8ad4d8', '#cfdd68', '#354449', '#a75d1f']; interface LineChartsProps { data?: any; names?: any; } export default class LineCharts extends Component<LineChartsProps, any> { render() { const { data, names } = this.props; return ( <WrapperCharts class_name="line-charts"> <LineChart data={data}> <CartesianGrid /> { names && <XAxis dataKey={names[0].dataKey} name={names[0].name} /> } <YAxis /> <Tooltip /> <Legend /> { names && names.slice(1).map((item, index) => ( <Line type="monotone" dataKey={item.dataKey} key={index} name={item.name} stroke={COLOR_LISTS[index]} /> )) } <Label /> </LineChart> </WrapperCharts> ) } }
github page deploy
npm i -g gh-pages
package.json
配置
"predeploy": "yarn run build", "deploy": "gh-pages -d build"
部署
yarn run deploy
引入圖片
以上就是這兩天作的小東西,寫的和講的都很潦草,請看管輕噴。