4766bd6e8c76b145c89a574789ee29dbce723d92.svn-base 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. <template>
  2. <div>
  3. <h4 :style="{ marginBottom: '20px' }" v-if="title">{{ title }}</h4>
  4. <v-chart :forceFit="true" :height="height" :data="data" :scale="scale" :padding="padding">
  5. <v-tooltip :showTitle="false" dataKey="type*percent" />
  6. <v-coord type="theta" :radius="0.5" />
  7. <v-pie position="percent" :color="field[0]" :label="label" :select="false" :vStyle="style" :tooltip="tooltip2" />
  8. <v-view :data="viewData" :scale="scale">
  9. <v-coord type="theta" :radius="0.75" :innerRadius="0.5 / 0.75" />
  10. <v-pie position="percent" :color="color" :label="labelConfig" :select="false" :vStyle="style" :tooltip="tooltip" />
  11. </v-view>
  12. </v-chart>
  13. </div>
  14. </template>
  15. <script>
  16. const DataSet = require('@antv/data-set')
  17. import { ChartEventMixins } from './mixins/ChartMixins'
  18. const color = ['#BAE7FF', '#7FC9FE', '#71E3E3', '#ABF5F5', '#8EE0A1', '#BAF5C4']
  19. const itemTpl = '<li><span style="background-color:{color};" class="g2-tooltip-marker"></span>{name}: {value}</li>'
  20. const tooltip = function(item, percent) {
  21. percent = (percent * 100).toFixed(2) + '%'
  22. return {
  23. name: item,
  24. value: percent
  25. }
  26. }
  27. export default {
  28. name: 'PieMultiStorey',
  29. mixins: [ChartEventMixins],
  30. props: {
  31. title: {
  32. type: String,
  33. default: ''
  34. },
  35. height: {
  36. type: Number,
  37. default: 300
  38. },
  39. field: {
  40. type: Array,
  41. default: () => ['type', 'name']
  42. },
  43. xField: {
  44. type: String,
  45. default: 'value'
  46. },
  47. dataSource: {
  48. type: Array,
  49. default: () => [
  50. { value: 251, type: '大事例一', name: '子事例一' },
  51. { value: 1048, type: '大事例一', name: '子事例二' },
  52. { value: 610, type: '大事例二', name: '子事例三' },
  53. { value: 434, type: '大事例二', name: '子事例四' },
  54. { value: 335, type: '大事例三', name: '' },
  55. { value: 250, type: '大事例三', name: '' }
  56. ]
  57. }
  58. },
  59. data() {
  60. return {
  61. scale: [{
  62. dataKey: 'percent',
  63. min: 0,
  64. formatter: '.0%'
  65. }],
  66. dataKey: this.field[0] + '*percent',
  67. color: [this.field[1], color],
  68. itemTpl,
  69. label: [this.field[0], { offset: -10 }],
  70. style: {
  71. lineWidth: 1,
  72. stroke: '#fff'
  73. },
  74. tooltip: [
  75. this.field[1] + '*percent', tooltip
  76. ],
  77. tooltip2: [
  78. this.field[0] + '*percent', (item, percent) => {
  79. percent = (percent * 100).toFixed(2) + '%'
  80. return {
  81. name: item + ',' + this.getTotalData[item],
  82. value: percent
  83. }
  84. }
  85. ],
  86. padding: { top: 0, right: 0, bottom: 0, left: 0 },
  87. labelConfig: ['percent', {
  88. formatter: (val, item) => {
  89. return item.point[this.field[1]] + ': ' + item.point[this.xField] + ', ' + val
  90. }
  91. }]
  92. }
  93. },
  94. computed: {
  95. data() {
  96. const dv = new DataSet.View().source(this.dataSource)
  97. dv.transform({
  98. type: 'percent',
  99. field: this.xField,
  100. dimension: this.field[0],
  101. as: 'percent'
  102. })
  103. return dv.rows
  104. },
  105. viewData() {
  106. const viewDv = new DataSet.View().source(this.dataSource)
  107. viewDv.transform({
  108. type: 'percent',
  109. field: this.xField,
  110. dimension: this.field[1],
  111. as: 'percent'
  112. })
  113. return viewDv.rows
  114. },
  115. getTotalData() {
  116. const obj = {}
  117. this.dataSource.forEach(item => {
  118. const key = item[this.field[0]]
  119. if (obj[key]) {
  120. obj[key] += item[this.xField]
  121. } else {
  122. obj[key] = item[this.xField]
  123. }
  124. })
  125. return obj
  126. }
  127. },
  128. methods() {
  129. }
  130. }
  131. </script>