1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package net.sf.statcvs.charts;
23
24 import java.awt.Color;
25 import java.awt.Dimension;
26 import java.awt.Font;
27 import java.awt.Rectangle;
28 import java.text.DecimalFormat;
29 import java.util.ArrayList;
30 import java.util.Calendar;
31 import java.util.Collections;
32 import java.util.Date;
33 import java.util.Iterator;
34 import java.util.List;
35 import java.util.SortedSet;
36
37 import net.sf.statcvs.Messages;
38 import net.sf.statcvs.model.Author;
39 import net.sf.statcvs.model.Repository;
40 import net.sf.statcvs.model.Revision;
41 import net.sf.statcvs.output.ReportConfig;
42
43 import org.jfree.chart.JFreeChart;
44 import org.jfree.chart.annotations.XYAnnotation;
45 import org.jfree.chart.axis.DateAxis;
46 import org.jfree.chart.axis.NumberAxis;
47 import org.jfree.chart.axis.NumberTickUnit;
48 import org.jfree.chart.plot.CombinedDomainXYPlot;
49 import org.jfree.chart.plot.XYPlot;
50 import org.jfree.chart.renderer.xy.StandardXYItemRenderer;
51 import org.jfree.chart.renderer.xy.XYItemRenderer;
52 import org.jfree.data.time.Second;
53 import org.jfree.data.time.TimeSeries;
54 import org.jfree.data.time.TimeSeriesCollection;
55
56
57
58
59
60
61 public class CommitScatterChartMaker {
62 private final static Color ALL_COMMITS_COLOR = new Color(128, 128, 255);
63 private final ReportConfig config;
64 private final Repository repository;
65 private final int width;
66
67
68
69
70
71
72 public CommitScatterChartMaker(final ReportConfig config, final int width) {
73 this.config = config;
74 this.repository = config.getRepository();
75 this.width = width;
76 }
77
78
79
80
81 public ChartImage toFile() {
82 final DateAxis timeAxis = new DateAxis(Messages.getString("TIME_CSC_DOMAIN"));
83 timeAxis.setVerticalTickLabels(true);
84 final CombinedDomainXYPlot combinedPlot = new CombinedDomainXYPlot(timeAxis);
85 List annotations = SymbolicNameAnnotation.createAnnotations(repository.getSymbolicNames());
86 combinedPlot.add(createPlot(createTimeSeries(this.repository.getRevisions()), "All (" + Messages.getString("TIME_CSC_RANGE") + ")", ALL_COMMITS_COLOR,
87 annotations));
88 annotations = SymbolicNameAnnotation.createAnnotations(repository.getSymbolicNames(), SymbolicNameAnnotation.STYLE_NO_LABELS);
89 final List authors = new ArrayList(this.repository.getAuthors());
90 Collections.sort(authors);
91 final Iterator it = authors.iterator();
92 while (it.hasNext()) {
93 final Author author = (Author) it.next();
94 final Color color = this.config.isDeveloper(author) ? Color.RED : Color.GRAY;
95 combinedPlot.add(createPlot(createTimeSeries(author.getRevisions()), author.getName(), color, annotations));
96 }
97 combinedPlot.setGap(10);
98 final JFreeChart chart = new JFreeChart(this.config.getProjectName() + ": " + Messages.getString("TIME_CSC_SUBTITLE"), JFreeChart.DEFAULT_TITLE_FONT,
99 combinedPlot, false);
100 return this.config.createChartImage("commitscatterauthors.png", Messages.getString("TIME_CSC_SUBTITLE"), chart, getSize());
101 }
102
103 private TimeSeries createTimeSeries(final SortedSet revisions) {
104 final TimeSeries result = new TimeSeries("Dummy", Second.class);
105 final Iterator it = revisions.iterator();
106 Date lastDate = new Date();
107 while (it.hasNext()) {
108 final Revision rev = (Revision) it.next();
109 if (lastDate != null) {
110 final Calendar cal = Calendar.getInstance();
111 cal.setTime(lastDate);
112 final double lastDateSeconds = cal.get(Calendar.SECOND);
113 cal.setTime(rev.getDate());
114 final double dateSeconds = cal.get(Calendar.SECOND);
115 if (lastDateSeconds == dateSeconds) {
116 continue;
117 }
118 }
119 lastDate = rev.getDate();
120 final Calendar cal = Calendar.getInstance();
121 cal.setTime(lastDate);
122 final double hour = cal.get(Calendar.HOUR_OF_DAY);
123 final double minutes = cal.get(Calendar.MINUTE);
124 result.add(new Second(lastDate), hour + minutes / 60.0);
125 }
126 return result;
127 }
128
129 private XYPlot createPlot(final TimeSeries series, final String label, final Color color, final List annotations) {
130 final NumberAxis valueAxis = new NumberAxis(label);
131 valueAxis.setTickUnit(new NumberTickUnit(6.0, new DecimalFormat("0")));
132 valueAxis.setAutoRangeIncludesZero(false);
133 valueAxis.setRange(0.0, 24.0);
134 valueAxis.setLabelFont(new Font("SansSerif", Font.PLAIN, 9));
135 final XYItemRenderer renderer = new StandardXYItemRenderer(StandardXYItemRenderer.SHAPES);
136 renderer.setShape(new Rectangle(new Dimension(2, 2)));
137 final XYPlot result = new XYPlot(new TimeSeriesCollection(series), null, valueAxis, renderer);
138 result.getRenderer().setSeriesPaint(0, color);
139 final Iterator it = annotations.iterator();
140 while (it.hasNext()) {
141 final XYAnnotation annotation = (XYAnnotation) it.next();
142 result.addAnnotation(annotation);
143 }
144 return result;
145 }
146
147 private Dimension getSize() {
148 return new Dimension(this.width, 70 * (this.repository.getAuthors().size() + 1) + 110);
149 }
150 }