1 package net.sf.statcvs.charts; 2 3 import java.awt.Color; 4 import java.awt.Dimension; 5 import java.awt.Paint; 6 import java.util.ArrayList; 7 import java.util.Collections; 8 import java.util.HashMap; 9 import java.util.Iterator; 10 import java.util.List; 11 import java.util.Map; 12 import java.util.SortedSet; 13 import java.util.Map.Entry; 14 15 import net.sf.statcvs.Messages; 16 import net.sf.statcvs.model.Author; 17 import net.sf.statcvs.model.Directory; 18 import net.sf.statcvs.model.Revision; 19 import net.sf.statcvs.model.VersionedFile; 20 import net.sf.statcvs.output.ReportConfig; 21 import net.sf.statcvs.pages.HTML; 22 import net.sf.statcvs.util.IntegerMap; 23 24 import org.jfree.chart.ChartFactory; 25 import org.jfree.chart.JFreeChart; 26 import org.jfree.chart.plot.PiePlot; 27 import org.jfree.data.general.DefaultPieDataset; 28 29 /** 30 * Class for producing directory pie charts 31 * @author jentzsch 32 * @author Richard Cyganiak (richard@cyganiak.de) 33 * @version $Id: DirectoryPieChartMaker.java,v 1.14 2009/08/21 23:06:51 benoitx Exp $ 34 */ 35 public abstract class DirectoryPieChartMaker { 36 private static final int SLICE_MIN_PERCENT = 5; 37 38 private final ReportConfig config; 39 private final String title; 40 private final String fileName; 41 private List directories = new ArrayList(); 42 private final String chartName; 43 44 /** 45 * Creates a new PieChartMaker 46 * @param config The report configuration to use 47 * @param directories The set of directories to consider 48 * @param title The chart title 49 * @param fileName The file name for chart 50 */ 51 public DirectoryPieChartMaker(final String chartName, final ReportConfig config, final SortedSet directories, final String title, final String fileName) { 52 this.chartName = chartName; 53 this.config = config; 54 this.title = title; 55 this.fileName = fileName; 56 this.directories = new ArrayList(directories); 57 } 58 59 public ChartImage toFile() { 60 final DefaultPieDataset data = new DefaultPieDataset(); 61 62 final IntegerMap dirSizes = new IntegerMap(); 63 Collections.sort(directories); 64 Iterator it = directories.iterator(); 65 while (it.hasNext()) { 66 final Directory dir = (Directory) it.next(); 67 dirSizes.addInt(dir, calculateValue(dir)); 68 } 69 70 int otherSum = 0; 71 final Map colors = new HashMap(); 72 it = dirSizes.iteratorSortedByValue(); 73 while (it.hasNext()) { 74 final Directory dir = (Directory) it.next(); 75 if (dirSizes.getPercent(dir) >= SLICE_MIN_PERCENT) { 76 final String dirName = dir.isRoot() ? "/" : dir.getPath(); 77 data.setValue(dirName, dirSizes.getInteger(dir)); 78 colors.put(dirName, ChartUtils.getStringColor(dirName)); 79 } else { 80 otherSum += dirSizes.get(dir); 81 } 82 } 83 data.setValue(Messages.getString("PIE_MODSIZE_OTHER"), new Integer(otherSum)); 84 colors.put(Messages.getString("PIE_MODSIZE_OTHER"), Color.GRAY); 85 86 final JFreeChart chart = ChartFactory.createPieChart(this.config.getProjectName() + ": " + title, data, false, false, false); 87 88 final PiePlot plot = (PiePlot) chart.getPlot(); 89 plot.setShadowPaint(null); 90 plot.setLabelShadowPaint(null); 91 plot.setLabelOutlinePaint(Color.LIGHT_GRAY); 92 plot.setForegroundAlpha(0.8f); 93 plot.setSectionOutlinePaint(Color.BLACK); 94 it = colors.entrySet().iterator(); 95 while (it.hasNext()) { 96 final Entry entry = (Entry) it.next(); 97 plot.setSectionPaint((String) entry.getKey(), (Paint) entry.getValue()); 98 } 99 100 plot.setBackgroundPaint(ChartConfigUtil.getPlotColor(chartName)); 101 chart.setBackgroundPaint(ChartConfigUtil.getBackgroundColor(chartName)); 102 ChartConfigUtil.configureCopyrightNotice(chartName, chart); 103 ChartConfigUtil.configureChartBackgroungImage(chartName, chart); 104 ChartConfigUtil.configurePlotImage(chartName, chart); 105 106 final Dimension dim = ChartConfigUtil.getDimension(chartName, config.getLargeChartSize()); 107 108 return this.config.createChartImage(this.fileName, this.title, chart, dim); 109 } 110 111 protected abstract int calculateValue(Directory directory); 112 113 public static class DirectorySizesChartMaker extends DirectoryPieChartMaker { 114 public DirectorySizesChartMaker(final ReportConfig config) { 115 super("directory_sizes", config, config.getRepository().getDirectories(), Messages.getString("PIE_DIRSIZE_SUBTITLE"), "directory_sizes.png"); 116 } 117 118 protected int calculateValue(final Directory directory) { 119 int result = 0; 120 final Iterator fileIt = directory.getFiles().iterator(); 121 while (fileIt.hasNext()) { 122 final VersionedFile element = (VersionedFile) fileIt.next(); 123 result += element.getCurrentLinesOfCode(); 124 } 125 return result; 126 } 127 } 128 129 public static class CodeDistributionChartMaker extends DirectoryPieChartMaker { 130 private static String getFileName(final Author author) { 131 return "directory_sizes_" + HTML.escapeAuthorName(author.getName()) + ".png"; 132 } 133 134 private final Author author; 135 136 public CodeDistributionChartMaker(final ReportConfig config, final Author author) { 137 super("directory_sizes", config, author.getDirectories(), Messages.getString("PIE_CODEDISTRIBUTION_SUBTITLE") + " " + author.getRealName(), 138 getFileName(author)); 139 this.author = author; 140 } 141 142 public ChartImage toFile() { 143 final Iterator it = this.author.getRevisions().iterator(); 144 int totalLinesOfCode = 0; 145 while (it.hasNext()) { 146 final Revision rev = (Revision) it.next(); 147 totalLinesOfCode += rev.getNewLines(); 148 } 149 if (totalLinesOfCode == 0) { 150 return null; 151 } 152 return super.toFile(); 153 } 154 155 protected int calculateValue(final Directory directory) { 156 int result = 0; 157 final Iterator it = directory.getRevisions().iterator(); 158 while (it.hasNext()) { 159 final Revision rev = (Revision) it.next(); 160 if (!this.author.equals(rev.getAuthor())) { 161 continue; 162 } 163 result += rev.getNewLines(); 164 } 165 return result; 166 } 167 } 168 }