| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596 |
- <template>
- <TechCard>
- <div class="card-header">
- <div class="title">设备在线率</div>
- </div>
- <BaseChart :option="chartOption" />
- <div class="footer">
- <div class="label">设备数量</div>
- <div class="count">{{ onlineCount }} / {{ deviceCount }} 台</div>
- </div>
- </TechCard>
- </template>
- <script lang="ts" setup>
- import { computed } from 'vue'
- import 'echarts-liquidfill'
- import TechCard from '../TechCard/index.vue'
- defineOptions({ name: 'DeviceOnlineRateCard' })
- type Props = {
- onlineCount: number
- deviceCount: number
- }
- const props = withDefaults(defineProps<Props>(), {
- onlineCount: 0,
- deviceCount: 0,
- })
- const onlineRate = computed(() =>
- props.deviceCount === 0
- ? '0'
- : Math.round((props.onlineCount / props.deviceCount) * 100).toFixed(2)
- )
- const chartOption = computed(() => ({
- series: [
- {
- type: 'liquidFill',
- radius: '70%',
- center: ['50%', '50%'],
- data: [parseFloat(onlineRate.value) / 100],
- label: {
- formatter: `${onlineRate.value}%`,
- fontSize: '1em',
- fontWeight: 'bold',
- color: '#00f0ff',
- },
- outline: {
- show: true,
- borderDistance: 4,
- itemStyle: {
- borderColor: '#00f0ff',
- borderWidth: 4,
- },
- },
- backgroundStyle: {
- color: '#2c5364',
- },
- itemStyle: {
- color: '#00f0ff',
- opacity: 0.6,
- },
- },
- ],
- }))
- </script>
- <style lang="less" scoped>
- .card-header {
- text-align: center;
- .title {
- font-size: 16px;
- font-weight: bold;
- color: #00f0ff;
- }
- }
- .footer {
- display: flex;
- justify-content: center;
- align-items: center;
- flex-wrap: wrap;
- margin-top: 12px;
- gap: 8px;
- font-size: 14px;
- color: #9cc5e0;
- .count {
- font-weight: bold;
- color: #00f0ff;
- font-size: 16px;
- }
- }
- </style>
|