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 431 * 432 * @param strm ObjectOutputStreamオブジェク? 433 */ 434 private void writeObject( final ObjectOutputStream strm ) throws IOException { 435 strm.defaultWriteObject(); 436 } 437 438 /** 439 * シリアライズ用のカスタ?リアライズ読み込みメソ? 440 * 441 * ここでは、transient 宣?れた?変数の??初期化が?なフィールド?み設定します? 442 * 443 * @og.rev 4.1.0.1(2008/01/19) 新規追? 444 * @serialData 445 * 446 * @param strm ObjectInputStreamオブジェク? 447 */ 448 private void readObject( final ObjectInputStream strm ) throws IOException , ClassNotFoundException { 449 strm.defaultReadObject(); 450 } 451 }