Commit 87f624dc authored by niko's avatar niko Committed by GitHub
parent 2ed3f76a
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
"dependencies": { "dependencies": {
"antd": "next", "antd": "next",
"dva": "^1.2.1", "dva": "^1.2.1",
"electron": "^1.7.9",
"g-cloud": "^1.0.2-beta", "g-cloud": "^1.0.2-beta",
"g2": "^2.3.8", "g2": "^2.3.8",
"g2-plugin-slider": "^1.2.1", "g2-plugin-slider": "^1.2.1",
...@@ -37,7 +38,7 @@ ...@@ -37,7 +38,7 @@
"babel-runtime": "^6.9.2", "babel-runtime": "^6.9.2",
"cross-port-killer": "^1.0.1", "cross-port-killer": "^1.0.1",
"enzyme": "^2.9.1", "enzyme": "^2.9.1",
"eslint": "^4.0.0", "eslint": "^4.8.0",
"eslint-config-airbnb": "^16.0.0", "eslint-config-airbnb": "^16.0.0",
"eslint-plugin-babel": "^4.0.0", "eslint-plugin-babel": "^4.0.0",
"eslint-plugin-import": "^2.2.0", "eslint-plugin-import": "^2.2.0",
......
...@@ -103,7 +103,7 @@ class Gauge extends PureComponent { ...@@ -103,7 +103,7 @@ class Gauge extends PureComponent {
} }
renderChart(nextProps) { renderChart(nextProps) {
const { height, color = '#00b1f8', bgColor = '#d3f3fe', title, percent } = nextProps || this.props; const { height, color = '#00b1f8', bgColor = '#d3f3fe', title, percent, format } = nextProps || this.props;
const data = [{ name: title, value: percent }]; const data = [{ name: title, value: percent }];
if (this.chart) { if (this.chart) {
...@@ -146,20 +146,7 @@ class Gauge extends PureComponent { ...@@ -146,20 +146,7 @@ class Gauge extends PureComponent {
stroke: color, stroke: color,
}, },
labelOffset: -12, labelOffset: -12,
formatter(val) { formatter: format,
switch (val * 1) {
case 20:
return '';
case 40:
return '';
case 60:
return '';
case 80:
return '';
default:
return '';
}
},
}); });
chart.point().position('value').shape('dashBoard'); chart.point().position('value').shape('dashBoard');
draw(data); draw(data);
......
...@@ -53,7 +53,7 @@ class Radar extends PureComponent { ...@@ -53,7 +53,7 @@ class Radar extends PureComponent {
hasLegend = true, hasLegend = true,
fit = true, fit = true,
tickCount = 4, tickCount = 4,
margin = [16, 0, 16, 0] } = this.props; margin = [16, 30, 16, 30] } = this.props;
if (!data || (data && data.length < 1)) { if (!data || (data && data.length < 1)) {
return; return;
......
import React from 'react'; import React from 'react';
import { Icon } from 'antd'; import PropTypes from 'prop-types';
import classNames from 'classnames';
import { Icon, Tooltip } from 'antd';
import styles from './index.less'; import styles from './index.less';
const Item = ({ title, flag, children, ...rest }) => ( const Item = ({ title, flag, children, ...rest }, { mini }) => {
<div {...rest} className={styles.trendItem}> const map = {
<span className={styles.title}>{title}</span> xs: 0,
{ flag && <span className={styles[flag]}><Icon type={`caret-${flag}`} /></span>} sm: 0,
<span className={styles.value}>{children}</span> md: 0,
</div> lg: 0,
); xlg: 0,
xl: 0,
const Trend = ({ colorType, children, ...rest }) => ( xxl: 0,
<div className={colorType ? (styles[`trend${colorType}`] || styles.trend) : styles.trend} {...rest}> };
{children}
</div> if (mini && mini.forEach) {
); mini.forEach((size) => {
map[size] = 1;
});
}
const clsObj = {};
Object.keys(map).forEach((k) => {
clsObj[styles[k]] = map[k];
});
const clsString = classNames(styles.trendItem, {
[styles.mini]: (typeof mini === 'boolean' && mini),
...clsObj,
});
const miniContent = (
<Tooltip title={children}>
<span className={styles.title}>{title}</span>
{ flag && <span className={styles[flag]}><Icon type={`caret-${flag}`} /></span>}
</Tooltip>
);
return (
<div {...rest} className={clsString}>
<div className={styles.content}>
<span className={styles.title}>{title}</span>
{ flag && <span className={styles[flag]}><Icon type={`caret-${flag}`} /></span>}
<span className={styles.value}>{children}</span>
</div>
<div className={styles.miniContent}>
{miniContent}
</div>
</div>
);
};
Item.contextTypes = {
mini: PropTypes.oneOfType([
PropTypes.array,
PropTypes.bool,
]),
};
class Trend extends React.Component {
getChildContext() {
return {
mini: this.props.mini,
};
}
render() {
const { colorType, children, mini, ...rest } = this.props;
return (
<div className={colorType ? (styles[`trend${colorType}`] || styles.trend) : styles.trend} {...rest}>
{children}
</div>
);
}
}
Trend.childContextTypes = {
mini: PropTypes.oneOfType([
PropTypes.array,
PropTypes.bool,
]),
};
Trend.Item = Item; Trend.Item = Item;
......
...@@ -7,43 +7,156 @@ ...@@ -7,43 +7,156 @@
white-space: nowrap; white-space: nowrap;
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
.trendItem { }
display: inline-block;
margin-right: 16px; .trendItem {
display: inline-block;
margin-right: 16px;
color: @text-color;
font-size: @font-size-base;
line-height: 22px;
height: 22px;
.content {
display: block;
}
.miniContent {
display: none;
}
.title {
margin-right: 4px;
}
.value {
color: @text-color; color: @text-color;
font-size: @font-size-base; font-weight: 600;
line-height: 22px; }
height: 22px; .up, .down {
.title { color: #00a854;
margin-right: 4px; margin-right: 4px;
} position: relative;
.value { top: 1px;
color: @text-color; i {
font-weight: 600; font-size: 12px;
} transform: scale(0.83);
.up, .down {
color: #00a854;
margin-right: 4px;
position: relative;
top: 1px;
i {
font-size: 12px;
transform: scale(0.83);
}
}
.down {
color: #f04134;
top: -1px;
} }
} }
.trendItem:last-child { .down {
margin-right: 0; color: #f04134;
top: -1px;
} }
} }
.trendItem:last-child {
margin-right: 0;
}
.trendgray { .trendgray {
.trend(); .trend();
.trendItem { .trendItem {
color: @text-color-secondary; color: @text-color-secondary;
} }
} }
.mini {
.content {
display: none;
}
.miniContent {
display: block;
}
}
.reset() {
.trendItem {
.content {
display: block;
}
.miniContent {
display: none;
}
}
}
@media screen and (max-width: @screen-xxl) {
.reset();
.xxl {
.content {
display: none;
}
.miniContent {
display: block;
}
}
}
@media screen and (max-width: @screen-xl) {
.reset();
.xl {
.content {
display: none;
}
.miniContent {
display: block;
}
}
}
@media screen and (max-width: @screen-lg) {
.reset();
.lg {
.content {
display: none;
}
.miniContent {
display: block;
}
}
}
// xlg
@media screen and (max-width: 1400px) {
.reset();
.xlg {
.content {
display: none;
}
.miniContent {
display: block;
}
}
}
@media screen and (max-width: @screen-md) {
.reset();
.md {
.content {
display: none;
}
.miniContent {
display: block;
}
}
}
@media screen and (max-width: @screen-sm) {
.reset();
.sm {
.content {
display: none;
}
.miniContent {
display: block;
}
}
}
@media screen and (max-width: @screen-xs) {
.reset();
.xs {
.content {
display: none;
}
.miniContent {
display: block;
}
}
}
...@@ -11,6 +11,8 @@ import Trend from './Trend'; ...@@ -11,6 +11,8 @@ import Trend from './Trend';
import Field from './Field'; import Field from './Field';
import NumberInfo from './NumberInfo'; import NumberInfo from './NumberInfo';
import WaterWave from './WaterWave'; import WaterWave from './WaterWave';
import TagCloud from './TagCloud';
import TimelineChart from './TimelineChart';
import { IconUp, IconDown } from './Icon'; import { IconUp, IconDown } from './Icon';
const yuan = val => `&yen; ${numeral(val).format('0,0')}`; const yuan = val => `&yen; ${numeral(val).format('0,0')}`;
...@@ -31,4 +33,6 @@ export default { ...@@ -31,4 +33,6 @@ export default {
Field, Field,
NumberInfo, NumberInfo,
WaterWave, WaterWave,
TagCloud,
TimelineChart,
}; };
---
order: 0
title: Simple
---
简单的页头。
````jsx
import CountDown from 'ant-design-pro/lib/CountDown';
const targetTime = new Date().getTime() + 3900000;
ReactDOM.render(
<CountDown target={targetTime} />
, mountNode);
````
...@@ -4,7 +4,7 @@ function fixedZero(val) { ...@@ -4,7 +4,7 @@ function fixedZero(val) {
return val * 1 < 10 ? `0${val}` : val; return val * 1 < 10 ? `0${val}` : val;
} }
class Countdown extends Component { class CountDown extends Component {
constructor(props) { constructor(props) {
super(props); super(props);
...@@ -102,4 +102,4 @@ class Countdown extends Component { ...@@ -102,4 +102,4 @@ class Countdown extends Component {
} }
} }
export default Countdown; export default CountDown;
---
category: Components
type: General
title: CountDown
subtitle: 倒计时
cols: 1
---
倒计时组件。
## API
| 参数 | 说明 | 类型 | 默认值 |
|----------|------------------------------------------|-------------|-------|
| format | 时间格式化显示显示 | Function(time) | |
| target | 目标时间 | Date | - |
import React, { Component } from 'react';
import { Tooltip } from 'antd';
import styles from './index.less';
/* eslint no-return-assign: 0 */
class MapChart extends Component {
getRect() {
// 0.4657 = 708 / 1520 (img origin size)
const width = this.root.offsetWidth;
const height = width * 0.4657;
return {
width,
height,
};
}
render() {
return (
<div className={styles.mapChart} ref={n => (this.root = n)}>
<Tooltip title="等待实现">
<div className={styles.canvas} ref={n => (this.root = n)}>
<img src="https://gw.alipayobjects.com/zos/rmsportal/fBcAYoxWIjlUXwDjqvzg.png" alt="map" />
<div ref={n => (this.node = n)} />
</div>
</Tooltip>
</div>
);
}
}
export default MapChart;
.mapChart {
background-color: #fff;
position: relative;
.canvas {
width: 100%;
& > img {
width: 100%;
}
}
}
import React from 'react';
import { Button, Input } from 'antd';
import styles from './index.less';
export default class SearchInput extends React.Component {
state = {
value: this.props.defaultValue,
}
handleOnChange = (e) => {
this.setState({
value: e.target.value,
});
}
handleOnSearch = () => {
if (this.props.onSearch) {
this.props.onSearch(this.state.value);
}
}
handleOnKey = (e) => {
if (e.keyCode === 13) {
this.handleOnSearch();
}
}
render() {
const { text = '搜索', reset } = this.props;
return (
<div className={styles.search}>
<Input
onKeyDown={this.handleOnKey}
placeholder="请输入"
size="large"
{...reset}
value={this.state.value}
onChange={this.handleOnChange}
addonAfter={<Button onClick={this.handleOnSearch} type="primary">{text}</Button>}
/>
</div>
);
}
}
@import "~antd/lib/style/themes/default.less";
.search {
display: inline-block;
:global {
.ant-input-group-addon {
border: none;
padding: 0;
}
.ant-input-group .ant-input {
width: 522px;
}
}
input {
border-right: none;
height: 40px;
line-height: 40px;
}
button {
border-radius: 0 @border-radius-base @border-radius-base 0;
width: 86px;
height: 40px;
}
}
---
order: 0
title: Simple
---
简单的页头。
````jsx
import TagSelect from 'ant-design-pro/lib/CountDown';
const TagOption = TagSelect.Option;
const TagExpand = TagSelect.Expand;
function handleFormSubmit(checkedValue) {
console.log(checkedValue);
}
ReactDOM.render(
<TagSelect onChange={handleFormSubmit}>
<TagOption value="cat1">类目一</TagOption>
<TagOption value="cat2">类目二</TagOption>
<TagOption value="cat3">类目三</TagOption>
<TagOption value="cat4">类目四</TagOption>
<TagExpand>
<TagOption value="cat5">类目五</TagOption>
<TagOption value="cat6">类目六</TagOption>
</TagExpand>
</TagSelect>
, mountNode);
````
...@@ -113,16 +113,16 @@ class TagSelect extends PureComponent { ...@@ -113,16 +113,16 @@ class TagSelect extends PureComponent {
render() { render() {
const { checkedTags, checkedAll, expand } = this.state; const { checkedTags, checkedAll, expand } = this.state;
const { children } = this.props; const { children, className, style } = this.props;
const expandNode = children.filter(child => child.props.displayName === 'TagSelectExpand')[0]; const expandNode = children.filter(child => child.props.displayName === 'TagSelectExpand')[0];
const cls = classNames(styles.tagSelect, { const cls = classNames(styles.tagSelect, className, {
[styles.expandTag]: expandNode, [styles.expandTag]: expandNode,
}); });
return ( return (
<div className={cls}> <div className={cls} style={style}>
<CheckableTag <CheckableTag
checked={checkedAll} checked={checkedAll}
key="tag-select-__all__" key="tag-select-__all__"
......
---
category: Components
type: General
title: TagSelect
subtitle: 标签选择器
cols: 1
---
倒计时组件。
## API
### TagSelect
| 参数 | 说明 | 类型 | 默认值 |
|----------|------------------------------------------|-------------|-------|
| onChange | 标签选择的回调函数 | Function(checkedTags) | |
### TagSelect.TagOption
| 参数 | 说明 | 类型 | 默认值 |
|----------|------------------------------------------|-------------|-------|
| value | 对应的值 | string | |
### TagSelect.TagExpand
包裹在 `TagSelect.TagExpand` 的元素会被折叠。
...@@ -3,9 +3,8 @@ import { connect } from 'dva'; ...@@ -3,9 +3,8 @@ import { connect } from 'dva';
import { Row, Col, Icon, Card, Tabs, Table, Radio, DatePicker, Tooltip } from 'antd'; import { Row, Col, Icon, Card, Tabs, Table, Radio, DatePicker, Tooltip } from 'antd';
import numeral from 'numeral'; import numeral from 'numeral';
import { ChartCard, Trend, yuan, MiniArea, MiniBar, MiniProgress, Field, Bar, Pie, NumberInfo, IconUp, IconDown } from '../../components/Charts'; import { ChartCard, Trend, yuan, MiniArea, MiniBar, MiniProgress, Field, Bar, Pie, NumberInfo, IconUp, IconDown, TimelineChart } from '../../components/Charts';
import TimelineChart from '../../components/TimelineChart';
import { getTimeDistance } from '../../utils/utils'; import { getTimeDistance } from '../../utils/utils';
import styles from './Analysis.less'; import styles from './Analysis.less';
...@@ -175,7 +174,9 @@ export default class Analysis extends Component { ...@@ -175,7 +174,9 @@ export default class Analysis extends Component {
const topColResponsiveProps = { const topColResponsiveProps = {
xs: 24, xs: 24,
sm: 12, sm: 12,
md: 6, md: 12,
lg: 12,
xl: 6,
style: { marginBottom: 24 }, style: { marginBottom: 24 },
}; };
...@@ -191,7 +192,7 @@ export default class Analysis extends Component { ...@@ -191,7 +192,7 @@ export default class Analysis extends Component {
footer={<Field label="日均销售额" value={numeral(12423).format('0,0')} />} footer={<Field label="日均销售额" value={numeral(12423).format('0,0')} />}
contentHeight={46} contentHeight={46}
> >
<Trend colorType="gray"> <Trend colorType="gray" mini={['xlg', 'md']}>
<Trend.Item title="周同比" flag="up">12.3%</Trend.Item> <Trend.Item title="周同比" flag="up">12.3%</Trend.Item>
<Trend.Item title="日环比" flag="down">11%</Trend.Item> <Trend.Item title="日环比" flag="down">11%</Trend.Item>
</Trend> </Trend>
...@@ -236,7 +237,7 @@ export default class Analysis extends Component { ...@@ -236,7 +237,7 @@ export default class Analysis extends Component {
action={<Tooltip title="购买效率"><Icon type="exclamation-circle-o" /></Tooltip>} action={<Tooltip title="购买效率"><Icon type="exclamation-circle-o" /></Tooltip>}
total="78%" total="78%"
footer={ footer={
<Trend> <Trend mini={['xlg', 'md']}>
<Trend.Item title="周同比" flag="up">12.3%</Trend.Item> <Trend.Item title="周同比" flag="up">12.3%</Trend.Item>
<Trend.Item title="日环比" flag="down">11%</Trend.Item> <Trend.Item title="日环比" flag="down">11%</Trend.Item>
</Trend> </Trend>
......
...@@ -3,10 +3,8 @@ import { connect } from 'dva'; ...@@ -3,10 +3,8 @@ import { connect } from 'dva';
import { Row, Col, Card } from 'antd'; import { Row, Col, Card } from 'antd';
import numeral from 'numeral'; import numeral from 'numeral';
import { NumberInfo, Pie, WaterWave, Gauge } from '../../components/Charts'; import { NumberInfo, Pie, WaterWave, Gauge, TagCloud } from '../../components/Charts';
import MapChart from '../../components/MapChart'; import CountDown from '../../components/CountDown';
import TagCloud from '../../components/TagCloud';
import Countdown from '../../components/Countdown';
import ActiveChart from '../../components/ActiveChart'; import ActiveChart from '../../components/ActiveChart';
import styles from './Monitor.less'; import styles from './Monitor.less';
...@@ -56,7 +54,7 @@ export default class Monitor extends PureComponent { ...@@ -56,7 +54,7 @@ export default class Monitor extends PureComponent {
<Col sm={6} xs={12}> <Col sm={6} xs={12}>
<NumberInfo <NumberInfo
subTitle="活动剩余时间" subTitle="活动剩余时间"
total={<Countdown target={targetTime} />} total={<CountDown target={targetTime} />}
/> />
</Col> </Col>
<Col sm={6} xs={12}> <Col sm={6} xs={12}>
...@@ -67,9 +65,7 @@ export default class Monitor extends PureComponent { ...@@ -67,9 +65,7 @@ export default class Monitor extends PureComponent {
</Col> </Col>
</Row> </Row>
<div className={styles.mapChart}> <div className={styles.mapChart}>
<MapChart <img src="https://gw.alipayobjects.com/zos/rmsportal/fBcAYoxWIjlUXwDjqvzg.png" alt="map" />
data={MapData}
/>
</div> </div>
</Card> </Card>
</Col> </Col>
...@@ -84,6 +80,20 @@ export default class Monitor extends PureComponent { ...@@ -84,6 +80,20 @@ export default class Monitor extends PureComponent {
bordered={false} bordered={false}
> >
<Gauge <Gauge
format={(val) => {
switch (val) {
case 20:
return '';
case 40:
return '';
case 60:
return '';
case 80:
return '';
default:
return '';
}
}}
title="核销率" title="核销率"
height={164} height={164}
percent={87} percent={87}
......
...@@ -4,6 +4,9 @@ ...@@ -4,6 +4,9 @@
.mapChart { .mapChart {
padding-top: 46px; padding-top: 46px;
height: 436px; height: 436px;
img {
width: 100%;
}
} }
@media screen and (max-width: @screen-lg) { @media screen and (max-width: @screen-lg) {
......
...@@ -2,13 +2,12 @@ import React, { PureComponent } from 'react'; ...@@ -2,13 +2,12 @@ import React, { PureComponent } from 'react';
import moment from 'moment'; import moment from 'moment';
import { connect } from 'dva'; import { connect } from 'dva';
import { routerRedux } from 'dva/router'; import { routerRedux } from 'dva/router';
import { Row, Col, Form, Card, Select, List } from 'antd'; import { Row, Col, Form, Card, Select, List, Input } from 'antd';
import PageHeaderLayout from '../../layouts/PageHeaderLayout'; import PageHeaderLayout from '../../layouts/PageHeaderLayout';
import StandardFormRow from '../../components/StandardFormRow'; import StandardFormRow from '../../components/StandardFormRow';
import TagSelect from '../../components/TagSelect'; import TagSelect from '../../components/TagSelect';
import AvatarList from '../../components/AvatarList'; import AvatarList from '../../components/AvatarList';
import SearchInput from '../../components/SearchInput';
import styles from './CoverCardList.less'; import styles from './CoverCardList.less';
...@@ -126,7 +125,13 @@ export default class CoverCardList extends PureComponent { ...@@ -126,7 +125,13 @@ export default class CoverCardList extends PureComponent {
const pageHeaderContent = ( const pageHeaderContent = (
<div style={{ textAlign: 'center' }}> <div style={{ textAlign: 'center' }}>
<SearchInput onSearch={this.handleFormSubmit} /> <Input.Search
placeholder="请输入"
enterButton="搜索"
size="large"
onSearch={this.handleFormSubmit}
style={{ width: 522 }}
/>
</div> </div>
); );
......
...@@ -2,12 +2,11 @@ import React, { PureComponent } from 'react'; ...@@ -2,12 +2,11 @@ import React, { PureComponent } from 'react';
import numeral from 'numeral'; import numeral from 'numeral';
import { connect } from 'dva'; import { connect } from 'dva';
import { routerRedux } from 'dva/router'; import { routerRedux } from 'dva/router';
import { Row, Col, Form, Card, Select, Icon, Avatar, List, Tooltip } from 'antd'; import { Row, Col, Form, Card, Select, Icon, Avatar, List, Tooltip, Input } from 'antd';
import PageHeaderLayout from '../../layouts/PageHeaderLayout'; import PageHeaderLayout from '../../layouts/PageHeaderLayout';
import StandardFormRow from '../../components/StandardFormRow'; import StandardFormRow from '../../components/StandardFormRow';
import TagSelect from '../../components/TagSelect'; import TagSelect from '../../components/TagSelect';
import SearchInput from '../../components/SearchInput';
import styles from './FilterCardList.less'; import styles from './FilterCardList.less';
...@@ -114,7 +113,13 @@ export default class FilterCardList extends PureComponent { ...@@ -114,7 +113,13 @@ export default class FilterCardList extends PureComponent {
const pageHeaderContent = ( const pageHeaderContent = (
<div style={{ textAlign: 'center' }}> <div style={{ textAlign: 'center' }}>
<SearchInput onSearch={this.handleFormSubmit} /> <Input.Search
placeholder="请输入"
enterButton="搜索"
size="large"
onSearch={this.handleFormSubmit}
style={{ width: 522 }}
/>
</div> </div>
); );
......
...@@ -2,12 +2,11 @@ import React, { Component } from 'react'; ...@@ -2,12 +2,11 @@ import React, { Component } from 'react';
import moment from 'moment'; import moment from 'moment';
import { connect } from 'dva'; import { connect } from 'dva';
import { routerRedux } from 'dva/router'; import { routerRedux } from 'dva/router';
import { Form, Card, Select, List, Tag, Icon, Avatar, Row, Col, Button } from 'antd'; import { Form, Card, Select, List, Tag, Icon, Avatar, Row, Col, Button, Input } from 'antd';
import PageHeaderLayout from '../../layouts/PageHeaderLayout'; import PageHeaderLayout from '../../layouts/PageHeaderLayout';
import StandardFormRow from '../../components/StandardFormRow'; import StandardFormRow from '../../components/StandardFormRow';
import TagSelect from '../../components/TagSelect'; import TagSelect from '../../components/TagSelect';
import SearchInput from '../../components/SearchInput';
import styles from './SearchList.less'; import styles from './SearchList.less';
const { Option } = Select; const { Option } = Select;
...@@ -150,7 +149,13 @@ export default class SearchList extends Component { ...@@ -150,7 +149,13 @@ export default class SearchList extends Component {
const pageHeaderContent = ( const pageHeaderContent = (
<div style={{ textAlign: 'center' }}> <div style={{ textAlign: 'center' }}>
<SearchInput onSearch={this.handleFormSubmit} /> <Input.Search
placeholder="请输入"
enterButton="搜索"
size="large"
onSearch={this.handleFormSubmit}
style={{ width: 522 }}
/>
</div> </div>
); );
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment