001    /*
002     * Sonar, open source software quality management tool.
003     * Copyright (C) 2008-2012 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))
115          || BaseChartWeb.BAR_CHART_VERTICAL_CUSTOM.equals(params.get(BaseChartWeb.CHART_PARAM_TYPE)) ?
116            PlotOrientation.VERTICAL :
117            PlotOrientation.HORIZONTAL);
118        plot.setOutlineVisible("y".equals(params.get(BaseChartWeb.CHART_PARAM_OUTLINE_VISIBLE)));
119        plot.setRangeGridlinesVisible("y".equals(params.get(BaseChartWeb.CHART_PARAM_OUTLINE_RANGEGRIDLINES_VISIBLE)));
120        String insetsParam = params.get(CHART_PARAM_INSETS);
121        if (isParamValueValid(insetsParam)) {
122          double insets = convertParamToDouble(insetsParam);
123          RectangleInsets rectangleInsets = new RectangleInsets(insets, insets, insets, insets);
124          plot.setInsets(rectangleInsets);
125        }
126    
127        // -- Category Axis
128        boolean categoryAxisIsVisible = "y".equals(params.get(BaseChartWeb.CHART_PARAM_CATEGORIES_AXISMARGIN_VISIBLE));
129        double categoryAxisUpperMargin = convertParamToDouble(params.get(BaseChartWeb.CHART_PARAM_CATEGORIES_AXISMARGIN_UPPER), DEFAULT_CATEGORIES_AXISMARGIN);
130        double categoryAxisLowerMargin = convertParamToDouble(params.get(BaseChartWeb.CHART_PARAM_CATEGORIES_AXISMARGIN_LOWER), DEFAULT_CATEGORIES_AXISMARGIN);
131        categoryAxis.setVisible(categoryAxisIsVisible);
132        categoryAxis.setTickLabelsVisible(categoryAxisIsVisible);
133        categoryAxis.setLowerMargin(categoryAxisLowerMargin);
134        categoryAxis.setUpperMargin(categoryAxisUpperMargin);
135    
136        // -- Range Axis
137        boolean rangeAxisIsVisible = "y".equals(params.get(BaseChartWeb.CHART_PARAM_RANGEAXIS_VISIBLE));
138        double rangeAxisUpperMargin = convertParamToDouble(params.get(BaseChartWeb.CHART_PARAM_SERIES_AXISMARGIN_UPPER), DEFAULT_SERIES_AXISMARGIN);
139        double rangeAxisLowerMargin = convertParamToDouble(params.get(BaseChartWeb.CHART_PARAM_SERIES_AXISMARGIN_LOWER), DEFAULT_SERIES_AXISMARGIN);
140        numberAxis.setTickLabelsVisible(rangeAxisIsVisible);
141        numberAxis.setVisible(rangeAxisIsVisible);
142        numberAxis.setLowerMargin(rangeAxisLowerMargin);
143        numberAxis.setUpperMargin(rangeAxisUpperMargin);
144        String rangeMax = params.get(BaseChartWeb.CHART_PARAM_RANGEMAX);
145        if (isParamValueValid(rangeMax)) {
146          double iRangeMax = Double.parseDouble(rangeMax);
147          numberAxis.setRange(0.0, iRangeMax);
148        }
149        String tickUnit = params.get(BaseChartWeb.CHART_PARAM_SERIES_AXISMARGIN_TICKUNIT);
150        if (isParamValueValid(tickUnit)) {
151          numberAxis.setTickUnit(new NumberTickUnit(convertParamToDouble(tickUnit)));
152        }
153      }
154    
155      private void applyParams() {
156        applyCommonParams();
157        applyCommomParamsBar();
158    
159        configureColors(params.get(BaseChartWeb.CHART_PARAM_COLORS), renderer);
160        addMeasures(params.get(BaseChartWeb.CHART_PARAM_VALUES));
161      }
162    
163      private void addMeasures(String values) {
164        if (values != null && values.length() > 0) {
165          // Values
166          StringTokenizer stValues = new StringTokenizer(values, ",");
167          int nbValues = stValues.countTokens();
168    
169          // Categories
170          String categoriesParam = params.get(BaseChartWeb.CHART_PARAM_CATEGORIES);
171          boolean categoriesPresent = categoriesParam != null && categoriesParam.length() > 0;
172          String[] categoriesSplit = null;
173          if (categoriesPresent) {
174            categoriesSplit = categoriesParam.split(",");
175          } else {
176            categoriesSplit = new String[1];
177            categoriesSplit[0] = BaseChartWeb.DEFAULT_NAME_CATEGORY;
178          }
179          int nbCategories = categoriesSplit.length;
180    
181          // Series
182          String seriesParam = params.get(BaseChartWeb.CHART_PARAM_SERIES);
183          boolean seriesPresent = seriesParam != null && seriesParam.length() > 0;
184          String[] seriesSplit = null;
185          if (seriesPresent) {
186            seriesSplit = seriesParam.split(",");
187          } else {
188            seriesSplit = new String[nbValues];
189            for (int i = 0; i < nbValues; i++) {
190              seriesSplit[i] = BaseChartWeb.DEFAULT_NAME_SERIE + i;
191            }
192          }
193          int nbSeries = seriesSplit.length;
194    
195          for (int iCategories = 0; iCategories < nbCategories; iCategories++) {
196            String currentCategory = categoriesSplit[iCategories];
197            for (int iSeries = 0; iSeries < nbSeries; iSeries++) {
198              String currentSerie = seriesSplit[iSeries];
199              double currentValue = 0.0;
200              if (stValues.hasMoreTokens()) {
201                try {
202                  currentValue = Double.parseDouble(stValues.nextToken());
203                } catch (NumberFormatException e) {
204                }
205              }
206              dataset.addValue(currentValue, currentSerie, currentCategory);
207            }
208          }
209        }
210      }
211    
212    }