123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204 |
- <template>
- <div class="el-statistic">
- <div class="head" v-if="title||$slots.title">
- <slot name="title">
- <span class="title">
- {{ title }}
- </span>
- </slot>
- </div>
- <div class="con">
- <span class="prefix" v-if="prefix||$slots.prefix">
- <slot name="prefix" >
- {{ prefix }}
- </slot>
- </span>
- <span class="number" :style="valueStyle">
- <slot name="formatter"> {{ disposeValue }}</slot>
- </span>
- <span class="suffix" v-if="suffix||$slots.suffix">
- <slot name="suffix">
- {{ suffix }}
- </slot>
- </span>
- </div>
- </div>
- </template>
- <script>
- import { isNumber, chain, multiply, padStart, reduce} from 'element-ui/src/utils/lodash';
- export default {
- name: 'ElStatistic',
- data() {
- return {
- disposeValue: '',
- timeTask: null,
- REFRESH_INTERVAL: 1000 / 30
- };
- },
- props: {
- decimalSeparator: {
- type: String,
- default: '.'
- },
- groupSeparator: {
- type: String,
- default: ''
- },
- precision: {
- type: Number,
- default: null
- },
- value: {
- type: [String, Number, Date],
- default: ''
- },
- prefix: {
- type: String,
- default: ''
- },
- suffix: {
- type: String,
- default: ''
- },
- title: {
- type: [String, Number],
- default: ''
- },
- timeIndices: {
- type: Boolean,
- default: false
- },
- valueStyle: {
- type: Object,
- default: function() {
- return {};
- }
- },
- format: {
- type: String,
- default: 'HH:mm:ss:SSS'
- },
- rate: {
- type: Number,
- default: 1000
- }
- },
- created() {
- this.branch();
- },
- watch: {
- value: function() {
- this.branch();
- },
- groupSeparator() {
- this.dispose();
- },
- mulriple() {
- this.dispose();
- }
- },
- methods: {
- branch() {
- let { timeIndices, countDown, dispose} = this;
- if (timeIndices) {
- countDown(this.value.valueOf() || this.value);
- } else {
- dispose();
- }
- },
- magnification(num, mulriple = 1000, groupSeparator = ',') {
- // magnification factor
- const level = String(mulriple).length ;
- return num.replace(new RegExp(`(\\d)(?=(\\d{${level - 1}})+$)`, 'g'), `$1${groupSeparator}`);
- },
- dispose() {
- let { value, rate, groupSeparator } = this;
- if (!isNumber(value)) return false;
- if (this.precision) {
- value = value.toFixed(this.precision);
- }
- let [integer, decimal] = String(value).split('.');
- // 1000 multiplying power
- if (groupSeparator) {
- integer = this.magnification(integer, rate, groupSeparator);
- }
- let result = `${integer}${decimal ? this.decimalSeparator + decimal : ''}`;
- this.disposeValue = result;
- return result;
- },
- diffDate(minuend, subtrahend) {
- return Math.max(minuend - subtrahend, 0);
- },
- suspend(isStop) {
- if (isStop) {
- if (this.timeTask) {
- clearInterval(this.timeTask);
- this.timeTask = null;
- }
- } else {
- this.branch();
- }
- return this.disposeValue;
- },
- formatTimeStr: function(time) {
- let {format} = this;
- const escapeRegex = /\[[^\]]*]/g;
- const keepList = (format.match(escapeRegex) || []).map(str => str.slice(1, -1));
- const timeUnits = [
- ['Y', 1000 * 60 * 60 * 24 * 365], // years
- ['M', 1000 * 60 * 60 * 24 * 30], // months
- ['D', 1000 * 60 * 60 * 24], // days
- ['H', 1000 * 60 * 60], // hours
- ['m', 1000 * 60], // minutes
- ['s', 1000], // seconds
- ['S', 1] // million seconds
- ];
- let formatText = reduce(
- timeUnits,
- (con, item) => {
- const name = item[0];
- return con.replace(new RegExp(`${name}+`, 'g'), (match) => {
- let sum = chain(time).divide(item[1]).floor(0).value();
- time -= multiply(sum, item[1]);
- return padStart(String(sum), String(match).length, 0);
- });
- },
- format
- );
- let index = 0;
- return formatText.replace(escapeRegex, () => {
- const match = keepList[index];
- index += 1;
- return match;
- });
- },
- stopTime(time) {
- let result = true; // stop
- if (time) {
- this.$emit('change', time);
- result = false;
- } else {
- result = true;
- this.suspend(true);
- this.$emit('finish', true);
- }
- return result;
- },
- countDown(timeVlaue) {
- let {REFRESH_INTERVAL, timeTask, diffDate, formatTimeStr, stopTime, suspend } = this;
- if (timeTask) return;
- let than = this;
- this.timeTask = setInterval(()=> {
- let diffTiem = diffDate(timeVlaue, Date.now());
- than.disposeValue = formatTimeStr(diffTiem);
- stopTime(diffTiem);
- }, REFRESH_INTERVAL);
- this.$once('hook:beforeDestroy', () => {
- suspend(true);
- });
- }
- }
- };
- </script>
|