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
019 import java.util.List;
020 import java.util.ArrayList;
021 import java.awt.Graphics2D;
022 import java.awt.geom.Rectangle2D;
023 import org.jfree.ui.RectangleEdge;
024 import org.jfree.text.TextBlock;
025 import org.jfree.chart.axis.AxisState;
026 import org.jfree.chart.axis.CategoryAxis;
027 import org.jfree.chart.axis.CategoryAnchor;
028
029 /**
030 * HybsCategoryAxis は、CategoryAxis クラスを継承した、横軸管ç�?‚¯ラスですã?
031 * 横軸ラベルの表示制御をã?主に行ってã�?�¾すã?
032 * 横軸表示にはã€?¼“つの制御機è?がカスタマイズされてã�?�¾すã?
033 *
034 * ?‘ï¼?_" ラベルのスキãƒ??(非表示)
035 * ?’.cutNo 属æ?による、ラベルæ–?—位置æŒ?®šã?キーブレイク
036 * ?“.skip 属æ?による、ラベルをスキãƒ??する間隔のæŒ?®?
037 *
038 * 上記ã??‘,2,ï¼?のé ?•ªで優先的に処ç�?�•れますã?
039 *
040 * @version 0.9.0 2007/06/21
041 * @author Kazuhiko Hasegawa
042 * @since JDK1.1,
043 */
044 public class HybsCategoryAxis extends CategoryAxis {
045 private static final long serialVersionUID = 519020100801L;
046
047 private static final TextBlock NULL_LABEL = new TextBlock() ;
048
049 // 4.1.2.0 (2008/03/12) 新規追åŠ?
050 private enum LabelVisible { TRUE(true) , FALSE(false) , UNDER(true) ;
051 private final boolean flag ;
052 LabelVisible( boolean flag ) { this.flag = flag; }
053 public boolean booleanValue() { return flag; }
054 };
055
056 /** For serialization. */
057 private int skip = 1; // skip数
058 private int count = 0; // skip 時ã?現在位置のカウンãƒ?
059
060 private transient List<LabelVisible> labelBreak = null;
061 private int cutNo = -1; // 4.1.1.0 (2008/02/04) ラベルブレイクのsubstring 位置
062 private String breakKey = null; // 4.1.1.0 (2008/02/04) ラベルブレイクの前回キー
063 private boolean isItemLabelLastVisible = false; // 4.1.2.0 (2008/03/12)
064 private final int hsCode = Long.valueOf( System.nanoTime() ).hashCode() ; // 5.1.9.0 (2010/08/01) equals,hashCode
065
066 /**
067 * 引数を指定して作æ?する コンストラクター
068 *
069 * skip(ラベルの表示間隔) = 1 , cutNo(ラベルブレイクのsubstring 位置) = -1 で初期化しますã?
070 *
071 * @param label ラベル
072 */
073 public HybsCategoryAxis( final String label ) {
074 this( label,1,-1 );
075 }
076
077 /**
078 * 引数を指定して作æ?する コンストラクター
079 *
080 * @og.rev 4.1.1.0 (2008/02/04) cutNo 新規追åŠ?
081 *
082 * @param label ラベル
083 * @param skip ラベルの表示間隔
084 * @param cutNo ラベルブレイクのsubstring 位置
085 */
086 protected HybsCategoryAxis( final String label,final int skip,final int cutNo ) {
087 super( label );
088 this.skip = skip ;
089 this.cutNo = cutNo ;
090 }
091
092 /**
093 * itemLabelVisible 時に、最後ã?値のみ表示するかどã�?�‹[true/false]を指定しますã?
094 *
095 * これは、itemLabelVisible 属æ?にã€?last" とã�?�†設定å?を指定したå?合ã?ã€?
096 * æœ?¾Œã?みラベル表示しますã?
097 * こã?メソãƒ?ƒ‰では、true が指定された場合ã?ã€?last" 属æ?が有効になったと
098 * 判断しますã?
099 *
100 * @og.rev 4.1.2.0 (2008/03/12) 新規追åŠ?
101 *
102 * @param flag æœ?¾Œã?値のみ表示するかどã�?�‹[true/false]
103 */
104 protected void setItemLabelLastVisible( final boolean flag ) {
105 isItemLabelLastVisible = flag;
106 }
107
108 /**
109 * 軸を引く場合ã?使用することができるチックのä¸?™‚çš?ƒªストを作æ?しますã?
110 *
111 * @og.rev 4.1.1.0 (2008/02/04) labelBreak 新規追åŠ?
112 *
113 * @param g2 Graphics2Dオブジェクãƒ?フォント測定に使用)
114 * @param state AxisStateオブジェクãƒ?
115 * @param dataArea インサイドエリアを示すRectangle2Dオブジェクãƒ?
116 * @param edge ロケーションを指定するRectangleEdgeオブジェクãƒ?
117 *
118 * @return チックのリスãƒ?
119 */
120 @Override
121 public List<?> refreshTicks( final Graphics2D g2,
122 final AxisState state,
123 final Rectangle2D dataArea,
124 final RectangleEdge edge) {
125 count = 0;
126 labelBreak = new ArrayList<LabelVisible>();
127
128 return super.refreshTicks( g2, state, dataArea, edge);
129 }
130
131 /**
132 * TextBlock オブジェクトを作æ?しますã?
133 *
134 * こã?メソãƒ?ƒ‰ではã€?¼“つの拡張機è?を実現してã�?�¾すã?
135 * ?‘ï¼?_" ラベルのスキãƒ??(非表示)
136 * ?’.cutNo 属æ?による、ラベルæ–?—位置æŒ?®šã?キーブレイク
137 * ?“.skip 属æ?による、ラベルをスキãƒ??する間隔のæŒ?®?
138 * cutNo が指定された場合ã?、skip 処ç�??行われません。またã?
139 * そã?場合ã?ラベルは、cutNoでæŒ?®šされた先é?æ–?—å?のみ表示されますã?
140 * æ–?—å?がã?cutNoでæŒ?®šされた数より小さã�??合ã?、そのまま使用されますã?
141 *
142 * @og.rev 4.1.1.0 (2008/02/04) cutNo,labelBreak 追åŠ?
143 * @og.rev 4.1.2.0 (2008/03/12) LabelVisible.UNDER 処ç�?‚’追åŠ?
144 * @og.rev 4.3.1.1 (2008/08/23) lbl の null参ç?はずしの対å¿?
145 *
146 * @param category カãƒ?‚´リå�?
147 * @param width å¹?
148 * @param edge 表示ç¯?›²を示すRectangleEdgeオブジェクãƒ?
149 * @param g2 Graphics2Dオブジェクãƒ?
150 *
151 * @return TextBlockオブジェクãƒ?
152 */
153 @SuppressWarnings("rawtypes")
154 protected TextBlock createLabel( final Comparable category, final float width,
155 final RectangleEdge edge, final Graphics2D g2) {
156 TextBlock label = null ;
157 String lbl = null;
158 // if( category != null && category instanceof String ) {
159 if( category instanceof String ) { // 4.3.1.1 (2008/08/23) instanceof チェãƒ?‚¯は、nullチェãƒ?‚¯不è¦?
160 lbl = (String)category;
161 if( lbl.startsWith( "_" ) ) {
162 label = NULL_LABEL;
163 }
164 }
165
166 // if( lbl.startsWith( "_" ) ) {
167 // label = NULL_LABEL;
168 // }
169 // else if( cutNo > 0 && lbl != null ) {
170 if( cutNo > 0 && lbl != null ) {
171 if( lbl.length() >= cutNo ) {
172 lbl = lbl.substring( 0,cutNo );
173 }
174
175 if( ! lbl.equals( breakKey ) ) {
176 label = super.createLabel( lbl, width, edge, g2);
177 breakKey = lbl ;
178 }
179 }
180 else {
181 if( count % skip == 0 ) {
182 label = super.createLabel( category, width, edge, g2);
183 }
184 count++;
185 }
186
187 if( label == null ) {
188 label = NULL_LABEL;
189 labelBreak.add( LabelVisible.FALSE );
190 }
191 else if( label.equals( NULL_LABEL ) ) {
192 labelBreak.add( LabelVisible.UNDER );
193 }
194 else {
195 labelBreak.add( LabelVisible.TRUE );
196 }
197
198 return label;
199 }
200
201 /**
202 * ラベルブレイクするかどã�?�‹を返しますã?
203 *
204 * skip またã?、cutNo によるラベルの間引き処ç�?�§、指定ã?CategoryAxis
205 * に対するカラãƒ?•ª号を指定する事で、判定å?を返しますã?
206 * 処ç�?�Œ、Label の作æ?済みかどã�?�‹に依存する為、その判定を先に行いますã?
207 *
208 * @og.rev 4.1.1.0 (2008/02/04) 新規追åŠ?
209 *
210 * @param column カラãƒ?•ª号
211 *
212 * @return ラベルブレイクするかどã�?�‹(true:する)
213 */
214 protected boolean isLabelBreak( final int column ) {
215 return labelBreak == null ||
216 labelBreak.size() <= column ||
217 labelBreak.get( column ).booleanValue() ;
218 }
219
220 /**
221 * ITEM ラベル(å�?ƒ‡ータの設定å?の説明用の値)を表示するかどã�?�‹を返しますã?
222 *
223 * ラベルの先é?に、アンãƒ??スコアがつã�?�Ÿラベルは、ラベルの表示と
224 * ItemLabel の表示を抑止しますã?(false)
225 * それ以外ã?ラベルは、表示する(true) を返しますã?
226 * 処ç�?�Œ、Label の作æ?済みかどã�?�‹に依存する為、その判定を先に行いますã?
227 *
228 * @og.rev 4.1.2.0 (2008/03/12) 新規追åŠ?
229 *
230 * @param column カラãƒ?•ª号
231 *
232 * @return ITEMラベルを表示するかどã�?�‹(true:する)
233 */
234 protected boolean isViewItemLabel( final int column ) {
235 boolean flag = labelBreak == null ||
236 labelBreak.size() <= column ||
237 labelBreak.get( column ) != LabelVisible.UNDER ;
238
239 if( flag && isItemLabelLastVisible && labelBreak.size() -1 != column ) {
240 flag = false;
241 }
242
243 return flag;
244 }
245
246 /**
247 * ドメイン(横軸)のカãƒ?‚´リ単位ã?ライン(縦ç·?の描画位置を返しますã?
248 *
249 * こã?位置は、labelBreak が存在しなã�?�‹、またã?、ブレークするときã?み
250 * 値を返しますã?これにより、ライン(縦ç·?の位置をã?グラフã?中å¿?�‹ã‚?
251 * ずらす事が可能になりますã?
252 * またã?labelBreak により、ラベルを描画しなã�??合ã?、線ã?位置をã???に
253 * 設定する事で、画面から見えなくしますã?
254 *
255 * @param anchor CategoryAnchorオブジェクãƒ?
256 * @param category カãƒ?‚´リ番号
257 * @param categoryCount カãƒ?‚´リ数
258 * @param area ç¯?›²を表すRectangle2Dオブジェクãƒ?
259 * @param edge ロケーションを指定するRectangleEdgeオブジェクãƒ?
260 *
261 * @return ライン(縦ç·?の描画位置
262 */
263 @Override
264 public double getCategoryJava2DCoordinate( final CategoryAnchor anchor,
265 final int category,
266 final int categoryCount,
267 final Rectangle2D area,
268 final RectangleEdge edge) {
269
270 final double result ;
271
272 // labelBreak が存在しなã�?�‹、またã?、ブレークするときã?み値を返すã€?
273 if( isLabelBreak( category ) ) {
274 result = super.getCategoryJava2DCoordinate(
275 anchor,category,categoryCount,area,edge
276 ) ;
277 }
278 else {
279 result = 0;
280 }
281 return result ;
282 }
283
284 /**
285 * こã?æ–?—å?とæŒ?®šされたオブジェクトを比è¼?�—ますã?
286 *
287 * 親クラスで、equals メソãƒ?ƒ‰が実è£?�•れてã�?‚‹ため、警告がでますã?
288 *
289 * @og.rev 5.1.8.0 (2010/07/01) findbug対å¿?
290 * @og.rev 5.1.9.0 (2010/08/01) findbug対å¿?
291 *
292 * @param object 比è¼?�™るオブジェクãƒ?
293 *
294 * @return Objectが等しã�??合ã? true、そã�?�§なã�??合ã? false
295 */
296 @Override
297 public boolean equals( final Object object ) {
298 // return super.equals( object );
299 if( super.equals( object ) ) {
300 return hsCode == ((HybsCategoryAxis)object).hsCode;
301 }
302 return false;
303 }
304
305 /**
306 * こã?オブジェクトã?ハッシュコードを取得しますã?
307 *
308 * @og.rev 5.1.8.0 (2010/07/01) findbug対å¿?
309 * @og.rev 5.1.9.0 (2010/08/01) findbug対å¿?
310 *
311 * @return ハッシュコーãƒ?
312 */
313 // public int hashCode() { return super.hashCode() ; }
314 @Override
315 public int hashCode() { return hsCode ; }
316
317 /**
318 * Tests this axis for equality with an arbitrary object.
319 *
320 * @og.rev 4.1.0.1(2008/01/19) 新規追åŠ?
321 * @og.rev 5.1.8.0 (2010/07/01) å»?¢
322 *
323 * @param obj the object (<code>null</code> permitted).
324 *
325 * @return A boolean.
326 */
327 // public boolean equals( final Object obj ) {
328 // if( obj == null ) {
329 // return false;
330 // }
331 // if( obj == this ) {
332 // return true;
333 // }
334 // if( !(obj instanceof HybsCategoryAxis) ) {
335 // return false;
336 // }
337 // if( !super.equals(obj) ) {
338 // return false;
339 // }
340 // HybsCategoryAxis that = (HybsCategoryAxis) obj;
341 // if( that.count != count || that.skip != skip || that.cutNo != cutNo ) {
342 // return false;
343 // }
344 //
345 // return true;
346 // }
347
348 /**
349 * Returns a hash code for this object.
350 *
351 * @og.rev 4.1.0.1(2008/01/19) 新規追åŠ?
352 * @og.rev 5.1.8.0 (2010/07/01) å»?¢
353 *
354 * @return A hash code.
355 */
356 // public int hashCode() {
357 // return ( getLabel() + ":" + count + ":" + skip + ":" + cutNo ).hashCode();
358 // }
359 }