diff --git a/src/vue2/src/components/features/WordCloud.vue b/src/vue2/src/components/features/WordCloud.vue new file mode 100644 index 0000000..01db806 --- /dev/null +++ b/src/vue2/src/components/features/WordCloud.vue @@ -0,0 +1,165 @@ + + + + + \ No newline at end of file diff --git a/src/vue2/src/main.js b/src/vue2/src/main.js index ef1fbb5..87569ba 100644 --- a/src/vue2/src/main.js +++ b/src/vue2/src/main.js @@ -12,11 +12,15 @@ import * as XLSX from 'xlsx' import Papa from 'papaparse' import _ from 'lodash' +// 确保echarts可以全局访问 Vue.prototype.$echarts = echarts Vue.prototype.$xlsx = XLSX Vue.prototype.$papa = Papa Vue.prototype.$_ = _ +// 移除错误的注册方式 +// echarts.use(require('echarts-wordcloud')) + Vue.use(ElementUI) Vue.config.productionTip = false diff --git a/src/vue2/src/utils/wordcloud.js b/src/vue2/src/utils/wordcloud.js index d9460c3..f8bae76 100644 --- a/src/vue2/src/utils/wordcloud.js +++ b/src/vue2/src/utils/wordcloud.js @@ -1,12 +1,158 @@ // 词云可视化(Cirrus)相关功能模块 // 负责词云数据生成、处理与可视化配置 -export function generateWordCloudData(text) { - // TODO: 实现分词与词频统计,返回词云数据结构 - return []; +// 中文常用停用词列表 +const STOPWORDS = ['的', '了', '在', '是', '我', '有', '和', '就', '不', '人', '都', '一', '一个', '上', '也', '很', '到', '说', '要', '去', '你', '会', '着', '没有', '看', '好', '自己', '这']; + +/** + * 生成词云数据 + * @param {string} text 输入文本 + * @param {number} limit 最大词数 + * @returns {Array} 词云数据数组 + */ +export function generateWordCloudData(text, limit = 100) { + if (!text) return []; + + // 简单分词 (仅用于示例,实际项目建议使用专业分词库) + let words = text + .replace(/[^\w\u4e00-\u9fa5]/g, ' ') + .split(/\s+/) + .filter(w => w && w.length > 1 && !STOPWORDS.includes(w)); + + // 统计词频 + const freq = {}; + words.forEach(w => { + freq[w] = (freq[w] || 0) + 1; + }); + + // 转为数组并按频率排序 + let arr = Object.entries(freq) + .map(([text, value]) => ({ text, value })) + .sort((a, b) => b.value - a.value) + .slice(0, limit); + + return arr; +} + +/** + * 获取示例词云数据 + * @returns {Array} 示例词云数据 + */ +export function getSampleWordCloudData() { + return [ + { text: '航空', value: 120 }, + { text: '航班', value: 98 }, + { text: '飞机', value: 85 }, + { text: '数据', value: 76 }, + { text: '分析', value: 65 }, + { text: '系统', value: 60 }, + { text: '处理', value: 55 }, + { text: '可视化', value: 50 }, + { text: '统计', value: 48 }, + { text: '机场', value: 45 }, + { text: '旅客', value: 40 }, + { text: '信息', value: 38 }, + { text: '服务', value: 36 }, + { text: '航线', value: 34 }, + { text: '出发', value: 32 }, + { text: '到达', value: 30 }, + { text: '延误', value: 28 }, + { text: '安全', value: 26 }, + { text: '乘客', value: 25 }, + { text: '行李', value: 24 }, + { text: '票价', value: 22 }, + { text: '订票', value: 20 }, + { text: '登机', value: 18 }, + { text: '起飞', value: 16 }, + { text: '降落', value: 15 }, + { text: '国际', value: 45 }, + { text: '航空公司', value: 75 }, + { text: '时刻表', value: 35 }, + { text: '客运', value: 28 }, + { text: '联程', value: 23 }, + { text: '机组', value: 22 }, + { text: '头等舱', value: 19 }, + { text: '商务舱', value: 17 }, + { text: '经济舱', value: 15 }, + { text: '转机', value: 32 }, + { text: '值机', value: 26 } + ]; } -export function getWordCloudOptions(data) { - // TODO: 返回词云图表的配置项 - return {}; +/** + * 获取词云配置 + * @param {Array} data 词云数据 + * @param {Object} options 自定义配置 + * @returns {Object} ECharts配置项 + */ +export function getWordCloudOptions(data, options = {}) { + const defaultOptions = { + sizeRange: [14, 60], + rotationRange: [-90, 90], + shape: 'circle', + fontFamily: '"Microsoft YaHei", "微软雅黑", Arial, sans-serif', + colorMode: 'random' // 'random' 或 'gradient' + }; + + const mergedOptions = { ...defaultOptions, ...options }; + + // 颜色函数 + let colorFunction; + if (mergedOptions.colorMode === 'random') { + const colors = [ + '#1890FF', '#2FC25B', '#FACC14', '#223273', '#8543E0', + '#13C2C2', '#3436C7', '#F04864', '#EE6666', '#749F83', + '#CA8622', '#409EFF', '#36CBCB', '#FFA74D', '#4B7AF0' + ]; + colorFunction = function(params) { + return colors[Math.abs(params.data.text.charCodeAt(0)) % colors.length]; + }; + } else { + // 渐变色 + colorFunction = function(params) { + // 根据值大小返回不同深浅的颜色 + const maxValue = data.length > 0 ? data[0].value : 100; + const ratio = params.data.value / maxValue; + // 从蓝色到红色的渐变 + const r = Math.round(255 * ratio); + const b = Math.round(255 * (1 - ratio)); + return `rgb(${r}, 100, ${b})`; + }; + } + + return { + series: [{ + type: 'wordCloud', + shape: mergedOptions.shape, + left: 'center', + top: 'center', + width: '90%', + height: '90%', + sizeRange: mergedOptions.sizeRange, + rotationRange: mergedOptions.rotationRange, + rotationStep: 45, + gridSize: 8, + drawOutOfBound: false, + textStyle: { + fontFamily: mergedOptions.fontFamily, + fontWeight: 'bold', + color: colorFunction + }, + emphasis: { + textStyle: { + fontWeight: 'bold', + shadowBlur: 10, + shadowColor: '#333' + } + }, + // 新增动画配置 + layoutAnimation: true, + animationDuration: 1000, + animationEasing: 'cubicOut', + animationDelay: function (idx) { + return idx * 100; + }, + data: data + }] + }; } \ No newline at end of file diff --git a/src/vue2/src/views/Statistics.vue b/src/vue2/src/views/Statistics.vue index 23d9e3b..1ec164b 100644 --- a/src/vue2/src/views/Statistics.vue +++ b/src/vue2/src/views/Statistics.vue @@ -6,40 +6,20 @@
-

词云可视化 (Cirrus)

+

词云可视化

- +
- - -
-
- -
词云图将显示在这里
-
-
-
- -
- - - - -
-
- - - -
+
+ +
@@ -181,11 +161,24 @@