vue 积分报表数据总结

技术分类1
constants.js 全局通用js 用来定义全局的变量

export const ConstantSourceType = {
  PURCHASE_REWARD: 'Purchase Reward',
  PURCHASE_DEDUCTION: 'Consumption Points',
  REFUND_REVOKE: 'Refund Revoke Rewards',
  REFUND_RECOVER: 'Refund Revoke',
  DECLINE_REVOKE: 'Decline Revoke Rewards',
  DECLINE_RECOVER: 'Decline Revoke',
  SIGN_UP_REWARD: 'Sign Up Reward',
  RECOMMEND_REWARD: 'Recommend Reward',
  REFERRAL_SIGN_UP_REWARD: 'Invite Friends',
  REFERRAL_SIGN_UP_REGISTER_REWARD: 'Invited Sign Up',
  REFERRAL_MEMBER_PLACE_ORDER_REWARD: 'Referral Purchase Commission',
  PURCHASE_PROMOTION_REWARD: 'Bonus Points',

  getSourceType(type) {
    switch (type) {
      case 'PURCHASE_REWARD':
        return ConstantSourceType.PURCHASE_REWARD
      case 'PURCHASE_DEDUCTION':
        return ConstantSourceType.PURCHASE_DEDUCTION
      case 'REFUND_REVOKE':
        return ConstantSourceType.REFUND_REVOKE
      case 'REFUND_RECOVER':
        return ConstantSourceType.REFUND_RECOVER
      case 'DECLINE_REVOKE':
        return ConstantSourceType.DECLINE_REVOKE
      case 'DECLINE_RECOVER':
        return ConstantSourceType.DECLINE_RECOVER
      case 'SIGN_UP_REWARD':
        return ConstantSourceType.SIGN_UP_REWARD
      case 'RECOMMEND_REWARD':
        return ConstantSourceType.RECOMMEND_REWARD
      case 'REFERRAL_SIGN_UP_REWARD':
        return ConstantSourceType.REFERRAL_SIGN_UP_REWARD
      case 'REFERRAL_SIGN_UP_REGISTER_REWARD':
        return ConstantSourceType.REFERRAL_SIGN_UP_REGISTER_REWARD
      case 'REFERRAL_MEMBER_PLACE_ORDER_REWARD':
        return ConstantSourceType.REFERRAL_MEMBER_PLACE_ORDER_REWARD
      case 'PURCHASE_PROMOTION_REWARD':
        return ConstantSourceType.PURCHASE_PROMOTION_REWARD
      default:
        return '---'
    }
  }
}

技术分类2

echarts的图形显示 data-points.js

/**
 * OverView
 */
export class Data_PointsOverview {
  constructor() {
    this.data = null
  }
  /**
   * 获取区间分布饼图配置
   */
  getDistributionChartOptions(dataList) {
    return {
      tooltip: {
        show: true,
        trigger: 'item',
        formatter: '{a} <br/>{b} : {c} ({d}%)'
      },
      legend: {
        orient: 'vertical',
        right: 30,
        top: 0,
        bottom: 20,
        itemWidth: 5,
        itemHeight: 5,
        itemGap: 10,
        textStyle: {
          color: '#909399',
          fontWeight: 'bolder'
        }
      },
      series: [
        {
          name: 'Point Outstanding',
          type: 'pie',
          radius: ['40%', '80%'],
          avoidLabelOverlap: false,
          itemStyle: {
            borderRadius: 10,
            borderColor: '#fff',
            borderWidth: 2
          },
          center: ['30%', '45%'],
          label: {
            show: false,
            position: 'center'
          },
          color: [
            'rgb(226,239,253)', 'rgb(204,228,252)', 'rgb(175,215,255)', 'rgb(139,196,255)', 'rgb(99,175,255)',
            'rgb(61,156,255)', 'rgb(55,132,255)', 'rgb(45,105,222)', 'rgb(34,83,176)', 'rgb(22,62,129)'
          ],
          data: dataList
        }
      ]
    }
  }
}

/**
 * trend
 */
export class Data_PointsTrend {
  constructor() {
    this.data = null
  }
  /**
   * 积分趋势折线图配置项
   */
  getTrendChartOptions(dateArr, pointsIssuedArr, pointsUsedArr, interactiveMembersArr, usedPercentageArr) {
    return {
      grid: {
        left: '20px',
        right: '20px',
        bottom: '20px',
        top: '40px',
        containLabel: true
      },
      legend: {
        data: ['Points Issued', 'Points Used', 'Interactive Members', 'Used Percentage'],
        left: 20,

        selected: {
          // 选中'系列1'
          'Points Issued': true,
          // 不选中'系列2'
          'Points Used': false,
          'Interactive Members': false,
          'Used Percentage': false
        },
        icon: 'roundRect',
        show: true
      },
      tooltip: {
        trigger: 'axis',
        textStyle: {
          color: 'rgba(48,49,51)'
        },
        backgroundColor: 'rgba(255,255,255,0.9)',
        borderColor: '#cccccc',
        borderWidth: 1,
        padding: [20],

        formatter: function(params) {
          var str = ''
          str += '<div>' + params[0].name + '</div>'
          for (var i = 0; i < params.length; i++) {
            if (params[i].seriesName === 'Used Percentage') {
              str += '<span style="display:inline-block;margin-right:5px;border-radius:10px;width:10px;height:10px;background-color:' + params[i].color + ';"></span>' + params[i].seriesName + '</span> <span style="display:inline-block;font-weight: bold;min-width: 46px;text-align: right;">' + (params[i].data + '%') + '</span><br>'
            } else {
              str += '<span style="display:inline-block;margin-right:5px;border-radius:10px;width:10px;height:10px;background-color:' + params[i].color + ';"></span>' + params[i].seriesName + '</span> <span style="display:inline-block;font-weight: bold;min-width: 46px;text-align: right;">' + (params[i].data) + '</span><br>'
            }
          }
          console.log(str)
          return str
        }
      },
      xAxis: [
        {
          type: 'category',
          boundaryGap: false,
          axisLine: {
            lineStyle: {
              color: '#EBEBEB'
            }
          },
          axisLabel: {
            color: '#9E9E9E'
          },
          data: dateArr
        }
      ],
      yAxis: [
        {
          type: 'value',
          splitNumber: 4,
          axisLine: {
            lineStyle: {
              color: '#EBEBEB',
              width: 0
            }
          },
          splitLine: {
            lineStyle: {
              color: '#EBEBEB'
            }
          },
          axisLabel: {
            color: '#9E9E9E',
            formatter: '{value}'
          }
        },
        {
          type: 'value',
          splitNumber: 4,
          axisLine: {
            lineStyle: {
              color: '#EBEBEB',
              width: 0
            }
          },
          splitLine: {
            lineStyle: {
              color: '#EBEBEB'
            }
          },
          axisLabel: {
            color: '#9E9E9E',
            formatter: '{value}%'
          }
        }
      ],
      series: [
        {
          name: 'Points Issued',
          type: 'line',
          smooth: true,
          lineStyle: {
            color: '#ff4848'
          },
          showSymbol: false,
          itemStyle: {
            color: '#ff4848'
          },
          data: pointsIssuedArr
        },
        {
          name: 'Points Used',
          type: 'line',
          smooth: true,
          lineStyle: {
            color: '#2a83ff'
          },
          itemStyle: {
            color: '#2a83ff'
          },
          showSymbol: false,
          data: pointsUsedArr
        },
        {
          name: 'Interactive Members',
          type: 'line',
          smooth: true,
          lineStyle: {
            color: '#FF9b00'
          },
          itemStyle: {
            color: '#FF9b00'
          },
          showSymbol: false,
          data: interactiveMembersArr
        },
        {
          name: 'Used Percentage',
          type: 'line',
          smooth: true,
          lineStyle: {
            color: '#00c290'
          },
          yAxisIndex: 1,
          itemStyle: {
            color: '#00c290'
          },
          showSymbol: false,
          data: usedPercentageArr
        }
      ]
    }
  }
  /**
   * 积分区间饼图配置项
   */
  getDistributionOptions(dataList, isUsed) {
    return {
      tooltip: {
        show: true,
        trigger: 'item',
        formatter: '{a} <br/>{b} : {c} ({d}%)'
      },
      legend: {
        orient: 'vertical',
        right: 10,
        top: 0,
        bottom: 20,
        itemWidth: 5,
        itemHeight: 5,
        itemGap: 8,
        textStyle: {
          color: '#909399',
          fontWeight: 'bolder'
        }
      },
      series: [
        {
          name: isUsed ? 'Point Used' : 'Issued',
          type: 'pie',
          radius: ['40%', '80%'],
          avoidLabelOverlap: false,
          itemStyle: {
            borderRadius: 10,
            borderColor: '#fff',
            borderWidth: 2
          },
          center: ['30%', '45%'],
          label: {
            show: false,
            position: 'center'
          },
          color: [
            'rgb(55,132,255)', 'rgb(61,156,255)', 'rgb(99,175,255)', 'rgb(139,196,255)', 'rgb(175,215,255)',
            'rgb(204,228,252)', 'rgb(226,239,253)'
          ],
          data: dataList
        }
      ]
    }
  }
}

1 首先定义一个 div

<div ref="distributionChart" class="chart-box" style="width: 100%" />

2 定义模型数据

distributionChart: undefined,

3 初始化 demo

this.distributionChart = echarts.init(this.$refs.distributionChart)

4 设置数据

this.distributionChart.setOption(this.overviewData.getDistributionChartOptions(this.memberPointOutstandingDistribution.outstandingDistributionList))

5 跟随浏览器只有缩放

 this.__resizeChartHandler = debounce(() => {
          this.distributionChart.resize()
        }, 50)
        window.addEventListener('resize', this.__resizeChartHandler)



import { debounce } from '@/utils'
/**
 * @param {Function} func
 * @param {number} wait
 * @param {boolean} immediate
 * @return {*}
 */
export function debounce(func, wait, immediate) {
  let timeout, args, context, timestamp, result

  const later = function() {
    // 据上一次触发时间间隔
    const last = +new Date() - timestamp

    // 上次被包装函数被调用时间间隔 last 小于设定时间间隔 wait
    if (last < wait && last > 0) {
      timeout = setTimeout(later, wait - last)
    } else {
      timeout = null
      // 如果设定为immediate===true,因为开始边界已经调用过了此处无需调用
      if (!immediate) {
        result = func.apply(context, args)
        if (!timeout) context = args = null
      }
    }
  }

技术分类三 自定普通组件1

<template>
  <div id="panel_item">
    <el-card>
      <el-row class="text_c title">
        {{ title }}
        <el-tooltip class="item" effect="dark" :content="tip" placement="bottom-end">
          <i v-if="tip" class="el-icon-question"></i>
        </el-tooltip>
      </el-row>
      <el-row class="text_c value">
        <count-to :start-val="0.00" :end-val="value" :duration="1000" :decimals="decimals" />
        <span v-if="unit">{{ unit }}</span>
      </el-row>
      <el-row class="price">
        <el-row v-if="price" class="text_c">
          =$
          <count-to :start-val="0.00" :end-val="price" :duration="1000" :decimals="decimals" />
        </el-row>
      </el-row>
    </el-card>
  </div>
</template>

<script>

import CountTo from 'vue-count-to'

export default {

  name: 'PanelItem',
  /**
     * 组件
     * *****************************************************************************************************************
     */
  components: {
    CountTo
  },

  /**
     * 外部变量
     * *****************************************************************************************************************
     */
  props: {
    title: {
      type: String,
      default: 'Panel ###'
    },
    value: {
      type: Number,
      default: 0
    },
    decimals: {
      type: Number,
      default: 0
    },
    unit: {
      type: String,
      default: null
    },
    price: {
      type: Number,
      default: 0
    },
    tip: {
      type: String,
      default: null
    }
  },

  /**
     * 数据定义
     * *****************************************************************************************************************
     */
  data() {
    return {

      REF: {}
    }
  },

  /**
     * 计算属性
     * *****************************************************************************************************************
     */
  computed: {},

  /**
     * 挂载完成
     * *****************************************************************************************************************
     */
  mounted() {
  },

  /**
     * 自定义方法
     * *****************************************************************************************************************
     */
  methods: {}

}

</script>

<style lang="scss" scoped>

</style>

<style lang="scss">
  #panel_item {

    .el-card__body {
      padding: 0;
    }

    .title {
      height: 20px;
      line-height: 20px;
      margin-top: 10px;
    }

    .value {
      font-size: 25px;
      font-weight: 800;
      line-height: 40px;
      height: 40px;
    }

    .price {
      margin-bottom: 10px;
      line-height: 10px;
      height: 10px;
      color: #909399;
      font-size: 12px;
    }
  }
</style>




!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define("CountTo",[],e):"object"==typeof exports?exports.CountTo=e():t.CountTo=e()}(this,function(){return function(t){function e(n){if(i[n])return i[n].exports;var a=i[n]={i:n,l:!1,exports:{}};return t[n].call(a.exports,a,a.exports,e),a.l=!0,a.exports}var i={};return e.m=t,e.c=i,e.i=function(t){return t},e.d=function(t,i,n){e.o(t,i)||Object.defineProperty(t,i,{configurable:!1,enumerable:!0,get:n})},e.n=function(t){var i=t&&t.__esModule?function(){return t.default}:function(){return t};return e.d(i,"a",i),i},e.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},e.p="/dist/",e(e.s=2)}([function(t,e,i){var n=i(4)(i(1),i(5),null,null);t.exports=n.exports},function(t,e,i){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var n=i(3);e.default={props:{startVal:{type:Number,required:!1,default:0},endVal:{type:Number,required:!1,default:2017},duration:{type:Number,required:!1,default:3e3},autoplay:{type:Boolean,required:!1,default:!0},decimals:{type:Number,required:!1,default:0,validator:function(t){return t>=0}},decimal:{type:String,required:!1,default:"."},separator:{type:String,required:!1,default:","},prefix:{type:String,required:!1,default:""},suffix:{type:String,required:!1,default:""},useEasing:{type:Boolean,required:!1,default:!0},easingFn:{type:Function,default:function(t,e,i,n){return i*(1-Math.pow(2,-10*t/n))*1024/1023+e}}},data:function(){return{localStartVal:this.startVal,displayValue:this.formatNumber(this.startVal),printVal:null,paused:!1,localDuration:this.duration,startTime:null,timestamp:null,remaining:null,rAF:null}},computed:{countDown:function(){return this.startVal>this.endVal}},watch:{startVal:function(){this.autoplay&&this.start()},endVal:function(){this.autoplay&&this.start()}},mounted:function(){this.autoplay&&this.start(),this.$emit("mountedCallback")},methods:{start:function(){this.localStartVal=this.startVal,this.startTime=null,this.localDuration=this.duration,this.paused=!1,this.rAF=(0,n.requestAnimationFrame)(this.count)},pauseResume:function(){this.paused?(this.resume(),this.paused=!1):(this.pause(),this.paused=!0)},pause:function(){(0,n.cancelAnimationFrame)(this.rAF)},resume:function(){this.startTime=null,this.localDuration=+this.remaining,this.localStartVal=+this.printVal,(0,n.requestAnimationFrame)(this.count)},reset:function(){this.startTime=null,(0,n.cancelAnimationFrame)(this.rAF),this.displayValue=this.formatNumber(this.startVal)},count:function(t){this.startTime||(this.startTime=t),this.timestamp=t;var e=t-this.startTime;this.remaining=this.localDuration-e,this.useEasing?this.countDown?this.printVal=this.localStartVal-this.easingFn(e,0,this.localStartVal-this.endVal,this.localDuration):this.printVal=this.easingFn(e,this.localStartVal,this.endVal-this.localStartVal,this.localDuration):this.countDown?this.printVal=this.localStartVal-(this.localStartVal-this.endVal)*(e/this.localDuration):this.printVal=this.localStartVal+(this.localStartVal-this.startVal)*(e/this.localDuration),this.countDown?this.printVal=this.printVal<this.endVal?this.endVal:this.printVal:this.printVal=this.printVal>this.endVal?this.endVal:this.printVal,this.displayValue=this.formatNumber(this.printVal),e<this.localDuration?this.rAF=(0,n.requestAnimationFrame)(this.count):this.$emit("callback")},isNumber:function(t){return!isNaN(parseFloat(t))},formatNumber:function(t){t=t.toFixed(this.decimals),t+="";var e=t.split("."),i=e[0],n=e.length>1?this.decimal+e[1]:"",a=/(\d+)(\d{3})/;if(this.separator&&!this.isNumber(this.separator))for(;a.test(i);)i=i.replace(a,"$1"+this.separator+"$2");return this.prefix+i+n+this.suffix}},destroyed:function(){(0,n.cancelAnimationFrame)(this.rAF)}}},function(t,e,i){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var n=i(0),a=function(t){return t&&t.__esModule?t:{default:t}}(n);e.default=a.default,"undefined"!=typeof window&&window.Vue&&window.Vue.component("count-to",a.default)},function(t,e,i){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var n=0,a="webkit moz ms o".split(" "),r=void 0,o=void 0;if("undefined"==typeof window)e.requestAnimationFrame=r=function(){},e.cancelAnimationFrame=o=function(){};else{e.requestAnimationFrame=r=window.requestAnimationFrame,e.cancelAnimationFrame=o=window.cancelAnimationFrame;for(var s=void 0,u=0;u<a.length&&(!r||!o);u++)s=a[u],e.requestAnimationFrame=r=r||window[s+"RequestAnimationFrame"],e.cancelAnimationFrame=o=o||window[s+"CancelAnimationFrame"]||window[s+"CancelRequestAnimationFrame"];r&&o||(e.requestAnimationFrame=r=function(t){var e=(new Date).getTime(),i=Math.max(0,16-(e-n)),a=window.setTimeout(function(){t(e+i)},i);return n=e+i,a},e.cancelAnimationFrame=o=function(t){window.clearTimeout(t)})}e.requestAnimationFrame=r,e.cancelAnimationFrame=o},function(t,e){t.exports=function(t,e,i,n){var a,r=t=t||{},o=typeof t.default;"object"!==o&&"function"!==o||(a=t,r=t.default);var s="function"==typeof r?r.options:r;if(e&&(s.render=e.render,s.staticRenderFns=e.staticRenderFns),i&&(s._scopeId=i),n){var u=Object.create(s.computed||null);Object.keys(n).forEach(function(t){var e=n[t];u[t]=function(){return e}}),s.computed=u}return{esModule:a,exports:r,options:s}}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement;return(t._self._c||e)("span",[t._v("\n  "+t._s(t.displayValue)+"\n")])},staticRenderFns:[]}}])});
//# sourceMappingURL=vue-count-to.min.js.map

2 父组件引用

 <panel-item
            title="Point Outstanding" :value="Number(memberPointOutstandingDistribution.pointsOutstanding)"
            :price="Number(memberPointOutstandingDistribution.pointsAmount)">
          </panel-item>
import PanelItem from '../components/panel-item'
 components: {
    PanelItem,
    ProgressBar,
    TrendAnalysis
  },

4 自定义 比例的条做一个 由左到右 扩展的动画 组件

<template>
  <div id="progress_bar">
    <el-row ref="container">
      <el-col class="line_box" :style="lineWidth"></el-col>
      <el-col v-if="showText" class="label_box">
        {{ value }}%
      </el-col>
    </el-row>
  </div>
</template>

<script>

export default {

  name: 'ProgressBar',
  /**
   * 组件
   * *****************************************************************************************************************
   */
  components: {},

  /**
   * 外部变量
   * *****************************************************************************************************************
   */
  props: {
    // 范围 0 - 100
    progress: {
      type: Number,
      default: 0
    },
    // 是否显示进度文字
    showText: {
      type: Boolean,
      default: true
    }
  },

  /**
   * 数据定义
   * *****************************************************************************************************************
   */
  data() {
    return {
      maxValue: 100,
      value: 0,
      REF: {}
    }
  },

  /**
   * 计算属性
   * *****************************************************************************************************************
   */
  computed: {
    lineWidth() {
      let containerWidth = this.getWidth()
      if (containerWidth > 65) {
        containerWidth = containerWidth - 65
      }
      const lineWidth = (this.value / 100) * containerWidth
      return 'width: ' + lineWidth + 'px;'
    }
  },

  /**
   * 属性监听
   * *****************************************************************************************************************
   */
  watch: {

  },

  /**
   * 挂载完成
   * *****************************************************************************************************************
   */
  mounted() {
    this.getWidth()
    if (this.value !== this.progress) {
      this.value = 0
      this.increase()
    }
  },

  /**
   * 自定义方法
   * *****************************************************************************************************************
   */
  methods: {
    /**
     * 自增
     */
    increase() {
      this.value = 0
      const timer = setInterval(() => {
        this.value = this.value + 1
        if (this.value >= this.progress) {
          this.value = this.progress
          clearInterval(timer)
        }
      }, 10)
    },

    /**
     * 获取容器宽度
     */
    getWidth() {
      if (this.$refs.container) {
        return this.$refs.container.$el.offsetWidth
      } else {
        return 0
      }
    }
  }

}

</script>

<style lang="scss" scoped>

</style>

<style lang="scss">
#progress_bar {

  .line_box {
    //width: calc(100% - 65px);
    width: 0;
    height: 10px;
    background-color: #1890ff;
    line-height: 20px;
    margin-top: 6px;
  }

  .label_box {
    width: 60px;
    margin-left: 5px;
    line-height: 20px;
  }
}
</style>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值