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.opengion.fukurou.util.StringUtil;
019    import org.opengion.hayabusa.common.HybsSystem;
020    import org.opengion.hayabusa.common.HybsSystemException;
021    import org.opengion.hayabusa.db.DBTableModel;
022    
023    import java.sql.Connection;
024    import java.sql.SQLException;
025    import java.util.Map;
026    import java.util.HashMap;
027    import java.util.Arrays;
028    
029    import org.jfree.chart.LegendItemSource;
030    import org.jfree.data.jdbc.JDBCPieDataset;
031    import org.jfree.data.jdbc.JDBCXYDataset;
032    import org.jfree.data.general.Dataset;
033    import org.jfree.data.general.DefaultValueDataset;
034    
035    import org.jfree.data.category.DefaultCategoryDataset;
036    import org.jfree.data.xy.CategoryTableXYDataset;
037    import org.jfree.data.general.DefaultPieDataset;
038    import org.jfree.data.DefaultKeyedValues;
039    
040    /**
041     * ChartFactory は、Dataset および、Renderer のオブジェクトを構築するファクトリクラスです?
042     * JFreeChart では、各種オブジェクト??合わせで、色?グラフを作?できます?
043     * ここでは、簡易的にオブジェクトを構築できるように、?のキーワードによって、各種作?する
044     * オブジェクト?キーワードを関連付けておきます?
045     *
046     * <table border="1" frame="box" rules="all" >
047     * <tr><th> チャートタイ?         </th><th> レン?ー(org.jfree.chart.renderer.)    </th><th> Dataset     </th></tr>
048     * <tr><td> HybsLine                </td><td> HybsLineRenderer                         </td><td> Category    </td></tr>
049     * <tr><td> HybsBar                 </td><td> HybsBarRenderer                          </td><td> Category    </td></tr>
050     * <tr><td> HybsStackedBar          </td><td> HybsStackedBarRenderer                   </td><td> Category    </td></tr>
051     * <tr><td> Area                    </td><td> category.AreaRenderer                    </td><td> Category    </td></tr>
052     * <tr><td> Bar                     </td><td> category.BarRenderer                     </td><td> Category    </td></tr>
053     * <tr><td> Bar3D                   </td><td> category.BarRenderer3D                   </td><td> Category    </td></tr>
054     * <tr><td> CategoryStep            </td><td> category.CategoryStepRenderer            </td><td> Category    </td></tr>
055     * <tr><td> Gantt                   </td><td> category.GanttRenderer                   </td><td> TaskSeries  </td></tr>
056     * <tr><td> GroupedStackedBar       </td><td> category.GroupedStackedBarRenderer       </td><td> Category    </td></tr>
057     * <tr><td> LayeredBar              </td><td> category.LayeredBarRenderer              </td><td> Category    </td></tr>
058     * <tr><td> Level                   </td><td> category.LevelRenderer                   </td><td> Category    </td></tr>
059     * <tr><td> LineAndShape            </td><td> category.LineAndShapeRenderer            </td><td> Category    </td></tr>
060     * <tr><td> Line3D                  </td><td> category.LineRenderer3D                  </td><td> Category    </td></tr>
061     * <tr><td> MinMax                  </td><td> category.MinMaxCategoryRenderer          </td><td> Category    </td></tr>
062     * <tr><td> StackedArea             </td><td> category.StackedAreaRenderer             </td><td> Category    </td></tr>
063     * <tr><td> StackedBar              </td><td> category.StackedBarRenderer              </td><td> Category    </td></tr>
064     * <tr><td> StackedBar3D            </td><td> category.StackedBarRenderer3D            </td><td> Category    </td></tr>
065     * <tr><td> StatisticalLineAndShape </td><td> category.StatisticalLineAndShapeRenderer </td><td> Category    </td></tr>
066     * <tr><td> WaterfallBar            </td><td> category.WaterfallBarRenderer            </td><td> Category    </td></tr>
067     * <tr><td> ClusteredXYBarV         </td><td> xy.ClusteredXYBarRenderer                </td><td> TimeSeries  </td></tr>
068     * <tr><td> CyclicXYItem            </td><td> xy.CyclicXYItemRenderer                  </td><td> XY          </td></tr>
069     * <tr><td> DeviationV              </td><td> xy.DeviationRenderer                     </td><td> TimeSeries  </td></tr>
070     * <tr><td> HighLow                 </td><td> xy.HighLowRenderer                       </td><td> XY          </td></tr>
071     * <tr><td> StackedXYArea           </td><td> xy.StackedXYAreaRenderer                 </td><td> XY          </td></tr>
072     * <tr><td> StackedXYArea2          </td><td> xy.StackedXYAreaRenderer2                </td><td> XY          </td></tr>
073     * <tr><td> StandardXYItem          </td><td> xy.StandardXYItemRenderer                </td><td> XY          </td></tr>
074     * <tr><td> XYArea                  </td><td> xy.XYAreaRenderer                        </td><td> XY          </td></tr>
075     * <tr><td> XYArea2                 </td><td> xy.XYAreaRenderer2                       </td><td> XY          </td></tr>
076     * <tr><td> XYBarV                  </td><td> xy.XYBarRenderer                         </td><td> TimeSeries  </td></tr>
077     * <tr><td> XYBlock                 </td><td> xy.XYBlockRenderer                       </td><td> XY          </td></tr>
078     * <tr><td> XYBubble                </td><td> xy.XYBubbleRenderer                      </td><td> XY          </td></tr>
079     * <tr><td> XYDifference            </td><td> xy.XYDifferenceRenderer                  </td><td> XY          </td></tr>
080     * <tr><td> XYDot                   </td><td> xy.XYDotRenderer                         </td><td> XY          </td></tr>
081     * <tr><td> XYError                 </td><td> xy.XYErrorRenderer                       </td><td> XY          </td></tr>
082     * <tr><td> XYLine3D                </td><td> xy.XYLine3DRenderer                      </td><td> XY          </td></tr>
083     * <tr><td> XYLineAndShape          </td><td> xy.XYLineAndShapeRenderer                </td><td> XY          </td></tr>
084     * <tr><td> XYStepArea              </td><td> xy.XYStepAreaRenderer                    </td><td> XY          </td></tr>
085     * <tr><td> XYStep                  </td><td> xy.XYStepRenderer                        </td><td> XY          </td></tr>
086     * <tr><td> YIntervalV              </td><td> xy.YIntervalRenderer                     </td><td> TimeSeries  </td></tr>
087     * <tr><td> PolarItem               </td><td> DefaultPolarItemRenderer                 </td><td> XY          </td></tr>
088     * <tr><td> Compass                 </td><td> null                                     </td><td> Value       </td></tr>
089     * <tr><td> Meter                   </td><td> null                                     </td><td> Value       </td></tr>
090     * <tr><td> MultiplePie             </td><td> null                                     </td><td> Category    </td></tr>
091     * <tr><td> Pie                     </td><td> null                                     </td><td> Pie         </td></tr>
092     * <tr><td> Pie3D                   </td><td> null                                     </td><td> Pie         </td></tr>
093     * <tr><td> Ring                    </td><td> null                                     </td><td> Pie         </td></tr>
094     * <tr><td> SpiderWeb               </td><td> null                                     </td><td> Category    </td></tr>
095     * <tr><td> Thermometer             </td><td> null                                     </td><td> Value       </td></tr>
096     * <tr><td> TimeSeriesLineV         </td><td> xy.StandardXYItemRenderer                </td><td> TimeSeries  </td></tr>
097     * <tr><td> TimeSeriesLineH         </td><td> xy.StandardXYItemRenderer                </td><td> TimeSeries  </td></tr>
098     * <tr><td> TimeSeriesBarV          </td><td> xy.XYBarRenderer                         </td><td> TimeSeries  </td></tr>
099     * <tr><td> TimeSeriesBarH          </td><td> xy.XYBarRenderer                         </td><td> TimeSeries  </td></tr>
100     * <tr><td> StackedTimeSeriesLineV  </td><td> xy.StandardXYItemRenderer                </td><td> TimeSeries  </td></tr>
101     * <tr><td> StackedTimeSeriesLineH  </td><td> xy.StandardXYItemRenderer                </td><td> TimeSeries  </td></tr>
102     * </table>
103     *
104     * @version  0.9.0      2007/06/21
105     * @author       Kazuhiko Hasegawa
106     * @since        JDK1.1,
107     */
108    public class ChartFactory {
109    
110            private static final String PLOT_SUB = "org.opengion.hayabusa.io.ChartPlot_" ;
111    
112            // ChartPlot オブジェクト?マルチスレ?で使用可能なため、キャ?ュして使?わします?
113            private static volatile ChartPlot plot_cat  = null ;
114            private static volatile ChartPlot plot_xy   = null ;
115            private static volatile ChartPlot plot_pie  = null ;
116            private static volatile ChartPlot plot_tim  = null ;            // 5.6.1.0 (2013/02/01)
117            private static volatile ChartPlot plot_xtim = null ;            // 5.6.1.0 (2013/02/01)
118    
119            private static final Object lock = new Object();
120    
121            /**
122             * ?ォルトコンストラクタ?private 化しておきます?
123             *
124             */
125            private ChartFactory() {}
126    
127            /**
128             * Connection と query ??から、Dataset オブジェクトを作?します?
129             *
130             * 引数のtypeは、?部定義の TYPE_RENDERER_MAP マップで関連付けられたキーワー?
131             * より、対象とするチャート特性を取得します?(getTypeRenderer)
132             * そ? TypeRenderer#getDatasetType() メソ?の値を?に、Dataset クラスは?
133             * "org.jfree.data.jdbc.JDBC****Dataset" の **** の?を特定します?
134             * 現状は、Category , Pie , XY の?種???Value??タセ?が選択されます?
135             *
136             * @og.rev 3.8.9.2 (2007/07/28) HybsJDBCCategoryDataset 追?
137             * @og.rev 5.3.0.0 (2010/12/01) そ?他?Dataset 追?
138             * @og.rev 5.6.1.0 (2013/02/01) 時間軸を持つチャー?TimeSeries 追?
139             *
140             * @param       conn    Dataset の取得?のコネクション
141             * @param       query   取得するクエリー??
142             * @param       type    Dataset オブジェクト?作??求めるキーワー?
143             *
144             * @return      Datasetオブジェク?
145             *
146             * @see     #getTypeRenderer( String )
147             * @see     #newDataset( DBTableModel ,String )
148             * @throws SQLException
149             */
150            public static final Dataset newDataset( final Connection conn,final String query,final String type )
151                                                                            throws SQLException {
152                    final Dataset dataset ;
153    
154                    TypeRenderer rend = getTypeRenderer( type );
155    
156                    String dsType = rend.getDatasetType();
157                    if( "Category".equalsIgnoreCase( dsType ) ) {
158                            dataset = new HybsJDBCCategoryDataset2( conn, query );          // series の横持ち
159                    }
160                    else if( "XY".equalsIgnoreCase( dsType ) ) {
161                            dataset = new JDBCXYDataset( conn, query );
162                    }
163                    else if( "Pie".equalsIgnoreCase( dsType ) ) {
164                            dataset = new JDBCPieDataset( conn, query );
165                    }
166                    else if( "Value".equalsIgnoreCase( dsType ) ) {
167                            dataset = new DefaultValueDataset();
168                    }
169                    // 5.3.0.0 (2010/12/01) そ?他?Dataset 追?
170    //              else if( "GanttCategory".equalsIgnoreCase( dsType ) ) {
171    //                      dataset = new HybsJDBCCategoryDataset2( conn, query );          // 代替
172    //              }
173    //              else if( "IntervalCategory".equalsIgnoreCase( dsType ) ) {
174    //                      dataset = new HybsJDBCCategoryDataset2( conn, query );          // 代替
175    //              }
176    //              else if( "StatisticalCategory".equalsIgnoreCase( dsType ) ) {
177    //                      dataset = new HybsJDBCCategoryDataset2( conn, query );          // 代替
178    //              }
179                    else if( "TimeSeries".equalsIgnoreCase( dsType ) ) {
180                            dataset = new HybsTimeSeriesCollection( type  );                                        // 5.6.1.0 (2013/02/01) 時間軸を持つチャー?
181                            ((HybsTimeSeriesCollection)dataset).executeQuery( conn, query );
182                    }
183                    else if( "TaskSeries".equalsIgnoreCase( dsType ) ) {
184                            dataset = new HybsTaskSeriesCollection();                                                       // 5.6.1.0 (2013/02/01) タスク??を持つチャー?
185                            ((HybsTaskSeriesCollection)dataset).executeQuery( conn, query );
186                    }
187                    else {
188                            String errMsg = "Category,Pie,XY,Value,TimeSeries 以外?Dataset はサポ?トして?せん?" + dsType + "]";
189                            throw new HybsSystemException( errMsg );
190                    }
191    
192                    return dataset ;
193            }
194    
195            /**
196             * DBTableModelオブジェクトから?Dataset オブジェクトを作?します?
197             *
198             * 引数のtypeは、?部定義の TYPE_RENDERER_MAP マップで関連付けられたキーワー?
199             * より、対象とするチャート特性を取得します?(getTypeRenderer)
200             * そ? TypeRenderer#getDatasetType() メソ?の値を?に、Dataset クラスを作?します?
201             *
202             * 現状は、Category , Pie , XY の?種???Value??タセ?が選択されます?
203             *
204             * @og.rev 5.3.0.0 (2010/12/01) 新規追?
205             *
206             * @param       table   Dataset の取得?の??ブルモ?
207             * @param       type    Dataset オブジェクト?作??求めるキーワー?
208             *
209             * @return      Datasetオブジェク?
210             *
211             * @see     #getTypeRenderer( String )
212             * @see     #newDataset( Connection ,String ,String )
213             */
214            public static final Dataset newDataset( final DBTableModel table , final String type ) {
215                    final Dataset dataset ;
216    
217                    TypeRenderer rend = getTypeRenderer( type );
218                    int clmNo = table.getColumnCount();
219                    int rowNo = table.getRowCount();
220    
221                    String dsType = rend.getDatasetType();
222                    if( "Category".equalsIgnoreCase( dsType ) ) {
223                            // select key,val1,val2,val3 ??? from ???
224    
225                            DefaultCategoryDataset cDataset = new DefaultCategoryDataset();         // series の横持ち
226                            String[] seri = table.getNames();               // ?番目(アドレス=1)から、データのシリーズ名称が始ま?
227                            for( int row=0; row<rowNo; row++ ) {
228                                    String   clmKey = table.getValue( row,0 );      // ?番目(アドレス=0)はカラ??設定?
229                                    String[] vals   = table.getValues( row );
230                                    for( int clm=1; clm<clmNo; clm++ ) {         // ?番目(アドレス=1)からカラ?ータを取?
231                                            String sval = vals[clm];
232                                            double val  = ( sval == null || sval.length() == 0 ) ? 0.0d : Double.parseDouble( sval ) ;
233                                            cDataset.addValue( val , seri[clm] , clmKey );
234                                    }
235                            }
236                            dataset = cDataset;
237                    }
238                    else if( "XY".equalsIgnoreCase( dsType ) ) {
239                            // select valx,valy from ???
240    
241                            CategoryTableXYDataset xyDataset = new CategoryTableXYDataset() ;
242                            String[] seri = table.getNames();               // ?番目(アドレス=1)から、データのシリーズ名称が始ま?
243                            for( int row=0; row<rowNo; row++ ) {
244                                    String[] vals   = table.getValues( row );
245                                    double rval = ( vals[0] == null || vals[0].length() == 0 ) ? 0.0d : Double.parseDouble( vals[0] );
246                                    for( int clm=1; clm<clmNo; clm++ ) {         // ?番目(アドレス=1)からカラ?ータを取?
247                                            String sval = vals[clm];
248                                            double val  = ( sval == null || sval.length() == 0 ) ? 0.0d : Double.parseDouble( sval ) ;
249                                            xyDataset.add( rval,val,seri[clm] );
250                                    }
251                            }
252    
253                            dataset = xyDataset;
254                    }
255                    else if( "Pie".equalsIgnoreCase( dsType ) ) {
256                            // select key,val from ???
257    
258                            DefaultKeyedValues keyVal = new DefaultKeyedValues();
259                            for( int row=0; row<rowNo; row++ ) {
260                                    String[] vals   = table.getValues( row );
261    
262                                    String key  = vals[0];  // KEY?
263                                    String sval = vals[1];  // VALUE?
264                                    double val = ( sval == null || sval.length() == 0 ) ? 0.0d : Double.parseDouble( sval ) ;
265                                    keyVal.addValue( key ,val );
266                            }
267                            dataset = new DefaultPieDataset( keyVal );
268                    }
269                    else if( "Value".equalsIgnoreCase( dsType ) ) {
270                            // Value は、オブジェクトを作?する?。?は、markValues ?ChartDataset.java で設?
271                            dataset = new DefaultValueDataset();
272                    }
273                    // 5.3.0.0 (2010/12/01) そ?他?Dataset 追?
274            //      else if( "GanttCategory".equalsIgnoreCase( dsType ) ) {
275            //              dataset = new TaskSeriesCollection();
276            //      }
277            //      else if( "IntervalCategory".equalsIgnoreCase( dsType ) ) {
278            //              dataset = new DefaultIntervalCategoryDataset( String[] seriesNames, Number[][] starts, Number[][] ends) ;
279            //      }
280            //      else if( "StatisticalCategory".equalsIgnoreCase( dsType ) ) {
281            //              dataset = new DefaultStatisticalCategoryDataset();
282            //      }
283            //      else if( "Wind".equalsIgnoreCase( dsType ) ) {
284            //              dataset = new DefaultWindDataset(java.lang.String[] seriesNames, java.lang.Object[][][] data);
285            //      }
286            //      else if( "OHLC".equalsIgnoreCase( dsType ) ) {
287            //              dataset = new DefaultOHLCDataset(java.lang.Comparable key, OHLCDataItem[] data);
288            //      }
289            //      else if( "BoxAndWhiskerXY".equalsIgnoreCase( dsType ) ) {
290            //              dataset = new org.jfree.data.statistics.DefaultBoxAndWhiskerXYDataset(java.lang.Comparable seriesKey);
291            //      }
292    //              else if( "WaferMap".equalsIgnoreCase( dsType ) ) {
293    //                      dataset = new JDBCXYDataset( conn, query );
294    //              }
295    //              else if( "float2".equalsIgnoreCase( dsType ) ) {
296    //                      float[][] を返すので、ここでは使えな??
297    //              }
298                    else {
299                            String errMsg = "Category,Pie,XY,Value 以外?Dataset はサポ?トして?せん?" + dsType + "]";
300                            throw new HybsSystemException( errMsg );
301                    }
302    
303                    return dataset ;
304            }
305    
306            /**
307             * TypeRenderer オブジェクトを作?します?
308             *
309             * 引数のtypeは、?部定義の TYPE_RENDERER_MAP マップで関連付けられたキーワー?
310             * より、対象とするチャート特性を取得します?
311             * typeは、org.jfree.chart.renderer.XXXX.YYYYRenderer のYYYY とほぼ??します?
312             * TYPE_RENDERER_MAP マップには、XXXX.YYYYRenderer 部?定義されて?す?
313             * XXXX は、category と xy が定義されており、それ以外?レン?ーは null に
314             * なって?す?Pie 関係?、レン?ーではなく?Plot と対応します?
315             * ただし?個?に設定情報が異なる為、ChartPlot_Pie クラスで個別対応して?す?
316             *
317             * @param       type    Rendererオブジェクト?作??求めるキーワー?
318             *
319             * @return      TypeRendererオブジェク?
320             */
321            public static final TypeRenderer getTypeRenderer( final String type ) {
322                    TypeRenderer rend = TYPE_RENDERER_MAP.get( type );
323    
324                    if( rend == null ) {
325                            String errMsg = "??タイプに該当す?Renderer はサポ?トして?せん?" + type + "]"
326                                            + HybsSystem.CR
327                                            + "Key=" + Arrays.toString( TYPE_RENDERER_MAP.keySet().toArray( new String[TYPE_RENDERER_MAP.size()] ) );
328                            throw new HybsSystemException( errMsg );
329                    }
330    
331                    return rend ;
332            }
333    
334            /**
335             * ChartPlot オブジェクトを作?します?
336             *
337             * ChartPlot オブジェクト?、ChartPlot インターフェースを継承した
338             * サブクラスで?org.opengion.hayabusa.io.ChartPlot_**** になります?
339             * **** には、Category , Pie , XY が指定できます?
340             *
341             * @og.rev 4.0.0.0 (2007/11/29) ChartPlot のサブクラスを動?作?、キャ?ュします?
342             * @og.rev 5.3.0.0 (2010/12/01) xxxPlot対?
343             * @og.rev 5.6.1.0 (2013/02/01) 時間軸を持つチャー?TimeSeries 追?
344             *
345             * @param       type    Rendererオブジェクト?作??求めるキーワー?
346             *
347             * @return      ChartPlotオブジェク?
348             */
349            public static final ChartPlot newChartPlot( final String type ) {
350    
351                    final ChartPlot plot ;
352    
353                    TypeRenderer rend = TYPE_RENDERER_MAP.get( type );
354    
355    //              String dsType = rend.getDatasetType();
356                    String pltType = rend.getPlotType();                    // 5.3.0.0 (2010/12/01) xxxPlot対?
357    //              if( "Category".equalsIgnoreCase( dsType ) ) {
358                    if( "Category".equalsIgnoreCase( pltType ) ) {
359                            synchronized( lock ) {
360                                    if( plot_cat == null ) {
361    //                                      plot_cat = (ChartPlot)StringUtil.newInstance( PLOT_SUB + dsType ) ;
362                                            plot_cat = (ChartPlot)StringUtil.newInstance( PLOT_SUB + pltType ) ;
363                                    }
364                            }
365                            plot = plot_cat;
366                    }
367    //              else if( "XY".equalsIgnoreCase( dsType ) ) {
368                    else if( "XY".equalsIgnoreCase( pltType ) ) {
369                            synchronized( lock ) {
370                                    if( plot_xy == null ) {
371    //                                      plot_xy = (ChartPlot)StringUtil.newInstance( PLOT_SUB + dsType ) ;
372                                            plot_xy = (ChartPlot)StringUtil.newInstance( PLOT_SUB + pltType ) ;
373                                    }
374                            }
375                            plot = plot_xy;
376                    }
377                    // 5.6.1.0 (2013/02/01) 時間軸を持つチャー?
378                    else if( "Time".equalsIgnoreCase( pltType ) ) {
379                            synchronized( lock ) {
380                                    if( plot_tim == null ) {
381                                            plot_tim = (ChartPlot)StringUtil.newInstance( PLOT_SUB + pltType ) ;
382                                    }
383                            }
384                            plot = plot_tim;
385                    }
386                    // 5.6.1.0 (2013/02/01) 時間軸を持つチャー?
387                    else if( "XYTime".equalsIgnoreCase( pltType ) ) {
388                            synchronized( lock ) {
389                                    if( plot_xtim == null ) {
390                                            plot_xtim = (ChartPlot)StringUtil.newInstance( PLOT_SUB + pltType ) ;
391                                    }
392                            }
393                            plot = plot_xtim;
394                    }
395                    else {
396                            synchronized( lock ) {
397                                    if( plot_pie == null ) {
398    //                                      plot_pie = (ChartPlot)StringUtil.newInstance( PLOT_SUB + dsType ) ;
399                                            plot_pie = (ChartPlot)StringUtil.newInstance( PLOT_SUB + "Pie" ) ;
400                                    }
401                            }
402                            plot = plot_pie;
403                    }
404    
405                    return plot ;
406            }
407    
408            /**
409             * 引数タイプに応じたレン?ー?ータセ?を規定します?
410             */
411            private static final Map<String,TypeRenderer> TYPE_RENDERER_MAP = new HashMap<String,TypeRenderer>();
412    
413            // 4.1.1.0 (2008/02/04) HybsBar 追?
414            // 5.3.0.0 (2010/12/01) xxxPlot 追????タ?修正、コメント部対?
415            static {
416                    String[][] data = new String[][] {
417                            // キーワー?                                   xxxRenderer                                                                             xxxDataset                                      xxxPlot
418                        {  "HybsLine"                                       , "HybsLineRenderer"                                                    , "Category"                            , "Category"    }
419                      , {  "HybsBar"                                        , "HybsBarRenderer"                                                             , "Category"                            , "Category"    }
420                      , {  "HybsStackedBar"                         , "HybsStackedBarRenderer"                                              , "Category"                            , "Category"    }
421                      , {  "Area"                                           , "category.AreaRenderer"                                               , "Category"                            , "Category"    }
422                      , {  "Bar"                                            , "category.BarRenderer"                                                , "Category"                            , "Category"    }
423                      , {  "Bar3D"                                          , "category.BarRenderer3D"                                              , "Category"                            , "Category"    }
424    //                , {  "BoxAndWhisker"                          , "category.BoxAndWhiskerRenderer"                              , "BoxAndWhisker"                       , "Category"    }
425                      , {  "CategoryStep"                           , "category.CategoryStepRenderer"                               , "Category"                            , "Category"    }
426                      , {  "Gantt"                                          , "category.GanttRenderer"                                              , "TaskSeries"                          , "Time"                }
427                      , {  "GroupedStackedBar"                      , "category.GroupedStackedBarRenderer"                  , "Category"                            , "Category"    }
428    //                , {  "IntervalBar"                            , "category.IntervalBarRenderer"                                , "IntervalCategory"            , "Category"    }
429                      , {  "LayeredBar"                                     , "category.LayeredBarRenderer"                                 , "Category"                            , "Category"    }
430                      , {  "Level"                                          , "category.LevelRenderer"                                              , "Category"                            , "Category"    }
431                      , {  "LineAndShape"                           , "category.LineAndShapeRenderer"                               , "Category"                            , "Category"    }
432                      , {  "Line3D"                                         , "category.LineRenderer3D"                                     , "Category"                            , "Category"    }
433                      , {  "MinMax"                                         , "category.MinMaxCategoryRenderer"                     , "Category"                            , "Category"    }
434                      , {  "StackedArea"                            , "category.StackedAreaRenderer"                                , "Category"                            , "Category"    }
435                      , {  "StackedBar"                                     , "category.StackedBarRenderer"                                 , "Category"                            , "Category"    }
436                      , {  "StackedBar3D"                           , "category.StackedBarRenderer3D"                               , "Category"                            , "Category"    }
437    //                , {  "StatisticalBar"                         , "category.StatisticalBarRenderer"                     , "StatisticalCategory"         , "Category"    }
438                      , {  "StatisticalLineAndShape"        , "category.StatisticalLineAndShapeRenderer"    , "Category"                            , "Category"    }
439                      , {  "WaterfallBar"                           , "category.WaterfallBarRenderer"                               , "Category"                            , "Category"    }
440    //                , {  "Candlestick"                            , "xy.CandlestickRenderer"                                              , "OHLC"                                        , "XY"                  }
441                      , {  "ClusteredXYBarV"                        , "xy.ClusteredXYBarRenderer"                                   , "TimeSeries"                          , "XYTime"              }
442                      , {  "CyclicXYItem"                           , "xy.CyclicXYItemRenderer"                                     , "XY"                                          , "XY"                  }
443                      , {  "DeviationV"                             , "xy.DeviationRenderer"                                                , "TimeSeries"                          , "XYTime"              }
444                      , {  "HighLow"                                        , "xy.HighLowRenderer"                                                  , "XY"                                          , "XY"                  }
445                      , {  "StackedXYArea"                          , "xy.StackedXYAreaRenderer"                                    , "XY"                                          , "XY"                  }
446                      , {  "StackedXYArea2"                         , "xy.StackedXYAreaRenderer2"                                   , "XY"                                          , "XY"                  }
447    //                , {  "StackedXYBarV"                          , "xy.StackedXYBarRenderer"                                     , "TableXY"                                     , "XY"                  }
448                      , {  "StandardXYItem"                         , "xy.StandardXYItemRenderer"                                   , "XY"                                          , "XY"                  }
449    //                , {  "WindItem"                                       , "xy.WindItemRenderer"                                                 , "Wind"                                        , "XY"                  }
450                      , {  "XYArea"                                         , "xy.XYAreaRenderer"                                                   , "XY"                                          , "XY"                  }
451                      , {  "XYArea2"                                        , "xy.XYAreaRenderer2"                                                  , "XY"                                          , "XY"                  }
452                      , {  "XYBarV"                                         , "xy.XYBarRenderer"                                                    , "TimeSeries"                          , "XYTime"              }
453                      , {  "XYBlock"                                        , "xy.XYBlockRenderer"                                                  , "XY"                                          , "XY"                  }
454    //                , {  "XYBoxAndWhisker"                        , "xy.XYBoxAndWhiskerRenderer"                                  , "BoxAndWhiskerXY"             , "XY"                  }
455                      , {  "XYBubble"                                       , "xy.XYBubbleRenderer"                                                 , "XY"                                          , "XY"                  }
456                      , {  "XYDifference"                           , "xy.XYDifferenceRenderer"                                     , "XY"                                          , "XY"                  }
457                      , {  "XYDot"                                          , "xy.XYDotRenderer"                                                    , "XY"                                          , "XY"                  }
458                      , {  "XYError"                                        , "xy.XYErrorRenderer"                                                  , "XY"                                          , "XY"                  }
459                      , {  "XYLine3D"                                       , "xy.XYLine3DRenderer"                                                 , "XY"                                          , "XY"                  }
460                      , {  "XYLineAndShape"                         , "xy.XYLineAndShapeRenderer"                                   , "XY"                                          , "XY"                  }
461                      , {  "XYStepArea"                                     , "xy.XYStepAreaRenderer"                                               , "XY"                                          , "XY"                  }
462                      , {  "XYStep"                                         , "xy.XYStepRenderer"                                                   , "XY"                                          , "XY"                  }
463                      , {  "YIntervalV"                             , "xy.YIntervalRenderer"                                                , "TimeSeries"                          , "XYTime"              }
464                      , {  "PolarItem"                                      , "DefaultPolarItemRenderer"                                    , "XY"                                          , "Polar"               }
465    //                , {  "WaferMap"                                       , "WaferMapRenderer"                                                    , "WaferMap"                            , "WaferMap"    }
466                      , {  "Compass"                                        ,  null                                                                                 , "Value"                                       , "Compass"             }
467    //                , {  "Contour"                                        ,  null                                                                                 , "Contour"                                     , "Contour"             }
468    //                , {  "FastScatter"                            ,  null                                                                                 , "float2"                                      , "FastScatter" }
469                      , {  "Meter"                                          ,  null                                                                                 , "Value"                                       , "Meter"               }
470                      , {  "MultiplePie"                            ,  null                                                                                 , "Category"                            , "MultiplePie" }
471                      , {  "Pie"                                            ,  null                                                                                 , "Pie"                                         , "Pie"                 }
472                      , {  "Pie3D"                                          ,  null                                                                                 , "Pie"                                         , "Pie"                 }
473                      , {  "Ring"                                           ,  null                                                                                 , "Pie"                                         , "Ring"                }
474                      , {  "SpiderWeb"                                      ,  null                                                                                 , "Category"                            , "SpiderWeb"   }
475                      , {  "Thermometer"                            ,  null                                                                                 , "Value"                                       , "Thermometer" }
476                      , {  "TimeSeriesLineV"                        ,  "xy.StandardXYItemRenderer"                                  , "TimeSeries"                          , "XYTime"              }       // 5.6.1.0 (2013/02/01) 時間軸を持つチャー?
477                      , {  "TimeSeriesLineH"                        ,  "xy.StandardXYItemRenderer"                                  , "TimeSeries"                          , "XYTime"              }       // 5.6.1.0 (2013/02/01) 時間軸を持つチャー?
478                      , {  "TimeSeriesBarV"                         ,  "xy.XYBarRenderer"                                                   , "TimeSeries"                          , "XYTime"              }       // 5.6.1.0 (2013/02/01) 時間軸を持つチャー?
479                      , {  "TimeSeriesBarH"                         ,  "xy.XYBarRenderer"                                                   , "TimeSeries"                          , "XYTime"              }       // 5.6.1.0 (2013/02/01) 時間軸を持つチャー?
480                      , {  "StackedTimeSeriesLineV"         ,  "xy.StandardXYItemRenderer"                                  , "TimeSeries"                          , "XYTime"              }       // 5.6.1.0 (2013/02/01) 時間軸を持つチャー?
481                      , {  "StackedTimeSeriesLineH"         ,  "xy.StandardXYItemRenderer"                                  , "TimeSeries"                          , "XYTime"              }       // 5.6.1.0 (2013/02/01) 時間軸を持つチャー?
482                    };
483    
484                    for( int i=0; i<data.length; i++ ) {
485    //                      TYPE_RENDERER_MAP.put( data[i][0],new TypeRenderer( data[i][0],data[i][1],data[i][2] ) );
486                            TYPE_RENDERER_MAP.put( data[i][0],new TypeRenderer( data[i][0],data[i][1],data[i][2],data[i][3] ) );
487                    }
488            }
489    }
490    
491    /**
492     * 引数タイプに応じたレン?ー?ータセ?を管?ます?
493     *
494     * タイプ?レン?ー、データセ? の?合わせで、構築するオブジェクトが異なります?
495     */
496    final class TypeRenderer {
497            private static final String REND_CLASS = "org.jfree.chart.renderer." ;
498            private static final String HYBS_CLASS = "org.opengion.hayabusa.io." ;          // 4.1.1.0 (2008/02/04)
499    
500            private final String type ;
501            private final String rend ;             // org.jfree.chart.renderer 以降???
502            private final String dtset ;    // org.opengion.hayabusa.io 以降???
503            private final String plot ;             // 以降???
504    
505            /**
506             * TypeRenderer オブジェクトを作?します?
507             *
508             * チャートタイ?は、外部からチャートを?する?に便利なように、キー?
509             * されて?す?こ?キーに基づ?、ChartFactory クラスの
510             * チャートタイプ変換表に基づ?、レン?ー????タセ?を作?します?
511             * こ?クラスは、これらの変換表の個?の属?を管?て?す?
512             *
513             * @og.rev 5.3.0.0 (2010/12/01) plot 追?
514             *
515             * @param       type            チャート?タイプを区別する??
516             * @param       renderer        チャート?タイプに応じたレン?ーのキー??
517             * @param       dtset           チャート?タイプに応じたデータセ?のキー??
518             * @param       plot            チャート?タイプに応じた?ロ?のキー??
519             */
520    //      public TypeRenderer( final String type,final String renderer,final String dtset ) {
521            public TypeRenderer( final String type,final String renderer,final String dtset,final String plot ) {
522                    this.type  = type ;
523                    this.rend  = renderer ;
524                    this.dtset = dtset ;
525                    this.plot  = plot ;                     // 5.3.0.0 (2010/12/01) plot 追?
526            }
527    
528            /**
529             * チャート?タイプを区別する??を返します?
530             *
531             * @return      チャート?タイプを区別する??
532             */
533            public String getType() { return type; }
534    
535            /**
536             * チャート?タイプに応じたレン?ーのキー??を返します?
537             *
538             * @return      チャート?タイプに応じたレン?ーのキー??
539             */
540            public String getRendererType() { return rend; }
541    
542            /**
543             * チャート?タイプに応じたレン?ーオブジェクトを返します?
544             *
545             * org.jfree.chart.renderer パッケージのサブモジュールのレン?ークラス?
546             * 先に登録してある レン?ーのキー?? と合?して、クラスを動?作?します?
547             *
548             * @og.rev 4.1.1.0 (2008/02/04) Barチャート追?
549             * @og.rev 5.3.0.0 (2010/12/01) レン?ー?null の場合?対?
550             *
551             * @return      LegendItemSource チャート?タイプに応じたレン?ーオブジェク?存在しな??合?、null)
552             */
553            public LegendItemSource getRenderer() {
554                    if( rend == null ) { return null; }             // 5.3.0.0 (2010/12/01)
555    
556                    String key ;
557                    if( type.startsWith( "Hybs" ) ) {
558                            key = HYBS_CLASS + rend ;
559                    }
560                    else {
561                            key = REND_CLASS + rend ;
562                    }
563    
564                    return (LegendItemSource)StringUtil.newInstance( key ) ;
565            }
566    
567            /**
568             * チャート?タイプに応じたデータセ?のキー??を返します?
569             *
570             * @return      チャート?タイプに応じたデータセ?のキー??
571             */
572            public String getDatasetType() { return dtset; }
573    
574            /**
575             * チャート?タイプに応じた?ロ?のキー??を返します?
576             *
577             * @og.rev 5.3.0.0 (2010/12/01) 新規追?
578             *
579             * @return      チャート?タイプに応じた?ロ?のキー??
580             */
581            public String getPlotType() { return plot; }
582    }