目录
一、数据源
二、后端API
package com.example.springbootdemo.web;
import com.hankcs.hanlp.HanLP;
import com.hankcs.hanlp.seg.common.Term;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.*;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;
@RestController
public class WordCloud {
@GetMapping("/wordcloud")
/**
* 获取词云
* @param type 好评,坏评
* @return 分词列表
*/
public List<Word> wordcloud(String type) {
String wordcloudPath = "F:\\Java-data\\ChnSentiCorp情感分析酒店评论\\wordcloud\\";
File wordcloudPathFile = new File(wordcloudPath);
if (!wordcloudPathFile.exists()) {
wordcloudPathFile.mkdirs();
}
File wordcloudFile = new File(wordcloudPath, type);
if (wordcloudFile.exists()) {
ObjectInputStream objectInputStream = null;
try {
objectInputStream = new ObjectInputStream(new FileInputStream(wordcloudFile));
LinkedList<Word> words = (LinkedList<Word>) objectInputStream.readObject();
if (words != null) {
return words;
}
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
} finally {
try {
objectInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
if (type.equals("")) {
return new ArrayList<>(0);
}
String path = "F:\\Java-data\\ChnSentiCorp情感分析酒店评论\\" + type;
File dir = new File(path);
File[] files = dir.listFiles(File::isFile);
StringBuilder text = new StringBuilder();
for (File file : files) {
try {
BufferedReader bufferedReader = new BufferedReader(new FileReader(file));
String line = bufferedReader.readLine();
line = line.replaceAll("[~!@#$%^&*()_+\\-*/.,\\.?/|\":;\\=]", "");
text.append(line);
} catch (IOException e) {
e.printStackTrace();
}
}
List<Term> segment = HanLP.segment(text.toString());
List<Term> segmentWord = segment.stream().filter(new Predicate<Term>() {
@Override
public boolean test(Term term) {
return term.nature.toString().equalsIgnoreCase("a");
}
}).collect(Collectors.toList());
List<String> segmentWordString = segmentWord.stream().map(term -> term.word).collect(Collectors.toList());
try {
List<String> stopWords = StopWorrUtil.loadStopWord("F:\\Java-data\\停留词.txt");
// 去停留词
segmentWordString.removeAll(stopWords);
} catch (IOException e) {
e.printStackTrace();
}
// 统计分词次数
LinkedList<Word> words = new LinkedList<>();
for (String word : segmentWordString) {
// 第一次循环
if (words.size() == 0) {
words.add(new Word(word, 1));
}
// 第2 - n 次循环
boolean exists = false;
Word word1 = null;
for (Word value : words) {
word1 = value;
if (word1.getName().equals(word)) {
exists = true;
break;
}
}
if (exists) {
word1.setValue(word1.getValue() + 1);
} else {
words.add(new Word(word, 1));
}
}
try {
ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream(wordcloudFile));
objectOutputStream.writeObject(words);
objectOutputStream.flush();
} catch (IOException e) {
e.printStackTrace();
}
return words;
}
}
三、后端测试
四、前端API
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>词云</title>
</head>
<body>
<div class="btn-group">
<button onclick="loadAndShowWordCloud('正面')" style="text-align: center; color: coral">正面</button>
<button onclick="loadAndShowWordCloud('负面')" style="text-align: center; color: coral">负面</button>
</div>
<div id="main" style="width: 500px; height: 500px"></div>
</body>
</html>
<script src="./js/echarts.min.js"></script>
<script src="./js/echarts-wordcloud.min.js"></script>
<script>
function loadAndShowWordCloud(type = '正面') {
var request = new XMLHttpRequest()
request.open('GET', '/wordcloud?type=' + type)
request.send()
request.onreadystatechange = function () {
if (request.readyState === 4) {
var chart = echarts.init(document.getElementById('main'));
chart.setOption({
series:
[{
type: 'wordCloud',
shape: 'star',
/**
* // 词云的形状,可选值有
* cardioid心形,diamond菱形,square正方形,
* triangle-forward指向右边的三角形,triangle-upright正三角形
* triangle三角形,pentagon五角形,star五角星形,
*/
keepAspect: false,
left: 'center',
top: 'center',
width: '100%',
height: '100%',
rotationStep: 90,
gridSize: 8,
drawOutOfBound: false,
shrinkToFit: false,
layoutAnimation: true,
textStyle: {
fontFamily: 'sans-serif',
fontWeight: 'bold',
// Color can be a callback function or a color string
color: function () {
// Random color
return 'rgb(' + [
Math.round(Math.random() * 160),
Math.round(Math.random() * 160),
Math.round(Math.random() * 160)
].join(',') + ')';
}
},
emphasis: {
focus: 'self',
textStyle: {
textShadowBlur: 10,
textShadowColor: '#333'
}
},
data: JSON.parse(request.responseText)
}]
});
}
}
}
loadAndShowWordCloud()
</script>