Browse Source

update Analysis

Sendya 6 years ago
parent
commit
ed697ef4c2

+ 61 - 45
src/components/ChartCard.vue

@@ -15,7 +15,9 @@
       </div>
     </div>
     <div class="chart-card-footer">
-      <slot name="footer"></slot>
+      <div class="field">
+        <slot name="footer"></slot>
+      </div>
     </div>
   </a-card>
 </template>
@@ -41,55 +43,69 @@
 </script>
 
 <style lang="scss" scoped>
-    .chart-card-header{
-        position: relative;
-        overflow: hidden;
-        width: 100%;
+  .chart-card-header {
+    position: relative;
+    overflow: hidden;
+    width: 100%;
 
-        .meta{
-            position: relative;
-            overflow: hidden;
-            width: 100%;
-            color: rgba(0,0,0,.45);
-            font-size: 14px;
-            line-height: 22px;
-        }
-    }
-    .chart-card-action{
-        cursor: pointer;
-        position: absolute;
-        top: 0;
-        right: 0;
+    .meta {
+      position: relative;
+      overflow: hidden;
+      width: 100%;
+      color: rgba(0, 0, 0, .45);
+      font-size: 14px;
+      line-height: 22px;
     }
-    .chart-card-footer{
-        border-top: 1px solid #e8e8e8;
-        padding-top: 9px;
-        margin-top: 8px;
+  }
+
+  .chart-card-action {
+    cursor: pointer;
+    position: absolute;
+    top: 0;
+    right: 0;
+  }
+
+  .chart-card-footer {
+    border-top: 1px solid #e8e8e8;
+    padding-top: 9px;
+    margin-top: 8px;
+
+    > * {
+      position: relative;
     }
-    .chart-card-content{
-        margin-bottom: 12px;
-        position: relative;
-        height: 46px;
-        width: 100%;
 
-        .content-fix{
-            position: absolute;
-            left: 0;
-            bottom: 0;
-            width: 100%;
-        }
+    .field {
+      white-space: nowrap;
+      overflow: hidden;
+      text-overflow: ellipsis;
+      margin: 0;
     }
+  }
+
+  .chart-card-content {
+    margin-bottom: 12px;
+    position: relative;
+    height: 46px;
+    width: 100%;
 
-    .total {
-        overflow: hidden;
-        text-overflow: ellipsis;
-        word-break: break-all;
-        white-space: nowrap;
-        color: #000;
-        margin-top: 4px;
-        margin-bottom: 0;
-        font-size: 30px;
-        line-height: 38px;
-        height: 38px;
+    .content-fix {
+      position: absolute;
+      left: 0;
+      bottom: 0;
+      width: 100%;
     }
+  }
+
+  .total {
+    overflow: hidden;
+    text-overflow: ellipsis;
+    word-break: break-all;
+    white-space: nowrap;
+    color: #000;
+    margin-top: 4px;
+    margin-bottom: 0;
+    font-size: 30px;
+    line-height: 38px;
+    height: 38px;
+  }
 </style>

+ 10 - 20
src/components/chart/MiniArea.vue

@@ -1,7 +1,7 @@
 <template>
-  <div class="antv-mini-chart">
-    <div class="chart-content" :style="{ height: 46 }">
-      <v-chart :force-fit="true" :height="height" :data="data" :padding="[36, 5, 18, 5]">
+  <div class="antv-chart-mini">
+    <div class="chart-wrapper" :style="{ height: 46 }">
+      <v-chart :force-fit="true" :height="height" :data="data" :padding="[36, 0, 18, 0]">
         <v-tooltip />
         <v-smooth-area position="x*y" />
       </v-chart>
@@ -10,16 +10,17 @@
 </template>
 
 <script>
-  import moment from 'moment'
+  import moment from 'dayjs'
   const data = []
   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) {
+
+  for (let i = 0; i < 10; i++) {
     data.push({
       x: moment(new Date(beginDay + 1000 * 60 * 60 * 24 * i)).format('YYYY-MM-DD'),
-      y: fakeY[i]
+      y: Math.round(Math.random() * 10)
     })
   }
+
   const tooltip = [
     'x*y',
     (x, y) => ({
@@ -42,8 +43,8 @@
     data () {
       return {
         data,
-        scale,
         tooltip,
+        scale,
         height: 100
       }
     }
@@ -51,16 +52,5 @@
 </script>
 
 <style lang="scss" scoped>
-    .antv-mini-chart {
-        position: relative;
-        width: 100%;
-
-        .chart-content {
-            position: absolute;
-            bottom: -28px;
-            width: 100%;
-            margin: 0 -5px;
-            overflow: hidden;
-        }
-    }
+  @import "chart";
 </style>

+ 57 - 0
src/components/chart/MiniBar.vue

@@ -0,0 +1,57 @@
+<template>
+  <div class="antv-chart-mini">
+    <div class="chart-wrapper" :style="{ height: 46 }">
+      <v-chart :force-fit="true" :height="height" :data="data" :padding="[36, 5, 18, 5]">
+        <v-tooltip />
+        <v-bar position="x*y" />
+      </v-chart>
+    </div>
+  </div>
+</template>
+
+<script>
+  import moment from 'dayjs'
+  const data = []
+  const beginDay = new Date().getTime()
+
+  for (let i = 0; i < 10; i++) {
+    data.push({
+      x: moment(new Date(beginDay + 1000 * 60 * 60 * 24 * i)).format('YYYY-MM-DD'),
+      y: Math.round(Math.random() * 10)
+    })
+  }
+
+  const tooltip = [
+    'x*y',
+    (x, y) => ({
+      name: x,
+      value: y
+    })
+  ]
+
+  const scale = [{
+    dataKey: 'x',
+    min: 2
+  }, {
+    dataKey: 'y',
+    title: '时间',
+    min: 1,
+    max: 30
+  }]
+
+  export default {
+    name: "MiniBar",
+    data () {
+      return {
+        data,
+        tooltip,
+        scale,
+        height: 100
+      }
+    }
+  }
+</script>
+
+<style lang="scss" scoped>
+  @import "chart";
+</style>

+ 75 - 0
src/components/chart/MiniProgress.vue

@@ -0,0 +1,75 @@
+<template>
+  <div class="chart-mini-progress">
+    <div class="target" :style="{ left: target + '%'}">
+      <span :style="{ backgroundColor: color }" />
+      <span :style="{ backgroundColor: color }"/>
+    </div>
+    <div class="progress-wrapper">
+      <div class="progress" :style="{ backgroundColor: color, width: percentage + '%', height: height }"></div>
+    </div>
+  </div>
+</template>
+
+<script>
+  export default {
+    name: "MiniProgress",
+    props: {
+      target: {
+        type: Number,
+        default: 0
+      },
+      height: {
+        type: String,
+        default: '10px'
+      },
+      color: {
+        type: String,
+        default: '#13C2C2'
+      },
+      percentage: {
+        type: Number,
+        default: 0
+      }
+    }
+  }
+</script>
+
+<style lang="scss" scoped>
+  .chart-mini-progress {
+    padding: 5px 0;
+    position: relative;
+    width: 100%;
+
+    .target {
+      position: absolute;
+      top: 0;
+      bottom: 0;
+
+      span {
+        border-radius: 100px;
+        position: absolute;
+        top: 0;
+        left: 0;
+        height: 4px;
+        width: 2px;
+
+        &:last-child {
+          top: auto;
+          bottom: 0;
+        }
+      }
+    }
+    .progress-wrapper {
+      background-color: #f5f5f5;
+      position: relative;
+
+      .progress {
+        transition: all .4s cubic-bezier(.08,.82,.17,1) 0s;
+        border-radius: 1px 0 0 1px;
+        background-color: #1890ff;
+        width: 0;
+        height: 100%;
+      }
+    }
+  }
+</style>

+ 82 - 0
src/components/chart/Trend.vue

@@ -0,0 +1,82 @@
+<template>
+  <div class="chart-trend">
+    {{ term }}
+    <span>{{ rate }}%</span>
+    <span :class="['trend-icon', trend]"><a-icon :type="'caret-' + trend"/></span>
+  </div>
+</template>
+
+<script>
+  export default {
+    name: "Trend",
+    props: {
+      term: {
+        type: String,
+        default: '',
+        required: true
+      },
+      percentage: {
+        type: Number,
+        default: null
+      },
+      type: {
+        type: Boolean,
+        default: null
+      },
+      target: {
+        type: Number,
+        default: 0
+      },
+      value: {
+        type: Number,
+        default: 0
+      },
+      fixed: {
+        type: Number,
+        default: 2
+      }
+    },
+    data () {
+      return {
+        trend: this.type && 'up' || 'down',
+        rate: this.percentage
+      }
+    },
+    created () {
+      let type = this.type === null ? this.value >= this.target : this.type
+      this.trend = type ? 'up' : 'down';
+      this.rate = (this.percentage === null ? Math.abs(this.value - this.target) * 100 / this.target : this.percentage).toFixed(this.fixed)
+    }
+  }
+</script>
+
+<style lang="scss" scoped>
+  .chart-trend {
+    display: inline-block;
+    font-size: 14px;
+    line-height: 22px;
+
+    .trend-icon {
+      font-size: 12px;
+
+      &.up, &.down {
+        margin-left: 4px;
+        position: relative;
+        top: 1px;
+
+        i {
+          font-size: 12px;
+          transform: scale(.83);
+        }
+      }
+
+      &.up {
+        color: #f5222d;
+      }
+      &.down {
+        color: #52c41a;
+        top: -1px;
+      }
+    }
+  }
+</style>

+ 13 - 0
src/components/chart/chart.scss

@@ -0,0 +1,13 @@
+.antv-chart-mini {
+  position: relative;
+  width: 100%;
+
+  .chart-wrapper {
+    position: absolute;
+    bottom: -28px;
+    width: 100%;
+
+/*    margin: 0 -5px;
+    overflow: hidden;*/
+  }
+}

+ 3 - 2
src/components/layout/LayoutMain.vue

@@ -48,9 +48,9 @@
   import LayoutHeader from './LayoutHeader'
   import LayoutFooter from './LayoutFooter'
   import SettingDrawer from '@/components/tools/SettingDrawer'
+  import { triggerResize } from '@/utils/util'
   import { mapState, mapActions } from 'vuex'
 
-
   export default {
     name: "LayoutView",
     components: {
@@ -86,7 +86,8 @@
     methods: {
       ...mapActions(['setSidebar']),
       toggle() {
-        this.collapsed = !this.collapsed;
+        this.collapsed = !this.collapsed
+        triggerResize()
         this.setSidebar(this.collapsed)
       },
       menuSelect() {

+ 10 - 1
src/utils/util.js

@@ -1,4 +1,3 @@
-
 export function timeFix() {
   const time = new Date()
   const hour = time.getHours()
@@ -9,4 +8,14 @@ export function welcome() {
   const arr = ['休息一会儿吧', '准备吃什么呢?', '要不要打一把 DOTA', '我猜你可能累了']
   let index = Math.floor((Math.random()*arr.length))
   return arr[index]
+}
+
+/**
+ * 触发 window.resize
+ */
+export function triggerResize() {
+  let event = document.createEvent('HTMLEvents')
+  event.initEvent('resize', true, true)
+  event.eventType = 'message'
+  window.dispatchEvent(event)
 }

+ 41 - 58
src/views/dashboard/Analysis.vue

@@ -7,69 +7,46 @@
             <a-icon type="info-circle-o" />
           </a-tooltip>
           <div>
-            <div style="display: inline-block; font-size: 14px; line-height: 22px; margin-right: 16px">
-              同周比
-              <span>12%</span>
-              <span style="color: #f5222d; font-size: 12px"><a-icon type="caret-up" /></span>
-            </div>
-            <div style="display: inline-block; font-size: 14px; line-height: 22px;">
-              日环比
-              <span>11%</span>
-              <span style="color: #52c41a; font-size: 12px"><a-icon type="caret-down" /></span>
-            </div>
+            <trend style="margin-right: 16px;" term="同周比" :percentage="12" :type="true" :fixed="0" />
+            <trend term="日环比" :target="100" :value="89" :fixed="0" />
           </div>
-          <div slot="footer">日均销售额<span>¥ 234.56</span></div>
+          <template slot="footer">日均销售额<span>¥ 234.56</span></template>
         </chart-card>
       </a-col>
       <a-col :sm="24" :md="12" :xl="6" :style="{ marginBottom: '24px' }">
-        <chart-card :loading="loading" title="总销售额" total="¥126,560">
+        <chart-card :loading="loading" title="访问量" :total="8846 | NumberFormat">
           <a-tooltip title="指标说明" slot="action">
             <a-icon type="info-circle-o" />
           </a-tooltip>
           <div>
             <mini-area />
           </div>
-          <div slot="footer">日均销售额<span>¥ 234.56</span></div>
+          <template slot="footer">日访问量<span> {{ '1234' | NumberFormat }}</span></template>
         </chart-card>
       </a-col>
       <a-col :sm="24" :md="12" :xl="6" :style="{ marginBottom: '24px' }">
-        <chart-card :loading="loading" title="总销售额" total="¥126,560">
+        <chart-card :loading="loading" title="支付笔数" :total="6560 | NumberFormat">
           <a-tooltip title="指标说明" slot="action">
             <a-icon type="info-circle-o" />
           </a-tooltip>
           <div>
-            <div style="display: inline-block; font-size: 14px; line-height: 22px; margin-right: 16px">
-              同周比
-              <span>12%</span>
-              <span style="color: #f5222d; font-size: 12px"><a-icon type="caret-up" /></span>
-            </div>
-            <div style="display: inline-block; font-size: 14px; line-height: 22px;">
-              日环比
-              <span>11%</span>
-              <span style="color: #52c41a; font-size: 12px"><a-icon type="caret-down" /></span>
-            </div>
+            <mini-bar />
           </div>
-          <div slot="footer">日均销售额<span>¥ 234.56</span></div>
+          <template slot="footer">转化率 <span>60%</span></template>
         </chart-card>
       </a-col>
       <a-col :sm="24" :md="12" :xl="6" :style="{ marginBottom: '24px' }">
-        <chart-card :loading="loading" title="总销售额" total="¥126,560">
+        <chart-card :loading="loading" title="运营活动效果" total="78%">
           <a-tooltip title="指标说明" slot="action">
             <a-icon type="info-circle-o" />
           </a-tooltip>
           <div>
-            <div style="display: inline-block; font-size: 14px; line-height: 22px; margin-right: 16px">
-              同周比
-              <span>12%</span>
-              <span style="color: #f5222d; font-size: 12px"><a-icon type="caret-up" /></span>
-            </div>
-            <div style="display: inline-block; font-size: 14px; line-height: 22px;">
-              日环比
-              <span>11%</span>
-              <span style="color: #52c41a; font-size: 12px"><a-icon type="caret-down" /></span>
-            </div>
+            <mini-progress color="rgb(19, 194, 194)" :target="80" :percentage="78" height="8px" />
           </div>
-          <div slot="footer">日均销售额<span>¥ 234.56</span></div>
+          <template slot="footer">
+            <trend style="margin-right: 16px;" term="同周比" :percentage="12" :type="true" :fixed="0" />
+            <trend term="日环比" :target="80" :value="78" :fixed="0" />
+          </template>
         </chart-card>
       </a-col>
     </a-row>
@@ -96,14 +73,16 @@
               </a-col>
             </a-row>
           </a-tab-pane>
-          <a-tab-pane tab="访问量" key="2"><a-row>
-            <a-col :xl="16" :lg="12" :md="12" :sm="24" :xs="24">
-              <bar title="销售额趋势" />
-            </a-col>
-            <a-col :xl="8" :lg="12" :md="12" :sm="24" :xs="24">
-              <rank-list title="门店销售排行榜" :list="rankList"/>
-            </a-col>
-          </a-row></a-tab-pane>
+          <a-tab-pane tab="访问量" key="2">
+            <a-row>
+              <a-col :xl="16" :lg="12" :md="12" :sm="24" :xs="24">
+                <bar title="销售额趋势" />
+              </a-col>
+              <a-col :xl="8" :lg="12" :md="12" :sm="24" :xs="24">
+                <rank-list title="门店销售排行榜" :list="rankList"/>
+              </a-col>
+            </a-row>
+          </a-tab-pane>
         </a-tabs>
       </div>
     </a-card>
@@ -154,13 +133,15 @@
 </template>
 
 <script>
-  import moment from "moment"
   import ChartCard from '@/components/ChartCard'
   import ACol from "ant-design-vue/es/grid/Col"
   import ATooltip from "ant-design-vue/es/tooltip/Tooltip"
   import MiniArea from '@/components/chart/MiniArea'
+  import MiniBar from '@/components/chart/MiniBar'
+  import MiniProgress from '@/components/chart/MiniProgress'
   import RankList from '@/components/chart/RankList'
   import Bar from '@/components/chart/Bar'
+  import Trend from '@/components/chart/Trend'
 
   const rankList = []
   for (let i = 0; i < 7; i++) {
@@ -177,12 +158,14 @@
       ACol,
       ChartCard,
       MiniArea,
+      MiniBar,
+      MiniProgress,
       RankList,
-      Bar
+      Bar,
+      Trend
     },
     data() {
       return {
-        moment,
         loading: true,
         rankList
       }
@@ -196,17 +179,17 @@
 </script>
 
 <style lang="scss" scoped>
-    .extra-wrapper {
-        line-height: 55px;
-        padding-right: 24px;
+  .extra-wrapper {
+    line-height: 55px;
+    padding-right: 24px;
 
-        .extra-item{
-            display: inline-block;
-            margin-right: 24px;
+    .extra-item {
+      display: inline-block;
+      margin-right: 24px;
 
-            a {
-                margin-left: 24px;
-            }
-        }
+      a {
+        margin-left: 24px;
+      }
     }
+  }
 </style>