index.vue 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. <template>
  2. <TechCard>
  3. <template #extra>
  4. <div class="toggle-group">
  5. <button :class="{ active: mode === 'day' }" @click="mode = 'day'">按日</button>
  6. <button :class="{ active: mode === 'month' }" @click="mode = 'month'">按月</button>
  7. </div>
  8. </template>
  9. <div class="card-title">历史告警统计</div>
  10. <BaseChart :option="chartOption" :height="175" />
  11. </TechCard>
  12. </template>
  13. <script setup lang="ts">
  14. import { computed, ref } from 'vue'
  15. import TechCard from '../TechCard/index.vue'
  16. import * as echarts from 'echarts'
  17. defineOptions({ name: 'AlarmHistoryCard' })
  18. // 切换模式:按日 / 按月
  19. const mode = ref<'day' | 'month'>('day')
  20. // 模拟接口数据结构
  21. const rawData = ref({
  22. dayStatInfo: [
  23. { date: '2024-07-01', fallingCount: 10 },
  24. { date: '2024-07-02', fallingCount: 15 },
  25. { date: '2024-07-03', fallingCount: 20 },
  26. { date: '2024-07-04', fallingCount: 12 },
  27. { date: '2024-07-05', fallingCount: 8 },
  28. ],
  29. monthStatInfo: [
  30. { month: '2024-06', fallingCount: 50 },
  31. { month: '2024-07', fallingCount: 65 },
  32. ],
  33. })
  34. // 根据模式转换图表数据
  35. const alarmHistoryData = computed(() => {
  36. const source = mode.value === 'day' ? rawData.value.dayStatInfo : rawData.value.monthStatInfo
  37. const dates = source.map((item) => ('date' in item ? item.date : item.month))
  38. const values = source.map((item) => item.fallingCount ?? 0)
  39. return { dates, values }
  40. })
  41. // 图表配置项
  42. const chartOption = computed(() => ({
  43. grid: { top: 10, right: 20, bottom: 30, left: 30 },
  44. tooltip: {
  45. trigger: 'axis',
  46. axisPointer: { type: 'shadow' },
  47. },
  48. xAxis: {
  49. type: 'category',
  50. data: alarmHistoryData.value.dates,
  51. axisLine: { lineStyle: { color: '#2a3b5a' } },
  52. axisLabel: { color: '#9cc5e0', fontSize: 12 },
  53. },
  54. yAxis: {
  55. type: 'value',
  56. axisLine: { lineStyle: { color: '#2a3b5a' } },
  57. axisLabel: { color: '#9cc5e0', fontSize: 12 },
  58. splitLine: { lineStyle: { color: 'rgba(42, 59, 90, 0.3)' } },
  59. },
  60. series: [
  61. {
  62. name: '告警次数',
  63. type: 'line',
  64. smooth: true,
  65. symbol: 'circle',
  66. symbolSize: 8,
  67. data: alarmHistoryData.value.values,
  68. itemStyle: { color: '#f39c12' },
  69. lineStyle: {
  70. width: 3,
  71. color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
  72. { offset: 0, color: '#f39c12' },
  73. { offset: 1, color: '#e74c3c' },
  74. ]),
  75. },
  76. areaStyle: {
  77. color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
  78. { offset: 0, color: 'rgba(243, 156, 18, 0.3)' },
  79. { offset: 1, color: 'rgba(243, 156, 18, 0.1)' },
  80. ]),
  81. },
  82. },
  83. ],
  84. }))
  85. </script>
  86. <style scoped lang="less">
  87. .card-title {
  88. font-size: 16px;
  89. font-weight: bold;
  90. color: #f39c12;
  91. margin-bottom: 12px;
  92. text-align: center;
  93. }
  94. .toggle-group {
  95. display: flex;
  96. gap: 8px;
  97. justify-content: flex-end;
  98. button {
  99. background: none;
  100. border: 1px solid #f39c12;
  101. color: #f39c12;
  102. padding: 4px 10px;
  103. border-radius: 4px;
  104. font-size: 12px;
  105. cursor: pointer;
  106. &.active {
  107. background-color: #f39c12;
  108. color: #fff;
  109. }
  110. }
  111. }
  112. </style>