001    /*
002     * Sonar, open source software quality management tool.
003     * Copyright (C) 2008-2011 SonarSource
004     * mailto:contact AT sonarsource DOT com
005     *
006     * Sonar is free software; you can redistribute it and/or
007     * modify it under the terms of the GNU Lesser General Public
008     * License as published by the Free Software Foundation; either
009     * version 3 of the License, or (at your option) any later version.
010     *
011     * Sonar 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 GNU
014     * Lesser General Public License for more details.
015     *
016     * You should have received a copy of the GNU Lesser General Public
017     * License along with Sonar; if not, write to the Free Software
018     * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
019     */
020    package org.sonar.server.charts.deprecated;
021    
022    import org.jfree.chart.JFreeChart;
023    import org.jfree.chart.axis.CategoryAxis;
024    import org.jfree.chart.axis.NumberAxis;
025    import org.jfree.chart.axis.NumberTickUnit;
026    import org.jfree.chart.plot.CategoryPlot;
027    import org.jfree.chart.plot.PlotOrientation;
028    import org.jfree.chart.renderer.category.BarRenderer;
029    import org.jfree.chart.renderer.category.StackedBarRenderer;
030    import org.jfree.chart.title.TextTitle;
031    import org.jfree.data.category.DefaultCategoryDataset;
032    import org.jfree.ui.RectangleInsets;
033    
034    import java.awt.image.BufferedImage;
035    import java.io.IOException;
036    import java.util.Map;
037    import java.util.StringTokenizer;
038    
039    public class BarChart extends BaseChartWeb implements DeprecatedChart {
040    
041      private BarRenderer renderer = null;
042      protected DefaultCategoryDataset dataset = null;
043      protected CategoryAxis categoryAxis = null;
044      protected NumberAxis numberAxis = null;
045    
046      public BarChart(Map<String, String> params) {
047        super(params);
048        jfreechart = new JFreeChart(null, TextTitle.DEFAULT_FONT, new CategoryPlot(), false);
049      }
050    
051      @Override
052      protected BufferedImage getChartImage() throws IOException {
053        configure();
054        return getBufferedImage(jfreechart);
055      }
056    
057      protected void configure() {
058        configureChart(jfreechart, false);
059        configureCategoryDataset();
060        configureCategoryAxis();
061        configureRenderer();
062        configureRangeAxis();
063        configureCategoryPlot();
064        applyParams();
065      }
066    
067      protected void configureCategoryPlot() {
068        CategoryPlot plot = jfreechart.getCategoryPlot();
069        plot.setNoDataMessage(DEFAULT_MESSAGE_NODATA);
070        plot.setInsets(RectangleInsets.ZERO_INSETS); // To remove inner space around chart
071        plot.setDataset(dataset);
072        plot.setDomainAxis(categoryAxis);
073        plot.setRenderer(renderer);
074        plot.setRangeAxis(numberAxis);
075      }
076    
077      protected void configureCategoryDataset() {
078        dataset = new DefaultCategoryDataset();
079      }
080    
081      protected void configureCategoryAxis() {
082        categoryAxis = new CategoryAxis();
083        categoryAxis.setLabelFont(DEFAULT_FONT);
084        categoryAxis.setLabelPaint(BASE_COLOR);
085        categoryAxis.setTickLabelFont(DEFAULT_FONT);
086        categoryAxis.setTickLabelPaint(BASE_COLOR);
087        categoryAxis.setVisible(false);
088      }
089    
090      protected void configureRenderer() {
091        if (params.get(BaseChartWeb.CHART_PARAM_TYPE).equals(BaseChartWeb.STACKED_BAR_CHART)) {
092          renderer = new StackedBarRenderer();
093        } else {
094          renderer = new BarRenderer();
095        }
096        renderer.setItemMargin(0.0);
097        renderer.setDrawBarOutline(false);
098      }
099    
100      protected void configureRangeAxis() {
101        numberAxis = new NumberAxis();
102        numberAxis.setLabelFont(DEFAULT_FONT);
103        numberAxis.setLabelPaint(BASE_COLOR);
104        numberAxis.setTickLabelFont(DEFAULT_FONT);
105        numberAxis.setTickLabelPaint(BASE_COLOR);
106        numberAxis.setTickMarksVisible(true);
107        numberAxis.setVisible(false);
108        numberAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
109      }
110    
111      protected void applyCommomParamsBar() {
112        // -- Plot
113        CategoryPlot plot = jfreechart.getCategoryPlot();
114        plot.setOrientation(BaseChartWeb.BAR_CHART_VERTICAL.equals(params.get(BaseChartWeb.CHART_PARAM_TYPE)) || BaseChartWeb.BAR_CHART_VERTICAL_CUSTOM.equals(params.get(BaseChartWeb.CHART_PARAM_TYPE)) ? PlotOrientation.VERTICAL : PlotOrientation.HORIZONTAL);
115        plot.setOutlineVisible("y".equals(params.get(BaseChartWeb.CHART_PARAM_OUTLINE_VISIBLE)));
116        plot.setRangeGridlinesVisible("y".equals(params.get(BaseChartWeb.CHART_PARAM_OUTLINE_RANGEGRIDLINES_VISIBLE)));
117        String insetsParam = params.get(CHART_PARAM_INSETS);
118        if (isParamValueValid(insetsParam)) {
119          double insets = convertParamToDouble(insetsParam);
120          RectangleInsets rectangleInsets = new RectangleInsets(insets, insets, insets, insets);
121          plot.setInsets(rectangleInsets);
122        }
123    
124        // -- Category Axis
125        boolean categoryAxisIsVisible = "y".equals(params.get(BaseChartWeb.CHART_PARAM_CATEGORIES_AXISMARGIN_VISIBLE));
126        double categoryAxisUpperMargin = convertParamToDouble(params.get(BaseChartWeb.CHART_PARAM_CATEGORIES_AXISMARGIN_UPPER), DEFAULT_CATEGORIES_AXISMARGIN);
127        double categoryAxisLowerMargin = convertParamToDouble(params.get(BaseChartWeb.CHART_PARAM_CATEGORIES_AXISMARGIN_LOWER), DEFAULT_CATEGORIES_AXISMARGIN);
128        categoryAxis.setVisible(categoryAxisIsVisible);
129        categoryAxis.setTickLabelsVisible(categoryAxisIsVisible);
130        categoryAxis.setLowerMargin(categoryAxisLowerMargin);
131        categoryAxis.setUpperMargin(categoryAxisUpperMargin);
132    
133        // -- Range Axis
134        boolean rangeAxisIsVisible = "y".equals(params.get(BaseChartWeb.CHART_PARAM_RANGEAXIS_VISIBLE));
135        double rangeAxisUpperMargin = convertParamToDouble(params.get(BaseChartWeb.CHART_PARAM_SERIES_AXISMARGIN_UPPER), DEFAULT_SERIES_AXISMARGIN);
136        double rangeAxisLowerMargin = convertParamToDouble(params.get(BaseChartWeb.CHART_PARAM_SERIES_AXISMARGIN_LOWER), DEFAULT_SERIES_AXISMARGIN);
137        numberAxis.setTickLabelsVisible(rangeAxisIsVisible);
138        numberAxis.setVisible(rangeAxisIsVisible);
139        numberAxis.setLowerMargin(rangeAxisLowerMargin);
140        numberAxis.setUpperMargin(rangeAxisUpperMargin);
141        String rangeMax = params.get(BaseChartWeb.CHART_PARAM_RANGEMAX);
142        if (isParamValueValid(rangeMax)) {
143          double iRangeMax = Double.parseDouble(rangeMax);
144          numberAxis.setRange(0.0, iRangeMax);
145        }
146        String tickUnit = params.get(BaseChartWeb.CHART_PARAM_SERIES_AXISMARGIN_TICKUNIT);
147        if (isParamValueValid(tickUnit)) {
148          numberAxis.setTickUnit(new NumberTickUnit(convertParamToDouble(tickUnit)));
149        }
150      }
151    
152      private void applyParams() {
153        applyCommonParams();
154        applyCommomParamsBar();
155    
156        configureColors(params.get(BaseChartWeb.CHART_PARAM_COLORS), renderer);
157        addMeasures(params.get(BaseChartWeb.CHART_PARAM_VALUES));
158      }
159    
160      private void addMeasures(String values) {
161        if (values != null && values.length() > 0) {
162          // Values
163          StringTokenizer stValues = new StringTokenizer(values, ",");
164          int nbValues = stValues.countTokens();
165    
166          // Categories
167          String categoriesParam = params.get(BaseChartWeb.CHART_PARAM_CATEGORIES);
168          boolean categoriesPresent = categoriesParam != null && categoriesParam.length() > 0;
169          String[] categoriesSplit = null;
170          if (categoriesPresent) {
171            categoriesSplit = categoriesParam.split(",");
172          } else {
173            categoriesSplit = new String[1];
174            categoriesSplit[0] = BaseChartWeb.DEFAULT_NAME_CATEGORY;
175          }
176          int nbCategories = categoriesSplit.length;
177    
178          // Series
179          String seriesParam = params.get(BaseChartWeb.CHART_PARAM_SERIES);
180          boolean seriesPresent = seriesParam != null && seriesParam.length() > 0;
181          String[] seriesSplit = null;
182          if (seriesPresent) {
183            seriesSplit = seriesParam.split(",");
184          } else {
185            seriesSplit = new String[nbValues];
186            for (int i = 0; i < nbValues; i++) {
187              seriesSplit[i] = BaseChartWeb.DEFAULT_NAME_SERIE + i;
188            }
189          }
190          int nbSeries = seriesSplit.length;
191    
192          for (int iCategories = 0; iCategories < nbCategories; iCategories++) {
193            String currentCategory = categoriesSplit[iCategories];
194            for (int iSeries = 0; iSeries < nbSeries; iSeries++) {
195              String currentSerie = seriesSplit[iSeries];
196              double currentValue = 0.0;
197              if (stValues.hasMoreTokens()) {
198                try {
199                  currentValue = Double.parseDouble(stValues.nextToken());
200                } catch (NumberFormatException e) {
201                }
202              }
203              dataset.addValue(currentValue, currentSerie, currentCategory);
204            }
205          }
206        }
207      }
208    
209    }