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