diff --git a/config/config.ts b/config/config.ts
index 8a8f9f61b92b8267dcf8d55219e077a5c32b0f80..e060403ccacb0a297fa4463b921856da8ed95360 100644
--- a/config/config.ts
+++ b/config/config.ts
@@ -4,12 +4,10 @@ import slash from 'slash2';
import { IPlugin, IConfig } from 'umi-types';
import defaultSettings from './defaultSettings';
import webpackPlugin from './plugin.config';
-
-const { pwa, primaryColor } = defaultSettings;
-// preview.pro.ant.design only do not use in your production ;
+const { pwa, primaryColor } = defaultSettings; // preview.pro.ant.design only do not use in your production ;
// preview.pro.ant.design 专用环境变量,请不要在你的项目中使用它。
-const { ANT_DESIGN_PRO_ONLY_DO_NOT_USE_IN_YOUR_PRODUCTION, TEST, NODE_ENV } = process.env;
+const { ANT_DESIGN_PRO_ONLY_DO_NOT_USE_IN_YOUR_PRODUCTION, TEST, NODE_ENV } = process.env;
const plugins: IPlugin[] = [
[
'umi-plugin-react',
@@ -59,10 +57,9 @@ const plugins: IPlugin[] = [
autoAddMenu: true,
},
],
-];
-
-// 针对 preview.pro.ant.design 的 GA 统计代码
+]; // 针对 preview.pro.ant.design 的 GA 统计代码
// preview.pro.ant.design only do not use in your production ; preview.pro.ant.design 专用环境变量,请不要在你的项目中使用它。
+
if (ANT_DESIGN_PRO_ONLY_DO_NOT_USE_IN_YOUR_PRODUCTION === 'site') {
plugins.push([
'umi-plugin-ga',
@@ -84,7 +81,6 @@ const uglifyJSOptions =
},
}
: {};
-
export default {
// add for transfer to umi
plugins,
@@ -107,9 +103,9 @@ export default {
routes: [
{
path: '/',
- name: 'Analysis',
- icon: 'dashboard',
- component: './analysis',
+ name: 'welcome',
+ icon: 'smile',
+ component: './Welcome',
},
],
},
@@ -147,7 +143,9 @@ export default {
) {
return localName;
}
+
const match = context.resourcePath.match(/src(.*)/);
+
if (match && match[1]) {
const antdProPath = match[1].replace('.less', '');
const arr = slash(antdProPath)
@@ -156,6 +154,7 @@ export default {
.map((a: string) => a.toLowerCase());
return `antd-pro${arr.join('-')}-${localName}`.replace(/--/g, '-');
}
+
return localName;
},
},
diff --git a/package.json b/package.json
index 7a2d04d3232d81d0e6b332afe520743277bc717f..e6da2ccc19f0bba85be200b0397dee2801113f78 100644
--- a/package.json
+++ b/package.json
@@ -61,6 +61,7 @@
"bizcharts-plugin-slider": "^2.1.1-beta.1",
"classnames": "^2.2.6",
"dva": "^2.4.0",
+ "hash.js": "^1.1.5",
"lodash": "^4.17.10",
"lodash-decorators": "^6.0.0",
"memoize-one": "^5.0.0",
@@ -77,7 +78,8 @@
"react-dom": "^16.7.0",
"react-fittext": "^1.0.0",
"react-media": "^1.9.2",
- "react-media-hook2": "^1.0.2"
+ "react-media-hook2": "^1.0.2",
+ "umi": "^2.7.0-beta.2"
},
"devDependencies": {
"@types/classnames": "^2.2.7",
diff --git a/src/pages/analysis/_mock.ts b/src/pages/analysis/_mock.ts
deleted file mode 100644
index 29100ede39df287ae10b52429d7d4b588d5126ef..0000000000000000000000000000000000000000
--- a/src/pages/analysis/_mock.ts
+++ /dev/null
@@ -1,197 +0,0 @@
-import moment from 'moment';
-import { IVisitData, IRadarData, IAnalysisData } from './data';
-
-// mock data
-const visitData: IVisitData[] = [];
-const beginDay = new Date().getTime();
-
-const fakeY = [7, 5, 4, 2, 4, 7, 5, 6, 5, 9, 6, 3, 1, 5, 3, 6, 5];
-for (let i = 0; i < fakeY.length; i += 1) {
- visitData.push({
- x: moment(new Date(beginDay + 1000 * 60 * 60 * 24 * i)).format('YYYY-MM-DD'),
- y: fakeY[i],
- });
-}
-
-const visitData2 = [];
-const fakeY2 = [1, 6, 4, 8, 3, 7, 2];
-for (let i = 0; i < fakeY2.length; i += 1) {
- visitData2.push({
- x: moment(new Date(beginDay + 1000 * 60 * 60 * 24 * i)).format('YYYY-MM-DD'),
- y: fakeY2[i],
- });
-}
-
-const salesData = [];
-for (let i = 0; i < 12; i += 1) {
- salesData.push({
- x: `${i + 1}月`,
- y: Math.floor(Math.random() * 1000) + 200,
- });
-}
-const searchData = [];
-for (let i = 0; i < 50; i += 1) {
- searchData.push({
- index: i + 1,
- keyword: `搜索关键词-${i}`,
- count: Math.floor(Math.random() * 1000),
- range: Math.floor(Math.random() * 100),
- status: Math.floor((Math.random() * 10) % 2),
- });
-}
-const salesTypeData = [
- {
- x: '家用电器',
- y: 4544,
- },
- {
- x: '食用酒水',
- y: 3321,
- },
- {
- x: '个护健康',
- y: 3113,
- },
- {
- x: '服饰箱包',
- y: 2341,
- },
- {
- x: '母婴产品',
- y: 1231,
- },
- {
- x: '其他',
- y: 1231,
- },
-];
-
-const salesTypeDataOnline = [
- {
- x: '家用电器',
- y: 244,
- },
- {
- x: '食用酒水',
- y: 321,
- },
- {
- x: '个护健康',
- y: 311,
- },
- {
- x: '服饰箱包',
- y: 41,
- },
- {
- x: '母婴产品',
- y: 121,
- },
- {
- x: '其他',
- y: 111,
- },
-];
-
-const salesTypeDataOffline = [
- {
- x: '家用电器',
- y: 99,
- },
- {
- x: '食用酒水',
- y: 188,
- },
- {
- x: '个护健康',
- y: 344,
- },
- {
- x: '服饰箱包',
- y: 255,
- },
- {
- x: '其他',
- y: 65,
- },
-];
-
-const offlineData = [];
-for (let i = 0; i < 10; i += 1) {
- offlineData.push({
- name: `Stores ${i}`,
- cvr: Math.ceil(Math.random() * 9) / 10,
- });
-}
-const offlineChartData = [];
-for (let i = 0; i < 20; i += 1) {
- offlineChartData.push({
- x: new Date().getTime() + 1000 * 60 * 30 * i,
- y1: Math.floor(Math.random() * 100) + 10,
- y2: Math.floor(Math.random() * 100) + 10,
- });
-}
-
-const radarOriginData = [
- {
- name: '个人',
- ref: 10,
- koubei: 8,
- output: 4,
- contribute: 5,
- hot: 7,
- },
- {
- name: '团队',
- ref: 3,
- koubei: 9,
- output: 6,
- contribute: 3,
- hot: 1,
- },
- {
- name: '部门',
- ref: 4,
- koubei: 1,
- output: 6,
- contribute: 5,
- hot: 7,
- },
-];
-
-const radarData: IRadarData[] = [];
-const radarTitleMap = {
- ref: '引用',
- koubei: '口碑',
- output: '产量',
- contribute: '贡献',
- hot: '热度',
-};
-radarOriginData.forEach(item => {
- Object.keys(item).forEach(key => {
- if (key !== 'name') {
- radarData.push({
- name: item.name,
- label: radarTitleMap[key],
- value: item[key],
- });
- }
- });
-});
-
-const getFakeChartData: IAnalysisData = {
- visitData,
- visitData2,
- salesData,
- searchData,
- offlineData,
- offlineChartData,
- salesTypeData,
- salesTypeDataOnline,
- salesTypeDataOffline,
- radarData,
-};
-
-export default {
- 'GET /api/analysis/fake_chart_data': getFakeChartData,
-};
diff --git a/src/pages/analysis/components/Charts/Bar/index.tsx b/src/pages/analysis/components/Charts/Bar/index.tsx
deleted file mode 100644
index b5507fe6ad898a2f19b8f5a5ae45b932db94ae86..0000000000000000000000000000000000000000
--- a/src/pages/analysis/components/Charts/Bar/index.tsx
+++ /dev/null
@@ -1,135 +0,0 @@
-import React, { Component } from 'react';
-import { Chart, Axis, Tooltip, Geom } from 'bizcharts';
-import Debounce from 'lodash-decorators/debounce';
-import Bind from 'lodash-decorators/bind';
-import styles from '../index.less';
-import autoHeight from '../autoHeight';
-
-export interface IBarProps {
- title: React.ReactNode;
- color?: string;
- padding?: [number, number, number, number];
- height?: number;
- data: Array<{
- x: string;
- y: number;
- }>;
- forceFit?: boolean;
- autoLabel?: boolean;
- style?: React.CSSProperties;
-}
-
-class Bar extends Component<
- IBarProps,
- {
- autoHideXLabels: boolean;
- }
-> {
- root: HTMLDivElement | undefined;
- node: HTMLDivElement | undefined;
-
- state = {
- height: 0,
- autoHideXLabels: false,
- };
-
- componentDidMount() {
- window.addEventListener('resize', this.resize, { passive: true });
- }
-
- componentWillUnmount() {
- window.removeEventListener('resize', this.resize);
- }
-
- handleRoot = (n: HTMLDivElement) => {
- this.root = n;
- };
- handleRef = (n: HTMLDivElement) => {
- this.node = n;
- };
-
- @Bind()
- @Debounce(400)
- resize() {
- if (!this.node || !this.node.parentNode) {
- return;
- }
- const canvasWidth = (this.node.parentNode as HTMLDivElement).clientWidth;
- const { data = [], autoLabel = true } = this.props;
- if (!autoLabel) {
- return;
- }
- const minWidth = data.length * 30;
- const { autoHideXLabels } = this.state;
-
- if (canvasWidth <= minWidth) {
- if (!autoHideXLabels) {
- this.setState({
- autoHideXLabels: true,
- });
- }
- } else if (autoHideXLabels) {
- this.setState({
- autoHideXLabels: false,
- });
- }
- }
-
- render() {
- const {
- height: propsHeight = 1,
- title,
- forceFit = true,
- data,
- color = 'rgba(24, 144, 255, 0.85)',
- padding,
- } = this.props;
-
- const { autoHideXLabels } = this.state;
-
- const scale = {
- x: {
- type: 'cat',
- },
- y: {
- min: 0,
- },
- };
-
- const tooltip: [string, (...args: any[]) => { name?: string; value: string }] = [
- 'x*y',
- (x: string, y: string) => ({
- name: x,
- value: y,
- }),
- ];
- const { height: stateHeight } = this.state;
- const height = propsHeight || stateHeight;
- return (
-
-
- {title &&
{title}
}
-
-
-
-
-
-
-
-
- );
- }
-}
-
-export default autoHeight()(Bar);
diff --git a/src/pages/analysis/components/Charts/ChartCard/index.less b/src/pages/analysis/components/Charts/ChartCard/index.less
deleted file mode 100644
index 282f17d9cf32af486e1c13d8d55bec1a9e5076f1..0000000000000000000000000000000000000000
--- a/src/pages/analysis/components/Charts/ChartCard/index.less
+++ /dev/null
@@ -1,75 +0,0 @@
-@import '~antd/lib/style/themes/default.less';
-
-.chartCard {
- position: relative;
- .chartTop {
- position: relative;
- width: 100%;
- overflow: hidden;
- }
- .chartTopMargin {
- margin-bottom: 12px;
- }
- .chartTopHasMargin {
- margin-bottom: 20px;
- }
- .metaWrap {
- float: left;
- }
- .avatar {
- position: relative;
- top: 4px;
- float: left;
- margin-right: 20px;
- img {
- border-radius: 100%;
- }
- }
- .meta {
- height: 22px;
- color: @text-color-secondary;
- font-size: @font-size-base;
- line-height: 22px;
- }
- .action {
- position: absolute;
- top: 4px;
- right: 0;
- line-height: 1;
- cursor: pointer;
- }
- .total {
- height: 38px;
- margin-top: 4px;
- margin-bottom: 0;
- overflow: hidden;
- color: @heading-color;
- font-size: 30px;
- line-height: 38px;
- white-space: nowrap;
- text-overflow: ellipsis;
- word-break: break-all;
- }
- .content {
- position: relative;
- width: 100%;
- margin-bottom: 12px;
- }
- .contentFixed {
- position: absolute;
- bottom: 0;
- left: 0;
- width: 100%;
- }
- .footer {
- margin-top: 8px;
- padding-top: 9px;
- border-top: 1px solid @border-color-split;
- & > * {
- position: relative;
- }
- }
- .footerMargin {
- margin-top: 20px;
- }
-}
diff --git a/src/pages/analysis/components/Charts/ChartCard/index.tsx b/src/pages/analysis/components/Charts/ChartCard/index.tsx
deleted file mode 100644
index 11f5f2052c176f10269fb29efd312714c5957c3a..0000000000000000000000000000000000000000
--- a/src/pages/analysis/components/Charts/ChartCard/index.tsx
+++ /dev/null
@@ -1,98 +0,0 @@
-import React from 'react';
-import { Card } from 'antd';
-import classNames from 'classnames';
-import { CardProps } from 'antd/lib/card';
-
-import styles from './index.less';
-
-type totalType = () => React.ReactNode;
-
-const renderTotal = (total?: number | totalType | React.ReactNode) => {
- if (!total) {
- return;
- }
- let totalDom;
- switch (typeof total) {
- case 'undefined':
- totalDom = null;
- break;
- case 'function':
- totalDom = {total()}
;
- break;
- default:
- totalDom = {total}
;
- }
- return totalDom;
-};
-
-export interface IChartCardProps extends CardProps {
- title: React.ReactNode;
- action?: React.ReactNode;
- total?: React.ReactNode | number | (() => React.ReactNode | number);
- footer?: React.ReactNode;
- contentHeight?: number;
- avatar?: React.ReactNode;
- style?: React.CSSProperties;
-}
-
-class ChartCard extends React.Component {
- renderContent = () => {
- const { contentHeight, title, avatar, action, total, footer, children, loading } = this.props;
- if (loading) {
- return false;
- }
- return (
-
-
-
{avatar}
-
-
- {title}
- {action}
-
- {renderTotal(total)}
-
-
- {children && (
-
- )}
- {footer && (
-
- {footer}
-
- )}
-
- );
- };
-
- render() {
- const {
- loading = false,
- contentHeight,
- title,
- avatar,
- action,
- total,
- footer,
- children,
- ...rest
- } = this.props;
- return (
-
- {this.renderContent()}
-
- );
- }
-}
-
-export default ChartCard;
diff --git a/src/pages/analysis/components/Charts/Field/index.less b/src/pages/analysis/components/Charts/Field/index.less
deleted file mode 100644
index 4124471cb522bf18fb7963675ddeeb3dc217b9e7..0000000000000000000000000000000000000000
--- a/src/pages/analysis/components/Charts/Field/index.less
+++ /dev/null
@@ -1,17 +0,0 @@
-@import '~antd/lib/style/themes/default.less';
-
-.field {
- margin: 0;
- overflow: hidden;
- white-space: nowrap;
- text-overflow: ellipsis;
- .label,
- .number {
- font-size: @font-size-base;
- line-height: 22px;
- }
- .number {
- margin-left: 8px;
- color: @heading-color;
- }
-}
diff --git a/src/pages/analysis/components/Charts/Field/index.tsx b/src/pages/analysis/components/Charts/Field/index.tsx
deleted file mode 100644
index ee3c12454ead9e275a7ed71dba1a20c79b083cf8..0000000000000000000000000000000000000000
--- a/src/pages/analysis/components/Charts/Field/index.tsx
+++ /dev/null
@@ -1,18 +0,0 @@
-import React from 'react';
-
-import styles from './index.less';
-
-export interface IFieldProps {
- label: React.ReactNode;
- value: React.ReactNode;
- style?: React.CSSProperties;
-}
-
-const Field: React.SFC = ({ label, value, ...rest }) => (
-
- {label}
- {value}
-
-);
-
-export default Field;
diff --git a/src/pages/analysis/components/Charts/Gauge/index.tsx b/src/pages/analysis/components/Charts/Gauge/index.tsx
deleted file mode 100644
index b5d33c60421e690358310fa418b909dbe2e30aca..0000000000000000000000000000000000000000
--- a/src/pages/analysis/components/Charts/Gauge/index.tsx
+++ /dev/null
@@ -1,177 +0,0 @@
-import React from 'react';
-import { Chart, Geom, Axis, Coord, Guide, Shape } from 'bizcharts';
-import autoHeight from '../autoHeight';
-
-const { Arc, Html, Line } = Guide;
-
-export interface IGaugeProps {
- title: React.ReactNode;
- color?: string;
- height?: number;
- bgColor?: number;
- percent: number;
- forceFit?: boolean;
- style?: React.CSSProperties;
- formatter: (value: string) => string;
-}
-
-const defaultFormatter = (val: string): string => {
- switch (val) {
- case '2':
- return '差';
- case '4':
- return '中';
- case '6':
- return '良';
- case '8':
- return '优';
- default:
- return '';
- }
-};
-
-Shape.registerShape!('point', 'pointer', {
- drawShape(cfg: any, group: any) {
- let point = cfg.points[0];
- point = (this as any).parsePoint(point);
- const center = (this as any).parsePoint({
- x: 0,
- y: 0,
- });
- group.addShape('line', {
- attrs: {
- x1: center.x,
- y1: center.y,
- x2: point.x,
- y2: point.y,
- stroke: cfg.color,
- lineWidth: 2,
- lineCap: 'round',
- },
- });
- return group.addShape('circle', {
- attrs: {
- x: center.x,
- y: center.y,
- r: 6,
- stroke: cfg.color,
- lineWidth: 3,
- fill: '#fff',
- },
- });
- },
-});
-
-class Gauge extends React.Component {
- render() {
- const {
- title,
- height = 1,
- percent,
- forceFit = true,
- formatter = defaultFormatter,
- color = '#2F9CFF',
- bgColor = '#F0F2F5',
- } = this.props;
- const cols = {
- value: {
- type: 'linear',
- min: 0,
- max: 10,
- tickCount: 6,
- nice: true,
- },
- };
- const renderHtml = () => `
-
-
${title}
-
- ${(data[0].value * 10).toFixed(2)}%
-
-
`;
- const data = [{ value: percent / 10 }];
- const textStyle: {
- fontSize: number;
- fill: string;
- textAlign: 'center';
- } = {
- fontSize: 12,
- fill: 'rgba(0, 0, 0, 0.65)',
- textAlign: 'center',
- };
- return (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- );
- }
-}
-
-export default autoHeight()(Gauge);
diff --git a/src/pages/analysis/components/Charts/MiniArea/index.tsx b/src/pages/analysis/components/Charts/MiniArea/index.tsx
deleted file mode 100644
index 5684aa51fb6c8cf3bbe5457c38a2dbe0168ef3c0..0000000000000000000000000000000000000000
--- a/src/pages/analysis/components/Charts/MiniArea/index.tsx
+++ /dev/null
@@ -1,133 +0,0 @@
-import React from 'react';
-import { Chart, Axis, Tooltip, Geom } from 'bizcharts';
-import autoHeight from '../autoHeight';
-import styles from '../index.less';
-
-export interface IAxis {
- title: any;
- line: any;
- gridAlign: any;
- labels: any;
- tickLine: any;
- grid: any;
-}
-
-export interface IMiniAreaProps {
- color?: string;
- height?: number;
- borderColor?: string;
- line?: boolean;
- animate?: boolean;
- xAxis?: IAxis;
- forceFit?: boolean;
- scale?: { x: any; y: any };
- yAxis?: IAxis;
- borderWidth?: number;
- data: Array<{
- x: number | string;
- y: number;
- }>;
-}
-
-class MiniArea extends React.Component {
- render() {
- const {
- height = 1,
- data = [],
- forceFit = true,
- color = 'rgba(24, 144, 255, 0.2)',
- borderColor = '#1089ff',
- scale = { x: {}, y: {} },
- borderWidth = 2,
- line,
- xAxis,
- yAxis,
- animate = true,
- } = this.props;
-
- const padding: [number, number, number, number] = [36, 5, 30, 5];
-
- const scaleProps = {
- x: {
- type: 'cat',
- range: [0, 1],
- ...scale!.x,
- },
- y: {
- min: 0,
- ...scale!.y,
- },
- };
-
- const tooltip: [string, (...args: any[]) => { name?: string; value: string }] = [
- 'x*y',
- (x: string, y: string) => ({
- name: x,
- value: y,
- }),
- ];
-
- const chartHeight = height + 54;
-
- return (
-
-
- {height > 0 && (
-
-
-
-
-
- {line ? (
-
- ) : (
-
- )}
-
- )}
-
-
- );
- }
-}
-
-export default autoHeight()(MiniArea);
diff --git a/src/pages/analysis/components/Charts/MiniBar/index.tsx b/src/pages/analysis/components/Charts/MiniBar/index.tsx
deleted file mode 100644
index d0fe9d4c160ddac885cf1246d455f675ba1822be..0000000000000000000000000000000000000000
--- a/src/pages/analysis/components/Charts/MiniBar/index.tsx
+++ /dev/null
@@ -1,61 +0,0 @@
-import React from 'react';
-import { Chart, Tooltip, Geom } from 'bizcharts';
-import autoHeight from '../autoHeight';
-import styles from '../index.less';
-
-export interface IMiniBarProps {
- color?: string;
- height?: number;
- data: Array<{
- x: number | string;
- y: number;
- }>;
- forceFit?: boolean;
- style?: React.CSSProperties;
-}
-
-class MiniBar extends React.Component {
- render() {
- const { height = 0, forceFit = true, color = '#1890FF', data = [] } = this.props;
-
- const scale = {
- x: {
- type: 'cat',
- },
- y: {
- min: 0,
- },
- };
-
- const padding: [number, number, number, number] = [36, 5, 30, 5];
-
- const tooltip: [string, (...args: any[]) => { name?: string; value: string }] = [
- 'x*y',
- (x: string, y: string) => ({
- name: x,
- value: y,
- }),
- ];
-
- // for tooltip not to be hide
- const chartHeight = height + 54;
-
- return (
-
- );
- }
-}
-export default autoHeight()(MiniBar);
diff --git a/src/pages/analysis/components/Charts/MiniProgress/index.less b/src/pages/analysis/components/Charts/MiniProgress/index.less
deleted file mode 100644
index e1e0b4fc5169615814efe60821f39dc3e1bc58b9..0000000000000000000000000000000000000000
--- a/src/pages/analysis/components/Charts/MiniProgress/index.less
+++ /dev/null
@@ -1,37 +0,0 @@
-@import '~antd/lib/style/themes/default.less';
-
-.miniProgress {
- position: relative;
- width: 100%;
- padding: 5px 0;
- .progressWrap {
- position: relative;
- background-color: @background-color-base;
- }
- .progress {
- width: 0;
- height: 100%;
- background-color: @primary-color;
- border-radius: 1px 0 0 1px;
- transition: all 0.4s cubic-bezier(0.08, 0.82, 0.17, 1) 0s;
- }
- .target {
- position: absolute;
- top: 0;
- bottom: 0;
- z-index: 9;
- width: 20px;
- span {
- position: absolute;
- top: 0;
- left: 0;
- width: 2px;
- height: 4px;
- border-radius: 100px;
- }
- span:last-child {
- top: auto;
- bottom: 0;
- }
- }
-}
diff --git a/src/pages/analysis/components/Charts/MiniProgress/index.tsx b/src/pages/analysis/components/Charts/MiniProgress/index.tsx
deleted file mode 100644
index c0d1507dd4c5ff0d6d36f40897a910910df7a737..0000000000000000000000000000000000000000
--- a/src/pages/analysis/components/Charts/MiniProgress/index.tsx
+++ /dev/null
@@ -1,43 +0,0 @@
-import React from 'react';
-import { Tooltip } from 'antd';
-import styles from './index.less';
-
-export interface IMiniProgressProps {
- target: number;
- targetLabel?: string;
- color?: string;
- strokeWidth?: number;
- percent?: number;
- style?: React.CSSProperties;
-}
-
-const MiniProgress: React.SFC = ({
- targetLabel,
- target,
- color = 'rgb(19, 194, 194)',
- strokeWidth,
- percent,
-}) => {
- return (
-
- );
-};
-
-export default MiniProgress;
diff --git a/src/pages/analysis/components/Charts/Pie/index.less b/src/pages/analysis/components/Charts/Pie/index.less
deleted file mode 100644
index fc961b41df8831d2da6e7cf987b89e3624133fbc..0000000000000000000000000000000000000000
--- a/src/pages/analysis/components/Charts/Pie/index.less
+++ /dev/null
@@ -1,94 +0,0 @@
-@import '~antd/lib/style/themes/default.less';
-
-.pie {
- position: relative;
- .chart {
- position: relative;
- }
- &.hasLegend .chart {
- width: ~'calc(100% - 240px)';
- }
- .legend {
- position: absolute;
- top: 50%;
- right: 0;
- min-width: 200px;
- margin: 0 20px;
- padding: 0;
- list-style: none;
- transform: translateY(-50%);
- li {
- height: 22px;
- margin-bottom: 16px;
- line-height: 22px;
- cursor: pointer;
- &:last-child {
- margin-bottom: 0;
- }
- }
- }
- .dot {
- position: relative;
- top: -1px;
- display: inline-block;
- width: 8px;
- height: 8px;
- margin-right: 8px;
- border-radius: 8px;
- }
- .line {
- display: inline-block;
- width: 1px;
- height: 16px;
- margin-right: 8px;
- background-color: @border-color-split;
- }
- .legendTitle {
- color: @text-color;
- }
- .percent {
- color: @text-color-secondary;
- }
- .value {
- position: absolute;
- right: 0;
- }
- .title {
- margin-bottom: 8px;
- }
- .total {
- position: absolute;
- top: 50%;
- left: 50%;
- max-height: 62px;
- text-align: center;
- transform: translate(-50%, -50%);
- & > h4 {
- height: 22px;
- margin-bottom: 8px;
- color: @text-color-secondary;
- font-weight: normal;
- font-size: 14px;
- line-height: 22px;
- }
- & > p {
- display: block;
- height: 32px;
- color: @heading-color;
- font-size: 1.2em;
- line-height: 32px;
- white-space: nowrap;
- }
- }
-}
-
-.legendBlock {
- &.hasLegend .chart {
- width: 100%;
- margin: 0 0 32px 0;
- }
- .legend {
- position: relative;
- transform: none;
- }
-}
diff --git a/src/pages/analysis/components/Charts/Pie/index.tsx b/src/pages/analysis/components/Charts/Pie/index.tsx
deleted file mode 100644
index 1b18f8a24900823147467bbb830c54c76d7df102..0000000000000000000000000000000000000000
--- a/src/pages/analysis/components/Charts/Pie/index.tsx
+++ /dev/null
@@ -1,306 +0,0 @@
-import React, { Component } from 'react';
-import { Chart, Tooltip, Geom, Coord } from 'bizcharts';
-import { DataView } from '@antv/data-set';
-import { Divider } from 'antd';
-import classNames from 'classnames';
-import ReactFitText from 'react-fittext';
-import Debounce from 'lodash-decorators/debounce';
-import Bind from 'lodash-decorators/bind';
-import styles from './index.less';
-import autoHeight from '../autoHeight';
-export interface IPieProps {
- animate?: boolean;
- color?: string;
- colors?: string[];
- selected?: boolean;
- height?: number;
- margin?: [number, number, number, number];
- hasLegend?: boolean;
- padding?: [number, number, number, number];
- percent?: number;
- data?: Array<{
- x: string | string;
- y: number;
- }>;
- inner?: number;
- lineWidth?: number;
- forceFit?: boolean;
- style?: React.CSSProperties;
- className?: string;
- total?: React.ReactNode | number | (() => React.ReactNode | number);
- title?: React.ReactNode;
- tooltip?: boolean;
- valueFormat?: (value: string) => string | React.ReactNode;
- subTitle?: React.ReactNode;
-}
-interface IPieState {
- legendData: Array<{ checked: boolean; x: string; color: string; percent: number; y: string }>;
- legendBlock: boolean;
-}
-class Pie extends Component {
- state: IPieState = {
- legendData: [],
- legendBlock: false,
- };
-
- requestRef: number | undefined;
- root!: HTMLDivElement;
- chart: G2.Chart | undefined;
-
- componentDidMount() {
- window.addEventListener(
- 'resize',
- () => {
- this.requestRef = requestAnimationFrame(() => this.resize());
- },
- { passive: true },
- );
- }
-
- componentDidUpdate(preProps: IPieProps) {
- const { data } = this.props;
- if (data !== preProps.data) {
- // because of charts data create when rendered
- // so there is a trick for get rendered time
- this.getLegendData();
- }
- }
-
- componentWillUnmount() {
- if (this.requestRef) {
- window.cancelAnimationFrame(this.requestRef);
- }
- window.removeEventListener('resize', this.resize);
- if (this.resize) {
- (this.resize as any).cancel();
- }
- }
-
- getG2Instance = (chart: G2.Chart) => {
- this.chart = chart;
- requestAnimationFrame(() => {
- this.getLegendData();
- this.resize();
- });
- };
-
- // for custom lengend view
- getLegendData = () => {
- if (!this.chart) return;
- const geom = this.chart.getAllGeoms()[0]; // 获取所有的图形
- if (!geom) return;
- const items = geom.get('dataArray') || []; // 获取图形对应的
-
- const legendData = items.map((item: { color: any; _origin: any }[]) => {
- /* eslint no-underscore-dangle:0 */
- const origin = item[0]._origin;
- origin.color = item[0].color;
- origin.checked = true;
- return origin;
- });
-
- this.setState({
- legendData,
- });
- };
- handleRoot = (n: HTMLDivElement) => {
- this.root = n;
- };
-
- handleLegendClick = (item: any, i: string | number) => {
- const newItem = item;
- newItem.checked = !newItem.checked;
-
- const { legendData } = this.state;
- legendData[i] = newItem;
-
- const filteredLegendData = legendData.filter(l => l.checked).map(l => l.x);
-
- if (this.chart) {
- this.chart.filter('x', val => filteredLegendData.indexOf(val + '') > -1);
- }
-
- this.setState({
- legendData,
- });
- };
-
- // for window resize auto responsive legend
- @Bind()
- @Debounce(300)
- resize() {
- const { hasLegend } = this.props;
- const { legendBlock } = this.state;
- if (!hasLegend || !this.root) {
- window.removeEventListener('resize', this.resize);
- return;
- }
- if (
- this.root &&
- this.root.parentNode &&
- (this.root.parentNode as HTMLElement).clientWidth <= 380
- ) {
- if (!legendBlock) {
- this.setState({
- legendBlock: true,
- });
- }
- } else if (legendBlock) {
- this.setState({
- legendBlock: false,
- });
- }
- }
-
- render() {
- const {
- valueFormat,
- subTitle,
- total,
- hasLegend = false,
- className,
- style,
- height = 0,
- forceFit = true,
- percent,
- color,
- inner = 0.75,
- animate = true,
- colors,
- lineWidth = 1,
- } = this.props;
-
- const { legendData, legendBlock } = this.state;
- const pieClassName = classNames(styles.pie, className, {
- [styles.hasLegend]: !!hasLegend,
- [styles.legendBlock]: legendBlock,
- });
-
- const {
- data: propsData,
- selected: propsSelected = true,
- tooltip: propsTooltip = true,
- } = this.props;
-
- let data = propsData || [];
- let selected = propsSelected;
- let tooltip = propsTooltip;
-
- const defaultColors = colors;
- data = data || [];
- selected = selected || true;
- tooltip = tooltip || true;
- let formatColor;
-
- const scale = {
- x: {
- type: 'cat',
- range: [0, 1],
- },
- y: {
- min: 0,
- },
- };
-
- if (percent || percent === 0) {
- selected = false;
- tooltip = false;
- formatColor = (value: string) => {
- if (value === '占比') {
- return color || 'rgba(24, 144, 255, 0.85)';
- }
- return '#F0F2F5';
- };
-
- data = [
- {
- x: '占比',
- y: parseFloat(percent + ''),
- },
- {
- x: '反比',
- y: 100 - parseFloat(percent + ''),
- },
- ];
- }
-
- const tooltipFormat: [string, (...args: any[]) => { name?: string; value: string }] = [
- 'x*percent',
- (x: string, p: number) => ({
- name: x,
- value: `${(p * 100).toFixed(2)}%`,
- }),
- ];
-
- const padding = [12, 0, 12, 0] as [number, number, number, number];
-
- const dv = new DataView();
- dv.source(data).transform({
- type: 'percent',
- field: 'y',
- dimension: 'x',
- as: 'percent',
- });
-
- return (
-
-
-
-
- {!!tooltip && }
-
-
-
-
- {(subTitle || total) && (
-
- {subTitle &&
{subTitle}
}
- {/* eslint-disable-next-line */}
- {total && (
-
{typeof total === 'function' ? total() : total}
- )}
-
- )}
-
-
- {hasLegend && (
-
- {legendData.map((item, i) => (
- - this.handleLegendClick(item, i)}>
-
- {item.x}
-
-
- {`${(Number.isNaN(item.percent) ? 0 : item.percent * 100).toFixed(2)}%`}
-
- {valueFormat ? valueFormat(item.y) : item.y}
-
- ))}
-
- )}
-
- );
- }
-}
-
-export default autoHeight()(Pie);
diff --git a/src/pages/analysis/components/Charts/TagCloud/index.less b/src/pages/analysis/components/Charts/TagCloud/index.less
deleted file mode 100644
index db8e4dabfdd3f1fd4566ff22f55962648c369c49..0000000000000000000000000000000000000000
--- a/src/pages/analysis/components/Charts/TagCloud/index.less
+++ /dev/null
@@ -1,6 +0,0 @@
-.tagCloud {
- overflow: hidden;
- canvas {
- transform-origin: 0 0;
- }
-}
diff --git a/src/pages/analysis/components/Charts/TagCloud/index.tsx b/src/pages/analysis/components/Charts/TagCloud/index.tsx
deleted file mode 100644
index fc809826df3e4d1f607ec83bb812d63f41fcbdd3..0000000000000000000000000000000000000000
--- a/src/pages/analysis/components/Charts/TagCloud/index.tsx
+++ /dev/null
@@ -1,206 +0,0 @@
-import React, { Component } from 'react';
-import { Chart, Geom, Coord, Shape, Tooltip } from 'bizcharts';
-import DataSet from '@antv/data-set';
-import Debounce from 'lodash-decorators/debounce';
-import Bind from 'lodash-decorators/bind';
-import classNames from 'classnames';
-import autoHeight from '../autoHeight';
-import styles from './index.less';
-
-/* eslint no-underscore-dangle: 0 */
-/* eslint no-param-reassign: 0 */
-
-const imgUrl = 'https://gw.alipayobjects.com/zos/rmsportal/gWyeGLCdFFRavBGIDzWk.png';
-
-export interface ITagCloudProps {
- data: Array<{
- name: string;
- value: number;
- }>;
- height?: number;
- className?: string;
- style?: React.CSSProperties;
-}
-
-interface ITagCloudState {
- dv: any;
- height?: number;
- width: number;
-}
-
-class TagCloud extends Component {
- state = {
- dv: null,
- height: 0,
- width: 0,
- };
- isUnmount!: boolean;
- requestRef!: number;
-
- root: HTMLDivElement | undefined;
- imageMask: HTMLImageElement | undefined;
-
- componentDidMount() {
- requestAnimationFrame(() => {
- this.initTagCloud();
- this.renderChart(this.props);
- });
- window.addEventListener('resize', this.resize, { passive: true });
- }
-
- componentDidUpdate(preProps?: ITagCloudProps) {
- const { data } = this.props;
- if (preProps && JSON.stringify(preProps.data) !== JSON.stringify(data)) {
- this.renderChart(this.props);
- }
- }
- componentWillUnmount() {
- this.isUnmount = true;
- window.cancelAnimationFrame(this.requestRef);
- window.removeEventListener('resize', this.resize);
- }
- resize = () => {
- this.requestRef = requestAnimationFrame(() => {
- this.renderChart(this.props);
- });
- };
- saveRootRef = (node: HTMLDivElement) => {
- this.root = node;
- };
-
- initTagCloud = () => {
- function getTextAttrs(cfg: {
- x?: any;
- y?: any;
- style?: any;
- opacity?: any;
- origin?: any;
- color?: any;
- }) {
- return Object.assign({}, cfg.style, {
- fillOpacity: cfg.opacity,
- fontSize: cfg.origin._origin.size,
- rotate: cfg.origin._origin.rotate,
- text: cfg.origin._origin.text,
- textAlign: 'center',
- fontFamily: cfg.origin._origin.font,
- fill: cfg.color,
- textBaseline: 'Alphabetic',
- });
- }
-
- (Shape as any).registerShape('point', 'cloud', {
- drawShape(
- cfg: { x: any; y: any },
- container: { addShape: (arg0: string, arg1: { attrs: any }) => void },
- ) {
- const attrs = getTextAttrs(cfg);
- return container.addShape('text', {
- attrs: Object.assign(attrs, {
- x: cfg.x,
- y: cfg.y,
- }),
- });
- },
- });
- };
-
- @Bind()
- @Debounce(500)
- renderChart(nextProps: ITagCloudProps) {
- // const colors = ['#1890FF', '#41D9C7', '#2FC25B', '#FACC14', '#9AE65C'];
- const { data, height } = nextProps || this.props;
-
- if (data.length < 1 || !this.root) {
- return;
- }
-
- const h = height;
- const w = this.root.offsetWidth;
-
- const onload = () => {
- const dv = new DataSet.View().source(data);
- const range = dv.range('value');
- const [min, max] = range;
- dv.transform({
- type: 'tag-cloud',
- fields: ['name', 'value'],
- imageMask: this.imageMask,
- font: 'Verdana',
- size: [w, h], // 宽高设置最好根据 imageMask 做调整
- padding: 0,
- timeInterval: 5000, // max execute time
- rotate() {
- return 0;
- },
- fontSize(d: { value: number }) {
- // eslint-disable-next-line
- return Math.pow((d.value - min) / (max - min), 2) * (17.5 - 5) + 5;
- },
- });
-
- if (this.isUnmount) {
- return;
- }
-
- this.setState({
- dv,
- width: w,
- height: h,
- });
- };
-
- if (!this.imageMask) {
- this.imageMask = new Image();
- this.imageMask.crossOrigin = '';
- this.imageMask.src = imgUrl;
-
- this.imageMask.onload = onload;
- } else {
- onload();
- }
- }
-
- render() {
- const { className, height } = this.props;
- const { dv, width, height: stateHeight } = this.state;
-
- return (
-
- {dv && (
-
-
-
-
-
- )}
-
- );
- }
-}
-
-export default autoHeight()(TagCloud);
diff --git a/src/pages/analysis/components/Charts/TimelineChart/index.less b/src/pages/analysis/components/Charts/TimelineChart/index.less
deleted file mode 100644
index 1751975692135769eebdcaf89ffafcf6b3037cb8..0000000000000000000000000000000000000000
--- a/src/pages/analysis/components/Charts/TimelineChart/index.less
+++ /dev/null
@@ -1,3 +0,0 @@
-.timelineChart {
- background: #fff;
-}
diff --git a/src/pages/analysis/components/Charts/TimelineChart/index.tsx b/src/pages/analysis/components/Charts/TimelineChart/index.tsx
deleted file mode 100644
index 2ccc37283623e27ff1cd48e7c569a683b1199684..0000000000000000000000000000000000000000
--- a/src/pages/analysis/components/Charts/TimelineChart/index.tsx
+++ /dev/null
@@ -1,133 +0,0 @@
-import React from 'react';
-import { Chart, Tooltip, Geom, Legend, Axis } from 'bizcharts';
-import DataSet from '@antv/data-set';
-import Slider from 'bizcharts-plugin-slider';
-import autoHeight from '../autoHeight';
-import styles from './index.less';
-
-export interface ITimelineChartProps {
- data: Array<{
- x: number;
- y1: number;
- y2: number;
- }>;
- title?: string;
- titleMap: { y1: string; y2: string };
- padding?: [number, number, number, number];
- height?: number;
- style?: React.CSSProperties;
- borderWidth?: number;
-}
-
-class TimelineChart extends React.Component {
- render() {
- const {
- title,
- height = 400,
- padding = [60, 20, 40, 40] as [number, number, number, number],
- titleMap = {
- y1: 'y1',
- y2: 'y2',
- },
- borderWidth = 2,
- data: sourceData,
- } = this.props;
-
- const data = Array.isArray(sourceData) ? sourceData : [{ x: 0, y1: 0, y2: 0 }];
-
- data.sort((a, b) => a.x - b.x);
-
- let max;
- if (data[0] && data[0].y1 && data[0].y2) {
- max = Math.max(
- [...data].sort((a, b) => b.y1 - a.y1)[0].y1,
- [...data].sort((a, b) => b.y2 - a.y2)[0].y2,
- );
- }
-
- const ds = new DataSet({
- state: {
- start: data[0].x,
- end: data[data.length - 1].x,
- },
- });
-
- const dv = ds.createView();
- dv.source(data)
- .transform({
- type: 'filter',
- callback: (obj: { x: string }) => {
- const date = obj.x;
- return date <= ds.state.end && date >= ds.state.start;
- },
- })
- .transform({
- type: 'map',
- callback(row: { y1: string; y2: string }) {
- const newRow = { ...row };
- newRow[titleMap.y1] = row.y1;
- newRow[titleMap.y2] = row.y2;
- return newRow;
- },
- })
- .transform({
- type: 'fold',
- fields: [titleMap.y1, titleMap.y2], // 展开字段集
- key: 'key', // key字段
- value: 'value', // value字段
- });
-
- const timeScale = {
- type: 'time',
- tickInterval: 60 * 60 * 1000,
- mask: 'HH:mm',
- range: [0, 1],
- };
-
- const cols = {
- x: timeScale,
- value: {
- max,
- min: 0,
- },
- };
-
- const SliderGen = () => (
- {
- ds.setState('start', startValue);
- ds.setState('end', endValue);
- }}
- />
- );
-
- return (
-
-
- {title &&
{title}
}
-
-
-
-
-
-
-
-
-
-
-
- );
- }
-}
-
-export default autoHeight()(TimelineChart);
diff --git a/src/pages/analysis/components/Charts/WaterWave/index.less b/src/pages/analysis/components/Charts/WaterWave/index.less
deleted file mode 100644
index 2e75f21464300dd1d443329943b363b16fee1e97..0000000000000000000000000000000000000000
--- a/src/pages/analysis/components/Charts/WaterWave/index.less
+++ /dev/null
@@ -1,28 +0,0 @@
-@import '~antd/lib/style/themes/default.less';
-
-.waterWave {
- position: relative;
- display: inline-block;
- transform-origin: left;
- .text {
- position: absolute;
- top: 32px;
- left: 0;
- width: 100%;
- text-align: center;
- span {
- color: @text-color-secondary;
- font-size: 14px;
- line-height: 22px;
- }
- h4 {
- color: @heading-color;
- font-size: 24px;
- line-height: 32px;
- }
- }
- .waterWaveCanvasWrapper {
- transform: scale(0.5);
- transform-origin: 0 0;
- }
-}
diff --git a/src/pages/analysis/components/Charts/WaterWave/index.tsx b/src/pages/analysis/components/Charts/WaterWave/index.tsx
deleted file mode 100644
index 9dba82160b99756506399cfac2416c08206bf78e..0000000000000000000000000000000000000000
--- a/src/pages/analysis/components/Charts/WaterWave/index.tsx
+++ /dev/null
@@ -1,230 +0,0 @@
-import React, { Component } from 'react';
-import autoHeight from '../autoHeight';
-import styles from './index.less';
-
-/* eslint no-return-assign: 0 */
-/* eslint no-mixed-operators: 0 */
-// riddle: https://riddle.alibaba-inc.com/riddles/2d9a4b90
-
-export interface IWaterWaveProps {
- title: React.ReactNode;
- color?: string;
- height?: number;
- percent: number;
- style?: React.CSSProperties;
-}
-
-class WaterWave extends Component {
- state = {
- radio: 1,
- };
- timer: number = 0;
- root: HTMLDivElement | undefined | null;
- node: HTMLCanvasElement | undefined | null;
-
- componentDidMount() {
- this.renderChart();
- this.resize();
- window.addEventListener(
- 'resize',
- () => {
- requestAnimationFrame(() => this.resize());
- },
- { passive: true },
- );
- }
-
- componentDidUpdate(props: IWaterWaveProps) {
- const { percent } = this.props;
- if (props.percent !== percent) {
- // 不加这个会造成绘制缓慢
- this.renderChart('update');
- }
- }
-
- componentWillUnmount() {
- cancelAnimationFrame(this.timer);
- if (this.node) {
- this.node.innerHTML = '';
- }
- window.removeEventListener('resize', this.resize);
- }
-
- resize = () => {
- if (this.root) {
- const { height = 1 } = this.props;
- const { offsetWidth } = this.root.parentNode as HTMLElement;
- this.setState({
- radio: offsetWidth < height ? offsetWidth / height : 1,
- });
- }
- };
- renderChart(type?: string) {
- const { percent, color = '#1890FF' } = this.props;
- const data = percent / 100;
- const self = this;
- cancelAnimationFrame(this.timer);
-
- if (!this.node || (data !== 0 && !data)) {
- return;
- }
-
- const canvas = this.node;
- const ctx = canvas.getContext('2d');
- if (!ctx) {
- return;
- }
- const canvasWidth = canvas.width;
- const canvasHeight = canvas.height;
- const radius = canvasWidth / 2;
- const lineWidth = 2;
- const cR = radius - lineWidth;
-
- ctx.beginPath();
- ctx.lineWidth = lineWidth * 2;
-
- const axisLength = canvasWidth - lineWidth;
- const unit = axisLength / 8;
- const range = 0.2; // 振幅
- let currRange = range;
- const xOffset = lineWidth;
- let sp = 0; // 周期偏移量
- let currData = 0;
- const waveupsp = 0.005; // 水波上涨速度
-
- let arcStack: number[][] = [];
- const bR = radius - lineWidth;
- const circleOffset = -(Math.PI / 2);
- let circleLock = true;
-
- for (let i = circleOffset; i < circleOffset + 2 * Math.PI; i += 1 / (8 * Math.PI)) {
- arcStack.push([radius + bR * Math.cos(i), radius + bR * Math.sin(i)]);
- }
-
- const cStartPoint = arcStack.shift() as number[];
- ctx.strokeStyle = color;
- ctx.moveTo(cStartPoint[0], cStartPoint[1]);
-
- function drawSin() {
- if (!ctx) {
- return;
- }
- ctx.beginPath();
- ctx.save();
-
- const sinStack = [];
- for (let i = xOffset; i <= xOffset + axisLength; i += 20 / axisLength) {
- const x = sp + (xOffset + i) / unit;
- const y = Math.sin(x) * currRange;
- const dx = i;
- const dy = 2 * cR * (1 - currData) + (radius - cR) - unit * y;
-
- ctx.lineTo(dx, dy);
- sinStack.push([dx, dy]);
- }
-
- const startPoint = sinStack.shift() as number[];
-
- ctx.lineTo(xOffset + axisLength, canvasHeight);
- ctx.lineTo(xOffset, canvasHeight);
- ctx.lineTo(startPoint[0], startPoint[1]);
-
- const gradient = ctx.createLinearGradient(0, 0, 0, canvasHeight);
- gradient.addColorStop(0, '#ffffff');
- gradient.addColorStop(1, color);
- ctx.fillStyle = gradient;
- ctx.fill();
- ctx.restore();
- }
-
- function render() {
- if (!ctx) {
- return;
- }
- ctx.clearRect(0, 0, canvasWidth, canvasHeight);
- if (circleLock && type !== 'update') {
- if (arcStack.length) {
- const temp = arcStack.shift() as number[];
- ctx.lineTo(temp[0], temp[1]);
- ctx.stroke();
- } else {
- circleLock = false;
- ctx.lineTo(cStartPoint[0], cStartPoint[1]);
- ctx.stroke();
- arcStack = [];
-
- ctx.globalCompositeOperation = 'destination-over';
- ctx.beginPath();
- ctx.lineWidth = lineWidth;
- ctx.arc(radius, radius, bR, 0, 2 * Math.PI, true);
-
- ctx.beginPath();
- ctx.save();
- ctx.arc(radius, radius, radius - 3 * lineWidth, 0, 2 * Math.PI, true);
-
- ctx.restore();
- ctx.clip();
- ctx.fillStyle = color;
- }
- } else {
- if (data >= 0.85) {
- if (currRange > range / 4) {
- const t = range * 0.01;
- currRange -= t;
- }
- } else if (data <= 0.1) {
- if (currRange < range * 1.5) {
- const t = range * 0.01;
- currRange += t;
- }
- } else {
- if (currRange <= range) {
- const t = range * 0.01;
- currRange += t;
- }
- if (currRange >= range) {
- const t = range * 0.01;
- currRange -= t;
- }
- }
- if (data - currData > 0) {
- currData += waveupsp;
- }
- if (data - currData < 0) {
- currData -= waveupsp;
- }
-
- sp += 0.07;
- drawSin();
- }
- self.timer = requestAnimationFrame(render);
- }
- render();
- }
- render() {
- const { radio } = this.state;
- const { percent, title, height = 1 } = this.props;
- return (
- (this.root = n)}
- style={{ transform: `scale(${radio})` }}
- >
-
-
-
- {title && {title}}
-
{percent}%
-
-
- );
- }
-}
-
-export default autoHeight()(WaterWave);
diff --git a/src/pages/analysis/components/Charts/autoHeight.tsx b/src/pages/analysis/components/Charts/autoHeight.tsx
deleted file mode 100644
index e7d14e07a6be59b9125bcc910c07ba9b162b5409..0000000000000000000000000000000000000000
--- a/src/pages/analysis/components/Charts/autoHeight.tsx
+++ /dev/null
@@ -1,75 +0,0 @@
-import React from 'react';
-
-export type IReactComponent =
- | React.StatelessComponent
- | React.ComponentClass
- | React.ClassicComponentClass
;
-
-function computeHeight(node: HTMLDivElement) {
- node.style.height = '100%';
- const totalHeight = parseInt(getComputedStyle(node).height + '', 10);
- const padding =
- parseInt(getComputedStyle(node).paddingTop + '', 10) +
- parseInt(getComputedStyle(node).paddingBottom + '', 10);
- return totalHeight - padding;
-}
-
-function getAutoHeight(n: HTMLDivElement) {
- if (!n) {
- return 0;
- }
-
- const node = n;
-
- let height = computeHeight(node);
- const parentNode = node.parentNode as HTMLDivElement;
- if (parentNode) {
- height = computeHeight(parentNode);
- }
-
- return height;
-}
-
-interface IAutoHeightProps {
- height?: number;
-}
-
-function autoHeight() {
- return function
(
- WrappedComponent: React.ComponentClass
| React.SFC
,
- ): React.ComponentClass
{
- class AutoHeightComponent extends React.Component
{
- state = {
- computedHeight: 0,
- };
- root!: HTMLDivElement;
- componentDidMount() {
- const { height } = this.props;
- if (!height) {
- let h = getAutoHeight(this.root);
- // eslint-disable-next-line
- this.setState({ computedHeight: h });
- if (h < 1) {
- h = getAutoHeight(this.root);
- this.setState({ computedHeight: h });
- }
- }
- }
- handleRoot = (node: HTMLDivElement) => {
- this.root = node;
- };
- render() {
- const { height } = this.props;
- const { computedHeight } = this.state;
- const h = height || computedHeight;
- return (
-
- {h > 0 && }
-
- );
- }
- }
- return AutoHeightComponent;
- };
-}
-export default autoHeight;
diff --git a/src/pages/analysis/components/Charts/bizcharts.d.ts b/src/pages/analysis/components/Charts/bizcharts.d.ts
deleted file mode 100644
index 0815ffeeffcacd0ac9710977ab3d4419d078491c..0000000000000000000000000000000000000000
--- a/src/pages/analysis/components/Charts/bizcharts.d.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-import * as BizChart from 'bizcharts';
-
-export = BizChart;
diff --git a/src/pages/analysis/components/Charts/bizcharts.tsx b/src/pages/analysis/components/Charts/bizcharts.tsx
deleted file mode 100644
index e08db8d6d2dca240451bdf6ab8a30be077a3fd9d..0000000000000000000000000000000000000000
--- a/src/pages/analysis/components/Charts/bizcharts.tsx
+++ /dev/null
@@ -1,3 +0,0 @@
-import * as BizChart from 'bizcharts';
-
-export default BizChart;
diff --git a/src/pages/analysis/components/Charts/index.less b/src/pages/analysis/components/Charts/index.less
deleted file mode 100644
index 190428bc80d7cd7f6f22d51fd48fa37b2d44eb10..0000000000000000000000000000000000000000
--- a/src/pages/analysis/components/Charts/index.less
+++ /dev/null
@@ -1,19 +0,0 @@
-.miniChart {
- position: relative;
- width: 100%;
- .chartContent {
- position: absolute;
- bottom: -28px;
- width: 100%;
- > div {
- margin: 0 -5px;
- overflow: hidden;
- }
- }
- .chartLoading {
- position: absolute;
- top: 16px;
- left: 50%;
- margin-left: -7px;
- }
-}
diff --git a/src/pages/analysis/components/Charts/index.tsx b/src/pages/analysis/components/Charts/index.tsx
deleted file mode 100644
index 5e0815f18ef573549dfc4c13de317568d02db80c..0000000000000000000000000000000000000000
--- a/src/pages/analysis/components/Charts/index.tsx
+++ /dev/null
@@ -1,45 +0,0 @@
-import numeral from 'numeral';
-import ChartCard from './ChartCard';
-import Field from './Field';
-import Bar from './Bar';
-import Pie from './Pie';
-import Gauge from './Gauge';
-import MiniArea from './MiniArea';
-import MiniBar from './MiniBar';
-import MiniProgress from './MiniProgress';
-import WaterWave from './WaterWave';
-import TagCloud from './TagCloud';
-import TimelineChart from './TimelineChart';
-
-const yuan = (val: number | string) => `¥ ${numeral(val).format('0,0')}`;
-
-const Charts = {
- yuan,
- Bar,
- Pie,
- Gauge,
- MiniBar,
- MiniArea,
- MiniProgress,
- ChartCard,
- Field,
- WaterWave,
- TagCloud,
- TimelineChart,
-};
-
-export {
- Charts as default,
- yuan,
- Bar,
- Pie,
- Gauge,
- MiniBar,
- MiniArea,
- MiniProgress,
- ChartCard,
- Field,
- WaterWave,
- TagCloud,
- TimelineChart,
-};
diff --git a/src/pages/analysis/components/IntroduceRow.tsx b/src/pages/analysis/components/IntroduceRow.tsx
deleted file mode 100755
index ee2cf44dc016a8e3d89bdcee4b79296cdbd8ee4b..0000000000000000000000000000000000000000
--- a/src/pages/analysis/components/IntroduceRow.tsx
+++ /dev/null
@@ -1,162 +0,0 @@
-import React from 'react';
-import { Row, Col, Icon, Tooltip } from 'antd';
-import { FormattedMessage } from 'umi-plugin-react/locale';
-import Charts from './Charts';
-import numeral from 'numeral';
-import styles from '../style.less';
-import Yuan from '../utils/Yuan';
-import Trend from './Trend';
-import { IVisitData } from '../data.d';
-const { ChartCard, MiniArea, MiniBar, MiniProgress, Field } = Charts;
-
-const topColResponsiveProps = {
- xs: 24,
- sm: 12,
- md: 12,
- lg: 12,
- xl: 6,
- style: { marginBottom: 24 },
-};
-
-const IntroduceRow = ({ loading, visitData }: { loading: boolean; visitData: IVisitData[] }) => {
- return (
-
-
-
- }
- action={
-
- }
- >
-
-
- }
- loading={loading}
- total={() => 126560}
- footer={
-
- }
- value={`¥${numeral(12423).format('0,0')}`}
- />
- }
- contentHeight={46}
- >
-
-
- 12%
-
-
-
- 11%
-
-
-
-
-
- }
- action={
-
- }
- >
-
-
- }
- total={numeral(8846).format('0,0')}
- footer={
-
- }
- value={numeral(1234).format('0,0')}
- />
- }
- contentHeight={46}
- >
-
-
-
-
- }
- action={
-
- }
- >
-
-
- }
- total={numeral(6560).format('0,0')}
- footer={
-
- }
- value="60%"
- />
- }
- contentHeight={46}
- >
-
-
-
-
-
- }
- action={
-
- }
- >
-
-
- }
- total="78%"
- footer={
-
-
-
- 12%
-
-
-
- 11%
-
-
- }
- contentHeight={46}
- >
-
-
-
-
- );
-};
-
-export default IntroduceRow;
diff --git a/src/pages/analysis/components/NumberInfo/index.less b/src/pages/analysis/components/NumberInfo/index.less
deleted file mode 100644
index 4a77288cc29d4bc24aa9ee660461bd44cb049897..0000000000000000000000000000000000000000
--- a/src/pages/analysis/components/NumberInfo/index.less
+++ /dev/null
@@ -1,68 +0,0 @@
-@import '~antd/lib/style/themes/default.less';
-
-.numberInfo {
- .suffix {
- margin-left: 4px;
- color: @text-color;
- font-size: 16px;
- font-style: normal;
- }
- .numberInfoTitle {
- margin-bottom: 16px;
- color: @text-color;
- font-size: @font-size-lg;
- transition: all 0.3s;
- }
- .numberInfoSubTitle {
- height: 22px;
- overflow: hidden;
- color: @text-color-secondary;
- font-size: @font-size-base;
- line-height: 22px;
- white-space: nowrap;
- text-overflow: ellipsis;
- word-break: break-all;
- }
- .numberInfoValue {
- margin-top: 4px;
- overflow: hidden;
- font-size: 0;
- white-space: nowrap;
- text-overflow: ellipsis;
- word-break: break-all;
- & > span {
- display: inline-block;
- height: 32px;
- margin-right: 32px;
- color: @heading-color;
- font-size: 24px;
- line-height: 32px;
- }
- .subTotal {
- margin-right: 0;
- color: @text-color-secondary;
- font-size: @font-size-lg;
- vertical-align: top;
- i {
- margin-left: 4px;
- font-size: 12px;
- transform: scale(0.82);
- }
- :global {
- .anticon-caret-up {
- color: @red-6;
- }
- .anticon-caret-down {
- color: @green-6;
- }
- }
- }
- }
-}
-.numberInfolight {
- .numberInfoValue {
- & > span {
- color: @text-color;
- }
- }
-}
diff --git a/src/pages/analysis/components/NumberInfo/index.tsx b/src/pages/analysis/components/NumberInfo/index.tsx
deleted file mode 100644
index a8df6e6d94efbd2dc579d315b28ba64cb4d20859..0000000000000000000000000000000000000000
--- a/src/pages/analysis/components/NumberInfo/index.tsx
+++ /dev/null
@@ -1,61 +0,0 @@
-import React from 'react';
-import { Icon } from 'antd';
-import classNames from 'classnames';
-import styles from './index.less';
-export interface NumberInfoProps {
- title?: React.ReactNode | string;
- subTitle?: React.ReactNode | string;
- total?: React.ReactNode | string;
- status?: 'up' | 'down';
- theme?: string;
- gap?: number;
- subTotal?: number;
- suffix?: string;
- style?: React.CSSProperties;
-}
-const NumberInfo: React.SFC = ({
- theme,
- title,
- subTitle,
- total,
- subTotal,
- status,
- suffix,
- gap,
- ...rest
-}) => (
-
- {title && (
-
- {title}
-
- )}
- {subTitle && (
-
- {subTitle}
-
- )}
-
-
- {total}
- {suffix && {suffix}}
-
- {(status || subTotal) && (
-
- {subTotal}
- {status && }
-
- )}
-
-
-);
-
-export default NumberInfo;
diff --git a/src/pages/analysis/components/OfflineData.tsx b/src/pages/analysis/components/OfflineData.tsx
deleted file mode 100755
index 64864bdc20955cfb39083cbdccb68c1b532ca613..0000000000000000000000000000000000000000
--- a/src/pages/analysis/components/OfflineData.tsx
+++ /dev/null
@@ -1,82 +0,0 @@
-import React from 'react';
-import { Card, Tabs, Row, Col } from 'antd';
-import { formatMessage, FormattedMessage } from 'umi-plugin-react/locale';
-import Charts from './Charts';
-import styles from '../style.less';
-import NumberInfo from './NumberInfo';
-import { IOfflineData, IOfflineChartData } from '../data';
-const { TimelineChart, Pie } = Charts;
-
-const CustomTab = ({
- data,
- currentTabKey: currentKey,
-}: {
- data: IOfflineData;
- currentTabKey: string;
-}) => {
- return (
-
-
-
- }
- gap={2}
- total={`${data.cvr * 100}%`}
- theme={currentKey !== data.name ? 'light' : undefined}
- />
-
-
-
-
-
- );
-};
-
-const { TabPane } = Tabs;
-
-const OfflineData = ({
- activeKey,
- loading,
- offlineData,
- offlineChartData,
- handleTabChange,
-}: {
- activeKey: string;
- loading: boolean;
- offlineData: IOfflineData[];
- offlineChartData: IOfflineChartData[];
- handleTabChange: (activeKey: string) => void;
-}) => (
-
-
- {offlineData.map(shop => (
- } key={shop.name}>
-
-
-
-
- ))}
-
-
-);
-
-export default OfflineData;
diff --git a/src/pages/analysis/components/PageLoading/index.tsx b/src/pages/analysis/components/PageLoading/index.tsx
deleted file mode 100644
index 77c0f165f9d20b4f974e754efb9cf08606c41a49..0000000000000000000000000000000000000000
--- a/src/pages/analysis/components/PageLoading/index.tsx
+++ /dev/null
@@ -1,10 +0,0 @@
-import React from 'react';
-import { Spin } from 'antd';
-
-// loading components from code split
-// https://umijs.org/plugin/umi-plugin-react.html#dynamicimport
-export default () => (
-
-
-
-);
diff --git a/src/pages/analysis/components/ProportionSales.tsx b/src/pages/analysis/components/ProportionSales.tsx
deleted file mode 100755
index b82888ef23fe2a1b29eafc6302bb25af9c436412..0000000000000000000000000000000000000000
--- a/src/pages/analysis/components/ProportionSales.tsx
+++ /dev/null
@@ -1,79 +0,0 @@
-import React from 'react';
-import { Card, Radio } from 'antd';
-import Charts from './Charts';
-import { FormattedMessage } from 'umi-plugin-react/locale';
-import styles from '../style.less';
-import Yuan from '../utils/Yuan';
-import { RadioChangeEvent } from 'antd/lib/radio';
-import { ISalesData } from '../data';
-
-const { Pie } = Charts;
-
-const ProportionSales = ({
- dropdownGroup,
- salesType,
- loading,
- salesPieData,
- handleChangeSalesType,
-}: {
- loading: boolean;
- dropdownGroup: React.ReactNode;
- salesType: 'all' | 'online' | 'stores';
- salesPieData: ISalesData[];
- handleChangeSalesType?: (e: RadioChangeEvent) => void;
-}) => {
- return (
-
- }
- bodyStyle={{ padding: 24 }}
- extra={
-
- {dropdownGroup}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- }
- style={{ marginTop: 24 }}
- >
-
-
-
-
-
}
- total={() =>
{salesPieData.reduce((pre, now) => now.y + pre, 0)}}
- data={salesPieData}
- valueFormat={value =>
{value}}
- height={248}
- lineWidth={4}
- />
-
-
- );
-};
-
-export default ProportionSales;
diff --git a/src/pages/analysis/components/SalesCard.tsx b/src/pages/analysis/components/SalesCard.tsx
deleted file mode 100755
index 05be982318ecf6df1b8483617ed881f7772712f8..0000000000000000000000000000000000000000
--- a/src/pages/analysis/components/SalesCard.tsx
+++ /dev/null
@@ -1,162 +0,0 @@
-import React from 'react';
-import { Row, Col, Card, Tabs, DatePicker } from 'antd';
-import { FormattedMessage, formatMessage } from 'umi-plugin-react/locale';
-import numeral from 'numeral';
-import Charts from './Charts';
-import { RangePickerValue } from 'antd/lib/date-picker/interface';
-import { ISalesData } from '../data';
-import styles from '../style.less';
-
-const { Bar } = Charts;
-
-const { RangePicker } = DatePicker;
-const { TabPane } = Tabs;
-
-const rankingListData: { title: string; total: number }[] = [];
-for (let i = 0; i < 7; i += 1) {
- rankingListData.push({
- title: formatMessage({ id: 'analysis.analysis.test' }, { no: i }),
- total: 323234,
- });
-}
-
-const SalesCard = ({
- rangePickerValue,
- salesData,
- isActive,
- handleRangePickerChange,
- loading,
- selectDate,
-}: {
- rangePickerValue: RangePickerValue;
- isActive: (key: 'today' | 'week' | 'month' | 'year') => string;
- salesData: ISalesData[];
- loading: boolean;
- handleRangePickerChange: (dates: RangePickerValue, dateStrings: [string, string]) => void;
- selectDate: (key: 'today' | 'week' | 'month' | 'year') => void;
-}) => (
-
-
- }
- size="large"
- tabBarStyle={{ marginBottom: 24 }}
- >
- }
- key="sales"
- >
-
-
-
-
- }
- data={salesData}
- />
-
-
-
-
-
-
-
-
- {rankingListData.map((item, i) => (
- -
-
- {i + 1}
-
-
- {item.title}
-
-
- {numeral(item.total).format('0,0')}
-
-
- ))}
-
-
-
-
-
- }
- key="views"
- >
-
-
-
-
- }
- data={salesData}
- />
-
-
-
-
-
-
-
-
- {rankingListData.map((item, i) => (
- -
-
- {i + 1}
-
-
- {item.title}
-
- {numeral(item.total).format('0,0')}
-
- ))}
-
-
-
-
-
-
-
-
-);
-
-export default SalesCard;
diff --git a/src/pages/analysis/components/TopSearch.tsx b/src/pages/analysis/components/TopSearch.tsx
deleted file mode 100755
index 717b6e35345a63eb8eb757272480135c3091a00f..0000000000000000000000000000000000000000
--- a/src/pages/analysis/components/TopSearch.tsx
+++ /dev/null
@@ -1,128 +0,0 @@
-import React from 'react';
-import { Row, Col, Table, Tooltip, Card, Icon } from 'antd';
-import { FormattedMessage } from 'umi-plugin-react/locale';
-import Charts from './Charts';
-import Trend from './Trend';
-import NumberInfo from './NumberInfo';
-import numeral from 'numeral';
-import styles from '../style.less';
-import { ISearchData, IVisitData2 } from '../data';
-
-const { MiniArea } = Charts;
-
-const columns = [
- {
- title: ,
- dataIndex: 'index',
- key: 'index',
- },
- {
- title: ,
- dataIndex: 'keyword',
- key: 'keyword',
- render: (text: React.ReactNode) => {text},
- },
- {
- title: ,
- dataIndex: 'count',
- key: 'count',
- sorter: (a: { count: number }, b: { count: number }) => a.count - b.count,
- className: styles.alignRight,
- },
- {
- title: ,
- dataIndex: 'range',
- key: 'range',
- sorter: (a: { range: number }, b: { range: number }) => a.range - b.range,
- render: (text: React.ReactNode, record: { status: number }) => (
-
- {text}%
-
- ),
- },
-];
-
-const TopSearch = ({
- loading,
- visitData2,
- searchData,
- dropdownGroup,
-}: {
- loading: boolean;
- visitData2: IVisitData2[];
- dropdownGroup: React.ReactNode;
- searchData: ISearchData[];
-}) => (
-
- }
- extra={dropdownGroup}
- style={{ marginTop: 24 }}
- >
-
-
-
-
-
- }
- >
-
-
-
- }
- gap={8}
- total={numeral(12321).format('0,0')}
- status="up"
- subTotal={17.1}
- />
-
-
-
-
-
-
- }
- >
-
-
-
- }
- total={2.7}
- status="down"
- subTotal={26.2}
- gap={8}
- />
-
-
-
-
- rowKey={record => record.index}
- size="small"
- columns={columns}
- dataSource={searchData}
- pagination={{
- style: { marginBottom: 0 },
- pageSize: 5,
- }}
- />
-
-);
-
-export default TopSearch;
diff --git a/src/pages/analysis/components/Trend/index.less b/src/pages/analysis/components/Trend/index.less
deleted file mode 100644
index 13618838afcd46f1fc0e724097a0af938ca6f7b3..0000000000000000000000000000000000000000
--- a/src/pages/analysis/components/Trend/index.less
+++ /dev/null
@@ -1,37 +0,0 @@
-@import '~antd/lib/style/themes/default.less';
-
-.trendItem {
- display: inline-block;
- font-size: @font-size-base;
- line-height: 22px;
-
- .up,
- .down {
- position: relative;
- top: 1px;
- margin-left: 4px;
- i {
- font-size: 12px;
- transform: scale(0.83);
- }
- }
- .up {
- color: @red-6;
- }
- .down {
- top: -1px;
- color: @green-6;
- }
-
- &.trendItemGrey .up,
- &.trendItemGrey .down {
- color: @text-color;
- }
-
- &.reverseColor .up {
- color: @green-6;
- }
- &.reverseColor .down {
- color: @red-6;
- }
-}
diff --git a/src/pages/analysis/components/Trend/index.tsx b/src/pages/analysis/components/Trend/index.tsx
deleted file mode 100644
index ee8df20ea51db0e14fe78c12ecf622a6f2772b96..0000000000000000000000000000000000000000
--- a/src/pages/analysis/components/Trend/index.tsx
+++ /dev/null
@@ -1,42 +0,0 @@
-import React from 'react';
-import { Icon } from 'antd';
-import classNames from 'classnames';
-import styles from './index.less';
-
-export interface ITrendProps {
- colorful?: boolean;
- flag: 'up' | 'down';
- style?: React.CSSProperties;
- reverseColor?: boolean;
- className?: string;
-}
-
-const Trend: React.SFC = ({
- colorful = true,
- reverseColor = false,
- flag,
- children,
- className,
- ...rest
-}) => {
- const classString = classNames(
- styles.trendItem,
- {
- [styles.trendItemGrey]: !colorful,
- [styles.reverseColor]: reverseColor && colorful,
- },
- className,
- );
- return (
-
- {children}
- {flag && (
-
-
-
- )}
-
- );
-};
-
-export default Trend;
diff --git a/src/pages/analysis/data.d.ts b/src/pages/analysis/data.d.ts
deleted file mode 100644
index 20df2e20dc6eeeff67414b3f6f50d8bfaeb7d62e..0000000000000000000000000000000000000000
--- a/src/pages/analysis/data.d.ts
+++ /dev/null
@@ -1,67 +0,0 @@
-export interface IVisitData {
- x: string;
- y: number;
-}
-
-export interface IVisitData2 {
- x: string;
- y: number;
-}
-
-export interface ISalesData {
- x: string;
- y: number;
-}
-
-export interface ISearchData {
- index: number;
- keyword: string;
- count: number;
- range: number;
- status: number;
-}
-
-export interface IOfflineData {
- name: string;
- cvr: number;
-}
-
-export interface IOfflineChartData {
- x: any;
- y1: number;
- y2: number;
-}
-
-export interface ISalesTypeData {
- x: string;
- y: number;
-}
-
-export interface ISalesTypeDataOnline {
- x: string;
- y: number;
-}
-
-export interface ISalesTypeDataOffline {
- x: string;
- y: number;
-}
-
-export interface IRadarData {
- name: string;
- label: string;
- value: number;
-}
-
-export interface IAnalysisData {
- visitData: IVisitData[];
- visitData2: IVisitData2[];
- salesData: ISalesData[];
- searchData: ISearchData[];
- offlineData: IOfflineData[];
- offlineChartData: IOfflineChartData[];
- salesTypeData: ISalesTypeData[];
- salesTypeDataOnline: ISalesTypeDataOnline[];
- salesTypeDataOffline: ISalesTypeDataOffline[];
- radarData: IRadarData[];
-}
diff --git a/src/pages/analysis/index.tsx b/src/pages/analysis/index.tsx
deleted file mode 100644
index 00d7e34c9e1b0d32c406b3c4a2a94e313621a3f6..0000000000000000000000000000000000000000
--- a/src/pages/analysis/index.tsx
+++ /dev/null
@@ -1,215 +0,0 @@
-import React, { Component, Suspense } from 'react';
-import { connect } from 'dva';
-import { Row, Col, Icon, Menu, Dropdown } from 'antd';
-import { RangePickerValue } from 'antd/lib/date-picker/interface';
-import { getTimeDistance } from './utils/utils';
-import styles from './style.less';
-import PageLoading from './components/PageLoading';
-import { Dispatch } from 'redux';
-import { IAnalysisData } from './data.d';
-import { RadioChangeEvent } from 'antd/lib/radio';
-import { GridContent } from '@ant-design/pro-layout';
-
-const IntroduceRow = React.lazy(() => import('./components/IntroduceRow'));
-const SalesCard = React.lazy(() => import('./components/SalesCard'));
-const TopSearch = React.lazy(() => import('./components/TopSearch'));
-const ProportionSales = React.lazy(() => import('./components/ProportionSales'));
-const OfflineData = React.lazy(() => import('./components/OfflineData'));
-
-interface AnalysisProps {
- analysis: IAnalysisData;
- dispatch: Dispatch;
- loading: boolean;
-}
-
-interface AnalysisState {
- salesType: 'all' | 'online' | 'stores';
- currentTabKey: string;
- rangePickerValue: RangePickerValue;
-}
-
-@connect(
- ({
- analysis,
- loading,
- }: {
- analysis: any;
- loading: {
- effects: { [key: string]: boolean };
- };
- }) => ({
- analysis,
- loading: loading.effects['analysis/fetch'],
- }),
-)
-class Analysis extends Component {
- state: AnalysisState = {
- salesType: 'all',
- currentTabKey: '',
- rangePickerValue: getTimeDistance('year'),
- };
- reqRef!: number;
- timeoutId!: number;
- componentDidMount() {
- const { dispatch } = this.props;
- this.reqRef = requestAnimationFrame(() => {
- dispatch({
- type: 'analysis/fetch',
- });
- });
- setTimeout(() => {
- this.setState({
- loading: false,
- });
- }, 2000);
- }
-
- componentWillUnmount() {
- const { dispatch } = this.props;
- dispatch({
- type: 'analysis/clear',
- });
- cancelAnimationFrame(this.reqRef);
- clearTimeout(this.timeoutId);
- }
-
- handleChangeSalesType = (e: RadioChangeEvent) => {
- this.setState({
- salesType: e.target.value,
- });
- };
-
- handleTabChange = (key: string) => {
- this.setState({
- currentTabKey: key,
- });
- };
-
- handleRangePickerChange = (rangePickerValue: RangePickerValue) => {
- const { dispatch } = this.props;
- this.setState({
- rangePickerValue,
- });
-
- dispatch({
- type: 'analysis/fetchSalesData',
- });
- };
-
- selectDate = (type: 'today' | 'week' | 'month' | 'year') => {
- const { dispatch } = this.props;
- this.setState({
- rangePickerValue: getTimeDistance(type),
- });
-
- dispatch({
- type: 'analysis/fetchSalesData',
- });
- };
-
- isActive = (type: 'today' | 'week' | 'month' | 'year') => {
- const { rangePickerValue } = this.state;
- const value = getTimeDistance(type);
- if (!rangePickerValue[0] || !rangePickerValue[1]) {
- return '';
- }
- if (
- rangePickerValue[0].isSame(value[0], 'day') &&
- rangePickerValue[1].isSame(value[1], 'day')
- ) {
- return styles.currentDate;
- }
- return '';
- };
-
- render() {
- const { rangePickerValue, salesType, currentTabKey } = this.state;
- const { analysis, loading } = this.props;
- const {
- visitData,
- visitData2,
- salesData,
- searchData,
- offlineData,
- offlineChartData,
- salesTypeData,
- salesTypeDataOnline,
- salesTypeDataOffline,
- } = analysis;
- let salesPieData;
- if (salesType === 'all') {
- salesPieData = salesTypeData;
- } else {
- salesPieData = salesType === 'online' ? salesTypeDataOnline : salesTypeDataOffline;
- }
- const menu = (
-
- );
-
- const dropdownGroup = (
-
-
-
-
-
- );
-
- const activeKey = currentTabKey || (offlineData[0] && offlineData[0].name);
- return (
-
-
- }>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- );
- }
-}
-
-export default Analysis;
diff --git a/src/pages/analysis/locales/en-US.ts b/src/pages/analysis/locales/en-US.ts
deleted file mode 100644
index a0a03f22105a642ceea239c470fc72bd7b634687..0000000000000000000000000000000000000000
--- a/src/pages/analysis/locales/en-US.ts
+++ /dev/null
@@ -1,34 +0,0 @@
-export default {
- 'analysis.analysis.test': 'Gongzhuan No.{no} shop',
- 'analysis.analysis.introduce': 'Introduce',
- 'analysis.analysis.total-sales': 'Total Sales',
- 'analysis.analysis.day-sales': 'Daily Sales',
- 'analysis.analysis.visits': 'Visits',
- 'analysis.analysis.visits-trend': 'Visits Trend',
- 'analysis.analysis.visits-ranking': 'Visits Ranking',
- 'analysis.analysis.day-visits': 'Daily Visits',
- 'analysis.analysis.week': 'WoW Change',
- 'analysis.analysis.day': 'DoD Change',
- 'analysis.analysis.payments': 'Payments',
- 'analysis.analysis.conversion-rate': 'Conversion Rate',
- 'analysis.analysis.operational-effect': 'Operational Effect',
- 'analysis.analysis.sales-trend': 'Stores Sales Trend',
- 'analysis.analysis.sales-ranking': 'Sales Ranking',
- 'analysis.analysis.all-year': 'All Year',
- 'analysis.analysis.all-month': 'All Month',
- 'analysis.analysis.all-week': 'All Week',
- 'analysis.analysis.all-day': 'All day',
- 'analysis.analysis.search-users': 'Search Users',
- 'analysis.analysis.per-capita-search': 'Per Capita Search',
- 'analysis.analysis.online-top-search': 'Online Top Search',
- 'analysis.analysis.the-proportion-of-sales': 'The Proportion Of Sales',
- 'analysis.channel.all': 'ALL',
- 'analysis.channel.online': 'Online',
- 'analysis.channel.stores': 'Stores',
- 'analysis.analysis.sales': 'Sales',
- 'analysis.analysis.traffic': 'Traffic',
- 'analysis.table.rank': 'Rank',
- 'analysis.table.search-keyword': 'Keyword',
- 'analysis.table.users': 'Users',
- 'analysis.table.weekly-range': 'Weekly Range',
-};
diff --git a/src/pages/analysis/locales/pt-BR.ts b/src/pages/analysis/locales/pt-BR.ts
deleted file mode 100644
index 7be015713ba9fc34fc103a641ca5d5d8c89785ea..0000000000000000000000000000000000000000
--- a/src/pages/analysis/locales/pt-BR.ts
+++ /dev/null
@@ -1,34 +0,0 @@
-export default {
- 'analysis.analysis.test': 'Gongzhuan No.{no} shop',
- 'analysis.analysis.introduce': 'Introduzir',
- 'analysis.analysis.total-sales': 'Vendas Totais',
- 'analysis.analysis.day-sales': 'Vendas do Dia',
- 'analysis.analysis.visits': 'Visitas',
- 'analysis.analysis.visits-trend': 'Tendência de Visitas',
- 'analysis.analysis.visits-ranking': 'Ranking de Visitas',
- 'analysis.analysis.day-visits': 'Visitas do Dia',
- 'analysis.analysis.week': 'Taxa Semanal',
- 'analysis.analysis.day': 'Taxa Diária',
- 'analysis.analysis.payments': 'Pagamentos',
- 'analysis.analysis.conversion-rate': 'Taxa de Conversão',
- 'analysis.analysis.operational-effect': 'Efeito Operacional',
- 'analysis.analysis.sales-trend': 'Tendência de Vendas das Lojas',
- 'analysis.analysis.sales-ranking': 'Ranking de Vendas',
- 'analysis.$2': 'Todo ano',
- 'analysis.analysis.all-month': 'Todo mês',
- 'analysis.analysis.all-week': 'Toda semana',
- 'analysis.analysis.all-day': 'Todo dia',
- 'analysis.analysis.search-users': 'Pesquisa de Usuários',
- 'analysis.analysis.per-capita-search': 'Busca Per Capta',
- 'analysis.analysis.online-top-search': 'Mais Buscadas Online',
- 'analysis.analysis.the-proportion-of-sales': 'The Proportion Of Sales',
- 'analysis.channel.all': 'Tudo',
- 'analysis.channel.online': 'Online',
- 'analysis.channel.stores': 'Lojas',
- 'analysis.analysis.sales': 'Vendas',
- 'analysis.analysis.traffic': 'Tráfego',
- 'analysis.table.rank': 'Rank',
- 'analysis.table.search-keyword': 'Palavra chave',
- 'analysis.table.users': 'Usuários',
- 'analysis.table.weekly-range': 'Faixa Semanal',
-};
diff --git a/src/pages/analysis/locales/zh-CN.ts b/src/pages/analysis/locales/zh-CN.ts
deleted file mode 100644
index 9308f9d5564fb1e5e2a717e5d507e468a1ae62e1..0000000000000000000000000000000000000000
--- a/src/pages/analysis/locales/zh-CN.ts
+++ /dev/null
@@ -1,34 +0,0 @@
-export default {
- 'analysis.analysis.test': '工专路 {no} 号店',
- 'analysis.analysis.introduce': '指标说明',
- 'analysis.analysis.total-sales': '总销售额',
- 'analysis.analysis.day-sales': '日销售额',
- 'analysis.analysis.visits': '访问量',
- 'analysis.analysis.visits-trend': '访问量趋势',
- 'analysis.analysis.visits-ranking': '门店访问量排名',
- 'analysis.analysis.day-visits': '日访问量',
- 'analysis.analysis.week': '周同比',
- 'analysis.analysis.day': '日同比',
- 'analysis.analysis.payments': '支付笔数',
- 'analysis.analysis.conversion-rate': '转化率',
- 'analysis.analysis.operational-effect': '运营活动效果',
- 'analysis.analysis.sales-trend': '销售趋势',
- 'analysis.analysis.sales-ranking': '门店销售额排名',
- 'analysis.analysis.all-year': '全年',
- 'analysis.analysis.all-month': '本月',
- 'analysis.analysis.all-week': '本周',
- 'analysis.analysis.all-day': '今日',
- 'analysis.analysis.search-users': '搜索用户数',
- 'analysis.analysis.per-capita-search': '人均搜索次数',
- 'analysis.analysis.online-top-search': '线上热门搜索',
- 'analysis.analysis.the-proportion-of-sales': '销售额类别占比',
- 'analysis.channel.all': '全部渠道',
- 'analysis.channel.online': '线上',
- 'analysis.channel.stores': '门店',
- 'analysis.analysis.sales': '销售额',
- 'analysis.analysis.traffic': '客流量',
- 'analysis.table.rank': '排名',
- 'analysis.table.search-keyword': '搜索关键词',
- 'analysis.table.users': '用户数',
- 'analysis.table.weekly-range': '周涨幅',
-};
diff --git a/src/pages/analysis/locales/zh-TW.ts b/src/pages/analysis/locales/zh-TW.ts
deleted file mode 100644
index 82a4d428924199404fa5622aac2b674c89404707..0000000000000000000000000000000000000000
--- a/src/pages/analysis/locales/zh-TW.ts
+++ /dev/null
@@ -1,34 +0,0 @@
-export default {
- 'analysis.analysis.test': '工專路 {no} 號店',
- 'analysis.analysis.introduce': '指標說明',
- 'analysis.analysis.total-sales': '總銷售額',
- 'analysis.analysis.day-sales': '日銷售額',
- 'analysis.analysis.visits': '訪問量',
- 'analysis.analysis.visits-trend': '訪問量趨勢',
- 'analysis.analysis.visits-ranking': '門店訪問量排名',
- 'analysis.analysis.day-visits': '日訪問量',
- 'analysis.analysis.week': '周同比',
- 'analysis.analysis.day': '日同比',
- 'analysis.analysis.payments': '支付筆數',
- 'analysis.analysis.conversion-rate': '轉化率',
- 'analysis.analysis.operational-effect': '運營活動效果',
- 'analysis.analysis.sales-trend': '銷售趨勢',
- 'analysis.analysis.sales-ranking': '門店銷售額排名',
- 'analysis.analysis.all-year': '全年',
- 'analysis.analysis.all-month': '本月',
- 'analysis.analysis.all-week': '本周',
- 'analysis.analysis.all-day': '今日',
- 'analysis.analysis.search-users': '搜索用戶數',
- 'analysis.analysis.per-capita-search': '人均搜索次數',
- 'analysis.analysis.online-top-search': '線上熱門搜索',
- 'analysis.analysis.the-proportion-of-sales': '銷售額類別占比',
- 'analysis.channel.all': '全部渠道',
- 'analysis.channel.online': '線上',
- 'analysis.channel.stores': '門店',
- 'analysis.analysis.sales': '銷售額',
- 'analysis.analysis.traffic': '客流量',
- 'analysis.table.rank': '排名',
- 'analysis.table.search-keyword': '搜索關鍵詞',
- 'analysis.table.users': '用戶數',
- 'analysis.table.weekly-range': '周漲幅',
-};
diff --git a/src/pages/analysis/model.tsx b/src/pages/analysis/model.tsx
deleted file mode 100644
index 5706013c7e35aa8f685befcbed806e83f97e7dcc..0000000000000000000000000000000000000000
--- a/src/pages/analysis/model.tsx
+++ /dev/null
@@ -1,84 +0,0 @@
-import { fakeChartData } from './service';
-import { IAnalysisData } from './data';
-import { Reducer } from 'redux';
-import { EffectsCommandMap } from 'dva';
-import { AnyAction } from 'redux';
-
-export type Effect = (
- action: AnyAction,
- effects: EffectsCommandMap & { select: (func: (state: IAnalysisData) => T) => T },
-) => void;
-
-export interface ModelType {
- namespace: string;
- state: IAnalysisData;
- effects: {
- fetch: Effect;
- fetchSalesData: Effect;
- };
- reducers: {
- save: Reducer;
- clear: Reducer;
- };
-}
-
-const Model: ModelType = {
- namespace: 'analysis',
-
- state: {
- visitData: [],
- visitData2: [],
- salesData: [],
- searchData: [],
- offlineData: [],
- offlineChartData: [],
- salesTypeData: [],
- salesTypeDataOnline: [],
- salesTypeDataOffline: [],
- radarData: [],
- },
-
- effects: {
- *fetch(_, { call, put }) {
- const response = yield call(fakeChartData);
- yield put({
- type: 'save',
- payload: response,
- });
- },
- *fetchSalesData(_, { call, put }) {
- const response = yield call(fakeChartData);
- yield put({
- type: 'save',
- payload: {
- salesData: response.salesData,
- },
- });
- },
- },
-
- reducers: {
- save(state, { payload }) {
- return {
- ...state,
- ...payload,
- };
- },
- clear() {
- return {
- visitData: [],
- visitData2: [],
- salesData: [],
- searchData: [],
- offlineData: [],
- offlineChartData: [],
- salesTypeData: [],
- salesTypeDataOnline: [],
- salesTypeDataOffline: [],
- radarData: [],
- };
- },
- },
-};
-
-export default Model;
diff --git a/src/pages/analysis/service.tsx b/src/pages/analysis/service.tsx
deleted file mode 100644
index 64744b9d05f57b1a81a174157dc7cacfbc0e285f..0000000000000000000000000000000000000000
--- a/src/pages/analysis/service.tsx
+++ /dev/null
@@ -1,5 +0,0 @@
-import request from 'umi-request';
-
-export async function fakeChartData() {
- return request('/api/analysis/fake_chart_data');
-}
diff --git a/src/pages/analysis/style.less b/src/pages/analysis/style.less
deleted file mode 100644
index 2bace9a3bc85f17dde9c57754760d2fb37220c20..0000000000000000000000000000000000000000
--- a/src/pages/analysis/style.less
+++ /dev/null
@@ -1,185 +0,0 @@
-@import '~antd/lib/style/themes/default.less';
-@import './utils/utils.less';
-
-.iconGroup {
- i {
- margin-left: 16px;
- color: @text-color-secondary;
- cursor: pointer;
- transition: color 0.32s;
- &:hover {
- color: @text-color;
- }
- }
-}
-
-.rankingList {
- margin: 25px 0 0;
- padding: 0;
- list-style: none;
- li {
- .clearfix();
-
- display: flex;
- align-items: center;
- margin-top: 16px;
- span {
- color: @text-color;
- font-size: 14px;
- line-height: 22px;
- }
- .rankingItemNumber {
- display: inline-block;
- width: 20px;
- height: 20px;
- margin-top: 1.5px;
- margin-right: 16px;
- font-weight: 600;
- font-size: 12px;
- line-height: 20px;
- text-align: center;
- background-color: @background-color-base;
- border-radius: 20px;
- &.active {
- color: #fff;
- background-color: #314659;
- }
- }
- .rankingItemTitle {
- flex: 1;
- margin-right: 8px;
- overflow: hidden;
- white-space: nowrap;
- text-overflow: ellipsis;
- }
- }
-}
-
-.salesExtra {
- display: inline-block;
- margin-right: 24px;
- a {
- margin-left: 24px;
- color: @text-color;
- &:hover {
- color: @primary-color;
- }
- &.currentDate {
- color: @primary-color;
- }
- }
-}
-
-.salesCard {
- .salesBar {
- padding: 0 0 32px 32px;
- }
- .salesRank {
- padding: 0 32px 32px 72px;
- }
- :global {
- .ant-tabs-bar {
- padding-left: 16px;
- .ant-tabs-nav .ant-tabs-tab {
- padding-top: 16px;
- padding-bottom: 14px;
- line-height: 24px;
- }
- }
- .ant-tabs-extra-content {
- padding-right: 24px;
- line-height: 55px;
- }
- .ant-card-head {
- position: relative;
- }
- .ant-card-head-title {
- align-items: normal;
- }
- }
-}
-
-.salesCardExtra {
- height: inherit;
-}
-
-.salesTypeRadio {
- position: absolute;
- right: 54px;
- bottom: 12px;
-}
-
-.offlineCard {
- :global {
- .ant-tabs-ink-bar {
- bottom: auto;
- }
- .ant-tabs-bar {
- border-bottom: none;
- }
- .ant-tabs-nav-container-scrolling {
- padding-right: 40px;
- padding-left: 40px;
- }
- .ant-tabs-tab-prev-icon::before {
- position: relative;
- left: 6px;
- }
- .ant-tabs-tab-next-icon::before {
- position: relative;
- right: 6px;
- }
- .ant-tabs-tab-active h4 {
- color: @primary-color;
- }
- }
-}
-
-.twoColLayout {
- .salesCard {
- height: calc(100% - 24px);
- }
-}
-
-.trendText {
- margin-left: 8px;
- color: @heading-color;
-}
-
-@media screen and (max-width: @screen-lg) {
- .salesExtra {
- display: none;
- }
-
- .rankingList {
- li {
- span:first-child {
- margin-right: 8px;
- }
- }
- }
-}
-
-@media screen and (max-width: @screen-md) {
- .rankingTitle {
- margin-top: 16px;
- }
-
- .salesCard .salesBar {
- padding: 16px;
- }
-}
-
-@media screen and (max-width: @screen-sm) {
- .salesExtraWrap {
- display: none;
- }
-
- .salesCard {
- :global {
- .ant-tabs-content {
- padding-top: 30px;
- }
- }
- }
-}
diff --git a/src/pages/analysis/utils/Yuan.tsx b/src/pages/analysis/utils/Yuan.tsx
deleted file mode 100644
index eafefd41526f7313d6baea44faebafe2cb27f16b..0000000000000000000000000000000000000000
--- a/src/pages/analysis/utils/Yuan.tsx
+++ /dev/null
@@ -1,33 +0,0 @@
-import React from 'react';
-import { yuan } from '../components/Charts';
-/**
- * 减少使用 dangerouslySetInnerHTML
- */
-export default class Yuan extends React.Component<{
- children: React.ReactText;
-}> {
- main: HTMLSpanElement | undefined | null;
- componentDidMount() {
- this.renderToHtml();
- }
-
- componentDidUpdate() {
- this.renderToHtml();
- }
- renderToHtml = () => {
- const { children } = this.props;
- if (this.main) {
- this.main.innerHTML = yuan(children);
- }
- };
-
- render() {
- return (
- {
- this.main = ref;
- }}
- />
- );
- }
-}
diff --git a/src/pages/analysis/utils/utils.less b/src/pages/analysis/utils/utils.less
deleted file mode 100644
index de1aa64222b6f14328d3a9e3c262ac5a31cce5af..0000000000000000000000000000000000000000
--- a/src/pages/analysis/utils/utils.less
+++ /dev/null
@@ -1,50 +0,0 @@
-.textOverflow() {
- overflow: hidden;
- white-space: nowrap;
- text-overflow: ellipsis;
- word-break: break-all;
-}
-
-.textOverflowMulti(@line: 3, @bg: #fff) {
- position: relative;
- max-height: @line * 1.5em;
- margin-right: -1em;
- padding-right: 1em;
- overflow: hidden;
- line-height: 1.5em;
- text-align: justify;
- &::before {
- position: absolute;
- right: 14px;
- bottom: 0;
- padding: 0 1px;
- background: @bg;
- content: '...';
- }
- &::after {
- position: absolute;
- right: 14px;
- width: 1em;
- height: 1em;
- margin-top: 0.2em;
- background: white;
- content: '';
- }
-}
-
-// mixins for clearfix
-// ------------------------
-.clearfix() {
- zoom: 1;
- &::before,
- &::after {
- display: table;
- content: ' ';
- }
- &::after {
- clear: both;
- height: 0;
- font-size: 0;
- visibility: hidden;
- }
-}
diff --git a/src/pages/analysis/utils/utils.ts b/src/pages/analysis/utils/utils.ts
deleted file mode 100644
index 7cdc266a523fe1bce8592fa49a719dda57ca54a5..0000000000000000000000000000000000000000
--- a/src/pages/analysis/utils/utils.ts
+++ /dev/null
@@ -1,53 +0,0 @@
-import moment from 'moment';
-import { RangePickerValue } from 'antd/lib/date-picker/interface';
-
-export function fixedZero(val: number) {
- return val * 1 < 10 ? `0${val}` : val;
-}
-
-export function getTimeDistance(type: 'today' | 'week' | 'month' | 'year'): RangePickerValue {
- const now = new Date();
- const oneDay = 1000 * 60 * 60 * 24;
-
- if (type === 'today') {
- now.setHours(0);
- now.setMinutes(0);
- now.setSeconds(0);
- return [moment(now), moment(now.getTime() + (oneDay - 1000))];
- }
-
- if (type === 'week') {
- let day = now.getDay();
- now.setHours(0);
- now.setMinutes(0);
- now.setSeconds(0);
-
- if (day === 0) {
- day = 6;
- } else {
- day -= 1;
- }
-
- const beginTime = now.getTime() - day * oneDay;
-
- return [moment(beginTime), moment(beginTime + (7 * oneDay - 1000))];
- }
-
- if (type === 'month') {
- const year = now.getFullYear();
- const month = now.getMonth();
- const nextDate = moment(now).add(1, 'months');
- const nextYear = nextDate.year();
- const nextMonth = nextDate.month();
-
- return [
- moment(`${year}-${fixedZero(month + 1)}-01 00:00:00`),
- moment(moment(`${nextYear}-${fixedZero(nextMonth + 1)}-01 00:00:00`).valueOf() - 1000),
- ];
- }
-
- return [
- moment(`${now.getFullYear()}-01-01 00:00:00`),
- moment(`${now.getFullYear()}-12-31 23:59:59`),
- ];
-}