Explorar o código

Add Loading (#4055)

* add loading in html

* add loading

* rm  console

* add ResizeObserver
陈帅 %!s(int64=6) %!d(string=hai) anos
pai
achega
29c23b1f5c

+ 3 - 3
docker/docker-compose.yml

@@ -1,9 +1,9 @@
-version: "3.5"
+version: '3.5'
 
 services:
   ant-design-pro_build:
     build: ../
-    container_name: "ant-design-pro_build"
+    container_name: 'ant-design-pro_build'
     volumes:
       - dist:/usr/src/app/dist
 
@@ -11,7 +11,7 @@ services:
     image: nginx
     ports:
       - 80:80
-    container_name: "ant-design-pro_web"
+    container_name: 'ant-design-pro_web'
     restart: unless-stopped
     volumes:
       - dist:/usr/share/nginx/html:ro

+ 1 - 0
package.json

@@ -79,6 +79,7 @@
     "react-dom": "^16.7.0",
     "react-fittext": "^1.0.0",
     "react-media": "^1.9.2",
+    "resize-observer-polyfill": "^1.5.1",
     "umi": "^2.4.4",
     "umi-plugin-react": "^1.7.2",
     "umi-request": "^1.0.5"

+ 25 - 4
src/components/Charts/Bar/index.js

@@ -2,12 +2,13 @@ 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 autoHeight from '../autoHeight';
+import ResizeObserver from 'resize-observer-polyfill';
 import styles from '../index.less';
 
-@autoHeight()
 class Bar extends Component {
   state = {
+    width: 0,
+    height: 0,
     autoHideXLabels: false,
   };
 
@@ -27,6 +28,24 @@ class Bar extends Component {
     this.node = n;
   };
 
+  resizeObserver() {
+    const ro = new ResizeObserver(entries => {
+      const { width, height } = entries[0].contentRect;
+      this.setState((preState, { hasLegend }) => {
+        if (preState.width !== width || preState.height !== height) {
+          return {
+            width: width - (hasLegend ? 240 : 0),
+            height,
+          };
+        }
+        return null;
+      });
+    });
+    if (this.root) {
+      ro.observe(this.root);
+    }
+  }
+
   @Bind()
   @Debounce(400)
   resize() {
@@ -56,7 +75,7 @@ class Bar extends Component {
 
   render() {
     const {
-      height,
+      height: propsHeight,
       title,
       forceFit = true,
       data,
@@ -82,13 +101,15 @@ class Bar extends Component {
         value: y,
       }),
     ];
-
+    const { height: stateHeight, width } = this.state;
+    const height = propsHeight || stateHeight;
     return (
       <div className={styles.chart} style={{ height }} ref={this.handleRoot}>
         <div ref={this.handleRef}>
           {title && <h4 style={{ marginBottom: 20 }}>{title}</h4>}
           <Chart
             scale={scale}
+            width={width}
             height={title ? height - 41 : height}
             forceFit={forceFit}
             data={data}

+ 25 - 8
src/components/Charts/Pie/index.js

@@ -6,14 +6,14 @@ import classNames from 'classnames';
 import ReactFitText from 'react-fittext';
 import Debounce from 'lodash-decorators/debounce';
 import Bind from 'lodash-decorators/bind';
-import autoHeight from '../autoHeight';
-
+import ResizeObserver from 'resize-observer-polyfill';
 import styles from './index.less';
 
 /* eslint react/no-danger:0 */
-@autoHeight()
 class Pie extends Component {
   state = {
+    width: 0,
+    height: 0,
     legendData: [],
     legendBlock: false,
   };
@@ -26,6 +26,7 @@ class Pie extends Component {
       },
       { passive: true }
     );
+    this.resizeObserver();
   }
 
   componentDidUpdate(preProps) {
@@ -93,6 +94,24 @@ class Pie extends Component {
     });
   };
 
+  resizeObserver() {
+    const ro = new ResizeObserver(entries => {
+      const { width, height } = entries[0].contentRect;
+      this.setState((preState, { hasLegend }) => {
+        if (preState.width !== width || preState.height !== height) {
+          return {
+            width: width - (hasLegend ? 240 : 0),
+            height,
+          };
+        }
+        return null;
+      });
+    });
+    if (this.root) {
+      ro.observe(this.root);
+    }
+  }
+
   // for window resize auto responsive legend
   @Bind()
   @Debounce(300)
@@ -125,7 +144,6 @@ class Pie extends Component {
       className,
       style,
       height,
-      forceFit = true,
       percent,
       color,
       inner = 0.75,
@@ -134,7 +152,7 @@ class Pie extends Component {
       lineWidth = 1,
     } = this.props;
 
-    const { legendData, legendBlock } = this.state;
+    const { legendData, height: StateHeight, width, legendBlock } = this.state;
     const pieClassName = classNames(styles.pie, className, {
       [styles.hasLegend]: !!hasLegend,
       [styles.legendBlock]: legendBlock,
@@ -211,9 +229,9 @@ class Pie extends Component {
           <div className={styles.chart}>
             <Chart
               scale={scale}
-              height={height}
-              forceFit={forceFit}
+              height={height || StateHeight}
               data={dv}
+              width={width}
               padding={padding}
               animate={animate}
               onGetG2Instance={this.getG2Instance}
@@ -241,7 +259,6 @@ class Pie extends Component {
             )}
           </div>
         </ReactFitText>
-
         {hasLegend && (
           <ul className={styles.legend}>
             {legendData.map((item, i) => (

+ 9 - 2
src/pages/Dashboard/Analysis.js

@@ -18,6 +18,7 @@ const OfflineData = React.lazy(() => import('./OfflineData'));
 }))
 class Analysis extends Component {
   state = {
+    loading: true,
     salesType: 'all',
     currentTabKey: '',
     rangePickerValue: getTimeDistance('year'),
@@ -30,6 +31,11 @@ class Analysis extends Component {
         type: 'chart/fetch',
       });
     });
+    setTimeout(() => {
+      this.setState({
+        loading: false,
+      });
+    }, 2000);
   }
 
   componentWillUnmount() {
@@ -90,8 +96,9 @@ class Analysis extends Component {
   };
 
   render() {
-    const { rangePickerValue, salesType, currentTabKey } = this.state;
-    const { chart, loading } = this.props;
+    const { rangePickerValue, salesType, currentTabKey, loading: stateLoading } = this.state;
+    const { chart, loading: propsLoading } = this.props;
+    const loading = stateLoading || propsLoading;
     const {
       visitData,
       visitData2,

+ 152 - 1
src/pages/document.ejs

@@ -12,6 +12,157 @@
   </head>
   <body>
     <noscript>Sorry, we need js to run correctly!</noscript>
-    <div id="root"></div>
+    <div id="root">
+      <style>
+        .page-loading-warp {
+          padding: 120px;
+          display: flex;
+          justify-content: center;
+          align-items: center;
+        }
+        .ant-spin {
+          -webkit-box-sizing: border-box;
+          box-sizing: border-box;
+          margin: 0;
+          padding: 0;
+          color: rgba(0, 0, 0, 0.65);
+          font-size: 14px;
+          font-variant: tabular-nums;
+          line-height: 1.5;
+          list-style: none;
+          -webkit-font-feature-settings: 'tnum';
+          font-feature-settings: 'tnum';
+          position: absolute;
+          display: none;
+          color: #1890ff;
+          text-align: center;
+          vertical-align: middle;
+          opacity: 0;
+          -webkit-transition: -webkit-transform 0.3s cubic-bezier(0.78, 0.14, 0.15, 0.86);
+          transition: -webkit-transform 0.3s cubic-bezier(0.78, 0.14, 0.15, 0.86);
+          transition: transform 0.3s cubic-bezier(0.78, 0.14, 0.15, 0.86);
+          transition: transform 0.3s cubic-bezier(0.78, 0.14, 0.15, 0.86),
+            -webkit-transform 0.3s cubic-bezier(0.78, 0.14, 0.15, 0.86);
+        }
+
+        .ant-spin-spinning {
+          position: static;
+          display: inline-block;
+          opacity: 1;
+        }
+
+        .ant-spin-dot {
+          position: relative;
+          display: inline-block;
+          font-size: 20px;
+          width: 20px;
+          height: 20px;
+        }
+
+        .ant-spin-dot-item {
+          position: absolute;
+          display: block;
+          width: 9px;
+          height: 9px;
+          background-color: #1890ff;
+          border-radius: 100%;
+          -webkit-transform: scale(0.75);
+          -ms-transform: scale(0.75);
+          transform: scale(0.75);
+          -webkit-transform-origin: 50% 50%;
+          -ms-transform-origin: 50% 50%;
+          transform-origin: 50% 50%;
+          opacity: 0.3;
+          -webkit-animation: antSpinMove 1s infinite linear alternate;
+          animation: antSpinMove 1s infinite linear alternate;
+        }
+
+        .ant-spin-dot-item:nth-child(1) {
+          top: 0;
+          left: 0;
+        }
+
+        .ant-spin-dot-item:nth-child(2) {
+          top: 0;
+          right: 0;
+          -webkit-animation-delay: 0.4s;
+          animation-delay: 0.4s;
+        }
+
+        .ant-spin-dot-item:nth-child(3) {
+          right: 0;
+          bottom: 0;
+          -webkit-animation-delay: 0.8s;
+          animation-delay: 0.8s;
+        }
+
+        .ant-spin-dot-item:nth-child(4) {
+          bottom: 0;
+          left: 0;
+          -webkit-animation-delay: 1.2s;
+          animation-delay: 1.2s;
+        }
+
+        .ant-spin-dot-spin {
+          -webkit-transform: rotate(45deg);
+          -ms-transform: rotate(45deg);
+          transform: rotate(45deg);
+          -webkit-animation: antRotate 1.2s infinite linear;
+          animation: antRotate 1.2s infinite linear;
+        }
+
+        .ant-spin-lg .ant-spin-dot {
+          font-size: 32px;
+          width: 32px;
+          height: 32px;
+        }
+
+        .ant-spin-lg .ant-spin-dot i {
+          width: 14px;
+          height: 14px;
+        }
+
+        @media all and (-ms-high-contrast: none), (-ms-high-contrast: active) {
+          .ant-spin-blur {
+            background: #fff;
+            opacity: 0.5;
+          }
+        }
+
+        @-webkit-keyframes antSpinMove {
+          to {
+            opacity: 1;
+          }
+        }
+
+        @keyframes antSpinMove {
+          to {
+            opacity: 1;
+          }
+        }
+
+        @-webkit-keyframes antRotate {
+          to {
+            -webkit-transform: rotate(405deg);
+            transform: rotate(405deg);
+          }
+        }
+
+        @keyframes antRotate {
+          to {
+            -webkit-transform: rotate(405deg);
+            transform: rotate(405deg);
+          }
+        }
+      </style>
+      <div class="page-loading-warp">
+        <div class="ant-spin ant-spin-lg ant-spin-spinning">
+          <span class="ant-spin-dot ant-spin-dot-spin"
+            ><i class="ant-spin-dot-item"></i><i class="ant-spin-dot-item"></i
+            ><i class="ant-spin-dot-item"></i><i class="ant-spin-dot-item"></i
+          ></span>
+        </div>
+      </div>
+    </div>
   </body>
 </html>