实践|自定义形状的词云

3,191 阅读2分钟

实践|自定义形状的词云

一、前言

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鱼背景效果图

image.png

三、使用实践小结

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>