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 */ 016package org.opengion.hayabusa.io; 017 018import java.awt.Graphics2D; 019import java.awt.Stroke; 020import java.awt.Paint; 021import java.awt.geom.Rectangle2D; 022import java.util.List; 023import java.util.Map; 024import java.util.HashMap; 025import java.util.Iterator; 026 027import org.jfree.chart.plot.CategoryPlot; 028import org.jfree.chart.plot.PlotRenderingInfo; 029import org.jfree.chart.urls.CategoryURLGenerator; 030import org.jfree.chart.axis.CategoryAxis; 031import org.jfree.chart.axis.ValueAxis; 032import org.jfree.chart.axis.ValueTick; 033import org.jfree.chart.renderer.category.CategoryItemRenderer; 034import org.jfree.chart.renderer.category.CategoryItemRendererState; 035import org.jfree.chart.renderer.category.StackedBarRenderer; 036import org.jfree.data.category.CategoryDataset; 037import 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 */ 053public 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 int rangeSkip = 1; // 4.1.1.0 (2008/02/04) 縦軸のグリッドをスキップする間隔 059 private final int hsCode = Long.valueOf( System.nanoTime() ).hashCode() ; // 5.1.9.0 (2010/08/01) equals,hashCode 060 061 /** 062 * デフォルトコンストラクター 063 * シリーズ番号を、初期化しておきます。 064 * 065 **/ 066 public HybsCategoryPlot() { 067 // 4.3.4.4 (2009/01/01) 068 this( -1 ); 069 } 070 071 /** 072 * シリーズ番号 を、指定して、オブジェクトを作成するコンストラクター 073 * 074 * @param serNo ピックアップするシリーズ番号 075 **/ 076 protected HybsCategoryPlot( final int serNo ) { 077 // 4.3.4.4 (2009/01/01) 078 this.serNo = serNo; 079 } 080 081 /** 082 * ピックアップするシリーズ番号を設定します。 083 * 084 * @og.rev 4.1.1.0 (2008/02/04) データの値(itemText)表示の継承 085 * 086 * @param newSerNo ピックアップするシリーズ番号 087 **/ 088 protected void setSeriesPikup( final int newSerNo ) { 089 int oldSerNo = serNo ; 090 serNo = newSerNo; 091 CategoryItemRenderer rend = getRenderer(); 092 CategoryURLGenerator urlGen = rend.getSeriesItemURLGenerator( oldSerNo ); 093 if( urlGen != null ) { 094 rend.setSeriesItemURLGenerator( oldSerNo,null ); 095 rend.setSeriesItemURLGenerator( serNo ,urlGen ); 096 } 097 098 // 4.1.1.0 (2008/02/04) データの値(itemText)表示の継承 099 if( rend.isSeriesItemLabelsVisible( oldSerNo ) ) { 100 rend.setSeriesItemLabelsVisible( oldSerNo,false ); 101 rend.setSeriesItemLabelsVisible( serNo ,true ); 102 } 103 } 104 105 /** 106 * 縦軸のグリッド線(水平線)をスキップする間隔を指定します。 107 * 108 * 縦軸のグリッド線を表示する際に、スキップする間隔を指定します。 109 * 通常は、ラベルと同じだけのグリッド線が掛かれますが、ラベルよりも 110 * 少ない数のグリッド線(例えば、2つおき)を出す場合に、値を設定します。 111 * "1" (初期値)では、1つづつ表示(つまり、すべて表示する)します。 112 * "2" とすると、1つおきに、"3" とすると、2つおきに表示します。 113 * 初期値は、"1" (すべて表示)です。 114 * なお、先頭から表示を開始します。 115 * 116 * @og.rev 4.1.1.0 (2008/02/04) 新規追加 117 * 118 * @param rngSkip 縦軸のグリッド線(水平線)をスキップする間隔 119 */ 120 protected void setRangeSkip( final int rngSkip ) { 121 rangeSkip = rngSkip; 122 } 123 124 /** 125 * BarChart のバーの幅を直接指定します。 126 * 通常は、maxBarWidth や itemMargin で比率指定しますが、 127 * ここでは、CategoryItemRendererState オブジェクトに直接設定する為の 128 * データセット単位のマップを作成します。 129 * 130 * @param index データセット番号 131 * @param width バーの幅 132 **/ 133 protected void setBarWidth( final int index,final Double width ) { 134 barWidths.put( index,width ); 135 } 136 137 /** 138 * Draws a representation of a dataset within the dataArea region using the 139 * appropriate renderer. 140 * 141 * @param g2 the graphics device. 142 * @param dataArea the region in which the data is to be drawn. 143 * @param index the dataset and renderer index. 144 * @param info an optional object for collection dimension information. 145 * 146 * @return 描画するデータが見つかった場合は、true 147 */ 148 public boolean render( final Graphics2D g2, final Rectangle2D dataArea, final int index, 149 final PlotRenderingInfo info ) { 150 boolean foundData = false; 151 CategoryDataset currentDataset = getDataset(index); 152 CategoryItemRenderer renderer = getRenderer(index); 153 // 4.3.1.0 (2008/08/19) 軸とデータセットのマッピング 154 this.mapDatasetToRangeAxis( index, index ); 155 156 CategoryAxis domainAxis = null ; 157 if( renderer instanceof StackedBarRenderer ) { 158 domainAxis = getDomainAxis(index); 159 } 160 else { 161 domainAxis = getDomainAxisForDataset(index); 162 } 163 164 ValueAxis rangeAxis = getRangeAxis(index); 165 boolean hasData = !DatasetUtilities.isEmptyOrNull(currentDataset); 166 if(hasData && renderer != null) { 167 foundData = true; 168 CategoryItemRendererState state = renderer.initialise(g2, dataArea, 169 this, index, info); 170 171 // 4.0.3.0 (2008/01/07) 棒グラフのバー幅指定 172 Double bwidth = barWidths.get( index ); 173 if( bwidth != null ) { state.setBarWidth( bwidth.doubleValue() ); } 174 175 if( renderer instanceof HybsDrawItem ) { 176 ((HybsDrawItem)renderer).drawItem2(g2, state, dataArea, this, 177 domainAxis, rangeAxis, currentDataset , serNo ); 178 } 179 else { 180 int columnCount = currentDataset.getColumnCount(); 181 int rowCount = currentDataset.getRowCount(); 182 int passCount = renderer.getPassCount(); 183 for( int pass=0; pass<passCount; pass++ ) { 184 for( int column=0; column<columnCount; column++ ) { 185 for( int row=0; row<rowCount; row++ ) { 186 if( row == serNo ) { continue; } // Mis Add 2007/07/23 187 renderer.drawItem(g2, state, dataArea, this, 188 domainAxis, rangeAxis, currentDataset, 189 row, column, pass); 190 } 191 // 指定のシリーズと一致する場合は、最後に描画する。 Mis Add 2007/07/23 192 if( serNo >= 0 ) { 193 renderer.drawItem(g2, state, dataArea, this, 194 domainAxis, rangeAxis, currentDataset, 195 serNo, column, pass); 196 } 197 } 198 } 199 } 200 } 201 return foundData; 202 } 203 204 /** 205 * Draws the gridlines for the plot. 206 * 207 * @param g2 the graphics device. 208 * @param dataArea the area inside the axes. 209 * @param ticks the ticks. 210 * 211 * @see #drawDomainGridlines(Graphics2D, Rectangle2D) 212 */ 213 @SuppressWarnings("rawtypes") 214 protected void drawRangeGridlines( final Graphics2D g2, final Rectangle2D dataArea, 215 final List ticks ) { 216 // draw the range grid lines, if any... 217 218 if (isRangeGridlinesVisible()) { 219 Stroke gridStroke = getRangeGridlineStroke(); 220 Paint gridPaint = getRangeGridlinePaint(); 221 if ( gridStroke != null && gridPaint != null ) { 222 ValueAxis axis = getRangeAxis(); 223 CategoryItemRenderer renderer1 = getRenderer(); 224 if (axis != null && renderer1 != null) { 225 Iterator<?> iterator = ticks.iterator(); 226 int cnt = 0; 227 while (iterator.hasNext()) { 228 ValueTick tick = (ValueTick) iterator.next(); 229 if( cnt % rangeSkip == 0 ) { 230 renderer1.drawRangeGridline(g2, this, 231 axis, dataArea, tick.getValue()); 232 } 233 cnt++ ; 234 } 235 } 236 } 237 } 238 } 239 240 /** 241 * この文字列と指定されたオブジェクトを比較します。 242 * 243 * 親クラスで、equals メソッドが実装されているため、警告がでます。 244 * 245 * @og.rev 5.1.8.0 (2010/07/01) findbug対応 246 * @og.rev 5.1.9.0 (2010/08/01) findbug対応 247 * 248 * @param object 比較するオブジェクト 249 * 250 * @return Objectが等しい場合は true、そうでない場合は false 251 */ 252 @Override 253 public boolean equals( final Object object ) { 254 if( super.equals( object ) ) { 255 return hsCode == ((HybsCategoryPlot)object).hsCode; 256 } 257 return false; 258 } 259 260 /** 261 * このオブジェクトのハッシュコードを取得します。 262 * 263 * @og.rev 5.1.8.0 (2010/07/01) findbug対応 264 * @og.rev 5.1.9.0 (2010/08/01) findbug対応 265 * 266 * @return ハッシュコード 267 */ 268 @Override 269 public int hashCode() { return hsCode ; } 270}