user-add-compare.vue 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. <template>
  2. <div class="flex flex-col">
  3. <el-row :gutter="16" class="mt-4">
  4. <el-col :span="8">
  5. <div class="statistic-card">
  6. <el-statistic title="今日" :value="todayRegNum" suffix="人" />
  7. <div class="statistic-footer">
  8. <span>对比昨日</span>
  9. <el-text :type="comparisonType">
  10. {{ comparisonValue }}%<el-icon><component :is="comparisonIcon" /></el-icon>
  11. </el-text>
  12. </div>
  13. </div>
  14. </el-col>
  15. <el-col :span="8">
  16. <el-statistic :value="yesterdayRegNum" title="昨日" suffix="人" />
  17. </el-col>
  18. <el-col :span="8">
  19. <el-statistic :value="averageRegNum" title="均值" suffix="人" />
  20. </el-col>
  21. </el-row>
  22. <v-chart ref="saleChartRef" style="height: 280px" :option="options" />
  23. </div>
  24. </template>
  25. <script setup>
  26. import { ref, reactive, computed } from 'vue';
  27. import VChart from 'vue-echarts';
  28. import { use } from 'echarts/core';
  29. import { CanvasRenderer } from 'echarts/renderers';
  30. import { LineChart } from 'echarts/charts';
  31. import {
  32. GridComponent,
  33. TooltipComponent,
  34. LegendComponent,
  35. ToolboxComponent
  36. } from 'echarts/components';
  37. import { Top, Bottom } from '@element-plus/icons-vue';
  38. // 按需加载echarts
  39. use([
  40. CanvasRenderer,
  41. LineChart,
  42. GridComponent,
  43. TooltipComponent,
  44. LegendComponent
  45. ]);
  46. const props = defineProps({
  47. todayRegNum: {
  48. type: Number,
  49. default: 0
  50. },
  51. yesterdayRegNum: {
  52. type: Number,
  53. default: 0
  54. },
  55. todayRegNumComparison: {
  56. type: Number,
  57. default: 0
  58. },
  59. chatAxis: {
  60. type: Array,
  61. default: () => []
  62. },
  63. todayRegNumCharts: {
  64. type: Array,
  65. default: () => []
  66. },
  67. yesterdayRegNumCharts: {
  68. type: Array,
  69. default: () => []
  70. }
  71. });
  72. // 计算均值
  73. const averageRegNum = computed(() => {
  74. if (props.todayRegNumCharts.length === 0) return 0;
  75. const sum = props.todayRegNumCharts.reduce((acc, val) => acc + val, 0);
  76. return Math.round(sum / props.todayRegNumCharts.length);
  77. });
  78. // 计算环比显示
  79. const comparisonType = computed(() => {
  80. return props.todayRegNumComparison > 0 ? 'success' : 'danger';
  81. });
  82. const comparisonValue = computed(() => {
  83. return Math.abs(props.todayRegNumComparison);
  84. });
  85. const comparisonIcon = computed(() => {
  86. return props.todayRegNumComparison > 0 ? Top : Bottom;
  87. });
  88. const options = computed(() => ({
  89. tooltip: {
  90. trigger: 'axis'
  91. },
  92. legend: {
  93. data: ['今日新增用户', '昨日新增用户']
  94. },
  95. grid: {
  96. left: '3%',
  97. right: '4%',
  98. bottom: '3%',
  99. containLabel: true
  100. },
  101. xAxis: {
  102. type: 'category',
  103. boundaryGap: false,
  104. data: props.chatAxis || []
  105. },
  106. yAxis: {
  107. type: 'value'
  108. },
  109. series: [
  110. {
  111. name: '今日新增用户',
  112. type: 'line',
  113. data: props.todayRegNumCharts || [],
  114. smooth: true
  115. },
  116. {
  117. name: '昨日新增用户',
  118. type: 'line',
  119. data: props.yesterdayRegNumCharts || [],
  120. smooth: true
  121. }
  122. ]
  123. }));
  124. </script>