dvCapsuleChart.vue 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. <template>
  2. <div class="dv-capsule-chart">
  3. <template v-if="mergedConfig">
  4. <div class="label-column">
  5. <div v-for="item in mergedConfig.data" :key="item.name" style="cursor: pointer" @click="getEventList(item)">
  6. {{ item.name }}
  7. </div>
  8. <div>&nbsp;</div>
  9. </div>
  10. <div class="capsule-container">
  11. <div class="capsule-item" v-for="(capsule, index) in capsuleLength" :key="index" style="cursor: pointer" @click="getEventList(mergedConfig.data[index])">
  12. <div
  13. class="capsule-item-column"
  14. :style="`width: ${capsule * 100}%; background-color: ${mergedConfig.colors[index % mergedConfig.colors.length]};`"
  15. >
  16. <div
  17. v-if="mergedConfig.showValue"
  18. class="capsule-item-value"
  19. >{{ capsuleValue[index] }}
  20. </div>
  21. </div>
  22. </div>
  23. <div class="unit-label">
  24. <div
  25. v-for="(label, index) in labelData"
  26. :key="label + index"
  27. >{{ label }}
  28. </div>
  29. </div>
  30. </div>
  31. <div class="unit-text" v-if="mergedConfig.unit">{{ mergedConfig.unit }}</div>
  32. </template>
  33. </div>
  34. </template>
  35. <script>
  36. import {deepMerge} from '@jiaminghi/charts/lib/util/index'
  37. import {deepClone} from '@jiaminghi/c-render/lib/plugin/util'
  38. export default {
  39. name: 'DvCapsuleChart',
  40. props: {
  41. config: {
  42. type: Object,
  43. default: () => ({})
  44. }
  45. },
  46. data() {
  47. return {
  48. defaultConfig: {
  49. /**
  50. * @description Capsule chart data
  51. * @type {Array<Object>}
  52. * @default data = []
  53. * @example data = [{ name: 'foo1', value: 100 }, { name: 'foo2', value: 100 }]
  54. */
  55. data: [],
  56. /**
  57. * @description Colors (hex|rgb|rgba|color keywords)
  58. * @type {Array<String>}
  59. * @default color = ['#37a2da', '#32c5e9', '#67e0e3', '#9fe6b8', '#ffdb5c', '#ff9f7f', '#fb7293']
  60. * @example color = ['#000', 'rgb(0, 0, 0)', 'rgba(0, 0, 0, 1)', 'red']
  61. */
  62. colors: [
  63. '#37a2da',
  64. '#32c5e9',
  65. '#67e0e3',
  66. '#9fe6b8',
  67. '#ffdb5c',
  68. '#ff9f7f',
  69. '#fb7293'
  70. ],
  71. /**
  72. * @description Chart unit
  73. * @type {String}
  74. * @default unit = ''
  75. */
  76. unit: '',
  77. /**
  78. * @description Show item value
  79. * @type {Boolean}
  80. * @default showValue = false
  81. */
  82. showValue: false
  83. },
  84. mergedConfig: null,
  85. capsuleLength: [],
  86. capsuleValue: [],
  87. labelData: [],
  88. labelDataLength: []
  89. }
  90. },
  91. watch: {
  92. config() {
  93. const {calcData} = this
  94. calcData()
  95. }
  96. },
  97. methods: {
  98. getEventList(val) {
  99. debugger
  100. let args = {eventTypeIdDl: [], eventTypeId: []}
  101. if (val.id != '0') {
  102. args.eventTypeIdDl.push(-1)
  103. args.eventTypeId.push(val.id)
  104. } else {
  105. args.eventTypeIdDl.push(val.parentId)
  106. args.eventTypeId.push(-1)
  107. }
  108. this.$emit('setEventTypeId', args)
  109. },
  110. calcData() {
  111. const {mergeConfig, calcCapsuleLengthAndLabelData} = this
  112. mergeConfig()
  113. calcCapsuleLengthAndLabelData()
  114. },
  115. mergeConfig() {
  116. let {config, defaultConfig} = this
  117. this.mergedConfig = deepMerge(
  118. deepClone(defaultConfig, true),
  119. config || {}
  120. )
  121. },
  122. calcCapsuleLengthAndLabelData() {
  123. const {data} = this.mergedConfig
  124. if (!data.length) return
  125. const capsuleValue = data.map(({value}) => value)
  126. const maxValue = Math.max(...capsuleValue)
  127. this.capsuleValue = capsuleValue
  128. this.capsuleLength = capsuleValue.map(v => (maxValue ? v / maxValue : 0))
  129. const oneFifth = maxValue / 5
  130. const labelData = Array.from(
  131. new Set(new Array(6).fill(0).map((v, i) => Math.ceil(i * oneFifth)))
  132. )
  133. this.labelData = labelData
  134. this.labelDataLength = Array.from(labelData).map(v =>
  135. maxValue ? v / maxValue : 0
  136. )
  137. }
  138. },
  139. mounted() {
  140. const {calcData} = this
  141. calcData()
  142. }
  143. }
  144. </script>