001: /*
002: * Hammurapi
003: * Automated Java code review system.
004: * Copyright (C) 2004 Johannes Bellert
005: *
006: * This program is free software; you can redistribute it and/or modify
007: * it under the terms of the GNU General Public License as published by
008: * the Free Software Foundation; either version 2 of the License, or
009: * (at your option) any later version.
010: *
011: * This program is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
014: * GNU General Public License for more details.
015: *
016: * You should have received a copy of the GNU General Public License
017: * along with this program; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
019: *
020: * URL: http://www.pavelvlasov.com/pv/content/menu.show?id=products.jtaste
021: * e-Mail: Johannes.Bellert@ercgroup.com
022: */
023: package org.hammurapi.inspectors.metrics.reporting;
024:
025: import java.awt.Color;
026: import java.awt.GradientPaint;
027:
028: import org.hammurapi.inspectors.metrics.statistics.DescriptiveStatistic;
029: import org.hammurapi.inspectors.metrics.statistics.IntVector;
030: import org.jfree.chart.ChartFactory;
031: import org.jfree.chart.ChartPanel;
032: import org.jfree.chart.JFreeChart;
033: import org.jfree.chart.axis.NumberAxis;
034: import org.jfree.chart.axis.ValueAxis;
035: import org.jfree.chart.plot.PlotOrientation;
036: import org.jfree.chart.plot.XYPlot;
037: import org.jfree.chart.renderer.xy.XYItemRenderer;
038: import org.jfree.data.DomainOrder;
039: import org.jfree.data.general.AbstractDataset;
040: import org.jfree.data.general.DatasetChangeListener;
041: import org.jfree.data.xy.IntervalXYDataset;
042: import org.jfree.ui.ApplicationFrame;
043: import org.jfree.ui.RefineryUtilities;
044:
045: //!! job variablize criteria and job Path program and for XSL
046: public class LocCharts extends ApplicationFrame {
047:
048: private IntVector locList = new IntVector();
049: IntVector distinctValues = new IntVector();
050: IntVector frequencies = new IntVector();
051: String chartName = "NA";
052: private int defectCriteria = 120;
053: private int graphicDimX = 500;
054: private int graphicDimY = 300;
055: private Integer chartDebugWindow;
056:
057: public LocCharts(String _chartName, int _defectCriteria,
058: IntVector _locList, Integer _chartDebugWindow) {
059: //!! job: Wrong super type .
060: super (_chartName);
061: chartName = _chartName;
062:
063: defectCriteria = _defectCriteria;
064: locList = _locList;
065: chartDebugWindow = _chartDebugWindow;
066: }
067:
068: public JFreeChart generateChart() {
069: JFreeChart chart;
070:
071: new DescriptiveStatistic().frequencies(locList, distinctValues,
072: frequencies);
073: //!! job: wrong method name and tailoring
074: chart = this .copyDeepXYSeries(distinctValues, frequencies);
075: // System.out.println( distinctValues );
076: // System.out.println( frequencies );
077: customizeChartBars(chart);
078: this .pack();
079:
080: if (chartDebugWindow.intValue() > 0) {
081: RefineryUtilities.centerFrameOnScreen(this );
082: this .setVisible(true);
083: }
084: return chart;
085: }
086:
087: private void customizeChartBars(JFreeChart chart) {
088: // NOW DO SOME OPTIONAL CUSTOMISATION OF THE CHART...
089: // set the background color for the chart...
090: chart.setBackgroundPaint(new Color(0xBBBBDD));
091: // get a reference to the plot for further customisation...
092: XYPlot plot = chart.getXYPlot();
093: // set the range axis to display integers only...
094: NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
095: rangeAxis.setStandardTickUnits(NumberAxis
096: .createIntegerTickUnits());
097: // disable bar outlines...
098: XYItemRenderer renderer = (XYItemRenderer) plot.getRenderer();
099: // renderer.ssetDrawBarOutline(false);
100: GradientPaint gp1 = new GradientPaint(0.0f, 0.0f, Color.green,
101: 0.0f, 0.0f, Color.lightGray);
102: GradientPaint gp2 = new GradientPaint(0.0f, 0.0f, Color.red,
103: 0.0f, 0.0f, Color.lightGray);
104: renderer.setSeriesPaint(0, gp1);
105: renderer.setSeriesPaint(1, gp2);
106: ValueAxis domainAxis = plot.getDomainAxis();
107: //domainAxis.setCategoryLabelPositions(CategoryLabelPositions.UP_90);
108: //domainAxis.setMaxCategoryLabelWidthRatio(5.0f);
109: // OPTIONAL CUSTOMISATION COMPLETED.
110: }
111:
112: private JFreeChart copyDeepXYSeries(IntVector distinctValues,
113: IntVector frequencies) {
114: IntervalXYDataset dataset = new LocIntervalXYDataset();
115: // create the chart...
116: JFreeChart chart = ChartFactory.createXYBarChart(chartName, // chart
117: // title
118: "NCSS", // domain axis label
119: "Occurance", // range axis label
120: dataset, // data
121: PlotOrientation.VERTICAL, true, // include legend
122: true, false);
123: // get a reference to the plot for further customisation...
124: XYPlot plot = chart.getXYPlot();
125: plot.setDomainAxis(new NumberAxis(
126: "Not Commented Source Statements"));
127: // add the chart to a panel...
128: ChartPanel chartPanel = new ChartPanel(chart);
129: chartPanel.setPreferredSize(new java.awt.Dimension(graphicDimX,
130: graphicDimY));
131: setContentPane(chartPanel);
132: return chart;
133: }
134:
135: class LocIntervalXYDataset extends AbstractDataset implements
136: IntervalXYDataset {
137: private int barWidth = -1;
138:
139: /**
140: * Creates a new dataset.
141: */
142: public LocIntervalXYDataset() {
143: super ();
144: }
145:
146: /**
147: * Returns the number of series in the dataset.
148: *
149: * @return the number of series in the dataset.
150: */
151: public int getSeriesCount() {
152: return 2;
153: }
154:
155: /**
156: * Returns the name of a series.
157: *
158: * @param series
159: * the series (zero-based index).
160: *
161: * @return the series name.
162: */
163: public String getSeriesName(int series) {
164: if (series == 0) {
165: return "Good";
166: } else if (series == 1) {
167: return "Defect";
168: }
169: return "N/A";
170: }
171:
172: /**
173: * Returns the number of items in a series.
174: *
175: * @param series
176: * the series (zero-based index).
177: *
178: * @return the number of items within a series.
179: */
180: public int getItemCount(int series) {
181: return distinctValues.size();
182: }
183:
184: /**
185: * Returns the x-value for an item within a series.
186: * <P>
187: * The implementation is responsible for ensuring that the x-values are
188: * presented in ascending order.
189: *
190: * @param series
191: * the series (zero-based index).
192: * @param item
193: * the item (zero-based index).
194: *
195: * @return the x-value for an item within a series.
196: */
197: public double getXValue(int series, int item) {
198: if (series == 0
199: && distinctValues.elementAt(item) < defectCriteria) {
200: // "Good";
201: return distinctValues.elementAt(item);
202: } else if (series == 1
203: && distinctValues.elementAt(item) > defectCriteria) {
204: // "Defect";
205: return distinctValues.elementAt(item);
206: }
207: return 0;
208: }
209:
210: /**
211: * Returns the y-value for an item within a series.
212: *
213: * @param series
214: * the series (zero-based index).
215: * @param item
216: * the item (zero-based index).
217: *
218: * @return the y-value for an item within a series.
219: */
220: public double getYValue(int series, int item) {
221: // return new Integer( frequencies.elementAt(item) );
222: if (series == 0
223: && distinctValues.elementAt(item) < defectCriteria) {
224: // "Good";
225: return frequencies.elementAt(item);
226: } else if (series == 1
227: && distinctValues.elementAt(item) >= defectCriteria) {
228: // "Defect";
229: return frequencies.elementAt(item);
230: }
231: return 0;
232: }
233:
234: /**
235: * Returns the starting X value for the specified series and item.
236: *
237: * @param series
238: * the series (zero-based index).
239: * @param item
240: * the item within a series (zero-based index).
241: *
242: * @return the start x value.
243: */
244: public double getStartXValue(int series, int item) {
245: //return new Integer( distinctValues.elementAt(item) ) ;
246: if (series == 0
247: && distinctValues.elementAt(item) < defectCriteria) {
248: // "Good";
249: return distinctValues.elementAt(item);
250: } else if (series == 1
251: && distinctValues.elementAt(item) > defectCriteria) {
252: // "Defect";
253: return distinctValues.elementAt(item);
254: }
255: return 0;
256: }
257:
258: /**
259: * Returns the ending X value for the specified series and item.
260: *
261: * @param series
262: * the series (zero-based index).
263: * @param item
264: * the item within a series (zero-based index).
265: *
266: * @return the end x value.
267: */
268: public double getEndXValue(int series, int item) {
269: barWidth = computeBarWidth();
270:
271: //!! job: compute bar width
272: if (series == 0
273: && distinctValues.elementAt(item) < defectCriteria) {
274: // "Good";
275: return distinctValues.elementAt(item) + barWidth;
276: } else if (series == 1
277: && distinctValues.elementAt(item) > defectCriteria) {
278: // "Defect";
279: return distinctValues.elementAt(item) + barWidth;
280: }
281: return 0;
282: }
283:
284: /*
285: * barWidth = 1 if MAX of distinctValues > 300 barWidth = 2 if MAX of
286: * distinctValues < 300 > 200 barWidth = 3 if MAX of distinctValues <
287: * 100
288: */
289: public int computeBarWidth() {
290: // lazy init
291: /* if (barWidth < 0) {
292: int max = distinctValues.elementAt(distinctValues.size() - 1);
293: if (max > 350) {
294: barWidth = 1;
295: };
296: if (max > 50 && max <= 350) {
297: barWidth = 2;
298: };
299: if (max <= 50) {
300: barWidth = 3;
301: };
302: // System.out.println(max + " barWidth " + barWidth);
303: *
304: */
305:
306: return 1;
307: }
308:
309: /**
310: * Returns the starting Y value for the specified series and item.
311: *
312: * @param series
313: * the series (zero-based index).
314: * @param item
315: * the item within a series (zero-based index).
316: *
317: * @return the start y value.
318: */
319: public double getStartYValue(int series, int item) {
320: // return new Integer( frequencies.elementAt(item) );
321: if (series == 0
322: && distinctValues.elementAt(item) < defectCriteria) {
323: // "Good";
324: return frequencies.elementAt(item);
325: } else if (series == 1
326: && distinctValues.elementAt(item) > defectCriteria) {
327: // "Defect";
328: return frequencies.elementAt(item);
329: }
330: return 0;
331: }
332:
333: /**
334: * Returns the ending Y value for the specified series and item.
335: *
336: * @param series
337: * the series (zero-based index).
338: * @param item
339: * the item within a series (zero-based index).
340: *
341: * @return the end y value.
342: */
343: public double getEndYValue(int series, int item) {
344: // return new Integer( frequencies.elementAt(item) );
345: if (series == 0
346: && distinctValues.elementAt(item) < defectCriteria) {
347: // "Good";
348: return frequencies.elementAt(item);
349: } else if (series == 1
350: && distinctValues.elementAt(item) > defectCriteria) {
351: // "Defect";
352: return frequencies.elementAt(item);
353: }
354: return 0;
355: }
356:
357: /**
358: * Registers an object for notification of changes to the dataset.
359: *
360: * @param listener
361: * the object to register.
362: */
363: public void addChangeListener(DatasetChangeListener listener) {
364: }
365:
366: /**
367: * Deregisters an object for notification of changes to the dataset.
368: *
369: * @param listener
370: * the object to deregister.
371: */
372: public void removeChangeListener(DatasetChangeListener listener) {
373:
374: }
375:
376: public Number getStartX(int series, int item) {
377: return new Double(getStartXValue(series, item));
378: }
379:
380: public Number getEndX(int series, int item) {
381: return new Double(getEndXValue(series, item));
382: }
383:
384: public Number getStartY(int series, int item) {
385: return new Double(getStartYValue(series, item));
386: }
387:
388: public Number getEndY(int series, int item) {
389: return new Double(getEndYValue(series, item));
390: }
391:
392: public DomainOrder getDomainOrder() {
393: return DomainOrder.ASCENDING;
394: }
395:
396: public Number getX(int series, int item) {
397: return new Double(getXValue(series, item));
398: }
399:
400: public Number getY(int series, int item) {
401: return new Double(getYValue(series, item));
402: }
403:
404: }
405:
406: /**
407: * @return Returns the graphicDimX.
408: */
409: public int getGraphicDimX() {
410: return graphicDimX;
411: }
412:
413: /**
414: * @param graphicDimX The graphicDimX to set.
415: */
416: public void setGraphicDimX(int graphicDimX) {
417: this .graphicDimX = graphicDimX;
418: }
419:
420: /**
421: * @return Returns the graphicDimY.
422: */
423: public int getGraphicDimY() {
424: return graphicDimY;
425: }
426:
427: /**
428: * @param graphicDimY The graphicDimY to set.
429: */
430: public void setGraphicDimY(int graphicDimY) {
431: this .graphicDimY = graphicDimY;
432: }
433:
434: /**
435: * @return Returns the chartName.
436: */
437: public String getChartName() {
438: return chartName;
439: }
440:
441: /**
442: * @return Returns the defectCriteria.
443: */
444: public int getDefectCriteria() {
445: return defectCriteria;
446: }
447:
448: /**
449: * @return Returns the distinctValues.
450: */
451: public IntVector getDistinctValues() {
452: return distinctValues;
453: }
454:
455: /**
456: * @return Returns the frequencies.
457: */
458: public IntVector getFrequencies() {
459: return frequencies;
460: }
461:
462: /**
463: * @return Returns the locList.
464: */
465: public IntVector getLocList() {
466: return locList;
467: }
468:
469: }
|