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 }