DayAndHourChart.vue 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. <template>
  2. <div class="cart-item">
  3. <slot name="title" />
  4. <v-chart
  5. :option="option"
  6. :init-options="{ height: 400 }"
  7. autoresize
  8. style="width: 100%; height: 100%"
  9. v-show="option.dataset.some((item) => item.source.length > 0)"
  10. />
  11. <el-empty :image="emptyImg" v-show="!option.dataset.some((item) => item.source && item.source.length > 0)">
  12. <template v-slot:description>&nbsp;</template>
  13. </el-empty>
  14. </div>
  15. </template>
  16. <script lang="ts">
  17. import { Vue, Component, Prop, Watch } from 'vue-property-decorator'
  18. import { IStatisticsDayNHour } from '../api/common'
  19. import emptyImg from '@/assets/icon/null.png'
  20. import { IPointTarget } from '../../configuration/api/common'
  21. @Component({ name: 'ChartItem' })
  22. export default class ChartItem extends Vue {
  23. @Prop({ type: String }) title!: string
  24. @Prop({ type: Object, default: () => ({}) }) data!: IStatisticsDayNHour
  25. @Prop({ type: Array, default: () => [] }) standards!: IPointTarget['showVos']
  26. @Prop({ type: String, default: 'rfallTotal' }) rainfallKey!: string
  27. emptyImg = emptyImg
  28. getCodeName(code) {
  29. const { targetName } = this.standards.find((item) => item.targetCode === code) || {}
  30. return targetName || code
  31. }
  32. get option() {
  33. const { datas = [], rainFallVos = [] } = this.data
  34. const dataset = [
  35. {
  36. id: 'rainfall',
  37. source: (rainFallVos || []).filter((item) => !!item[this.rainfallKey])
  38. },
  39. ...datas.map(({ checkCode, statisticalData }) => ({
  40. id: checkCode,
  41. source: statisticalData
  42. }))
  43. ]
  44. const series = dataset
  45. .map(({ id }, index) => {
  46. return index === 0
  47. ? {
  48. name: '降雨量',
  49. dimensions: ['xposition', this.rainfallKey],
  50. datasetIndex: index,
  51. type: 'line',
  52. symbol: 'circle',
  53. smooth: true,
  54. yAxisIndex: 1
  55. }
  56. : [
  57. { name: 'maxValue', displayName: '最大值' },
  58. { name: 'avgValue', displayName: '平均值' },
  59. { name: 'minValue', displayName: '最小值' }
  60. ].map((item, typeIndex) => {
  61. return {
  62. name: `${this.getCodeName(id)}-${item.displayName}`,
  63. dimensions: ['xposition', item],
  64. datasetIndex: index,
  65. type: 'line',
  66. symbol: { '0': 'emptyCircle', '1': 'rect', '2': 'triangle' }[String(typeIndex)],
  67. smooth: true,
  68. yAxisIndex: 0
  69. }
  70. })
  71. })
  72. .flat()
  73. return {
  74. tooltip: { trigger: 'axis' },
  75. calculable: true,
  76. xAxis: [
  77. {
  78. type: 'category',
  79. boundaryGap: false,
  80. data: [
  81. ...new Set(
  82. dataset.map((item) => (item.source as { xposition: string }[]).map((item) => item.xposition)).flat()
  83. )
  84. ].sort((a, b) => {
  85. const reg = /(?<=\d{4}年)(\d)(?=月)/
  86. const left = a.replace(reg, `0$1`)
  87. const right = b.replace(reg, `0$1`)
  88. return left.localeCompare(right)
  89. })
  90. }
  91. ],
  92. yAxis: [
  93. { type: 'value', boundaryGap: false },
  94. {
  95. type: 'value',
  96. boundaryGap: false,
  97. inverse: true,
  98. alignTicks: true,
  99. position: 'right',
  100. name: '降雨量',
  101. nameLocation: 'start'
  102. }
  103. ],
  104. dataZoom: dataset.some(({ source }) => source.length > 100) && [
  105. { type: 'inside', start: 0, end: 100 },
  106. { start: 0, end: 100 }
  107. ],
  108. legend: { show: true, type: 'scroll', width: '80%' },
  109. grid: { top: 45, left: 45, right: 45, bottom: 45, containLabel: true },
  110. toolbox: { show: true, feature: { restore: { show: true }, saveAsImage: { show: true } } },
  111. dataset,
  112. series
  113. }
  114. }
  115. @Watch('option')
  116. log(val) {
  117. console.log(val)
  118. }
  119. }
  120. </script>
  121. <style lang="scss"></style>