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 */
016 package org.opengion.hayabusa.io;
017
018 import java.awt.Graphics2D;
019 import java.awt.Stroke;
020 import java.awt.Paint;
021 import java.awt.geom.Rectangle2D;
022 import java.util.List;
023 import java.util.Map;
024 import java.util.HashMap;
025 import java.util.Iterator;
026
027 import org.jfree.chart.plot.CategoryPlot;
028 import org.jfree.chart.plot.PlotRenderingInfo;
029 import org.jfree.chart.urls.CategoryURLGenerator;
030 import org.jfree.chart.axis.CategoryAxis;
031 import org.jfree.chart.axis.ValueAxis;
032 import org.jfree.chart.axis.ValueTick;
033 import org.jfree.chart.renderer.category.CategoryItemRenderer;
034 import org.jfree.chart.renderer.category.CategoryItemRendererState;
035 import org.jfree.chart.renderer.category.StackedBarRenderer;
036 import org.jfree.data.category.CategoryDataset;
037 import org.jfree.data.general.DatasetUtilities;
038
039 /**
040 * HybsCategoryPlot は、CategoryPlot を拡張したカスタマイズクラスですã?
041 * これは、シリーズの表示色を変更するç®?‰€で、描画é ?�«より、きれいに表示されなã�?
042 * 現象への対応案ですã?
043 * 描画é ?‚’、最も最後に行うように、修正してã�?�¾すã?
044 *
045 * renders each data item using a {@link CategoryItemRenderer}.
046 *
047 * @og.rev 3.8.9.2 (2007/07/28) 新規作æ?
048 *
049 * @version 0.9.0 2001/05/05
050 * @author Kazuhiko Hasegawa
051 * @since JDK1.1,
052 */
053 public class HybsCategoryPlot extends CategoryPlot {
054 private static final long serialVersionUID = 519020100801L ;
055
056 private final Map<Integer,Double> barWidths = new HashMap<Integer,Double>(); // 4.3.1.1 (2008/08/23) final�
057 private int serNo = -1;
058 // private boolean isNotify = false;
059 private int rangeSkip = 1; // 4.1.1.0 (2008/02/04) 縦軸のグリãƒ?ƒ‰をスキãƒ??する間隔
060 private final int hsCode = Long.valueOf( System.nanoTime() ).hashCode() ; // 5.1.9.0 (2010/08/01) equals,hashCode
061
062 /**
063 * ãƒ?ƒ•ォルトコンストラクター
064 * シリーズ番号をã?初期化しておきますã?
065 *
066 **/
067 public HybsCategoryPlot() {
068 // 4.3.4.4 (2009/01/01)
069 this( -1 );
070 }
071
072 /**
073 * シリーズ番号 をã?æŒ?®šして、オブジェクトを作æ?するコンストラクター
074 *
075 * @param serNo ピックアãƒ??するシリーズ番号
076 **/
077 protected HybsCategoryPlot( final int serNo ) {
078 // 4.3.4.4 (2009/01/01)
079 // super();
080 this.serNo = serNo;
081 }
082
083 /**
084 * ピックアãƒ??するシリーズ番号を設定しますã?
085 *
086 * @og.rev 4.1.1.0 (2008/02/04) ãƒ??タの値(itemText)表示の継承
087 *
088 * @param newSerNo ピックアãƒ??するシリーズ番号
089 **/
090 protected void setSeriesPikup( final int newSerNo ) {
091 int oldSerNo = serNo ;
092 serNo = newSerNo;
093 CategoryItemRenderer rend = getRenderer();
094 CategoryURLGenerator urlGen = rend.getSeriesItemURLGenerator( oldSerNo );
095 if( urlGen != null ) {
096 rend.setSeriesItemURLGenerator( oldSerNo,null );
097 rend.setSeriesItemURLGenerator( serNo ,urlGen );
098 }
099
100 // 4.1.1.0 (2008/02/04) ãƒ??タの値(itemText)表示の継承
101 if( rend.isSeriesItemLabelsVisible( oldSerNo ) ) {
102 rend.setSeriesItemLabelsVisible( oldSerNo,false );
103 rend.setSeriesItemLabelsVisible( serNo ,true );
104 }
105 }
106
107 /**
108 * Notifyを設定しますã?
109 *
110 * @og.rev 5.1.4.0 (2010/03/01) 継承å…?? Plot クラスに public で追åŠ?�•れた対å¿?
111 * @og.rev 5.1.8.0 (2010/07/01) 実質çš?�«使用されてã�?�ªã�??で、削除
112 *
113 * @param isNotify boolean
114 **/
115 // protected void setNotify( final boolean isNotify ) {
116 // public void setNotify( final boolean isNotify ) {
117 // this.isNotify = isNotify;
118 // }
119
120 /**
121 * 縦軸のグリãƒ?ƒ‰ç·?水平ç·?をスキãƒ??する間隔を指定しますã?
122 *
123 * 縦軸のグリãƒ?ƒ‰線を表示する際に、スキãƒ??する間隔を指定しますã?
124 * 通常は、ラベルと同じã�?�‘のグリãƒ?ƒ‰線が掛かれますが、ラベルよりã‚?
125 * 少なã�?•°のグリãƒ?ƒ‰ç·?例えばã€?¼’つおき)をå?すå?合に、å?を設定しますã?
126 * "1" (初期値)ではã€?¼‘つづつ表示(つまりã?すべて表示する)しますã?
127 * "2" とするとã€?¼‘つおきにã€?3" とするとã€?¼’つおきに表示しますã?
128 * 初期値はã€?1" (すべて表示)ですã?
129 * なおã?先é?から表示を開始しますã?
130 *
131 * @og.rev 4.1.1.0 (2008/02/04) 新規追åŠ?
132 *
133 * @param rngSkip 縦軸のグリãƒ?ƒ‰ç·?水平ç·?をスキãƒ??する間隔
134 */
135 protected void setRangeSkip( final int rngSkip ) {
136 rangeSkip = rngSkip;
137 }
138
139 /**
140 * BarChart のバã?のå¹?‚’直接æŒ?®šしますã?
141 * 通常は、maxBarWidth ã‚?itemMargin で比率æŒ?®šしますがã€?
142 * ここでは、CategoryItemRendererState オブジェクトに直接設定する為の
143 * ãƒ??タセãƒ?ƒˆ単位ã?マップを作æ?しますã?
144 *
145 * @param index ãƒ??タセãƒ?ƒˆ番号
146 * @param width バã?のå¹?
147 **/
148 protected void setBarWidth( final int index,final Double width ) {
149 barWidths.put( index,width );
150 }
151
152 /**
153 * Draws a representation of a dataset within the dataArea region using the
154 * appropriate renderer.
155 *
156 * @param g2 the graphics device.
157 * @param dataArea the region in which the data is to be drawn.
158 * @param index the dataset and renderer index.
159 * @param info an optional object for collection dimension information.
160 *
161 * @return 描画するãƒ??タが見つかったå?合ã?、true
162 */
163 public boolean render( final Graphics2D g2, final Rectangle2D dataArea, final int index,
164 final PlotRenderingInfo info ) {
165 boolean foundData = false;
166 CategoryDataset currentDataset = getDataset(index);
167 CategoryItemRenderer renderer = getRenderer(index);
168 // 4.3.1.0 (2008/08/19) 軸とãƒ??タセãƒ?ƒˆのマッピング
169 this.mapDatasetToRangeAxis( index, index );
170
171 CategoryAxis domainAxis = null ;
172 if( renderer instanceof StackedBarRenderer ) {
173 domainAxis = getDomainAxis(index);
174 }
175 else {
176 domainAxis = getDomainAxisForDataset(index);
177 }
178
179 ValueAxis rangeAxis = getRangeAxis(index);
180 boolean hasData = !DatasetUtilities.isEmptyOrNull(currentDataset);
181 if(hasData && renderer != null) {
182 foundData = true;
183 CategoryItemRendererState state = renderer.initialise(g2, dataArea,
184 this, index, info);
185
186 // 4.0.3.0 (2008/01/07) 棒グラフã?バã?å¹?Œ‡å®?
187 Double bwidth = barWidths.get( index );
188 if( bwidth != null ) { state.setBarWidth( bwidth.doubleValue() ); }
189
190 if( renderer instanceof HybsDrawItem ) {
191 ((HybsDrawItem)renderer).drawItem2(g2, state, dataArea, this,
192 domainAxis, rangeAxis, currentDataset , serNo );
193 }
194 else {
195 int columnCount = currentDataset.getColumnCount();
196 int rowCount = currentDataset.getRowCount();
197 int passCount = renderer.getPassCount();
198 for( int pass=0; pass<passCount; pass++ ) {
199 for( int column=0; column<columnCount; column++ ) {
200 for( int row=0; row<rowCount; row++ ) {
201 if( row == serNo ) { continue; } // Mis Add 2007/07/23
202 renderer.drawItem(g2, state, dataArea, this,
203 domainAxis, rangeAxis, currentDataset,
204 row, column, pass);
205 }
206 // æŒ?®šã?シリーズとä¸??する場合ã?、最後に描画するã€?Mis Add 2007/07/23
207 if( serNo >= 0 ) {
208 renderer.drawItem(g2, state, dataArea, this,
209 domainAxis, rangeAxis, currentDataset,
210 serNo, column, pass);
211 }
212 }
213 }
214 }
215 }
216 return foundData;
217 }
218
219 /**
220 * Draws the gridlines for the plot.
221 *
222 * @param g2 the graphics device.
223 * @param dataArea the area inside the axes.
224 * @param ticks the ticks.
225 *
226 * @see #drawDomainGridlines(Graphics2D, Rectangle2D)
227 */
228 @SuppressWarnings("rawtypes")
229 protected void drawRangeGridlines( final Graphics2D g2, final Rectangle2D dataArea,
230 final List ticks ) {
231 // draw the range grid lines, if any...
232
233 if (isRangeGridlinesVisible()) {
234 Stroke gridStroke = getRangeGridlineStroke();
235 Paint gridPaint = getRangeGridlinePaint();
236 if ((gridStroke != null) && (gridPaint != null)) {
237 ValueAxis axis = getRangeAxis();
238 CategoryItemRenderer renderer1 = getRenderer();
239 if (axis != null && renderer1 != null) {
240 Iterator<?> iterator = ticks.iterator();
241 int cnt = 0;
242 while (iterator.hasNext()) {
243 ValueTick tick = (ValueTick) iterator.next();
244 if( cnt % rangeSkip == 0 ) {
245 renderer1.drawRangeGridline(g2, this,
246 axis, dataArea, tick.getValue());
247 }
248 cnt++ ;
249 }
250 }
251 }
252 }
253 }
254
255 /**
256 * こã?æ–?—å?とæŒ?®šされたオブジェクトを比è¼?�—ますã?
257 *
258 * 親クラスで、equals メソãƒ?ƒ‰が実è£?�•れてã�?‚‹ため、警告がでますã?
259 *
260 * @og.rev 5.1.8.0 (2010/07/01) findbug対å¿?
261 * @og.rev 5.1.9.0 (2010/08/01) findbug対å¿?
262 *
263 * @param object 比è¼?�™るオブジェクãƒ?
264 *
265 * @return Objectが等しã�??合ã? true、そã�?�§なã�??合ã? false
266 */
267 @Override
268 public boolean equals( final Object object ) {
269 if( super.equals( object ) ) {
270 return hsCode == ((HybsCategoryPlot)object).hsCode;
271 }
272 return false;
273 }
274
275 /**
276 * こã?オブジェクトã?ハッシュコードを取得しますã?
277 *
278 * @og.rev 5.1.8.0 (2010/07/01) findbug対å¿?
279 * @og.rev 5.1.9.0 (2010/08/01) findbug対å¿?
280 *
281 * @return ハッシュコーãƒ?
282 */
283 // public int hashCode() { return super.hashCode() ; }
284 @Override
285 public int hashCode() { return hsCode ; }
286
287 /**
288 * こã?オブジェクトとæŒ?®šされたオブジェクトを比è¼?�—ますã?
289 *
290 * @og.rev 4.0.0.0 (2007/11/28) 新規追åŠ?
291 * @og.rev 5.1.4.0 (2010/03/01) 削除しますã?
292 *
293 * @param anObject Object 比è¼?�•れるオブジェクãƒ?
294 *
295 * @return æŒ?®šされたオブジェクトが等しã�??合ã? true、そã�?�§なã�??合ã? false
296 */
297 // public boolean equals( final Object anObject ) {
298 // if( super.equals( anObject ) ) {
299 // HybsCategoryPlot other = ((HybsCategoryPlot)anObject);
300 //// if( other.serNo == serNo && other.isNotify == isNotify ) {
301 // if( other.serNo == serNo ) {
302 // return true;
303 // }
304 // }
305 // return false;
306 // }
307
308 /**
309 * こã?オブジェクトã?ハッシュコードを返しますã?
310 *
311 * @og.rev 4.0.0.0 (2007/11/28) 新規追åŠ?
312 * @og.rev 5.1.4.0 (2010/03/01) 削除しますã?
313 *
314 * @return こã?オブジェクトã?ハッシュコードå?
315 */
316 // public int hashCode() {
317 //// return super.hashCode() + serNo + Boolean.valueOf( isNotify ).hashCode() ;
318 // return super.hashCode() + serNo ;
319 // }
320 }