You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
216 lines
9.1 KiB
216 lines
9.1 KiB
package com.crawler.ui;
|
|
|
|
import com.crawler.analysis.MovieAnalyzer;
|
|
import com.crawler.model.Movie;
|
|
import org.jfree.chart.ChartFactory;
|
|
import org.jfree.chart.ChartUtils;
|
|
import org.jfree.chart.JFreeChart;
|
|
import org.jfree.chart.plot.PlotOrientation;
|
|
import org.jfree.data.category.DefaultCategoryDataset;
|
|
import org.jfree.data.general.DefaultPieDataset;
|
|
import org.jfree.data.statistics.HistogramDataset;
|
|
import org.jfree.chart.plot.PiePlot;
|
|
import org.jfree.chart.labels.StandardPieSectionLabelGenerator;
|
|
import java.text.DecimalFormat;
|
|
import java.text.NumberFormat;
|
|
|
|
import java.io.File;
|
|
import java.io.IOException;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
|
|
public class MovieResultDisplay {
|
|
// 控制台输出统计结果
|
|
public static void displayResults(List<Movie> movieList) {
|
|
System.out.println("\n=== 电影数据统计结果 ===");
|
|
System.out.println("爬取电影总数: " + movieList.size());
|
|
|
|
// 平均评分
|
|
double averageRating = MovieAnalyzer.calculateAverageRating(movieList);
|
|
System.out.printf("平均评分: %.2f\n", averageRating);
|
|
|
|
// 电影评分分布
|
|
System.out.println("\n=== 电影评分分布 ===");
|
|
Map<Double, Integer> ratingDistribution = MovieAnalyzer.analyzeRatingDistribution(movieList);
|
|
for (Map.Entry<Double, Integer> entry : ratingDistribution.entrySet()) {
|
|
System.out.printf("评分 %.1f: %d部\n", entry.getKey(), entry.getValue());
|
|
}
|
|
|
|
// 电影年份分布(最近20年)
|
|
System.out.println("\n=== 电影年份分布(最近20年)===");
|
|
Map<String, Integer> yearDistribution = MovieAnalyzer.analyzeYearDistribution(movieList);
|
|
int count = 0;
|
|
for (Map.Entry<String, Integer> entry : yearDistribution.entrySet()) {
|
|
if (count >= yearDistribution.size() - 20) { // 只显示最近20年
|
|
System.out.printf("%s年: %d部\n", entry.getKey(), entry.getValue());
|
|
}
|
|
count++;
|
|
}
|
|
|
|
// 电影类型分布
|
|
System.out.println("\n=== 电影类型分布 ===");
|
|
Map<String, Integer> genreDistribution = MovieAnalyzer.analyzeGenreDistribution(movieList);
|
|
genreDistribution.entrySet().stream()
|
|
.sorted(Map.Entry.<String, Integer>comparingByValue().reversed())
|
|
.limit(10) // 只显示前10种类型
|
|
.forEach(entry -> System.out.printf("%-10s: %d部\n", entry.getKey(), entry.getValue()));
|
|
|
|
// 导演作品数量排行
|
|
System.out.println("\n=== 导演作品数量排行 ===");
|
|
Map<String, Integer> directorWorks = MovieAnalyzer.analyzeDirectorWorks(movieList);
|
|
count = 0;
|
|
for (Map.Entry<String, Integer> entry : directorWorks.entrySet()) {
|
|
if (count < 10) { // 只显示前10位导演
|
|
System.out.printf("%-20s: %d部\n", entry.getKey(), entry.getValue());
|
|
count++;
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
|
|
// 评分与年份相关性
|
|
System.out.println("\n=== 评分与年份相关性 ===");
|
|
Map<String, Double> yearRatingCorrelation = MovieAnalyzer.analyzeYearRatingCorrelation(movieList);
|
|
for (Map.Entry<String, Double> entry : yearRatingCorrelation.entrySet()) {
|
|
System.out.printf("%s年: 平均评分 %.2f\n", entry.getKey(), entry.getValue());
|
|
}
|
|
}
|
|
|
|
// 生成电影评分分布直方图
|
|
public static void generateRatingDistributionChart(List<Movie> movieList) throws IOException {
|
|
Map<Double, Integer> ratingDistribution = MovieAnalyzer.analyzeRatingDistribution(movieList);
|
|
DefaultCategoryDataset dataset = new DefaultCategoryDataset();
|
|
|
|
for (Map.Entry<Double, Integer> entry : ratingDistribution.entrySet()) {
|
|
dataset.addValue(entry.getValue(), "Count", entry.getKey().toString());
|
|
}
|
|
|
|
JFreeChart chart = ChartFactory.createBarChart(
|
|
"Movie Rating Distribution",
|
|
"Rating",
|
|
"Count",
|
|
dataset,
|
|
PlotOrientation.VERTICAL,
|
|
true,
|
|
true,
|
|
false
|
|
);
|
|
|
|
ChartUtils.saveChartAsPNG(new File("movie_rating_distribution.png"), chart, 800, 600);
|
|
System.out.println("电影评分分布图表已保存为 movie_rating_distribution.png");
|
|
}
|
|
|
|
// 生成电影年份分布折线图
|
|
public static void generateYearDistributionChart(List<Movie> movieList) throws IOException {
|
|
Map<String, Integer> yearDistribution = MovieAnalyzer.analyzeYearDistribution(movieList);
|
|
DefaultCategoryDataset dataset = new DefaultCategoryDataset();
|
|
|
|
System.out.println("年份分布数据:");
|
|
for (Map.Entry<String, Integer> entry : yearDistribution.entrySet()) {
|
|
System.out.println("年份: '" + entry.getKey() + "', 数量: " + entry.getValue());
|
|
// 尝试提取年份数字
|
|
String year = entry.getKey();
|
|
// 提取4位数字作为年份
|
|
String yearMatch = year.replaceAll("[^0-9]", "");
|
|
if (yearMatch.length() >= 4) {
|
|
yearMatch = yearMatch.substring(0, 4);
|
|
dataset.addValue(entry.getValue(), "Count", yearMatch);
|
|
}
|
|
}
|
|
|
|
JFreeChart chart = ChartFactory.createLineChart(
|
|
"Movie Year Distribution",
|
|
"Year",
|
|
"Count",
|
|
dataset,
|
|
PlotOrientation.VERTICAL,
|
|
true,
|
|
true,
|
|
false
|
|
);
|
|
|
|
ChartUtils.saveChartAsPNG(new File("movie_year_distribution.png"), chart, 800, 600);
|
|
System.out.println("电影年份分布图表已保存为 movie_year_distribution.png");
|
|
}
|
|
|
|
// 生成电影类型分布饼图
|
|
public static void generateGenreDistributionChart(List<Movie> movieList) throws IOException {
|
|
Map<String, Integer> genreDistribution = MovieAnalyzer.analyzeGenreDistribution(movieList);
|
|
DefaultPieDataset dataset = new DefaultPieDataset();
|
|
|
|
// 只显示前10种类型
|
|
genreDistribution.entrySet().stream()
|
|
.sorted(Map.Entry.<String, Integer>comparingByValue().reversed())
|
|
.limit(10)
|
|
.forEach(entry -> {
|
|
// 使用英文标签避免中文显示问题
|
|
String englishLabel = getEnglishGenre(entry.getKey()) + " (" + entry.getValue() + ")";
|
|
dataset.setValue(englishLabel, entry.getValue());
|
|
});
|
|
|
|
JFreeChart chart = ChartFactory.createPieChart(
|
|
"Movie Genre Distribution", // 使用英文标题
|
|
dataset,
|
|
true, // 显示图例
|
|
true, // 显示工具提示
|
|
false // 不显示URL
|
|
);
|
|
|
|
ChartUtils.saveChartAsPNG(new File("movie_genre_distribution.png"), chart, 800, 600);
|
|
System.out.println("电影类型分布图表已保存为 movie_genre_distribution.png");
|
|
}
|
|
|
|
// 将中文类型转换为英文
|
|
private static String getEnglishGenre(String chineseGenre) {
|
|
switch (chineseGenre) {
|
|
case "冒险": return "Adventure";
|
|
case "奇幻": return "Fantasy";
|
|
case "爱情": return "Romance";
|
|
case "惊悚": return "Thriller";
|
|
case "动画": return "Animation";
|
|
case "悬疑": return "Mystery";
|
|
case "家庭": return "Family";
|
|
case "犯罪": return "Crime";
|
|
case "同性": return "LGBTQ+";
|
|
case "历史": return "History";
|
|
case "剧情": return "Drama";
|
|
case "动作": return "Action";
|
|
case "喜剧": return "Comedy";
|
|
case "科幻": return "Sci-Fi";
|
|
default: return chineseGenre;
|
|
}
|
|
}
|
|
|
|
// 生成评分与年份相关性图表
|
|
public static void generateYearRatingChart(List<Movie> movieList) throws IOException {
|
|
Map<String, Double> yearRatingCorrelation = MovieAnalyzer.analyzeYearRatingCorrelation(movieList);
|
|
DefaultCategoryDataset dataset = new DefaultCategoryDataset();
|
|
|
|
System.out.println("评分与年份相关性数据:");
|
|
for (Map.Entry<String, Double> entry : yearRatingCorrelation.entrySet()) {
|
|
System.out.println("年份: '" + entry.getKey() + "', 平均评分: " + entry.getValue());
|
|
// 尝试提取年份数字
|
|
String year = entry.getKey();
|
|
// 提取4位数字作为年份
|
|
String yearMatch = year.replaceAll("[^0-9]", "");
|
|
if (yearMatch.length() >= 4) {
|
|
yearMatch = yearMatch.substring(0, 4);
|
|
dataset.addValue(entry.getValue(), "Avg Rating", yearMatch);
|
|
}
|
|
}
|
|
|
|
JFreeChart chart = ChartFactory.createLineChart(
|
|
"Year vs Rating Correlation",
|
|
"Year",
|
|
"Average Rating",
|
|
dataset,
|
|
PlotOrientation.VERTICAL,
|
|
true,
|
|
true,
|
|
false
|
|
);
|
|
|
|
ChartUtils.saveChartAsPNG(new File("movie_year_rating.png"), chart, 800, 600);
|
|
System.out.println("评分与年份相关性图表已保存为 movie_year_rating.png");
|
|
}
|
|
}
|