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 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 ratingDistribution = MovieAnalyzer.analyzeRatingDistribution(movieList); for (Map.Entry entry : ratingDistribution.entrySet()) { System.out.printf("评分 %.1f: %d部\n", entry.getKey(), entry.getValue()); } // 电影年份分布(最近20年) System.out.println("\n=== 电影年份分布(最近20年)==="); Map yearDistribution = MovieAnalyzer.analyzeYearDistribution(movieList); int count = 0; for (Map.Entry 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 genreDistribution = MovieAnalyzer.analyzeGenreDistribution(movieList); genreDistribution.entrySet().stream() .sorted(Map.Entry.comparingByValue().reversed()) .limit(10) // 只显示前10种类型 .forEach(entry -> System.out.printf("%-10s: %d部\n", entry.getKey(), entry.getValue())); // 导演作品数量排行 System.out.println("\n=== 导演作品数量排行 ==="); Map directorWorks = MovieAnalyzer.analyzeDirectorWorks(movieList); count = 0; for (Map.Entry 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 yearRatingCorrelation = MovieAnalyzer.analyzeYearRatingCorrelation(movieList); for (Map.Entry entry : yearRatingCorrelation.entrySet()) { System.out.printf("%s年: 平均评分 %.2f\n", entry.getKey(), entry.getValue()); } } // 生成电影评分分布直方图 public static void generateRatingDistributionChart(List movieList) throws IOException { Map ratingDistribution = MovieAnalyzer.analyzeRatingDistribution(movieList); DefaultCategoryDataset dataset = new DefaultCategoryDataset(); for (Map.Entry 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 movieList) throws IOException { Map yearDistribution = MovieAnalyzer.analyzeYearDistribution(movieList); DefaultCategoryDataset dataset = new DefaultCategoryDataset(); System.out.println("年份分布数据:"); for (Map.Entry 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 movieList) throws IOException { Map genreDistribution = MovieAnalyzer.analyzeGenreDistribution(movieList); DefaultPieDataset dataset = new DefaultPieDataset(); // 只显示前10种类型 genreDistribution.entrySet().stream() .sorted(Map.Entry.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 movieList) throws IOException { Map yearRatingCorrelation = MovieAnalyzer.analyzeYearRatingCorrelation(movieList); DefaultCategoryDataset dataset = new DefaultCategoryDataset(); System.out.println("评分与年份相关性数据:"); for (Map.Entry 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"); } }