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 }