gauge.vue 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. <script setup lang="ts">
  2. import * as echarts from 'echarts'
  3. import {
  4. onUnmounted,
  5. onMounted, ref, watch
  6. } from 'vue'
  7. const props = withDefaults(defineProps<{
  8. value: number,
  9. gears?: string
  10. }>(), {
  11. value: 0,
  12. gears: '前进'
  13. })
  14. const chartDom = ref()
  15. const chart = ref(null as any)
  16. const option = ref({
  17. series: {
  18. name: 'Pressure',
  19. type: 'gauge',
  20. itemStyle: { color: '#FFFFFF' },
  21. startAngle: 180,
  22. max: 60,
  23. endAngle: 0,
  24. axisLine: { lineStyle: { width: 1 } },
  25. axisTick: {
  26. distance: 0,
  27. length: 10,
  28. lineStyle: { color: '#FFFFFF' }
  29. },
  30. splitLine: {
  31. length: 15,
  32. distance: 0,
  33. lineStyle: { color: '#FFFFFF' }
  34. },
  35. axisLabel: {
  36. distance: 8,
  37. color: '#FFFFFF'
  38. },
  39. progress: { show: true },
  40. radius: '190%',
  41. center: [ '50%', '98%' ],
  42. detail: {
  43. offsetCenter: [ 0, -25 ],
  44. valueAnimation: true,
  45. formatter: (value: number) => `{value|${value.toFixed(0)}}{unit|km/h}\n{num|${props.gears}}`,
  46. rich: {
  47. value: {
  48. fontSize: 20,
  49. fontWeight: 'bolder',
  50. color: '#FFFFFF'
  51. },
  52. unit: {
  53. fontSize: 20,
  54. color: '#FFFFFF',
  55. padding: [ 0, 0, 0, 10 ]
  56. },
  57. num: {
  58. fontSize: 20,
  59. color: '#FFFFFF',
  60. padding: [ 0, 0, 0, 10 ]
  61. }
  62. }
  63. },
  64. pointer: { show: false },
  65. data: [ 0 ]
  66. }
  67. })
  68. function resetChart() {
  69. if (!chart.value) return
  70. chart.value.resize()
  71. }
  72. watch(() => props.value, (v: number) => {
  73. if (!chart.value) return
  74. if (v >= 60) v = 60
  75. if (v <= 0) v = 0
  76. option.value.series.data[0] = v
  77. chart.value.setOption(option.value)
  78. })
  79. watch(() => props.gears, () => {
  80. if (!chart.value) return
  81. chart.value.setOption(option.value)
  82. })
  83. onMounted(() => {
  84. chart.value = echarts.init(chartDom.value)
  85. chart.value.setOption(option.value)
  86. window.addEventListener('resize', resetChart, false)
  87. })
  88. onUnmounted(() => {
  89. window.removeEventListener('resize', resetChart, false)
  90. })
  91. </script>
  92. <template>
  93. <div
  94. id="charts"
  95. ref="chartDom"
  96. />
  97. </template>
  98. <style scoped>
  99. #charts {
  100. width: 30vw;
  101. height: 15vw;
  102. max-width: 460px;
  103. max-height: 230px;
  104. position: absolute;
  105. bottom: 0;
  106. left: 50%;
  107. transform: translateX(-50%);
  108. z-index: 2;
  109. }
  110. </style>