chart.vue 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. <script setup>
  2. import util from "@tools/util";
  3. import chartTheme from './../rateAnalysis.json'
  4. import {
  5. ref,
  6. toRaw,
  7. computed,
  8. onMounted,
  9. watch,
  10. nextTick
  11. } from 'vue';
  12. import {
  13. useStore
  14. } from 'vuex';
  15. import * as echarts from 'echarts'
  16. const chartId = 'chart-' + util.newGUID(); //chartId
  17. const chartIns = ref(null) //chart 实例
  18. const props = defineProps({
  19. xAxis: {
  20. type: Object,
  21. required: true,
  22. default: () => ({})
  23. },
  24. series: {
  25. type: Array,
  26. required: true
  27. },
  28. height: {
  29. type: String,
  30. required: false,
  31. default: '500px'
  32. },
  33. width: {
  34. type: String,
  35. required: false,
  36. default: '500px'
  37. },
  38. title: {
  39. type: String,
  40. required: false
  41. },
  42. subtext: {
  43. type: String,
  44. required: false
  45. },
  46. // 是否为dialog中单表
  47. isDiaAlone: {
  48. type: Boolean,
  49. default: false
  50. },
  51. // 是否含雷达图
  52. isRadar: {
  53. type: Boolean,
  54. default: false
  55. },
  56. theme: {
  57. type: Boolean,
  58. default: false
  59. },
  60. echartsTheme: {
  61. type: String,
  62. default: ''
  63. },
  64. })
  65. /**定义option */
  66. const option = computed({
  67. get() {
  68. let radar = null
  69. if (props.isRadar && props.xAxis.data.length) {
  70. radar = {
  71. radius: '70%',
  72. center: ['60%', '50%'],
  73. indicator: props.xAxis.data.map(o => {
  74. return {
  75. text: '',
  76. max: 1000
  77. }
  78. }),
  79. splitArea: {
  80. show: false
  81. },
  82. splitLine: {
  83. show: false
  84. }
  85. }
  86. }
  87. return {
  88. backgroundColor: '',
  89. title: {
  90. text: props.title || '',
  91. subtext: props.subtext || '',
  92. top: 10,
  93. left: props.isDiaAlone ? '22%' : '5%',
  94. },
  95. angleAxis: props.xAxis || {},
  96. radiusAxis: {},
  97. polar: {
  98. radius: '70%',
  99. center: ['60%', '50%']
  100. },
  101. radar: radar,
  102. tooltip: {
  103. formatter: (params) => {
  104. return params.componentSubType === 'radar' ?
  105. `${params.marker}${params.seriesName}` :
  106. `${params.marker}${params.seriesName}m<br/>${params.value>1? '频次:'+ params.value: ''}`
  107. },
  108. confine: true
  109. },
  110. series: props.series || [],
  111. legend: {
  112. show: true,
  113. orient: 'vertical',
  114. left: props.isDiaAlone ? '22%' : '5%',
  115. itemWidth: 16,
  116. itemHeight: 10,
  117. textStyle: {
  118. fontSize: util.vh(10)
  119. },
  120. top: 'middle',
  121. // data: ['0-2.5', '2.5-5', '5-7.5', '7.5-10', '10-12.5', '12.5-15', '15-17.5', '17.5-20',
  122. // '20-22.5', '22.5-25', '25-inf'
  123. // ]
  124. data: ['0-3', '3-5', '5-10', '10-12', '12-25', '25-inf']
  125. }
  126. }
  127. },
  128. set(val) {}
  129. })
  130. watch(() => option, (newVal, oldVal) => {
  131. if (chartIns.value) {
  132. const echartIns = toRaw(chartIns.value)
  133. echartIns.setOption(newVal.value)
  134. }
  135. }, {
  136. deep: true
  137. })
  138. watch([() => props.width, () => props.height], (newVal, oldVal) => {
  139. if (chartIns.value) {
  140. const echartIns = toRaw(chartIns.value)
  141. nextTick(() => echartIns.resize())
  142. }
  143. })
  144. const store = useStore()
  145. const collapse = computed({
  146. get() {
  147. return store.state.collapse
  148. },
  149. set(val) {}
  150. })
  151. watch(collapse, (val) => {
  152. if (chartIns.value) {
  153. setTimeout(() => {
  154. chartIns.value.resize()
  155. }, 300)
  156. }
  157. })
  158. onMounted(() => {
  159. nextTick(() => {
  160. init()
  161. })
  162. })
  163. watch(() => props.echartsTheme, (newVal, oldVal) => init())
  164. const init = () => {
  165. echarts.registerTheme('chartTheme', chartTheme)
  166. const echartIns = echarts.init(document.getElementById(chartId), props.echartsTheme)
  167. document.getElementById(chartId).removeAttribute("_echarts_instance_") ? document.getElementById(chartId)
  168. .removeAttribute("_echarts_instance_") : ''
  169. chartIns.value = echartIns
  170. echartIns.setOption(option.value)
  171. window.addEventListener('resize', () => {
  172. echartIns.resize()
  173. })
  174. }
  175. </script>
  176. <template>
  177. <div :id="chartId" :style="{ height: props.height, width: props.width }"></div>
  178. </template>