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.GradientPaint;
019    import java.awt.Graphics2D;
020    import java.awt.Paint;
021    import java.awt.geom.Rectangle2D;
022    
023    import org.jfree.chart.entity.EntityCollection;
024    import org.jfree.chart.renderer.category.StackedBarRenderer;
025    import org.jfree.chart.renderer.category.CategoryItemRendererState;
026    import org.jfree.chart.axis.CategoryAxis;
027    import org.jfree.chart.axis.ValueAxis;
028    import org.jfree.chart.labels.CategoryItemLabelGenerator;
029    import org.jfree.chart.plot.CategoryPlot;
030    import org.jfree.chart.plot.PlotOrientation;
031    import org.jfree.data.category.CategoryDataset;
032    import org.jfree.ui.GradientPaintTransformer;
033    import org.jfree.ui.RectangleEdge;
034    import org.jfree.data.DataUtilities;
035    
036    /**
037     * HybsStackedBarRenderer ã¯ã€org.jfree.chart.renderer.category.StackedBarRenderer ã‚?
038     * æ‹¡å¼µã—ãŸã‚«ã‚¹ã‚¿ãƒžã‚¤ã‚ºã‚¯ãƒ©ã‚¹ã§ã™ã?
039     * ã“れã¯ã€ã‚°ãƒ©ãƒ•ã?書ãå?ã—ä½ç½®ã®èª¿æ•´æ¯”率(domainMargin)を設定ã§ãã¾ã™ã?
040     *
041     * @og.rev 4.1.1.0 (2008/02/16) æ–°è¦ä½œæ?
042     *
043     * @version  0.9.0      2001/05/05
044     * @author       Kazuhiko Hasegawa
045     * @since        JDK1.1,
046     */
047    public class HybsStackedBarRenderer extends StackedBarRenderer  {
048            private static final long serialVersionUID = 519020100801L ;
049    
050            private double  domainMargin    = 0.0;          // 4.1.1.0 (2008/02/14) グラフã?書ãå?ã—ä½ç½®ã®èª¿æ•´æ¯”率
051    
052            private final int hsCode = Long.valueOf( System.nanoTime() ).hashCode() ;       // 5.1.9.0 (2010/08/01) equals,hashCode
053    
054            // 4.3.4.4 (2009/01/01)
055    //      /**
056    //       * Creates a new bar renderer with default settings.
057    //       */
058    //      public HybsStackedBarRenderer() {
059    //              super();
060    //      }
061    
062            /**
063             * グラフã?書ãå?ã—ä½ç½®ã®èª¿æ•´æ¯”率を指定ã—ã¾ã™ã?
064             *
065             * グラフをæç”»ã™ã‚‹å ´åˆã?ã€æ›¸ãå?ã—ä½ç½®ã‚’å°‘ã—ãšã‚‰ã—ã¾ã™ã?
066             * ã“れã¯ã€ã‚°ãƒ©ãƒ•ã?å¹?«å¯¾ã—ã¦ã€æ¯”çŽ‡ã§æŒ?®šã—ã¾ã™ã?
067             * 0.0(åˆæœŸå€¤)ã®å ´åˆã?ã€å?期æç”»ä½ç½®ã§ã‚ã‚‹ã€CategoryAnchor.Middle ã¨
068             * åŒã˜ç®?‰€ã‹ã‚‰ã€æ›¸ãå?ã•れã¾ã™ã?
069             * 1.0 ã®å ´åˆã?中å¿?‹ã‚‰ã?グラフå¹??åŠå?ãŒåŠ ç®—ã•れã?ENDä½ç½®ã«å¯?‚Šã¾ã™ã?
070             * åŒæ§˜ã«ã€?1.0 ã®å ´åˆã?ã€ã‚°ãƒ©ãƒ•å¹??åŠå?ãŒæ¸›ç®—ã•れã?START ä½ç½®ã«ãªã‚Šã¾ã™ã?
071             * ã¤ã¾ã‚Šã?中å¿?‹ã‚‰ã?グラフå¹??åŠå?å˜ä½ã§ã€å‰æ–¹/後方ã«ãšã‚‰ã™äº‹ãŒå‡ºæ¥ã¾ã™ã?
072             *   書ãå?ã—ä½ç½® ??中å¿?Middle) + (domainMargin)?Šå¹???
073             * åˆæœŸå€¤ã¯ã€?.0(真ん中:MIDDLE)ã§ã™ã?
074             *
075             * @og.rev 4.1.1.0 (2008/02/14) æ–°è¦è¿½åŠ?
076             *
077             * @param       margin  グラフã?書ãå?ã—ä½ç½®ã®èª¿æ•´æ¯”率
078             */
079            public void setDomainMargin( final double margin ) {
080                    domainMargin = margin;
081            }
082    
083            /**
084             * Draws a stacked bar for a specific item.
085             *
086             * @param g2  the graphics device.
087             * @param state  the renderer state.
088             * @param dataArea      the plot area.
089             * @param plot  the plot.
090             * @param domainAxis  the domain (category) axis.
091             * @param rangeAxis  the range (value) axis.
092             * @param dataset  the data.
093             * @param row  the row index (zero-based).
094             * @param column  the column index (zero-based).
095             * @param pass  the pass index.
096             */
097            @Override
098            public void drawItem( final Graphics2D g2,
099                                                      final CategoryItemRendererState state,
100                                                      final Rectangle2D dataArea,
101                                                      final CategoryPlot plot,
102                                                      final CategoryAxis domainAxis,
103                                                      final ValueAxis rangeAxis,
104                                                      final CategoryDataset dataset,
105                                                      final int row,
106                                                      final int column,
107                                                      final int pass) {
108    
109                    // nothing is drawn for null values...
110                    Number dataValue = dataset.getValue(row, column);
111                    if (dataValue == null) {
112                            return;
113                    }
114    
115                    double value = dataValue.doubleValue();
116                    double total = 0.0;  // only needed if calculating percentages
117                    if (getRenderAsPercentages()) {
118                            total = DataUtilities.calculateColumnTotal(dataset, column);
119                            value = value / total;
120                    }
121    
122                    PlotOrientation orientation = plot.getOrientation();
123    
124                    double barW0 = domainAxis.getCategoryStart(column, getColumnCount(),
125                                    dataArea, plot.getDomainAxisEdge())
126                                    + domainMargin * state.getBarWidth() / 2.0;
127    
128                    double positiveBase = getBase();
129                    double negativeBase = positiveBase;
130    
131                    // 4.3.1.1 (2008/08/23) 変数åãŒçŸ­ã??ã§å¤‰æ›´(v â‡?nm , d â‡?vd )
132                    for (int i = 0; i < row; i++) {
133                            Number nm = dataset.getValue(i, column);
134                            if (nm != null) {
135                                    double vd = nm.doubleValue();
136                                    if (getRenderAsPercentages()) {
137                                            vd = vd / total;
138                                    }
139                                    if (vd > 0) {
140                                            positiveBase = positiveBase + vd;
141                                    }
142                                    else {
143                                            negativeBase = negativeBase + vd;
144                                    }
145                            }
146                    }
147    
148                    double translatedBase;
149                    double translatedValue;
150                    RectangleEdge location = plot.getRangeAxisEdge();
151                    if (value >= 0.0) {
152                            translatedBase = rangeAxis.valueToJava2D(positiveBase, dataArea,
153                                            location);
154                            translatedValue = rangeAxis.valueToJava2D(positiveBase + value,
155                                            dataArea, location);
156                    }
157                    else {
158                            translatedBase = rangeAxis.valueToJava2D(negativeBase, dataArea,
159                                            location);
160                            translatedValue = rangeAxis.valueToJava2D(negativeBase + value,
161                                            dataArea, location);
162                    }
163                    double barL0 = Math.min(translatedBase, translatedValue);
164                    double barLength = Math.max(Math.abs(translatedValue - translatedBase),
165                                    getMinimumBarLength());
166    
167                    Rectangle2D bar = null;
168                    if (orientation == PlotOrientation.HORIZONTAL) {
169                            bar = new Rectangle2D.Double(barL0, barW0, barLength,
170                                            state.getBarWidth());
171                    }
172                    else {
173                            bar = new Rectangle2D.Double(barW0, barL0, state.getBarWidth(),
174                                            barLength);
175                    }
176                    if (pass == 0) {
177                            Paint itemPaint = getItemPaint(row, column);
178                            // 4.3.1.1 (2008/08/23) 変数åã‚’ t â‡?gpt ã«å¤‰æ›´
179                            GradientPaintTransformer gpt = getGradientPaintTransformer();
180                            if (gpt != null && itemPaint instanceof GradientPaint) {
181                                    itemPaint = gpt.transform((GradientPaint) itemPaint, bar);
182                            }
183                            g2.setPaint(itemPaint);
184                            g2.fill(bar);
185                            if (isDrawBarOutline()
186                                            && state.getBarWidth() > BAR_OUTLINE_WIDTH_THRESHOLD) {
187                                    g2.setStroke(getItemOutlineStroke(row, column));
188                                    g2.setPaint(getItemOutlinePaint(row, column));
189                                    g2.draw(bar);
190                            }
191    
192                            // add an item entity, if this information is being collected
193                            EntityCollection entities = state.getEntityCollection();
194                            if (entities != null) {
195                                    addItemEntity(entities, dataset, row, column, bar);
196                            }
197                    }
198                    else if (pass == 1) {
199                            CategoryItemLabelGenerator generator = getItemLabelGenerator(row,
200                                            column);
201                            if (generator != null && isItemLabelVisible(row, column)) {
202                                    drawItemLabel(g2, dataset, row, column, plot, generator, bar,
203                                                    (value < 0.0));
204                            }
205                    }
206            }
207    
208            /**
209             * ã“ã?æ–?­—å?ã¨æŒ?®šã•れãŸã‚ªãƒ–ジェクトを比è¼?—ã¾ã™ã?
210             *
211             * 親クラスã§ã€equals メソãƒ?ƒ‰ãŒå®Ÿè£?•れã¦ã?‚‹ãŸã‚ã€è­¦å‘ŠãŒã§ã¾ã™ã?
212             *
213             * @og.rev 5.1.8.0 (2010/07/01) findbug対�
214             * @og.rev 5.1.9.0 (2010/08/01) findbug対�
215             *
216             * @param       object  比è¼?™ã‚‹ã‚ªãƒ–ジェクãƒ?
217             *
218             * @return      ObjectãŒç­‰ã—ã??åˆã? trueã€ãã?§ãªã??åˆã? false
219             */
220            @Override
221            public boolean equals( final Object object ) {
222    //              return super.equals( object );
223                    if( super.equals( object ) ) {
224                            return hsCode == ((HybsStackedBarRenderer)object).hsCode;
225                    }
226                    return false;
227            }
228    
229            /**
230             * ã“ã?オブジェクトã?ãƒãƒƒã‚·ãƒ¥ã‚³ãƒ¼ãƒ‰ã‚’å–å¾—ã—ã¾ã™ã?
231             *
232             * @og.rev 5.1.8.0 (2010/07/01) findbug対�
233             * @og.rev 5.1.9.0 (2010/08/01) findbug対�
234             *
235             * @return      ãƒãƒƒã‚·ãƒ¥ã‚³ãƒ¼ãƒ?
236             */
237    //      public int hashCode() { return super.hashCode() ; }
238            @Override
239            public int hashCode() { return hsCode ; }
240    
241            /**
242             * ã“ã?ã‚ªãƒ–ã‚¸ã‚§ã‚¯ãƒˆã¨æŒ?®šã•れãŸã‚ªãƒ–ジェクトを比è¼?—ã¾ã™ã?
243             *
244             * @og.rev 4.3.1.1 (2008/08/23) æ–°è¦è¿½åŠ?
245             * @og.rev 5.1.8.0 (2010/07/01) å»?­¢
246             *
247             * @param anObject Object 比è¼?•れるオブジェクãƒ?
248             *
249             * @return      æŒ?®šã•れãŸã‚ªãƒ–ジェクトãŒç­‰ã—ã??åˆã? trueã€ãã?§ãªã??åˆã? false
250             */
251    //      public boolean equals( final Object anObject ) {
252    //              if( super.equals( anObject ) ) {
253    //                      HybsStackedBarRenderer other = ((HybsStackedBarRenderer)anObject);
254    ////                    return ( domainMargin == other.domainMargin );
255    //                      return Double.compare( domainMargin,other.domainMargin ) == 0 ;
256    //              }
257    //              return false;
258    //      }
259    
260            /**
261             * ã“ã?オブジェクトã?ãƒãƒƒã‚·ãƒ¥ã‚³ãƒ¼ãƒ‰ã‚’è¿”ã—ã¾ã™ã?
262             *
263             * @og.rev 4.3.1.1 (2008/08/23) æ–°è¦è¿½åŠ?
264             * @og.rev 5.1.8.0 (2010/07/01) å»?­¢
265             *
266             * @return      ã“ã?オブジェクトã?ãƒãƒƒã‚·ãƒ¥ã‚³ãƒ¼ãƒ‰å?
267             */
268    //      public int hashCode() {
269    //              return super.hashCode() ^ Double.valueOf( domainMargin ).hashCode() ;
270    //      }
271    }