    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.GradientPaint;
    019import java.awt.Graphics2D;
    020import java.awt.Paint;
    021import java.awt.Stroke;
    022import java.awt.geom.Rectangle2D;
    023
    024import org.jfree.chart.renderer.category.BarRenderer;
    025import org.jfree.chart.renderer.category.CategoryItemRendererState;
    026import org.jfree.chart.axis.CategoryAxis;
    027import org.jfree.chart.axis.ValueAxis;
    028import org.jfree.chart.labels.CategoryItemLabelGenerator;
    029import org.jfree.chart.plot.CategoryPlot;
    030import org.jfree.chart.plot.PlotOrientation;
    031import org.jfree.chart.entity.EntityCollection;
    032import org.jfree.data.category.CategoryDataset;
    033import org.jfree.ui.GradientPaintTransformer;
    034import org.jfree.ui.RectangleEdge;
    035
    036/**
    037 * HybsBarRenderer は、org.jfree.chart.renderer.category.BarRenderer を
    038 * 拡張したカスタマイズクラスです。
    039 * これは、描画に対して、予め制限を設けて、処理速度の向上を図っています。
    040 *
    041 * @og.rev 4.1.1.0 (2008/02/04) 新規作成
    042 *
    043 * @version  0.9.0      2001/05/05
    044 * @author       Kazuhiko Hasegawa
    045 * @since        JDK1.1,
    046 */
    047public class HybsBarRenderer extends BarRenderer implements HybsDrawItem {
    048        private static final long serialVersionUID = 519020100801L ;
    049
    050        private transient ValueMarkOverColors overColors = null;        // 5.9.24.3 (2017/09/29) マーカーラインでShapeを切り替える時の色指定
    051        private int             dynamicOCNo  = -1;                      // 4.1.1.0 (2008/02/04) 動的なマーカーラインの基準シリーズ番号
    052
    053
    054        private boolean isItemLabelLastVisible = false; // 4.1.2.0 (2008/03/12)
    055        private final int hsCode = Long.valueOf( System.nanoTime() ).hashCode() ;       // 5.1.9.0 (2010/08/01) equals,hashCode
    056
    057        // 4.3.4.4 (2009/01/01)
    058//      /**
    059//       * Creates a new bar renderer with default settings.
    060//       */
    061//      public HybsBarRenderer() {
    062//              super();
    063//      }
    064
    065        /**
    066         * itemLabelVisible 時に、最後の値のみ表示するかどうか[true:有効/false:無効]を指定します。
    067         *
    068         * これは、itemLabelVisible 属性に、"last" という設定値を指定した場合は、
    069         * 最後のみラベル表示します。
    070         * このメソッドでは、true が指定された場合は、"last" 属性が有効になったと
    071         * 判断します。
    072         *
    073         * @og.rev 4.1.2.0 (2008/03/12) 新規追加
    074         *
    075         * @param       flag    最後の値のみ表示するかどうか[true:有効/false:無効]
    076         */
    077        public void setItemLabelLastVisible( final boolean flag ) {
    078                isItemLabelLastVisible = flag;
    079        }
    080
    081        /**
    082         * マーカーラインの超過時のShape色管理クラスを設定します。
    083         *
    084         * 動的なマーカーラインを使用する場合は、引数のシリーズデータが
    085         * マーカーラインの最下位閾値に相当します。これは、グラフ化されますが、
    086         * Shape は自動的に削除されます。
    087         * 逆に、最上位のデータ(シリーズ＝０)のShape は必ず付けます。
    088         *
    089         * @og.rev 4.1.0.1(2008/01/19) 新規追加
    090         *
    091         * @param       vmoc    マーカーラインの超過時のShape色管理クラス
    092         * @param       dynamicOverColorNo      動的なマーカーラインの基準シリーズ番号
    093         */
    094        protected void setValueMarkOverColors( final ValueMarkOverColors vmoc,
    095                                                                                final int dynamicOverColorNo ) {
    096                overColors      = vmoc;
    097                dynamicOCNo     = dynamicOverColorNo;
    098        }
    099
    100        /**
    101         * drawItem と同等の機能を持った、高速版メソッドです。
    102         *
    103         * @og.rev 4.1.1.0 (2008/02/04) 新規追加
    104         * @og.rev 4.1.2.0 (2008/03/12) ラベルのアンダーライン時にItemLavelを表示しない
    105         * @og.rev 5.9.24.3 (2017/09/29) overColor対応
    106         *
    107         * @param g2                    Graphics2Dオブジェクト
    108         * @param state                 CategoryItemRendererStateオブジェクト
    109         * @param dataArea              Rectangle2Dオブジェクト
    110         * @param plot                  CategoryPlotオブジェクト
    111         * @param domainAxis    CategoryAxisオブジェクト
    112         * @param rangeAxis             ValueAxisオブジェクト
    113         * @param dataset               CategoryDatasetオブジェクト
    114         * @param serNo                 シリアル番号
    115         */
    116        public void drawItem2( final Graphics2D g2, final CategoryItemRendererState state,
    117                        final Rectangle2D dataArea, final CategoryPlot plot, final CategoryAxis domainAxis,
    118                        final ValueAxis rangeAxis, final CategoryDataset dataset, final int serNo ) {
    119
    120                int clmCount = dataset.getColumnCount();
    121                int rowCount = dataset.getRowCount();
    122                RectangleEdge edge = plot.getRangeAxisEdge();
    123
    124                PlotOrientation orientation = plot.getOrientation();
    125                double minBarLen = getMinimumBarLength();
    126                double barWidth  = state.getBarWidth();
    127                boolean isDrawOutline = isDrawBarOutline() &&
    128                                                                        state.getBarWidth() > BAR_OUTLINE_WIDTH_THRESHOLD ;
    129
    130                // 4.1.2.0 (2008/03/12)
    131                HybsCategoryAxis hybsAxis = null;
    132                if( domainAxis instanceof HybsCategoryAxis ) {
    133                        hybsAxis = (HybsCategoryAxis)domainAxis;
    134                        hybsAxis.setItemLabelLastVisible( isItemLabelLastVisible );
    135                }
    136
    137                for( int row=0; row<rowCount; row++ ) {
    138                        boolean isItemLabelsVisible = isSeriesItemLabelsVisible( row );
    139
    140                        for( int column=0; column<clmCount; column++ ) {
    141                                Number v1Num = dataset.getValue( row,column );
    142                                if(v1Num == null) { continue; }
    143                                double value = v1Num.doubleValue();
    144
    145                                // 書き出し開始位置をずらす。
    146                                double barW0 = calculateBarW0( plot,orientation,dataArea,domainAxis,state,row,column );
    147                                double[] barL0L1 = calculateBarL0L1( value );
    148                                if (barL0L1 == null) { continue; }
    149
    150                                double transL0 = rangeAxis.valueToJava2D( barL0L1[0],dataArea,edge );
    151                                double transL1 = rangeAxis.valueToJava2D( barL0L1[1],dataArea,edge );
    152                                double barL0 = Math.min( transL0,transL1 );
    153                                double barLength = Math.max( Math.abs( transL1 - transL0 ),minBarLen );
    154
    155
    156
    157                                // Bar の描画
    158                                Rectangle2D bar = null;
    159                                if( orientation == PlotOrientation.HORIZONTAL ) {
    160                                        bar = new Rectangle2D.Double( barL0,barW0,barLength,barWidth );
    161                                }
    162                                else {
    163                                        bar = new Rectangle2D.Double( barW0,barL0,barWidth,barLength );
    164                                }
    165
    166                                Paint itemPaint = getItemPaint( row,column );
    167                                // 4.3.1.1 (2008/08/23) 変数名を t ⇒ gpt に変更
    168                                GradientPaintTransformer gpt = getGradientPaintTransformer();
    169                                if( gpt != null && itemPaint instanceof GradientPaint ) {
    170                                        itemPaint = gpt.transform( (GradientPaint) itemPaint,bar );
    171                                }
    172
    173                                // 5.9.24.3 (2017/09/29) overColor対応 とりあえずfillカラーのみ
    174                                Paint paint = itemPaint;
    175                                if( overColors != null ) {
    176                                        if( dynamicOCNo >= 0 ) {
    177                                                paint = overColors.getColor( value,dataset.getValue( dynamicOCNo,column ) );
    178                                        }
    179                                        else {
    180                                                paint = overColors.getColor( value );
    181                                        }
    182                                }
    183
    184//                              g2.setPaint( itemPaint );
    185                                g2.setPaint( paint );
    186                                g2.fill( bar );
    187
    188                                // outline の描画
    189                                if( isDrawOutline ) {
    190                                        Stroke stroke = getItemOutlineStroke( row,column );
    191//                                      Paint paint = getItemOutlinePaint( row,column );
    192                                        paint = getItemOutlinePaint( row,column ); // 5.9.24.3 (2017/09/29)
    193                                        if( stroke != null && paint != null ) {
    194                                                g2.setStroke( stroke );
    195                                                g2.setPaint( paint );
    196                                                g2.draw( bar );
    197                                        }
    198                                }
    199
    200                                // ItemLabel の描画
    201                                CategoryItemLabelGenerator generator = getItemLabelGenerator( row,column );
    202                                if( generator != null && isItemLabelsVisible ) {
    203                                        // 4.1.2.0 (2008/03/12) アンダースコアの場合は、表示しない。
    204                                        if( hybsAxis != null && hybsAxis.isViewItemLabel( column ) ) {
    205                                                drawItemLabel( g2,dataset,row,column,plot,generator,bar,(value < 0.0) );
    206                                        }
    207                                }
    208                                // 4.3.1.0 (2008/08/09) item entity の追加
    209                                EntityCollection entities = state.getEntityCollection();
    210                                if( entities != null ) {
    211                                        addItemEntity( entities, dataset, row, column, bar );
    212                                }
    213                        }
    214                }
    215        }
    216
    217        /**
    218         * この文字列と指定されたオブジェクトを比較します。
    219         *
    220         * 親クラスで、equals メソッドが実装されているため、警告がでます。
    221         *
    222         * @og.rev 5.1.8.0 (2010/07/01) findbug対応
    223         * @og.rev 5.1.9.0 (2010/08/01) findbug対応
    224         *
    225         * @param       object  比較するオブジェクト
    226         *
    227         * @return      Objectが等しい場合は true、そうでない場合は false
    228         */
    229        @Override
    230        public boolean equals( final Object object ) {
    231//              return super.equals( object );
    232                if( super.equals( object ) ) {
    233                        return hsCode == ((HybsBarRenderer)object).hsCode;
    234                }
    235                return false;
    236        }
    237
    238        /**
    239         * このオブジェクトのハッシュコードを取得します。
    240         *
    241         * @og.rev 5.1.8.0 (2010/07/01) findbug対応
    242         * @og.rev 5.1.9.0 (2010/08/01) findbug対応
    243         *
    244         * @return      ハッシュコード
    245         */
    246//      public int hashCode() { return super.hashCode() ; }
    247        @Override
    248        public int hashCode() { return hsCode ; }
    249
    250        /**
    251         * このオブジェクトと指定されたオブジェクトを比較します。
    252         *
    253         * @og.rev 4.3.1.1 (2008/08/23) 新規追加
    254         * @og.rev 5.1.8.0 (2010/07/01) 廃止
    255         *
    256         * @param anObject Object 比較されるオブジェクト
    257         *
    258         * @return      指定されたオブジェクトが等しい場合は true、そうでない場合は false
    259         */
    260//      public boolean equals( final Object anObject ) {
    261//              if( super.equals( anObject ) ) {
    262//                      HybsBarRenderer other = ((HybsBarRenderer)anObject);
    263//                      return ( isItemLabelLastVisible == other.isItemLabelLastVisible );
    264//              }
    265//              return false;
    266//      }
    267
    268        /**
    269         * このオブジェクトのハッシュコードを返します。
    270         *
    271         * @og.rev 4.3.1.1 (2008/08/23) 新規追加
    272         * @og.rev 5.1.8.0 (2010/07/01) 廃止
    273         *
    274         * @return      このオブジェクトのハッシュコード値
    275         */
    276//      public int hashCode() {
    277//              return super.hashCode() + ( (isItemLabelLastVisible) ? 1 : 0 );
    278//      }
    279}