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 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
@@ -181,11 +161,24 @@