View Javadoc

1   /*
2       StatCvs - CVS statistics generation 
3       Copyright (C) 2002  Lukasz Pekacki <lukasz@pekacki.de>
4       http://statcvs.sf.net/
5       
6       This library is free software; you can redistribute it and/or
7       modify it under the terms of the GNU Lesser General Public
8       License as published by the Free Software Foundation; either
9       version 2.1 of the License, or (at your option) any later version.
10  
11      This library is distributed in the hope that it will be useful,
12      but WITHOUT ANY WARRANTY; without even the implied warranty of
13      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14      Lesser General Public License for more details.
15  
16      You should have received a copy of the GNU Lesser General Public
17      License along with this library; if not, write to the Free Software
18      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19      
20  	Created on $Date: 2008/04/02 11:22:15 $ 
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   * Produces the commit scatter chart.
58   * @author jentzsch
59   * @author Richard Cyganiak (richard@cyganiak.de)
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       * Creates a new CommitScatterChartMaker.
69       * @param repository The repository to be analyzed
70       * @param width The width of the chart in pixels
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       * @return An image file for the chart
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 }