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