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 org.jfree.chart.renderer.category.LineAndShapeRenderer;
019 import org.jfree.chart.renderer.category.CategoryItemRendererState;
020 import org.jfree.ui.RectangleEdge;
021
022 import java.awt.Graphics2D;
023 import java.awt.Shape;
024 import java.awt.Color;
025 import java.awt.Paint;
026 import java.awt.Stroke;
027 import java.awt.geom.Line2D;
028 import java.awt.geom.Rectangle2D;
029 import java.io.IOException;
030 import java.io.ObjectOutputStream;
031 import java.io.ObjectInputStream;
032
033 import org.jfree.chart.axis.CategoryAxis;
034 import org.jfree.chart.axis.ValueAxis;
035 import org.jfree.chart.entity.EntityCollection;
036 import org.jfree.chart.plot.CategoryPlot;
037 import org.jfree.chart.plot.PlotOrientation;
038 import org.jfree.data.category.CategoryDataset;
039 import org.jfree.data.general.DatasetUtilities;
040 import org.jfree.data.Range;
041 import org.jfree.util.ShapeUtilities;
042
043 import java.awt.geom.AffineTransform;
044
045 /**
046 * HybsLineRenderer は、org.jfree.chart.renderer.category.LineAndShapeRenderer ã‚?
047 * 拡張したカスタマイズクラスですã?
048 * これは、描画に対して、予め制限を設けて、å?ç�??度の向上を図ってã�?�¾すã?
049 *
050 * @og.rev 3.8.9.2 (2007/07/28) 新規作æ?
051 *
052 * @version 0.9.0 2001/05/05
053 * @author Kazuhiko Hasegawa
054 * @since JDK1.1,
055 */
056 public class HybsLineRenderer extends LineAndShapeRenderer implements HybsDrawItem {
057 private static final long serialVersionUID = 519020100801L ;
058
059 private transient ValueMarkOverColors overColors = null; // 4.0.3.0 (2008/01/07) マã?カーラインでShapeをå?り替える時ã?色æŒ?®?
060
061 private Color[] shapeColors = null; // 4.0.3.0 (2008/01/07) ãƒ??タ毎にShapeをå?り替える時ã?色æŒ?®?
062 private double visibleLimit = Double.NEGATIVE_INFINITY;
063 private int dynamicOCNo = -1; // 4.1.1.0 (2008/02/04) 動的なマã?カーラインの基準シリーズ番号
064 private String shapeScale = null; // 4.1.1.0 (2008/02/04) shapeの大きさの倍率
065 private boolean isItemLabelLastVisible = false; // 4.1.2.0 (2008/03/12)
066 private final int hsCode = Long.valueOf( System.nanoTime() ).hashCode() ; // 4.3.1.1 (2008/08/23)
067
068 /**
069 * Creates a renderer with both lines and shapes visible by default.
070 */
071 public HybsLineRenderer() {
072 super(true, true);
073 }
074
075 /**
076 * Creates a new renderer with lines and/or shapes visible.
077 *
078 * @param lines draw lines?
079 * @param shapes draw shapes?
080 */
081 public HybsLineRenderer( final boolean lines, final boolean shapes ) {
082 super(lines,shapes);
083 }
084
085 /**
086 * ãƒ??タ毎にShapeをå?り替える時ã?色の繰返しパターンを文字å?配å?でæŒ?®šしますã?
087 *
088 * HybsLine でのみ使用可能ですã?
089 * これは、データそã?もã?がã?繰返し性のある場合に、その繰返し性に対応しã�?
090 * 形状のShape を表示させるå?合に使用しますã?
091 * 繰返しShapeの形状は、JFreeChart のシリーズ毎ã?繰返し標準形状を使用しますã?
092 * 現在のバã?ジョンではã€?¼‘0å?までの繰返しに対応可能ですã?
093 * 繰返し色をã?æŒ?®šしたå?ã�?�‘ã€??に使用されてã�?��ますã?
094 *
095 * æŒ?®š文字å?は、java.awt.Color クラスのstatic フィールド名でæŒ?®šしますã?
096 * BLACK , BLUE , CYAN , DARK_GRAY , GRAY , GREEN , LIGHT_GRAY ,
097 * MAGENTA , ORANGE , PINK , RED , WHITE , YELLOW , (PURPLE) が指定できますã?
098 * またã?#XXXXXX形式ã?16bitRGB表è¨?でも指定可能ですã?
099 *
100 * @og.rev 4.0.3.0 (2008/01/07) 新規追åŠ?
101 *
102 * @param colors ãƒ??タ毎ã?色の繰返しパターン(æ–?—å?配å?)
103 * @see java.awt.Color#BLACK
104 */
105 protected void setShapeColors( final Color[] colors ) {
106 shapeColors = colors;
107 }
108
109 /**
110 * shapeの大きさをå?çŽ?Œ‡定で変更しまã�?初期値:null)ã€?
111 *
112 * ラインチャートã?Shape(å�?‚°ラフã?ポイントã?マã?カー)の大きさはã€??常はã€?
113 * 自動設定されますã?
114 * こã?大きさをã?倍率æŒ?®šで、変更可能ですã?
115 * æŒ?®šã?、double 型ですã?
116 * 初期値は、null は、スケール変更しません(自動設定ã?ままの大きさ)
117 *
118 * @og.rev 4.1.1.0 (2008/02/04) 新規追åŠ?
119 *
120 * @param scale shapeの大きさの倍率
121 */
122 protected void setShapeScale( final String scale ) {
123 shapeScale = scale;
124 }
125
126 /**
127 * マã?カーラインのè¶?�Ž時ã?Shape色管ç�?‚¯ラスを設定しますã?
128 *
129 * 動的なマã?カーラインを使用する場合ã?、引数のシリーズãƒ??タã�?
130 * マã?カーラインのæœ?¸‹位閾値に相当しますã?これは、グラフ化されますがã€?
131 * Shape は自動的に削除されますã?
132 * é€?�«、最上位ã?ãƒ??タ(シリーズ?�ï¼?のShape はå¿?�š付けますã?
133 *
134 * @og.rev 4.1.0.1(2008/01/19) 新規追åŠ?
135 * @og.rev 4.1.1.0 (2008/02/04) 動的なオーバã?カラー
136 *
137 * @param vmoc マã?カーラインのè¶?�Ž時ã?Shape色管ç�?‚¯ラス
138 * @param dynamicOverColorNo 動的なマã?カーラインの基準シリーズ番号
139 */
140 protected void setValueMarkOverColors( final ValueMarkOverColors vmoc,
141 final int dynamicOverColorNo ) {
142 overColors = vmoc;
143 dynamicOCNo = dynamicOverColorNo;
144 }
145
146 /**
147 * 表示下限値(これ以下ã?ãƒ??タは未表示)の値(double)を指定しますã?
148 *
149 * HybsLine でのみ使用可能ですã?
150 * こã?設定å?以下ã?ãƒ??タは、存在しなã�?‰±ã�?�¨しますã?
151 * Lineを引くときã?こã?ãƒ??タと、存在してã�?‚‹ãƒ??タ間にラインは引かれませんã€?
152 * 何もæŒ?®šしなã�??合ã?、設定しませんã€?
153 *
154 * @og.rev 4.0.3.0 (2008/01/07) 新規追åŠ?
155 *
156 * @param limit 表示下限値(これ以下ã?ãƒ??タは未表示)
157 */
158 protected void setVisibleLimit( final double limit ) {
159 visibleLimit = limit;
160 }
161
162 /**
163 * itemLabelVisible 時に、最後ã?値のみ表示するかどã�?�‹[true:有効/false:無効]を指定しますã?
164 *
165 * これは、itemLabelVisible 属æ?にã€?last" とã�?�†設定å?を指定したå?合ã?ã€?
166 * æœ?¾Œã?みラベル表示しますã?
167 * こã?メソãƒ?ƒ‰では、true が指定された場合ã?ã€?last" 属æ?が有効になったと
168 * 判断しますã?
169 *
170 * @og.rev 4.1.2.0 (2008/03/12) 新規追åŠ?
171 *
172 * @param flag æœ?¾Œã?値のみ表示するかどã�?�‹[true:有効/false:無効]
173 */
174 public void setItemLabelLastVisible( final boolean flag ) {
175 isItemLabelLastVisible = flag;
176 }
177
178 /**
179 * drawItem と同等ã?機è?を持ったã?高é?版メソãƒ?ƒ‰ですã?
180 *
181 * @og.rev 4.0.3.0 (2008/01/07) shapeColors 属æ?追åŠ?
182 * @og.rev 4.1.1.0 (2008/02/04) 繰返しshapeの開始番号(shapeStartNo)追åŠ?
183 * @og.rev 4.1.1.0 (2008/02/04) seriesColors 属æ?は、色(Paint)のみåˆ?‚Š替えるようにするã€?
184 * @og.rev 4.1.1.0 (2008/02/04) ラベルブレイク機è?の追åŠ?HybsCategoryAxis)
185 * @og.rev 4.1.1.0 (2008/02/04) 動的なマã?カーライン
186 * @og.rev 4.1.1.0 (2008/02/22) Stroke を設定するロジãƒ?‚¯を追åŠ?
187 * @og.rev 4.1.2.0 (2008/03/12) ラベルのアンãƒ??ライン時にItemLavelを表示しなã�?
188 *
189 * @param g2 Graphics2Dオブジェクãƒ?
190 * @param state CategoryItemRendererStateオブジェクãƒ?
191 * @param dataArea Rectangle2Dオブジェクãƒ?
192 * @param plot CategoryPlotオブジェクãƒ?
193 * @param domainAxis CategoryAxisオブジェクãƒ?
194 * @param rangeAxis ValueAxisオブジェクãƒ?
195 * @param dataset CategoryDatasetオブジェクãƒ?
196 * @param serNo シリアル番号
197 */
198 public void drawItem2( final Graphics2D g2, final CategoryItemRendererState state,
199 final Rectangle2D dataArea, final CategoryPlot plot, final CategoryAxis domainAxis,
200 final ValueAxis rangeAxis, final CategoryDataset dataset, final int serNo ) {
201
202 int clmCount = dataset.getColumnCount();
203 int rowCount = dataset.getRowCount();
204 RectangleEdge domEdge = plot.getDomainAxisEdge();
205 RectangleEdge rangeEdge = plot.getRangeAxisEdge();
206
207 boolean isShape = getBaseShapesVisible() ;
208
209 HybsCategoryAxis hybsAxis = null;
210 if( domainAxis instanceof HybsCategoryAxis ) {
211 hybsAxis = (HybsCategoryAxis)domainAxis;
212 hybsAxis.setItemLabelLastVisible( isItemLabelLastVisible );
213 }
214
215 // ãƒ??タ毎にShapeをå?り替える時ã?色の繰返しパターン
216 int shpCnt = ( shapeColors == null ) ? 1 : shapeColors.length;
217
218 // Shape の形状を指定できる。任意ではなくã?表示é ??開始位置のæŒ?®?
219 int shapeNo = 0 ;
220
221 // shapeの大きさの倍率
222 AffineTransform transform = null;
223 if( shapeScale != null ) {
224 double scale = Double.parseDouble( shapeScale );
225 transform = AffineTransform.getScaleInstance( scale, scale );
226 }
227
228 // 4.1.1.0 (2008/02/22) Stroke を設定するロジãƒ?‚¯を追åŠ?
229 Stroke baseStroke = getBaseStroke();
230 if( baseStroke != null ) { g2.setStroke( baseStroke ); }
231
232 // トリãƒ?‚ー?šrow == serNo をå?ç�?�—たいがためにã€?¼‘回余å?にループをまわすã€?
233 for( int row=0; row<=rowCount; row++ ) {
234 if( row == serNo ) { continue; } // Mis Add 2007/07/23
235 if( row >= rowCount ) {
236 if( serNo >= 0 ) {
237 row = serNo;
238 rowCount = -1; // 終äº?�¡件
239 }
240 else {
241 break;
242 }
243 }
244
245 // 4.1.1.0 (2008/02/22) Stroke を設定するロジãƒ?‚¯を追åŠ?
246 Stroke serStroke = getSeriesStroke( row );
247 if( serStroke != null ) { g2.setStroke( serStroke ); }
248
249 Paint rowPaint = lookupSeriesPaint( row );
250 Shape rowShape = lookupSeriesShape( shapeNo );
251
252 // shapeの大きさの倍率
253 if( transform != null ) {
254 rowShape = transform.createTransformedShape(rowShape);
255 }
256
257 Paint linePaint = rowPaint ;
258 // 4.1.1.0 (2008/02/04) 動的なマã?カーライン(row==dynamicOCNoのãƒ??タで判å®?
259 boolean shapeFlag = false;
260 if( row == dynamicOCNo ) { // 使わなã�??合ã?ã€?1 なので、ã?ãƒ?ƒ�しなã�??
261 if( overColors != null ) {
262 linePaint = overColors.getDynamicColor();
263 }
264 }
265 else {
266 // 動的なマã?カーライン使用æ™?dynamicOCNo >= 0)は、row == 0 で、Shape を使ã�?�¾すã?
267 if( isShape || row == serNo || ( dynamicOCNo >= 0 && row == 0 ) ) {
268 shapeFlag = true;
269 shapeNo++ ; // Shape 形状の変更は、使用した場合ã?み
270 }
271 }
272
273 double v0 = 0;
274 double x0 = 0;
275 double y0 = 0;
276
277 boolean isItemLabelsVisible = isSeriesItemLabelsVisible( row );
278
279 int clmSeq = 0; // カラãƒ??繰返し制御(Shape色のé ?•ª表示用)
280 for( int column=0; column<clmCount; column++ ) {
281 // nothing is drawn for null...
282 Number v1Num = dataset.getValue( row,column );
283 if(v1Num == null) { continue; }
284 double v1 = v1Num.doubleValue();
285 double x1 = domainAxis.getCategoryMiddle( column,clmCount,dataArea,domEdge );
286 double y1 = rangeAxis.valueToJava2D( v1,dataArea,rangeEdge );
287
288 // Line の描画
289 if( column > 0 && v0 >= visibleLimit && v1 >= visibleLimit ) {
290 Line2D line = new Line2D.Double( x0,y0,x1,y1 );
291 g2.setPaint( linePaint );
292 g2.draw( line );
293 }
294
295 // Shape の描画
296 if( shapeFlag ) {
297 // ラベルブレイク処ç�?
298 if( hybsAxis != null && hybsAxis.isLabelBreak( column ) ) {
299 clmSeq = 0; // 初期åŒ?
300 }
301
302 int adrs = clmSeq%shpCnt;
303 clmSeq++ ;
304 Paint paint = ( shapeColors == null ) ? rowPaint : shapeColors[adrs];
305 // 4.1.1.0 (2008/02/04) 動的なマã?カーライン(row==dynamicOCNoのãƒ??タで判å®?
306 if( overColors != null ) {
307 if( dynamicOCNo >= 0 ) {
308 paint = overColors.getColor( v1,dataset.getValue( dynamicOCNo,column ) );
309 }
310 else {
311 paint = overColors.getColor( v1 );
312 }
313 }
314 g2.setPaint(paint);
315 Shape shape = ShapeUtilities.createTranslatedShape( rowShape,x1,y1 );
316 g2.fill(shape);
317 g2.setPaint(rowPaint); // 色を戻すã?
318 // 4.3.1.0 (2008/08/09) add an item entity, if this information is being collected
319 EntityCollection entities = state.getEntityCollection();
320 if( entities != null ) {
321 addItemEntity( entities, dataset, row, column, shape );
322 }
323 }
324
325 // ItemLabel の描画
326 // 山形 0-1-0 nega=fale , x= 0 上中
327 // 右å�?0-1-2 nega=true , x=10 下右
328 // 谷形 1-0-1 nega=true , x= 0 下中
329 // 左å�?2-1-0 nega=fale , x=10 上右
330 if( isItemLabelsVisible ) {
331 // 4.1.2.0 (2008/03/12) アンãƒ??スコアの場合ã?、表示しなã�??
332 if( hybsAxis != null && hybsAxis.isViewItemLabel( column ) ) {
333 double v2 = v0 ; // 仮設å®?æœ?¾Œã?columnとnull の場å�?
334 if( column+1 < clmCount ) {
335 Number v2Num = dataset.getValue( row,column+1 );
336 if( v2Num != null ) {
337 v2 = v2Num.doubleValue();
338 }
339 }
340 boolean nega = ( v1<v2 ) ;
341 double lblx = ( nega && v0<v1 || !nega && v0>v1 ) ? x1 + 10 : x1 ;
342
343 drawItemLabel( g2,PlotOrientation.VERTICAL,dataset,row,column,lblx,y1,nega );
344 }
345 }
346
347 v0 = v1; // Lineを消す処ç�?�«ã€?�Ž去の値がå¿?¦?
348 x0 = x1;
349 y0 = y1;
350 }
351 }
352 }
353
354 /**
355 * こã?æ–?—å?とæŒ?®šされたオブジェクトを比è¼?�—ますã?
356 *
357 * 親クラスで、equals メソãƒ?ƒ‰が実è£?�•れてã�?‚‹ため、警告がでますã?
358 *
359 * @og.rev 5.1.8.0 (2010/07/01) findbug対å¿?
360 *
361 * @param object Object
362 *
363 * @return Objectが等しã�??合ã? true、そã�?�§なã�??合ã? false
364 */
365 // @Override
366 // public boolean equals( final Object object ) {
367 // return super.equals( object );
368 // }
369
370 /**
371 * こã?オブジェクトã?ハッシュコードを取得しますã?
372 *
373 * @og.rev 5.1.8.0 (2010/07/01) findbug対å¿?
374 *
375 * @return ハッシュコーãƒ?
376 */
377 // public int hashCode() { return super.hashCode() ; }
378
379 /**
380 * こã?オブジェクトとæŒ?®šされたオブジェクトを比è¼?�—ますã?
381 *
382 * @og.rev 4.3.1.1 (2008/08/23) 新規追åŠ?
383 * @og.rev 5.1.9.0 (2010/08/01) findbug対å¿?
384 *
385 * @param anObject 比è¼?�•れるオブジェクãƒ?
386 *
387 * @return æŒ?®šされたオブジェクトが等しã�??合ã? true、そã�?�§なã�??合ã? false
388 */
389 @Override
390 public boolean equals( final Object anObject ) {
391 // return this == anObject;
392 if( super.equals( anObject ) ) {
393 return hsCode == ((HybsLineRenderer)anObject).hsCode;
394 }
395 return false;
396 }
397
398 /**
399 * こã?オブジェクトã?ハッシュコードを返しますã?
400 *
401 * @og.rev 4.3.1.1 (2008/08/23) 新規追åŠ?
402 * @og.rev 5.1.9.0 (2010/08/01) findbug対å¿?
403 *
404 * @return こã?オブジェクトã?ハッシュコードå?
405 */
406 @Override
407 public int hashCode() { return hsCode ; }
408
409 /**
410 * æŒ?®šされたãƒ??タセãƒ?ƒˆからのアイãƒ?ƒ をすべて表示するために、要求するå?のç¯?›²を返しますã?
411 *
412 * @param dataset カãƒ?‚´リDataset
413 *
414 * @return Rangeオブジェクãƒ?
415 */
416 @Override
417 public Range findRangeBounds( final CategoryDataset dataset ) {
418 if( dataset instanceof HybsJDBCCategoryDataset2 ) {
419 return ((HybsJDBCCategoryDataset2)dataset).getRange();
420 }
421 else {
422 return DatasetUtilities.findRangeBounds(dataset);
423 }
424 }
425
426 /**
427 * シリアライズ用のカスタãƒ?‚·リアライズ書き込みメソãƒ?ƒ‰
428 *
429 * @og.rev 4.1.0.1(2008/01/19) 新規追åŠ?
430 * @serialData ä¸?ƒ¨のオブジェクãƒ?ValueMarkOverColors)は、シリアライズされませんã€?
431 *
432 * @param strm ObjectOutputStreamオブジェクãƒ?
433 * @throws IOException 入出力エラーが発生したå?å�?
434 */
435 private void writeObject( final ObjectOutputStream strm ) throws IOException {
436 strm.defaultWriteObject();
437 }
438
439 /**
440 * シリアライズ用のカスタãƒ?‚·リアライズ読み込みメソãƒ?ƒ‰
441 *
442 * ここでは、transient 宣è¨?�•れたå†?ƒ¨変数のå†??初期化がå¿?¦�なフィールドã?み設定しますã?
443 *
444 * @og.rev 4.1.0.1(2008/01/19) 新規追åŠ?
445 * @serialData ä¸?ƒ¨のオブジェクãƒ?ValueMarkOverColors)は、読み込まれませんã€?
446 *
447 * @param strm ObjectInputStreamオブジェクãƒ?
448 * @throws IOException シリアライズに関する入出力エラーが発生したå?å�?
449 * @throws ClassNotFoundException クラスを見つけることができなかったå?å�?
450 */
451 private void readObject( final ObjectInputStream strm ) throws IOException , ClassNotFoundException {
452 strm.defaultReadObject();
453 }
454 }