001/* 002 * Copyright (c) 2009 The openGion Project. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 013 * either express or implied. See the License for the specific language 014 * governing permissions and limitations under the License. 015 */ 016package org.opengion.hayabusa.io; 017 018import java.awt.GradientPaint; 019import java.awt.Graphics2D; 020import java.awt.Paint; 021import java.awt.geom.Rectangle2D; 022 023import org.jfree.chart.entity.EntityCollection; 024import org.jfree.chart.renderer.category.StackedBarRenderer; 025import org.jfree.chart.renderer.category.CategoryItemRendererState; 026import org.jfree.chart.axis.CategoryAxis; 027import org.jfree.chart.axis.ValueAxis; 028import org.jfree.chart.labels.CategoryItemLabelGenerator; 029import org.jfree.chart.plot.CategoryPlot; 030import org.jfree.chart.plot.PlotOrientation; 031import org.jfree.data.category.CategoryDataset; 032import org.jfree.ui.GradientPaintTransformer; 033import org.jfree.ui.RectangleEdge; 034import org.jfree.data.DataUtilities; 035 036/** 037 * HybsStackedBarRenderer は、org.jfree.chart.renderer.category.StackedBarRenderer を 038 * 拡張したカスタマイズクラスです。 039 * これは、グラフの書き出し位置の調整比率(domainMargin)を設定できます。 040 * 041 * @og.rev 4.1.1.0 (2008/02/16) 新規作成 042 * 043 * @version 0.9.0 2001/05/05 044 * @author Kazuhiko Hasegawa 045 * @since JDK1.1, 046 */ 047public class HybsStackedBarRenderer extends StackedBarRenderer { 048 private static final long serialVersionUID = 519020100801L ; 049 050 private double domainMargin = 0.0; // 4.1.1.0 (2008/02/14) グラフの書き出し位置の調整比率 051 052 private final int hsCode = Long.valueOf( System.nanoTime() ).hashCode() ; // 5.1.9.0 (2010/08/01) equals,hashCode 053 054 // 4.3.4.4 (2009/01/01) 055// /** 056// * Creates a new bar renderer with default settings. 057// */ 058// public HybsStackedBarRenderer() { 059// super(); 060// } 061 062 /** 063 * グラフの書き出し位置の調整比率を指定します。 064 * 065 * グラフを描画する場合の、書き出し位置を少しずらします。 066 * これは、グラフの幅に対して、比率で指定します。 067 * 0.0(初期値)の場合は、初期描画位置である、CategoryAnchor.Middle と 068 * 同じ箇所から、書き出されます。 069 * 1.0 の場合、中心から、グラフ幅の半分が加算され、END位置に寄ります。 070 * 同様に、-1.0 の場合は、グラフ幅の半分が減算され、START 位置になります。 071 * つまり、中心から、グラフ幅の半分単位で、前方/後方にずらす事が出来ます。 072 * 書き出し位置 = 中心(Middle) + (domainMargin)*幅/2 073 * 初期値は、0.0(真ん中:MIDDLE)です。 074 * 075 * @og.rev 4.1.1.0 (2008/02/14) 新規追加 076 * 077 * @param margin グラフの書き出し位置の調整比率 078 */ 079 public void setDomainMargin( final double margin ) { 080 domainMargin = margin; 081 } 082 083 /** 084 * Draws a stacked bar for a specific item. 085 * 086 * @param g2 the graphics device. 087 * @param state the renderer state. 088 * @param dataArea the plot area. 089 * @param plot the plot. 090 * @param domainAxis the domain (category) axis. 091 * @param rangeAxis the range (value) axis. 092 * @param dataset the data. 093 * @param row the row index (zero-based). 094 * @param column the column index (zero-based). 095 * @param pass the pass index. 096 */ 097 @Override 098 public void drawItem( final Graphics2D g2, 099 final CategoryItemRendererState state, 100 final Rectangle2D dataArea, 101 final CategoryPlot plot, 102 final CategoryAxis domainAxis, 103 final ValueAxis rangeAxis, 104 final CategoryDataset dataset, 105 final int row, 106 final int column, 107 final int pass) { 108 109 // nothing is drawn for null values... 110 Number dataValue = dataset.getValue(row, column); 111 if (dataValue == null) { 112 return; 113 } 114 115 double value = dataValue.doubleValue(); 116 double total = 0.0; // only needed if calculating percentages 117 if (getRenderAsPercentages()) { 118 total = DataUtilities.calculateColumnTotal(dataset, column); 119 value = value / total; 120 } 121 122 PlotOrientation orientation = plot.getOrientation(); 123 124 double barW0 = domainAxis.getCategoryStart(column, getColumnCount(), 125 dataArea, plot.getDomainAxisEdge()) 126 + domainMargin * state.getBarWidth() / 2.0; 127 128 double positiveBase = getBase(); 129 double negativeBase = positiveBase; 130 131 // 4.3.1.1 (2008/08/23) 変数名が短いので変更(v ⇒ nm , d ⇒ vd ) 132 for (int i = 0; i < row; i++) { 133 Number nm = dataset.getValue(i, column); 134 if (nm != null) { 135 double vd = nm.doubleValue(); 136 if (getRenderAsPercentages()) { 137 vd = vd / total; 138 } 139 if (vd > 0) { 140 positiveBase = positiveBase + vd; 141 } 142 else { 143 negativeBase = negativeBase + vd; 144 } 145 } 146 } 147 148 double translatedBase; 149 double translatedValue; 150 RectangleEdge location = plot.getRangeAxisEdge(); 151 if (value >= 0.0) { 152 translatedBase = rangeAxis.valueToJava2D(positiveBase, dataArea, 153 location); 154 translatedValue = rangeAxis.valueToJava2D(positiveBase + value, 155 dataArea, location); 156 } 157 else { 158 translatedBase = rangeAxis.valueToJava2D(negativeBase, dataArea, 159 location); 160 translatedValue = rangeAxis.valueToJava2D(negativeBase + value, 161 dataArea, location); 162 } 163 double barL0 = Math.min(translatedBase, translatedValue); 164 double barLength = Math.max(Math.abs(translatedValue - translatedBase), 165 getMinimumBarLength()); 166 167 Rectangle2D bar = null; 168 if (orientation == PlotOrientation.HORIZONTAL) { 169 bar = new Rectangle2D.Double(barL0, barW0, barLength, 170 state.getBarWidth()); 171 } 172 else { 173 bar = new Rectangle2D.Double(barW0, barL0, state.getBarWidth(), 174 barLength); 175 } 176 if (pass == 0) { 177 Paint itemPaint = getItemPaint(row, column); 178 // 4.3.1.1 (2008/08/23) 変数名を t ⇒ gpt に変更 179 GradientPaintTransformer gpt = getGradientPaintTransformer(); 180 if (gpt != null && itemPaint instanceof GradientPaint) { 181 itemPaint = gpt.transform((GradientPaint) itemPaint, bar); 182 } 183 g2.setPaint(itemPaint); 184 g2.fill(bar); 185 if (isDrawBarOutline() 186 && state.getBarWidth() > BAR_OUTLINE_WIDTH_THRESHOLD) { 187 g2.setStroke(getItemOutlineStroke(row, column)); 188 g2.setPaint(getItemOutlinePaint(row, column)); 189 g2.draw(bar); 190 } 191 192 // add an item entity, if this information is being collected 193 EntityCollection entities = state.getEntityCollection(); 194 if (entities != null) { 195 addItemEntity(entities, dataset, row, column, bar); 196 } 197 } 198 else if (pass == 1) { 199 CategoryItemLabelGenerator generator = getItemLabelGenerator(row, 200 column); 201 if (generator != null && isItemLabelVisible(row, column)) { 202 drawItemLabel(g2, dataset, row, column, plot, generator, bar, 203 (value < 0.0)); 204 } 205 } 206 } 207 208 /** 209 * この文字列と指定されたオブジェクトを比較します。 210 * 211 * 親クラスで、equals メソッドが実装されているため、警告がでます。 212 * 213 * @og.rev 5.1.8.0 (2010/07/01) findbug対応 214 * @og.rev 5.1.9.0 (2010/08/01) findbug対応 215 * 216 * @param object 比較するオブジェクト 217 * 218 * @return Objectが等しい場合は true、そうでない場合は false 219 */ 220 @Override 221 public boolean equals( final Object object ) { 222// return super.equals( object ); 223 if( super.equals( object ) ) { 224 return hsCode == ((HybsStackedBarRenderer)object).hsCode; 225 } 226 return false; 227 } 228 229 /** 230 * このオブジェクトのハッシュコードを取得します。 231 * 232 * @og.rev 5.1.8.0 (2010/07/01) findbug対応 233 * @og.rev 5.1.9.0 (2010/08/01) findbug対応 234 * 235 * @return ハッシュコード 236 */ 237// public int hashCode() { return super.hashCode() ; } 238 @Override 239 public int hashCode() { return hsCode ; } 240 241 /** 242 * このオブジェクトと指定されたオブジェクトを比較します。 243 * 244 * @og.rev 4.3.1.1 (2008/08/23) 新規追加 245 * @og.rev 5.1.8.0 (2010/07/01) 廃止 246 * 247 * @param anObject Object 比較されるオブジェクト 248 * 249 * @return 指定されたオブジェクトが等しい場合は true、そうでない場合は false 250 */ 251// public boolean equals( final Object anObject ) { 252// if( super.equals( anObject ) ) { 253// HybsStackedBarRenderer other = ((HybsStackedBarRenderer)anObject); 254//// return ( domainMargin == other.domainMargin ); 255// return Double.compare( domainMargin,other.domainMargin ) == 0 ; 256// } 257// return false; 258// } 259 260 /** 261 * このオブジェクトのハッシュコードを返します。 262 * 263 * @og.rev 4.3.1.1 (2008/08/23) 新規追加 264 * @og.rev 5.1.8.0 (2010/07/01) 廃止 265 * 266 * @return このオブジェクトのハッシュコード値 267 */ 268// public int hashCode() { 269// return super.hashCode() ^ Double.valueOf( domainMargin ).hashCode() ; 270// } 271}