inleft
2022-03-01 88f419df77ade235ea5e5e24be204842a24b7b33
commit | author | age
9bcb19 1 <template>
I 2   <v-chart :width="width" :height="height" :padding="[0]" :data="data" :scale="scale">
3     <v-tooltip :show-title="false" />
4     <v-coord type="rect" direction="TL" />
5     <v-point position="x*y" color="category" shape="cloud" tooltip="value*category" />
6   </v-chart>
7 </template>
8
9 <script>
10 import { registerShape } from 'viser-vue'
11 const DataSet = require('@antv/data-set')
12
13 const imgUrl = 'https://gw.alipayobjects.com/zos/rmsportal/gWyeGLCdFFRavBGIDzWk.png'
14
15 const scale = [
16   { dataKey: 'x', nice: false },
17   { dataKey: 'y', nice: false }
18 ]
19
20 registerShape('point', 'cloud', {
21   draw (cfg, container) {
22     return container.addShape('text', {
23       attrs: {
24         fillOpacity: cfg.opacity,
25         fontSize: cfg.origin._origin.size,
26         rotate: cfg.origin._origin.rotate,
27         text: cfg.origin._origin.text,
28         textAlign: 'center',
29         fontFamily: cfg.origin._origin.font,
30         fill: cfg.color,
31         textBaseline: 'Alphabetic',
32         ...cfg.style,
33         x: cfg.x,
34         y: cfg.y
35       }
36     })
37   }
38 })
39
40 export default {
41   name: 'TagCloud',
42   props: {
43     tagList: {
44       type: Array,
45       required: true
46     },
47     height: {
48       type: Number,
49       default: 400
50     },
51     width: {
52       type: Number,
53       default: 640
54     }
55   },
56   data () {
57     return {
58       data: [],
59       scale
60     }
61   },
62   watch: {
63     tagList: function (val) {
64       if (val.length > 0) {
65         this.initTagCloud(val)
66       }
67     }
68   },
69   mounted () {
70     if (this.tagList.length > 0) {
71       this.initTagCloud(this.tagList)
72     }
73   },
74   methods: {
75     initTagCloud (dataSource) {
76       const { height, width } = this
77
78       const dv = new DataSet.View().source(dataSource)
79       const range = dv.range('value')
80       const min = range[0]
81       const max = range[1]
82       const imageMask = new Image()
83       imageMask.crossOrigin = ''
84       imageMask.src = imgUrl
85       imageMask.onload = () => {
86         dv.transform({
87           type: 'tag-cloud',
88           fields: ['name', 'value'],
89           size: [width, height],
90           imageMask,
91           font: 'Verdana',
92           padding: 0,
93           timeInterval: 5000, // max execute time
94           rotate () {
95             let random = ~~(Math.random() * 4) % 4
96             if (random === 2) {
97               random = 0
98             }
99             return random * 90 // 0, 90, 270
100           },
101           fontSize (d) {
102             if (d.value) {
103               return ((d.value - min) / (max - min)) * (32 - 8) + 8
104             }
105             return 0
106           }
107         })
108         this.data = dv.rows
109       }
110     }
111   }
112 }
113 </script>