实践|自定义形状的词云
一、前言
tips1:我捣鼓半天才发现,keepAspect 保持maskImage的纵横比或1:1的形状,这个选项是在 echarts-wordcloud 2.1.0 才支持,今天是2022年4月22日,目前默认安装的版本号仍是2.0.0,2.1.0还是beta版本,npm 安装需要指定版本。
tips2:最好给容器元素显性的写一个合适的高度,而且这个版本(@2.1.0beta)似乎对高度大小要求,这可能和使用了keepAspect:true,以及背景图宽高有关,但我并不确定,因为我给容器元素写height:200px时,词云没能正常渲染出来,没报错,改为height:400px词云才能正常渲染出来,反复测试多次,依然如此。
此外,以前就安装了 echarts,现在才安装 echarts-wordcloud 的尤其需要注意, echarts-wordcloud 版本为2的对应的是 echarts 版本为5系列, echarts-wordcloud 版本为1的对应的是 echarts 版本为4的系列。
使用 echarts-wordcloud 生成的词云,能达到效果:
1.色彩:不同词语使用不同颜色。
2.排版:还可以根据按照图形的形状排版, 例如爱形状,大树现状,小jin鱼等,你提供普通的png图形,echarts-wordcloud 就会自动按照图形范围分布词语。
3.大小:按照词语不同的系数频率值,生成不同的字体大小效果。
4.其他
二、效果图
从左到右,图1:心形背景效果图,图2:小jin鱼背景效果图
三、使用实践小结
1.安装 echarts 和 echarts-wordcloud
安装方式一:可以是 npm 或 yarn 导入
// 此时 echarts-wordcloud 的2.1.0还是beta版本,
// 但想启用keepAspect,所以指定@2.1.0-beta版本
npm 命令安装
npm install echarts -s
npm install echarts-wordcloud@2.1.0-beta -s
yarn 命令安装
npm install echarts -s
yarn add echarts-wordcloud@2.1.0-beta -s
安装方式二:也可以是脚本引入的方式
<script src="echarts.min.js"></script>
<script src="echarts-wordcloud.min.js"></script>
2.引入 echarts 和 echarts-wordcloud
tips:可以在 入口文件做全局引入,例如在 main.js 引入,也可以在局部按需引入, 这边建议在使用到的地方,按需引入即可。
import * as echarts from 'echarts';
import 'echarts-wordcloud';
四、完整 demo 示例
<template>
<div>
<h1>测试 词云</h1>
<div id="main" style="height: 800px"></div>
</div>
</template>
<script>
import * as echarts from 'echarts'
import 'echarts-wordcloud'
// 引入背景图,后面赋值给 maskImage
import circleImg from '../assets/circle.png'
import treeImg from '../assets/tree.png'
import whaleImg from '../assets/whale.png'
export default {
name: 'EchartsWordCloud',
mounted () {
this.init()
},
methods: {
init () {
const chart = echarts.init(document.getElementById('main'))
// 词汇请自行添加
const keywords = {
'词汇1': 12199,
'词汇2': 10288,
}
let data = []
for (let name in keywords) {
data.push({
name: name,
value: Math.sqrt(keywords[name])
})
}
const maskImage = new Image()
// 下面一些翻译是借助翻译工具翻译的,可能不够准确,但我主要是自用够用就行。
// 也可能是不是翻译,而是自我需要的备注,请注意这点,避免误解。
const option = {
series: [{
// echarts 类型
type: 'wordCloud',
// 字体大小范围。默认最小12px,最大60px大小。
// Text size range which the value in data will be mapped to.
// Default to have minimum 12px and maximum 60px size.
sizeRange: [4, 150],
// [0, 0] 词不旋转,步长为0。
// 文字旋转范围和步进度。文本将在[0,0]范围内由rotationStep 0 随机旋转。
rotationRange: [0, 0],
// 词旋转步长
rotationStep: 0,
// 网格大小以像素为单位,用于标记画布的可用性,网格大小越大,词之间的间隙越大。
// size of the grid in pixels for marking the availability of the canvas
// the larger the grid size, the bigger the gap between words.
gridSize: 5,
// 把“云”的形状画出来。可以是任何表示为回调函数的极坐标方程,也可以是present的关键字。
// 有圆形(默认)、心形(苹果或心形曲线,最著名的极坐标方程)、菱形(正方形的别名)、正三角形、
// 三角形、(直三角形、五边形、星形的别名)。
// The shape of the "cloud" to draw. Can be any polar equation represented as a
// callback function, or a keyword present. Available presents are circle (default),
// cardioid (apple or heart shape curve, the most known polar equation), diamond (
// alias of square), triangle-forward, triangle, (alias of triangle-upright, pentagon, and star.
shape: 'pentagon',
// 背景图,可自定义背景图,词云会按照背景图的范围分布。比如背景图是一个心形,
// 那么词云足够多的时候就会形成一个心形。
// A silhouette image which the white area will be excluded from drawing texts.
// The shape option will continue to apply as the shape of the cloud to grow.
maskImage: maskImage,
// 设置为true,允许词超出画布范围。允许词大于画布的尺寸被绘制。
// set to true to allow word being draw partly outside of the canvas.
// Allow word bigger than the size of the canvas to be drawn
drawOutOfBound: false,
// 是否开启动画效果
// If perform layout animation.
// NOTE disable it will lead to UI blocking when there is lots of words.
layoutAnimation: false,
// 保持maskImage的纵横比或1:1的形状这个选项是支持的echarts-wordcloud@2.1.0
// Keep aspect ratio of maskImage or 1:1 for shapes
// This option is supported from echarts-wordcloud@2.1.0
keepAspect: true,
// 全局设置词的样式
// Global text style
textStyle: {
fontWeight: 'bold',
// 配色函数制定配色机制: Math.round() 和 Math.random() 随机给词配色
color: function () {
return 'rgb(' + [
Math.round(Math.random() * 200) + 50,
Math.round(Math.random() * 50),
Math.round(Math.random() * 50) + 50
].join(',') + ')'
}
},
emphasis: {
textStyle: {
color: '#528'
}
},
// 数据是一个数组,每个数据项必须包含 name 和 value 属性。name是词,value是词的系数(频率)。
// 每个数据项还支持 textStyle,给单个词自定义文本样式
// Data is an array. Each array item must have name and value property.
data: data.sort(function (a, b) {
return b.value - a.value
})
}]
}
maskImage.onload = function () {
chart.setOption(option)
}
// 放在 public 的img资源使用绝对路径引入有效,或先 import 引入图片资源,再赋值也有效。
// maskImage.src = '/img/circle.png'
// circleImg:爱心背景,树形背景:treeImg,jin鱼背景:whaleImg
maskImage.src = whaleImg
// 注意,在 vue src 内部中,这种直接通过相对地址引入的方式,是无效的,maskImage.onload 会加载失败,
// 不会进入onload的回调函数,因此在onload回调里面调用echarts初始化是无效的,因为根本不会进入到这里。
// maskImage.src = './circle.png';
let timer = null
// 设备视口大小改变时,重置 echarts
window.onresize = function () {
// 简单的防抖动处理
clearTimeout(timer)
timer = setTimeout(() => {
console.log(timer)
chart.resize()
}, 500)
}
}
}
}
</script>