hudson.graph.jfreechart.JFreeChartSupport.java Source code

Java tutorial

Introduction

Here is the source code for hudson.graph.jfreechart.JFreeChartSupport.java

Source

/*
 * The MIT License
 *
 * Copyright 2011 Winston.Prakash@oracle.com
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
package hudson.graph.jfreechart;

import hudson.util.ColorPalette;
import hudson.util.StackedAreaRenderer2;
import hudson.util.ShiftedCategoryAxis;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.chart.ChartRenderingInfo;
import org.jfree.chart.ChartUtilities;
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.StackedAreaRenderer;
import org.jfree.data.category.CategoryDataset;
import org.jfree.ui.RectangleInsets;

import hudson.Extension;
import org.eclipse.hudson.graph.ChartLabel;
import org.eclipse.hudson.graph.DataSet;
import org.eclipse.hudson.graph.Graph;
import org.eclipse.hudson.graph.GraphSupport;
import org.eclipse.hudson.graph.GraphSupportDescriptor;
import org.eclipse.hudson.graph.MultiStageTimeSeries;
import java.awt.BasicStroke;
import java.awt.image.BufferedImage;
import java.awt.Color;
import java.awt.Paint;
import java.util.List;
import java.util.TreeSet;
import java.util.logging.Logger;
import org.jfree.chart.renderer.category.LineAndShapeRenderer;
import org.kohsuke.stapler.DataBoundConstructor;

/**
 * JFreeChart Support for Hudson Graph Support
 * @author Winston Prakash
 */
public class JFreeChartSupport extends GraphSupport {

    private static final Logger LOGGER = Logger.getLogger(JFreeChartSupport.class.getName());
    private JFreeChart jFreeChart;
    private ChartRenderingInfo info = new ChartRenderingInfo();
    private DefaultCategoryDataset dataset = new DefaultCategoryDataset();
    private String chartTitle;
    private String xAxisLabel;
    private String yAxisLabel;
    public List<MultiStageTimeSeries> multiStageTimeSeries;

    private int chartType = Graph.TYPE_STACKED_AREA; // 1 - StackedArea, 2 - Line, 3 - StackedBar

    @DataBoundConstructor
    public JFreeChartSupport() {
    }

    public void setChartType(int chartType) {
        this.chartType = chartType;
    }

    public void setTitle(String title) {
        chartTitle = title;
    }

    @Override
    public void setXAxisLabel(String xLabel) {
        xAxisLabel = xLabel;
    }

    @Override
    public void setYAxisLabel(String yLabel) {
        yAxisLabel = yLabel;
    }

    public void setMultiStageTimeSeries(List<MultiStageTimeSeries> multiStageTimeSeries) {
        this.multiStageTimeSeries = multiStageTimeSeries;
    }

    public JFreeChart createChart() {

        if (chartType == Graph.TYPE_STACKED_AREA) {
            jFreeChart = ChartFactory.createStackedAreaChart(null, // chart
                    chartTitle, // // title 
                    xAxisLabel, // range axis label
                    dataset, // data
                    PlotOrientation.VERTICAL, // orientation
                    false, // include legend
                    true, // tooltips
                    false // urls
            );
        } else if (chartType == Graph.TYPE_LINE) {
            jFreeChart = ChartFactory.createLineChart(null, // chart title
                    chartTitle, // // title 
                    xAxisLabel, // range axis label
                    dataset, // data
                    PlotOrientation.VERTICAL, // orientation
                    true, // include legend
                    true, // tooltips
                    false // urls
            );
        }

        jFreeChart.setBackgroundPaint(Color.white);

        final CategoryPlot plot = jFreeChart.getCategoryPlot();

        // plot.setAxisOffset(new Spacer(Spacer.ABSOLUTE, 5.0, 5.0, 5.0, 5.0));
        plot.setBackgroundPaint(Color.WHITE);
        plot.setOutlinePaint(null);
        plot.setForegroundAlpha(0.8f);
        // plot.setDomainGridlinesVisible(true);
        // plot.setDomainGridlinePaint(Color.white);
        plot.setRangeGridlinesVisible(true);
        plot.setRangeGridlinePaint(Color.black);

        if (chartType == Graph.TYPE_LINE) {
            final LineAndShapeRenderer renderer = (LineAndShapeRenderer) plot.getRenderer();
            renderer.setBaseStroke(new BasicStroke(3));

            if (multiStageTimeSeries != null) {
                for (int i = 0; i < multiStageTimeSeries.size(); i++) {
                    renderer.setSeriesPaint(i, multiStageTimeSeries.get(i).color);
                }
            }
        }

        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 = (NumberAxis) plot.getRangeAxis();
        Utils.adjustChebyshev(dataset, rangeAxis);
        rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());

        if (chartType == Graph.TYPE_STACKED_AREA) {
            StackedAreaRenderer ar = new StackedAreaRenderer2() {

                @Override
                public Paint getItemPaint(int row, int column) {
                    if (row == 2) {
                        return ColorPalette.BLUE;
                    }
                    if (row == 1) {
                        return ColorPalette.YELLOW;
                    }
                    if (row == 0) {
                        return ColorPalette.RED;
                    }
                    ChartLabel key = (ChartLabel) dataset.getColumnKey(column);
                    return key.getColor(row, column);
                }

                @Override
                public String generateURL(CategoryDataset dataset, int row, int column) {
                    ChartLabel label = (ChartLabel) dataset.getColumnKey(column);
                    return label.getLink(row, column);
                }

                @Override
                public String generateToolTip(CategoryDataset dataset, int row, int column) {
                    ChartLabel label = (ChartLabel) dataset.getColumnKey(column);
                    return label.getToolTip(row, column);
                }
            };
            plot.setRenderer(ar);
            ar.setSeriesPaint(0, ColorPalette.RED); // Failures.
            ar.setSeriesPaint(1, ColorPalette.YELLOW); // Skips.
            ar.setSeriesPaint(2, ColorPalette.BLUE); // Total.
        }

        // crop extra space around the graph
        plot.setInsets(new RectangleInsets(0, 0, 0, 5.0));

        return jFreeChart;
    }

    @Override
    public BufferedImage render(int width, int height) {
        createChart();
        return jFreeChart.createBufferedImage(width, height, info);
    }

    @Override
    public void setData(DataSet data) {

        TreeSet rowSet = new TreeSet(data.getRows());
        TreeSet colSet = new TreeSet(data.getColumns());

        Comparable[] _rows = (Comparable[]) rowSet.toArray(new Comparable[rowSet.size()]);
        Comparable[] _cols = (Comparable[]) colSet.toArray(new Comparable[colSet.size()]);

        // insert rows and columns in the right order
        for (Comparable r : _rows) {
            dataset.setValue(null, r, _cols[0]);
        }
        for (Comparable c : _cols) {
            dataset.setValue(null, _rows[0], c);
        }

        for (int i = 0; i < data.getValues().size(); i++) {
            dataset.addValue((Number) data.getValues().get(i), (Comparable) data.getRows().get(i),
                    (Comparable) data.getColumns().get(i));
        }
    }

    @Override
    public String getImageMap(String id, int width, int height) {
        //Unfortunately we have to render it again, because the map is loaded lazily in another HTTP request
        render(width, height);
        return ChartUtilities.getImageMap(id, info);
    }

    @Extension
    public static class DescriptorImpl extends GraphSupportDescriptor {

        @Override
        public String getDisplayName() {
            return "JFreeChart";
        }
    }
}