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

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");
}
}