自学内容网 自学内容网

Vue3+Echarts+echarts-wordcloud插件创建词云图


在这里插入图片描述

这里主要记录一下,我在项目中使用到词云图的过程,用于学习使用,也方便后续在其他项目中使用。我创建的是vue3+vite+Element Plus的项目。

1、环境准备

我去echarts官网(https://echarts.apache.org/zh/index.html)看了一下,并没有找到词云图相关的内容,后面经过查找资料得知,echarts并没有词云图,要使用echarts实现词云图,需要安装一个插件echarts-wordcloud,这个插件是依托echarts的,所以在使用插件的时候也是需要安装echarts的,下面是安装的命令。

npm install echarts echarts-wordcloud

我这里的package.json环境如下所示

您那里的环境不一定非要跟我一样,我这里是vue3+vite+Element Plus的项目,只要项目中保证有echarts和echarts-wordcloud这环境即可。

{
  "name": "smart_mining_vue_cesium",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "preview": "vite preview"
  },
  "dependencies": {
    "axios": "^1.7.7",
    "echarts": "^5.5.1",
    "echarts-wordcloud": "^2.1.0",
    "element-plus": "^2.8.4",
    "vue": "^3.4.37",
    "vue-router": "^4.4.5"
  },
  "devDependencies": {
    "@vitejs/plugin-vue": "^5.1.2",
    "cesium": "^1.121.1",
    "vite": "^5.4.7",
    "vite-plugin-cesium": "^1.2.23"
  }
}

2、封装的组件WordCloud.vue

这个组件封装了图表的创建过程,直接引入使用即可。

<template>
    <div ref="chartRef" :style="{ width: width, height: height }"></div>
</template>

<script setup>
import { ref, onMounted, onBeforeUnmount, watch } from 'vue'
import * as echarts from 'echarts'
import 'echarts-wordcloud'

const props = defineProps({
    // 词云数据
    data: {
        type: Array,
        required: true
    },
    // 容器宽度
    width: {
        type: String,
        default: '100%'
    },
    // 容器高度
    height: {
        type: String,
        default: '300px'
    },
    // 文字大小范围
    sizeRange: {
        type: Array,
        default: () => [14, 30]
    },
    // 旋转角度范围
    rotationRange: {
        type: Array,
        default: () => [-45, 45]
    },
    // 自定义颜色数组
    colors: {
        type: Array,
        default: () => ['#5BE9FF', '#47FFFF', '#00F6EC', '#D4FFFD', '#4AEEFF']
    },
    // 形状
    shape: {
        type: String,
        default: 'circle'
    }
})

// 定义事件
const emit = defineEmits(['click'])

const chartRef = ref(null)
let chart = null

// 初始化词云图
const initChart = () => {
    if (!chartRef.value) return
    
    chart = echarts.init(chartRef.value)
    const option = {
        backgroundColor: 'transparent',
        tooltip: {
            show: true,
            formatter: '{b}: {c}',
            textStyle: {
                color: '#5BE9FF'
            },
            backgroundColor: 'rgba(0,0,0,0.7)',
            borderColor: '#5BE9FF',
            borderWidth: 1
        },
        series: [{
            type: 'wordCloud',
            shape: props.shape,
            left: 'center',
            top: 'center',
            width: '90%',
            height: '90%',
            sizeRange: props.sizeRange,
            rotationRange: props.rotationRange,
            rotationStep: 45,
            gridSize: 8,
            drawOutOfBound: false,
            textStyle: {
                fontFamily: 'sans-serif',
                fontWeight: 'bold',
                color: function () {
                    return props.colors[Math.floor(Math.random() * props.colors.length)]
                }
            },
            emphasis: {
                textStyle: {
                    shadowBlur: 10,
                    shadowColor: 'rgba(0, 255, 255, 0.5)'
                }
            },
            data: props.data.sort((a, b) => b.value - a.value)
        }]
    }
    
    chart.setOption(option)

    // 注册点击事件
    chart.on('click', (params) => {
        emit('click', {
            name: params.name,
            value: params.value,
            dataIndex: params.dataIndex,
            data: props.data[params.dataIndex]
        })
    })
}

// 处理窗口大小变化
const handleResize = () => {
    chart && chart.resize()
}

// 监听数据变化
watch(() => props.data, () => {
    initChart()
}, { deep: true })

onMounted(() => {
    initChart()
    window.addEventListener('resize', handleResize)
})

onBeforeUnmount(() => {
    if (chart) {
        chart.dispose()
        chart = null
    }
    window.removeEventListener('resize', handleResize)
})
</script> 

3、组件的使用方式

直接在组件中引入上面封装的组件,传入对应的数据就可以使用了。

<template>
  <div style="width: 100%; height: 100%; display: flex; justify-content: center; align-items: start; background-color:  rgba( 22, 50, 83, 0.5);">
    <div class="word-cloud-container">
      <WordCloud :data="wordCloudData" height="300px" :colors="['#5BE9FF', '#47FFFF', '#00F6EC', '#D4FFFD', '#4AEEFF']"
        @click="handleWordClick" />
    </div>
  </div>
</template>

<script setup>
import { onMounted, ref, watch, inject } from 'vue'
import WordCloud from '@/components/common/WordCloud.vue'
import { ElMessage } from 'element-plus'

const wordCloudData = [
  { id: 1, name: '露天矿', value: 30 },
  { id: 2, name: '地下矿', value: 25 },
  { id: 3, name: '采石场', value: 20 },
  { id: 4, name: '砂石料场', value: 18 },
  { id: 5, name: '尾矿库', value: 15 },
  { id: 6, name: '废石场', value: 12 },
  { id: 7, name: '选矿厂', value: 10 },
  { id: 8, name: '矿石加工', value: 8 },
  { id: 9, name: '矿山机械', value: 6 },
  { id: 10, name: '环境治理', value: 5 }
]

// 处理词云点击事件
const handleWordClick = (data) => {
  console.log('点击的词云数据:', data)
  ElMessage.info(`点击了: ${data.name},值为: ${data.value},ID为: ${data.data.id}`)
  // 这里可以根据 id 进行其他操作
  // 比如根据 id 查询详细数据
  // 或者根据 id 进行筛选等
}
</script>

<style scoped>
.word-cloud-container {
  width: 100%;
  margin: 20px 0;
  background: rgba(0, 0, 0, 0.2);
  border-radius: 4px;
}
</style>

4、结果如下所示

点击图表中某一项文字的时候,可以直接得到点击项的数据。
在这里插入图片描述


原文地址:https://blog.csdn.net/m0_62317155/article/details/144170765

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!