第一种
<template>
<div class='word-box'>
<!-- 第一种 -->
<svg :width='width' :height='height' @mousemove='listener($event)'>
<a href="#" v-for='(tag, index) in tags' :key="index" style="background:red">
<text :x='tag.x' :y='tag.y' :font-size='14 * (600 / (600 - tag.z))' :fill-opacity='((400 + tag.z) / 600)'
:fill='tag.color'>{{ tag.text }}</text>
</a>
</svg>
</div>
</template>
<script>
export default {
name: "wordCloud",
props: {
word: {
type: Array,
default: () => {
return [
{
wordName: '好吃',
wordValue: 18
},
{
wordName: '美味',
wordValue: 5
},
{
wordName: '物美价廉',
wordValue: 7
},
{
wordName: '好吃',
wordValue: 18
},
{
wordName: '美味',
wordValue: 15
},
{
wordName: '物美价廉',
wordValue: 2
},
{
wordName: '好吃',
wordValue: 18
},
{
wordName: '美味',
wordValue: 15
},
{
wordName: '物美价廉',
wordValue: 2
},
{
wordName: '物美价廉',
wordValue: 2
},
{
wordName: '好吃',
wordValue: 18
},
{
wordName: '美味',
wordValue: 15
},
{
wordName: '物美价廉',
wordValue: 2
},
{
wordName: '物美价廉',
wordValue: 2
},
{
wordName: '好吃',
wordValue: 18
},
{
wordName: '美味',
wordValue: 15
},
{
wordName: '物美价廉',
wordValue: 2
},
]
}
},
},
data () {
return {
width: 600,
height: 400,
tagsNum: 20,
RADIUS: 160,
speedX: Math.PI / 360,
speedY: Math.PI / 360,
tags: [],
};
},
components: {},
computed: {
CX () {
return this.width / 2;
},
CY () {
return this.height / 2;
},
},
created () {
setInterval(() => {
this.rotateX(this.speedX);
this.rotateY(this.speedY);
}, 17);
},
watch: {
word: {
handler (val) {
console.log(val);
this.setWord();
},
deep: true,
immediate: true
},
},
methods: {
rotateX (angleX) {
var cos = Math.cos(angleX);
var sin = Math.sin(angleX);
for (let tag of this.tags) {
var y1 = (tag.y - this.CY) * cos - tag.z * sin + this.CY;
var z1 = tag.z * cos + (tag.y - this.CY) * sin;
tag.y = y1;
tag.z = z1;
}
},
rotateY (angleY) {
var cos = Math.cos(angleY);
var sin = Math.sin(angleY);
for (let tag of this.tags) {
var x1 = (tag.x - this.CX) * cos - tag.z * sin + this.CX;
var z1 = tag.z * cos + (tag.x - this.CX) * sin;
tag.x = x1;
tag.z = z1;
}
},
setWord () {
let tags = [];
this.word.forEach((ele, i) => {
let tag = {};
let k = -1 + (2 * (i + 1) - 1) / this.tagsNum;
let a = Math.acos(k);
let b = a * Math.sqrt(this.tagsNum * Math.PI);
tag.text = ele.wordName;
tag.x = this.CX + this.RADIUS * Math.sin(a) * Math.cos(b);
tag.y = this.CY + this.RADIUS * Math.sin(a) * Math.sin(b);
tag.z = this.RADIUS * (ele.wordValue / 10);
tag.color = this.rgb();
tag.size = ele.wordValue;
tags.push(tag);
});
this.tags = tags;
},
listener (event) {
var x = event.clientX - this.CX;
var y = event.clientY - this.CY;
this.speedX =
x * 0.0001 > 0
? Math.min(this.RADIUS * 0.00002, x * 0.0001)
: Math.max(-this.RADIUS * 0.00002, x * 0.0001);
this.speedY =
y * 0.0001 > 0
? Math.min(this.RADIUS * 0.00002, y * 0.0001)
: Math.max(-this.RADIUS * 0.00002, y * 0.0001);
},
rgb () {
var r = Math.floor(Math.random() * 256);
var g = Math.floor(Math.random() * 256);
var b = Math.floor(Math.random() * 256);
var color = "#" + r.toString(16) + g.toString(16) + b.toString(16);
return color;
},
},
};
</script>
<style lang='scss' scoped>
.word-box {
display: flex;
justify-content: center;
width: 600px;
margin: 200px auto;
background: #ccc;
}
.word-cloud {
height: 500px;
width: 1100px;
}
</style>
第二种
<template>
<div class='word-box'>
<div id="word" ref="word-box" class='word-cloud'></div>
</div>
</template>
<script>
import * as echarts from "echarts";
import "echarts-wordcloud/dist/echarts-wordcloud";
import "echarts-wordcloud/dist/echarts-wordcloud.min.js";
export default {
name: "wordCloud",
props: {
word: {
type: Array,
default: () => {
return [
{
wordName: '好吃',
wordValue: 18
},
{
wordName: '美味',
wordValue: 5
},
{
wordName: '物美价廉',
wordValue: 7
},
{
wordName: '好吃',
wordValue: 18
},
{
wordName: '美味',
wordValue: 15
},
{
wordName: '物美价廉',
wordValue: 2
},
{
wordName: '好吃',
wordValue: 18
},
{
wordName: '美味',
wordValue: 15
},
{
wordName: '物美价廉',
wordValue: 2
},
{
wordName: '物美价廉',
wordValue: 2
},
{
wordName: '好吃',
wordValue: 18
},
{
wordName: '美味',
wordValue: 15
},
{
wordName: '物美价廉',
wordValue: 2
},
{
wordName: '物美价廉',
wordValue: 2
},
{
wordName: '好吃',
wordValue: 18
},
{
wordName: '美味',
wordValue: 15
},
{
wordName: '物美价廉',
wordValue: 2
},
]
}
},
},
data () {
return {};
},
mounted () {
this.setWord()
},
watch: {
word: {
handler (val) {
this.setWord();
},
deep: true,
},
},
methods: {
setWord () {
let wordList = this.word.map((res) => {
return { value: res.wordValue, name: res.wordName };
});
let a = this.$refs["word-box"];
let myChart2 = echarts.init(a);
myChart2.setOption({
series: [
{
type: "wordCloud",
gridSize: 10,
sizeRange: [14, 60],
rotationRange: [-90, 90],
textStyle: {
fontFamily: "sans-serif",
fontWeight: "bold",
color: function () {
return (
"rgb(" +
[
Math.round(Math.random() * 160),
Math.round(Math.random() * 160),
Math.round(Math.random() * 160),
].join(",") +
")"
);
},
},
emphasis: {
focus: "self",
textStyle: {
shadowBlur: 10,
shadowColor: "#333",
},
},
left: "center",
top: "center",
right: null,
bottom: null,
width: "200%",
height: "200%",
data: wordList,
},
],
});
myChart2.on("click", function (params) {
alert(params.name);
});
},
},
};
</script>
<style lang='scss' scoped>
.word-box {
display: flex;
justify-content: center;
width: 100%;
}
.word-cloud {
height: 500px;
width: 1100px;
}
</style>