package hudson.plugins.rubyMetrics; import hudson.model.AbstractBuild; import hudson.model.HealthReport; import hudson.model.HealthReportingAction; import hudson.model.Result; import hudson.util.ChartUtil; import hudson.util.ColorPalette; import hudson.util.DataSetBuilder; import hudson.util.ShiftedCategoryAxis; import java.awt.BasicStroke; import java.awt.Color; import java.io.IOException; import java.util.Calendar; import org.jfree.chart.ChartFactory; import org.jfree.chart.JFreeChart; import org.jfree.chart.axis.CategoryAxis; import org.jfree.chart.axis.CategoryLabelPositions; import org.jfree.chart.axis.NumberAxis; import org.jfree.chart.plot.CategoryPlot; import org.jfree.chart.plot.PlotOrientation; import org.jfree.chart.renderer.category.LineAndShapeRenderer; import org.jfree.chart.title.LegendTitle; import org.jfree.data.category.CategoryDataset; import org.jfree.ui.RectangleEdge; import org.jfree.ui.RectangleInsets; import org.kohsuke.stapler.StaplerRequest; import org.kohsuke.stapler.StaplerResponse; @SuppressWarnings("unchecked") public abstract class AbstractRubyMetricsBuildAction implements HealthReportingAction { protected final AbstractBuild<?, ?> owner; protected AbstractRubyMetricsBuildAction(AbstractBuild<?, ?> owner) { this.owner = owner; } public <T extends AbstractRubyMetricsBuildAction>T getPreviousResult() { AbstractBuild<?, ?> b = owner; while (true) { b = b.getPreviousBuild(); if (b == null) return null; if (b.getResult() == Result.FAILURE) continue; AbstractRubyMetricsBuildAction r = b.getAction(this.getClass()); if (r != null) return (T) r; } } protected abstract DataSetBuilder<String, ChartUtil.NumberOnlyBuildLabel> getDataSetBuilder(); public void doGraph(StaplerRequest req, StaplerResponse rsp) throws IOException { if (ChartUtil.awtProblemCause != null) { rsp.sendRedirect2(req.getContextPath() + "/images/headless.png"); return; } Calendar t = owner.getTimestamp(); if (req.checkIfModified(t, rsp)) { return; // up to date } ChartUtil.generateGraph(req, rsp, createChart(getDataSetBuilder().build(), getRangeAxisLabel()), 500, 200); } private JFreeChart createChart(CategoryDataset dataset, String rangeAxisLabel) { final JFreeChart chart = ChartFactory.createLineChart( null, // chart title null, // unused rangeAxisLabel, // range axis label dataset, // data PlotOrientation.VERTICAL, // orientation true, // include legend true, // tooltips false // urls ); // NOW DO SOME OPTIONAL CUSTOMISATION OF THE CHART... final LegendTitle legend = chart.getLegend(); legend.setPosition(RectangleEdge.RIGHT); chart.setBackgroundPaint(Color.white); final CategoryPlot plot = chart.getCategoryPlot(); // plot.setAxisOffset(new Spacer(Spacer.ABSOLUTE, 5.0, 5.0, 5.0, 5.0)); plot.setBackgroundPaint(Color.WHITE); plot.setOutlinePaint(null); plot.setRangeGridlinesVisible(true); plot.setRangeGridlinePaint(Color.black); CategoryAxis domainAxis = new ShiftedCategoryAxis(null); plot.setDomainAxis(domainAxis); domainAxis.setCategoryLabelPositions(CategoryLabelPositions.UP_90); domainAxis.setLowerMargin(0.0); domainAxis.setUpperMargin(0.0); domainAxis.setCategoryMargin(0.0); final NumberAxis rangeAxis = getRangeAxis(plot); final LineAndShapeRenderer renderer = (LineAndShapeRenderer) plot.getRenderer(); renderer.setBaseStroke(new BasicStroke(2.0f)); ColorPalette.apply(renderer); // crop extra space around the graph plot.setInsets(new RectangleInsets(5.0, 0, 0, 5.0)); return chart; } public AbstractBuild<?, ?> getOwner() { return owner; } protected NumberAxis getRangeAxis(CategoryPlot plot) { NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis(); rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits()); rangeAxis.setUpperBound(100); rangeAxis.setLowerBound(0); return rangeAxis; } protected String getRangeAxisLabel() { return ""; } public HealthReport getBuildHealth() { // TODO Auto-generated method stub return null; } public String getIconFileName() { return "graph.gif"; } }