index.vue 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. <template>
  2. <TechCard>
  3. <div class="card-header">
  4. <div class="title">设备在线率</div>
  5. </div>
  6. <BaseChart :option="chartOption" />
  7. <div class="footer">
  8. <div class="label">设备数量</div>
  9. <div class="count">{{ onlineCount }} / {{ deviceCount }} 台</div>
  10. </div>
  11. </TechCard>
  12. </template>
  13. <script lang="ts" setup>
  14. import { computed } from 'vue'
  15. import 'echarts-liquidfill'
  16. import TechCard from '../TechCard/index.vue'
  17. defineOptions({ name: 'DeviceOnlineRateCard' })
  18. type Props = {
  19. onlineCount: number
  20. deviceCount: number
  21. }
  22. const props = withDefaults(defineProps<Props>(), {
  23. onlineCount: 0,
  24. deviceCount: 0,
  25. })
  26. const onlineRate = computed(() =>
  27. props.deviceCount === 0
  28. ? '0'
  29. : Math.round((props.onlineCount / props.deviceCount) * 100).toFixed(2)
  30. )
  31. const chartOption = computed(() => ({
  32. series: [
  33. {
  34. type: 'liquidFill',
  35. radius: '70%',
  36. center: ['50%', '50%'],
  37. data: [parseFloat(onlineRate.value) / 100],
  38. label: {
  39. formatter: `${onlineRate.value}%`,
  40. fontSize: '1em',
  41. fontWeight: 'bold',
  42. color: '#00f0ff',
  43. },
  44. outline: {
  45. show: true,
  46. borderDistance: 4,
  47. itemStyle: {
  48. borderColor: '#00f0ff',
  49. borderWidth: 4,
  50. },
  51. },
  52. backgroundStyle: {
  53. color: '#2c5364',
  54. },
  55. itemStyle: {
  56. color: '#00f0ff',
  57. opacity: 0.6,
  58. },
  59. },
  60. ],
  61. }))
  62. </script>
  63. <style lang="less" scoped>
  64. .card-header {
  65. text-align: center;
  66. .title {
  67. font-size: 16px;
  68. font-weight: bold;
  69. color: #00f0ff;
  70. }
  71. }
  72. .footer {
  73. display: flex;
  74. justify-content: center;
  75. align-items: center;
  76. flex-wrap: wrap;
  77. margin-top: 12px;
  78. gap: 8px;
  79. font-size: 14px;
  80. color: #9cc5e0;
  81. .count {
  82. font-weight: bold;
  83. color: #00f0ff;
  84. font-size: 16px;
  85. }
  86. }
  87. </style>