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