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.taglib;
017
018import static org.opengion.fukurou.util.StringUtil.nval ;
019import org.opengion.hayabusa.common.HybsSystem;
020import org.opengion.hayabusa.common.HybsSystemException;
021import org.opengion.hayabusa.io.ChartCreate;
022import org.opengion.hayabusa.io.ChartDataset;
023import org.opengion.hayabusa.io.HybsURLTagFragmentGenerator;
024
025import java.io.File;
026import java.io.IOException;
027import java.io.ObjectOutputStream;
028import java.io.ObjectInputStream;
029import java.util.List;
030import java.util.ArrayList;
031import java.util.Map ;
032import java.util.HashMap ;
033
034import org.jfree.chart.JFreeChart;
035import org.jfree.chart.ChartUtilities;
036
037import org.jfree.chart.ChartRenderingInfo;
038import org.jfree.chart.entity.StandardEntityCollection;
039import org.jfree.chart.imagemap.ImageMapUtilities;
040import org.jfree.chart.imagemap.StandardToolTipTagFragmentGenerator;
041import org.jfree.chart.imagemap.ToolTipTagFragmentGenerator;
042import org.jfree.chart.imagemap.URLTagFragmentGenerator;
043
044/**
045 * BODY部に指定のSQLの検索結果をチャート(円、棒、線)で表示するタグです。
046 *
047 * チャート化には、JFreeChart (http://www.jfree.org/jfreechart/) を使用しています。
048 * チャートの種類は、chartDataset タグで指定します。これは、複数の異なるチャートを
049 * 合成表示する機能が、JFreeChart にある為です。ただし、専門的には、CategoryDataset のみ
050 * いまは、合成が可能です。
051 * 処理の実行にあたり、キャッシュが有効(useCache="true")であれば、キャッシュデータを
052 * 使用します。キャッシュは、masterKey 属性で指定されたキーワード毎に、JFreeChart
053 * オブジェクトをキャッシュします。また、seriesPikup 違いの場合は、再検索せずに、
054 * キャッシュが使用できます。さらに、seriesPikup が同じ場合(masterKey も同じ)は、
055 * すでに画像ファイルが作成済みなので、画像ファイルのみを返します。
056 *
057 * 各属性は、{@XXXX} 変数が使用できます。
058 * これは、ServletRequest から、XXXX をキーに値を取り出し,この変数に割り当てます。
059 * つまり、このXXXXをキーにリクエストすれば、この変数に値をセットすることができます。
060 *
061 * @og.formSample
062 * ●形式:<og:chartCreate title="…" … />
063 * ●body:あり(EVAL_BODY_BUFFERED:BODYを評価し、{@XXXX} を解析します)
064 *
065 * ●Tag定義:
066 *   <og:chartCreate
067 *       title              【TAG】チャートのタイトルをセットします
068 *       width              【TAG】チャートの横幅をセットします(初期値:200)
069 *       height             【TAG】チャートの縦幅をセットします(初期値:200)
070 *       domainLabel        【TAG】チャートのドメインラベルを指定します
071 *       showLegend         【TAG】チャートの凡例の表示可否[true/false]をセットします(初期値:true[表示する])
072 *       rectangleEdge      【TAG】チャートの表示箇所を、[TOP/BOTTOM/RIGHT/LEFT]で指定します(初期値:BOTTOM)
073 *       plotOrientation    【TAG】チャートのプロット(Plot)表示方向を、[VERTICAL(or V),HORIZONTAL(or H)]で指定します
074 *       chartBackColor     【TAG】チャートの背景色を指定します
075 *       plotBackColor      【TAG】チャートの描画領域の色を指定します
076 *       rotationLabel      【TAG】チャートのカテゴリーラベルの方向を指定します[1:180度 、2:90度 、3:60度 、4:45度 、6:30度 ・・・ ](初期値:3:60度)
077 *       useVerticalLabels  【TAG】横軸ラベルの表示向きを縦にするかどうか[false/true]を指定します(初期値:false)
078 *       domainMarker       【TAG】チャートの横軸の値(ドメイン)に合致する位置にマーカーラインを設定します
079 *       useDomainLabel     【TAG】横軸ラベルのラベルを表示するかどうか[true/false]を指定します(初期値:true)
080 *       useMarkerLabel     【TAG】マーカーラインに、その設定値を表示するかどうか[true/false]を指定します(初期値:true)
081 *       useCache           【TAG】JFreeChart オブジェクトをキャッシュするかどうか[true/false]を指定します(初期値:false)
082 *       masterKey          【TAG】キャッシュ用マスタキーを指定します
083 *       seriesPikup        【TAG】複数シリーズのピックアップを行う場合のシリーズ番号を指定します
084 *       imageMapUrl        【TAG】クリッカブル・マップ用URLを指定します
085 *       imageMapTarget     【TAG】クリッカブル・マップ用TARGETを指定します
086 *       categoryMargin     【TAG】カテゴリマージン(0.0〜1.0)を指定します
087 *       lowerMargin        【TAG】下方マージン(0.0〜1.0)を指定します
088 *       upperMargin        【TAG】上方マージン(0.0〜1.0)を指定します
089 *       useDomainLine      【TAG】横軸のグリッド表示有無(垂直線)を指定します(初期値:false)
090 *       domainLineColor    【TAG】横軸のグリッド線の色を指定します
091 *       categorySkip       【TAG】横軸ラベルをスキップする間隔を指定します
092 *       categoryCutNo      【TAG】横軸ラベルの文字位置指定のキーブレイクを指定します
093 *       categoryAnchor     【TAG】横軸のグリッド(垂直線)の書き出し位置(START,MIDDLE,END)を指定します
094 *       useRangeLine       【TAG】縦軸のグリッド表示有無(水平線)を指定します(初期値:true)
095 *       useToolTip         【TAG】ツールチップスの使用可否[true:利用する/false:利用しない]を指定します(初期値:false)
096 *       rangeLineColor     【TAG】縦軸のグリッド線の色を指定します
097 *       rangeSkip          【TAG】縦軸のグリッド線(水平線)をスキップする間隔を指定します
098 *       dateAxisFormat     【TAG】Time,XYTime Polt関係の時間軸を表す場合のフォーマットを指定します(初期値:MM/dd)
099 *       debug              【TAG】デバッグ情報を出力するかどうか[true/false]を指定します(初期値:false)
100 *   >   ... Body ...
101 *   </og:chartCreate>
102 *
103 * ●使用例
104 *      <og:chartCreate
105 *          title       = "JFreeChart Test"             チャートタイトル
106 *          domainLabel = "ドメインラベル"              横軸ラベル
107 *          width       = "200"                         チャート表示幅
108 *          height      = "200"                         チャート表示高さ
109 *          showLegend  = "[true/false]"                凡例の表示可否[true/false]
110 *          rectangleEdge   = "[TOP|BOTTOM|RIGHT|LEFT]" 凡例の表示箇所
111 *          plotOrientation = "[VERTICAL|HORIZONTAL]"   チャートの軸表示方向
112 *          chartBackColor  = "WHITE"                   背景色
113 *          plotBackColor   = "LIGHT_GRAY"              描画領域色
114 *          rotationLabel   = "3"                       横軸ラベルの傾き
115 *          useVerticalLabels = "false"                                 横軸ラベルの向き(true:縦/false:横)
116 *          domainMarker    = "KING"                    横軸のマーカーライン(縦棒)
117 *          useMarkerLabel  = "[true/false]"            マーカーラインの文字有無
118 *          useDomainLabel  = "[true/false]"            横軸ラベルの表示有無
119 *          categorySkip    = "3"                       横軸ラベルをスキップする間隔
120 *          categoryCutNo   = "6"                       横軸ラベルの文字位置指定のキーブレイク
121 *          categoryAnchor  = "[START|MIDDLE|END]"      横軸のグリッド(垂直線)の書き出し位置
122 *          useDomainLine   = "[false/true]"            横軸のグリッド表示有無(垂直線)
123 *          domainLineColor = "LIGHT_GRAY"              横軸のグリッド線の色
124 *          useRangeLine    = "[true/false]"            縦軸のグリッド表示有無(水平線)
125 *          rangeLineColor  = "LIGHT_GRAY"              縦軸のグリッド線の色
126 *          rangeSkip       = "-5"                      縦軸のグリッド(水平線)をスキップする間隔
127 *          useCache        = "[false|true]"            キャッシュの有無
128 *          masterKey       = "{@XXXX}"            キャッシュ用マスタキー
129 *          seriesPikup     = "2"                       ピックアップするシリーズNo
130 *          imageMapUrl     = "link.jsp,BLOCK"          クリッカブル・マップ用URL
131 *          imageMapTarget  = "CONTENTS"                クリッカブル・マップ用TARGET
132 *          categoryMargin  = "[0.0〜1.0]"              カテゴリマージン(0.0〜1.0)
133 *          lowerMargin     = "[0.0〜1.0]"              下方マージン(0.0〜1.0)
134 *          upperMargin     = "[0.0〜1.0]"              上方マージン(0.0〜1.0)
135 *       >
136 *              <og:chartDataset
137 *                  chartType   = "{@chartType}"
138 *                  valueLabel  = "{@valueLabel}"
139 *                  lowerBound  = "{@lowerBound}"
140 *                  upperBound  = "{@upperBound}"
141 *                  markValues  = "{@markValues}"
142 *                  markColors  = "{@markColors}"
143 *                  useGradient   = "{@useGradient}"
144 *                  shapesVisible = "{@shapesVisible}"
145 *                  useDottedLine = "{@useDottedLine}"
146 *                  seriesColors  = "{@seriesColors}"
147 *                  valueLabelsVisible = "[true|false]"
148 *                  valueMarksVisible  = "[true|false]"
149 *              >
150 *                         {@SQL}
151 *              </og:chartDataset>
152 *      </og:chartCreate>
153 *
154 *    複数のグラフを重ね合わせる場合は、chartDataset タグを chartCreate のBODY部に
155 *    複数記述します。
156 *      <og:chartCreate
157 *          title       = "{@title}"
158 *          domainLabel = "{@domainLabel}"
159 *          width       = "{@width}"
160 *          height      = "{@height}" >
161 *              <og:chartDataset
162 *                  chartType   = "{@chartType1}"
163 *                  valueLabel  = "{@valueLabel1}"
164 *                  lowerBound  = "{@lowerBound1}"
165 *                  upperBound  = "{@upperBound1}"
166 *                  markValues  = "{@markValues1}"
167 *                  markColors  = "{@markColors1}"
168 *              >
169 *                         {@SQL1}
170 *              </og:chartDataset>
171 *              <og:chartDataset
172 *                  chartType   = "{@chartType2}"
173 *                  valueLabel  = "{@valueLabel2}"
174 *                  lowerBound  = "{@lowerBound2}"
175 *                  upperBound  = "{@upperBound2}"
176 *                  markValues  = "{@markValues2}"
177 *                  markColors  = "{@markColors2}"
178 *              >
179 *                         {@SQL2}
180 *              </og:chartDataset>
181 *      </og:chartCreate>
182 *
183 *    rectangleEdge属性 は、凡例の表示箇所を示す、RectangleEdge クラスの値を設定します。
184 *    [rectangleEdge属性]
185 *      TOP      上側
186 *      BOTTOM   下側
187 *      RIGHT    右側
188 *      LEFT     左側
189 *
190 *    plotOrientation属性 は、チャートの軸表示方向を設定します。
191 *    [renderer属性]
192 *      VERTICAL    縦方向
193 *      HORIZONTAL  横方向
194 *
195 * @og.group 画面表示
196 *
197 * @version  0.9.0      2007/06/19
198 * @author       Nakamura
199 * @since        JDK1.4,
200 */
201public class ChartCreateTag extends CommonTagSupport {
202        //* このプログラムのVERSION文字列を設定します。   {@value} */
203        private static final String VERSION = "5.6.4.3 (2013/05/24)" ;
204
205        private static final long serialVersionUID = 564320130524L ;    // 5.6.4.3 (2013/05/24)
206
207        private static final String FILE_URL = HybsSystem.sys( "CHART_TEMP_DIR" );
208
209        private         List<ChartDataset>        chartDataset    = null;
210
211        private static final String CHART_CACHE_KEY = HybsSystem.JF_CHART_CACHE_KEY;
212
213        private String  title                   = null;
214        private int             width                   = 200;
215        private int             height                  = 200;
216        private String  domainLabel             = null;
217        private boolean showLegend              = true;
218        private String  rectangleEdge   = "BOTTOM";
219        private String  plotOrientation = "VERTICAL";
220        private String  chartBackColor  = null;                 // 背景色の設定
221        private String  plotBackColor   = null;                 // 描画領域の設定
222        private int             rotationLabel   = 3;                    // 横軸ラベルの傾き(1:180度 、2:90度 、3:60度 、4:45度 、6:30度 ・・・ )
223        private boolean useVerticalLabels = false;              // 5.6.4.3 (2013/05/24) 横軸ラベルの表示向き(横書き:false/縦書き:true) 
224        private String  domainMarker    = null;                 // 横軸のマーカーライン
225        private boolean useDomainLabel  = true;                 // 横軸ラベルの表示有無
226        private boolean useMarkerLabel  = true;                 // マーカーライン時の文字有無
227        private boolean useCache                = false;                // JFreeChart オブジェクトをキャッシュするかどうか
228        private int             seriesPikup             = -1;                   // ピックアップするシリーズ番号
229        private String  masterKey               = null;                 // キャッシュ用マスタキー
230        private transient Map<String,ChartCache>  map     = null;         // キャッシュ用マップ
231        private transient ChartCache    cache           = null;                 // キャッシュ
232        private String          imgTag          = null;                 // キャッシュ用画像ファイル
233        private String  imageMapUrl             = null;                 // クリッカブル・マップ用URL
234        private String  imageMapTarget  = null;                 // クリッカブル・マップ用TARGET
235        // 3.5.4.7 (2004/02/06) 実行時間測定用のDIV要素を出力します。
236        private long dyStart = 0;
237
238        // 4.0.2.0 (2007/12/20)
239        private String          categoryMargin  = null;         // カテゴリマージン(0.0〜1.0)
240        private String          lowerMargin             = null;         // 下方マージン(0.0〜1.0)
241        private String          upperMargin             = null;         // 上方マージン(0.0〜1.0)
242//      private String[]        shapeColors             = null;         // 4.0.3.0 (2008/01/07) データ毎にShapeを切り替える時の色指定
243
244        private boolean useDomainLine   = false;                // 4.0.3.0 (2008/01/07) 横軸のグリッド表示有無(垂直線)
245        private String  domainLineColor = null;                 // 4.0.3.0 (2008/01/07) 横軸のグリッド線の色
246        private boolean useRangeLine    = true;                 // 4.0.3.0 (2008/01/07) 縦軸のグリッド表示有無(水平線)
247        private String  rangeLineColor  = null;                 // 4.0.3.0 (2008/01/07) 縦軸のグリッド線の色
248        private int             categorySkip    = 1;                    // 4.0.3.0 (2008/01/07) 横軸ラベルをスキップする間隔
249        private int             categoryCutNo   = -1;                   // 4.1.1.0 (2008/02/04) 横軸ラベルの文字位置指定のキーブレイク
250        private String  categoryAnchor  = null;                 // 4.1.1.0 (2008/02/14) 横軸のグリッド(垂直線)の書き出し位置(START,MIDDLE,END)
251//      private double  lineOffset              = 0.0;                  // 4.1.1.0 (2008/02/04) DomainLineの書き出し位置
252        private int             rangeSkip               = 1;                    // 4.1.1.0 (2008/02/04) 縦軸のグリッドをスキップする間隔
253        private boolean useToolTip              = false;                // 4.3.1.0 (2008/08/09) ツールチップスを利用するか
254
255        private String  dateAxisFormat  = "MM/dd";              // 5.6.1.0 (2013/02/01) Time,XYTime Polt関係の時間軸を表す場合のフォーマット
256        private int             dateSegSize             ;                               // 5.9.16.2 (2017/1/28) 6.7.3.0 (2017/01/27) SegmentedTimelineのsegment size を、分単位で指定します。
257        private int             dateSegIncluded ;                               // 5.9.16.2 (2017/1/28) 6.7.3.0 (2017/01/27) SegmentedTimelineのincluded segments(スペース)を数値で指定します。
258        private int             dateSegExcluded ;                               // 5.9.16.2 (2017/1/28) 6.7.3.0 (2017/01/27) SegmentedTimelineのexcluded segments(EE)を数値で指定します。
259        private String  dateStartTime   ;                               // 5.9.16.2 (2017/1/28) 6.7.3.0 (2017/01/27) SegmentedTimelineのStartTime(segment groupの開始位置) を、yyyyMMddHHmmss形式で指定します。 
260        
261        private String  chartFile               ;                               // 5.9.16.2 (2017/1/28) 6.3.5.0 (2015/08/08) チャートの画像ファイル名
262
263        
264        /**
265         * Taglibの開始タグが見つかったときに処理する doStartTag() を オーバーライドします。
266         *
267         * @return      後続処理の指示
268         */
269        @SuppressWarnings(value={"unchecked"})
270        @Override
271        public int doStartTag() {
272                dyStart = System.currentTimeMillis();
273
274                if( useCache ) {
275                        // キャッシュから、取り出す。
276                        map = (Map<String,ChartCache>)getSessionAttribute( CHART_CACHE_KEY );
277                        if( map != null ) {
278                                cache = map.get( masterKey );
279                                if( cache != null && cache.isAvailable() ) {    // キャッシュ有効
280                                        String subKey = String.valueOf( seriesPikup );
281                                        // キャッシュから、イメージを取り出す。存在しなければ、null
282                                        imgTag = cache.getFileAddress( subKey );
283                                        return(SKIP_BODY);              // キャッシュ使用
284                                }
285                        }
286                }
287
288                return EVAL_BODY_BUFFERED;
289        }
290
291        /**
292         * Taglibの終了タグが見つかったときに処理する doEndTag() を オーバーライドします。
293         *
294         * @og.rev 5.2.1.0 (2010/10/01) debugPrint() メソッドの処理条件見直し
295         *
296         * @return      後続処理の指示
297         */
298        @Override
299        public int doEndTag() {
300//              if( isDebug() ) { debugPrint(); }
301                debugPrint();           // 5.2.1.0 (2010/10/01) debugPrint() メソッド自体に、isDebug() が組み込まれている。
302
303                long queryEnd = System.currentTimeMillis();
304                jspPrint( "<div id=\"queryTime\" value=\"" + (queryEnd-dyStart) + "\"></div>" );    // 3.5.6.3 (2004/07/12)
305
306                // 画像ファイルのキャッシュがあれば、それを返す。
307                if( imgTag != null ) {
308                        jspPrint( imgTag );
309                }
310                else {
311                        JFreeChart chart ;
312                        if( cache != null ) {
313                                // キャッシュがあれば、チャートを取り出す。
314                                chart = cache.getJFreeChart() ;
315                                // チャートは、変更(modifying)のみ行う。
316                                chart = ChartCreate.modifying( chart,seriesPikup );
317                        }
318                        else {
319                                // チャートがない、または、無効になっている場合は、新規作成する。
320                                ChartCreate chartCreate = create();
321                                chart = chartCreate.getChart();
322                        }
323
324                        File file = getTempFile( FILE_URL );
325                        try {
326                                // クリッカブル・マップ
327                                String fname = file.getName();
328                                String filename = getContextPath() + "/" + FILE_URL + fname;
329                                String keyword = fname.substring( 0, fname.length() - 4 ); // ".png" 分を削除
330                                ToolTipTagFragmentGenerator toolTipGen = null;
331                                URLTagFragmentGenerator urlGen = null;
332                                // 4.3.1.0 (2008/08/09) ツールチップスのマップ情報取得
333                                if( useToolTip ) {
334                                        toolTipGen = new StandardToolTipTagFragmentGenerator();
335                                }
336                                if( imageMapUrl != null ) {
337                                        urlGen = new HybsURLTagFragmentGenerator( imageMapTarget );
338                                }
339                                if( ( imageMapUrl != null ) || ( useToolTip ) ) {
340                                        ChartRenderingInfo objCri = new ChartRenderingInfo( new StandardEntityCollection() );
341                                        ChartUtilities.saveChartAsPNG( file, chart, width, height, objCri );
342                                        imgTag = ImageMapUtilities.getImageMap( keyword, objCri, toolTipGen, urlGen ) + makeTag2( filename, keyword );
343                                }
344                                else {
345                                        ChartUtilities.saveChartAsPNG( file, chart, width, height );
346                                        imgTag = makeTag2( filename, null );
347                                }
348                        }
349                        catch(IOException ex) {
350                                String errMsg = "ファイル I/O が実行できませんでした。"
351                                        + HybsSystem.CR + file + HybsSystem.CR
352                                                + ex.getMessage();
353                                throw new HybsSystemException( errMsg,ex );
354                        }
355
356                        jspPrint( imgTag );
357
358                        // キャッシュ時にセーブする。
359                        if( useCache ) {
360                                if( cache == null ) {
361                                        cache = new ChartCache( masterKey );
362                                        cache.setJFreeChart( chart );
363                                }
364                                String subKey = String.valueOf( seriesPikup );
365                                cache.putFileAddress( subKey,imgTag );
366                                if( map == null ) {
367                                        map = new HashMap<String,ChartCache>();
368                                }
369                                map.put( masterKey,cache );
370                                setSessionAttribute( CHART_CACHE_KEY,map );
371                        }
372                        else {
373                //              map = (Map<String,ChartCache>)getSessionAttribute( CHART_CACHE_KEY );
374                //              if( map != null ) { map.clear() ; }
375                                removeSessionAttribute( CHART_CACHE_KEY );
376                        }
377                }
378
379                // 3.5.4.7 (2004/02/06)
380                long dyEnd = System.currentTimeMillis();
381                jspPrint( "<div id=\"viewTime\" value=\"" + (dyEnd-dyStart) + "\"></div>" );        // 3.5.6.3 (2004/07/12)
382                return EVAL_PAGE;
383        }
384
385        /**
386         * タグリブオブジェクトをリリースします。
387         * キャッシュされて再利用されるので、フィールドの初期設定を行います。
388         *
389         * @og.rev 4.0.1.0 (2007/12/13) categoryMargin、lowerMargin、upperMargin 属性を追加
390         * @og.rev 4.1.1.0 (2008/02/04) categoryCutNo , categoryAnchor , rangeSkip 属性を追加
391         * @og.rev 5.6.1.0 (2013/02/01) dateAxisFormat 属性を追加
392         * @og.rev 5.6.4.3 (2013/05/24) useVerticalLabels 属性を追加
393         * @og.rev 5.9.16.2 (2017/1/28) 6.7.3.0 (2017/01/27) 日付軸(dateAxis)の指定、画像ファイル名指定を追加します。
394         */
395        @Override
396        protected void release2() {
397                super.release2();
398                chartDataset    = null;
399                title                   = null;
400                width                   = 200;
401                height                  = 200;
402                domainLabel             = null;
403                showLegend              = true;
404                rectangleEdge   = "BOTTOM";
405                plotOrientation = "VERTICAL";
406                chartBackColor  = null;                 // 背景色の設定
407                plotBackColor   = null;                 // 描画領域の設定
408                rotationLabel   = 3;                    // 横軸ラベルの傾き(1:180度 、2:90度 、3:60度 、4:45度 、6:30度 ・・・ )
409                useVerticalLabels = false;              // 5.6.4.3 (2013/05/24) 横軸ラベルの表示向き(横書き:false/縦書き:true) 
410                domainMarker    = null;                 // 横軸のマーカーライン
411                useDomainLabel  = true;                 // 横軸ラベルの表示有無
412                useMarkerLabel  = true;                 // マーカーライン時の文字有無
413                useCache                = false;                // キャッシュするかどうか
414                seriesPikup             = -1;                   // ピックアップするシリーズ番号
415                masterKey               = null;                 // キャッシュ用マスタキー
416                map                             = null;                 // キャッシュ用マップ
417                cache                   = null;                 // キャッシュ
418                imgTag                  = null;                 // キャッシュ用画像ファイル
419                imageMapUrl             = null;                 // クリッカブル・マップ
420                imageMapTarget  = null;                 // クリッカブル・マップ用TARGET
421                categoryMargin  = null;                 // 4.0.2.0 (2007/12/20) カテゴリマージン(0.0〜1.0)
422                lowerMargin             = null;                 // 4.0.2.0 (2007/12/20) 下方マージン(0.0〜1.0)
423                upperMargin             = null;                 // 4.0.2.0 (2007/12/20) 上方マージン(0.0〜1.0)
424//              shapeColors             = null;                 // 4.0.3.0 (2008/01/07) データ毎にShapeを切り替える時の色指定
425                useDomainLine   = false;                // 4.0.3.0 (2008/01/07) 横軸のグリッド表示有無(垂直線)
426                domainLineColor = null;                 // 4.0.3.0 (2008/01/07) 横軸のグリッド線の色
427                useRangeLine    = true;                 // 4.0.3.0 (2008/01/07) 縦軸のグリッド表示有無(水平線)
428                rangeLineColor  = null;                 // 4.0.3.0 (2008/01/07) 縦軸のグリッド線の色
429                categorySkip    = 1;                    // 4.0.3.0 (2008/01/07) 横軸ラベルをスキップする間隔
430                categoryCutNo   = -1;                   // 4.1.1.0 (2008/02/04) 横軸ラベルの文字位置指定のキーブレイク
431                categoryAnchor  = null;                 // 4.1.1.0 (2008/02/14) 横軸のグリッド(垂直線)の書き出し位置(START,MIDDLE,END)
432//              lineOffset              = 0.0;                  // 4.1.1.0 (2008/02/04) DomainLineの書き出し位置
433                rangeSkip               = 1;                    // 4.1.1.0 (2008/02/04) 縦軸のグリッドをスキップする間隔
434                dateAxisFormat  = "MM/dd";              // 5.6.1.0 (2013/02/01) Time,XYTime Polt関係の時間軸を表す場合のフォーマット
435                dateSegSize             = 0;                    // 5.9.16.2 (2017/1/28) 6.7.3.0 (2017/01/27) SegmentedTimelineのsegment size を、分単位で指定します。
436                dateSegIncluded = 0;                    // 5.9.16.2 (2017/1/28) 6.7.3.0 (2017/01/27) SegmentedTimelineのincluded segments(スペース)を数値で指定します。
437                dateSegExcluded = 0;                    // 5.9.16.2 (2017/1/28) 6.7.3.0 (2017/01/27) SegmentedTimelineのexcluded segments(EE)を数値で指定します。
438                dateStartTime   = null;                 // 5.9.16.2 (2017/1/28) 6.7.3.0 (2017/01/27) SegmentedTimelineのStartTime(segment groupの開始位置) を、yyyyMMddHHmmss形式で指定します。 
439                chartFile               = null;                 // 5.9.16.2 (2017/1/28) 6.3.5.0 (2015/08/08) チャートの画像ファイル名
440        }
441
442        /**
443         * チャートを表示するためのタグを作成します。
444         *
445         * @param       filename        画像ファイル
446         * @param       keyword         クリッカブル・マップの対応づける為のキーワード
447         *
448         * @return      タグ文字列
449         */
450        private String makeTag2( final String filename,final String keyword ) {
451                StringBuilder rtn = new StringBuilder( HybsSystem.BUFFER_MIDDLE );
452
453                rtn.append( "<img" );
454                if( keyword != null ) {
455                        rtn.append( " usemap=\"#").append( keyword ).append( "\"");
456                }
457                rtn.append( " width=\""  ).append( width  ).append( "px\"");
458                rtn.append( " height=\"" ).append( height ).append( "px\"");
459                rtn.append( " src=\""    ).append( filename ).append( "\" /> ");
460
461                return rtn.toString();
462        }
463
464        /**
465         * ChartCreate のオブジェクトを生成します。
466         *
467         * @og.rev 4.1.1.0 (2008/02/04) categoryCutNo , categoryAnchor 属性を追加
468         * @og.rev 5.6.1.0 (2013/02/01) dateAxisFormat 属性を追加
469         * @og.rev 5.6.1.0 (2013/02/01) useVerticalLabels 属性を追加
470         * @og.rev 5.9.16.2 (2017/1/28) 6.7.3.0 (2017/01/27) 日付軸(dateAxis)の指定で、dateSegSize,dateSegIncluded,dateSegExcluded,dateStartTime を追加します。
471         *
472         * @return  ChartCreateオブジェクト
473         */
474        private ChartCreate create() {
475                ChartCreate tempCreate = new ChartCreate();
476
477                tempCreate.setTitle( title );
478                tempCreate.setDomainLabel( domainLabel );
479                tempCreate.setShowLegend( showLegend );
480                tempCreate.setRectangleEdge( rectangleEdge );
481                tempCreate.setPlotOrientation( plotOrientation );
482                tempCreate.setChartBackColor( chartBackColor );                 // 背景色の設定
483                tempCreate.setPlotBackColor( plotBackColor );                   // 描画領域の設定
484                tempCreate.setRotationLabel( rotationLabel );                   // 横軸ラベルの傾き
485                tempCreate.setUseVerticalLabels( useVerticalLabels );   // 5.6.4.3 (2013/05/24)) ラベルの表示向き
486                tempCreate.setDomainMarker( domainMarker );                             // ドメインマーカー
487                tempCreate.setUseDomainLabel( useDomainLabel );                 // 横軸ラベルの表示有無
488                tempCreate.setUseMarkerLabel( useMarkerLabel );                 // マーカーの設定値表示
489                tempCreate.setSeriesPikup( seriesPikup );                               // ピックアップするシリーズ番号
490                tempCreate.setImageMapUrl( imageMapUrl );                               // クリッカブル・マップ用URL
491                tempCreate.setCategoryMargin( categoryMargin );                 // 4.0.2.0 (2007/12/20) カテゴリマージン(0.0〜1.0)
492                tempCreate.setLowerMargin( lowerMargin );                               // 4.0.2.0 (2007/12/20) 下方マージン(0.0〜1.0)
493                tempCreate.setUpperMargin( upperMargin );                               // 4.0.2.0 (2007/12/20) 上方マージン(0.0〜1.0)
494//              tempCreate.setShapeColors( shapeColors );                               // 4.0.2.0 (2007/12/20) 上方マージン(0.0〜1.0)
495                tempCreate.setUseDomainLine( useDomainLine );                   // 4.0.3.0 (2008/01/07) 横軸のグリッド表示有無(垂直線)
496                tempCreate.setDomainLineColor( domainLineColor );               // 4.0.3.0 (2008/01/07) 横軸のグリッド線の色
497                tempCreate.setUseRangeLine( useRangeLine );                             // 4.0.3.0 (2008/01/07) 縦軸のグリッド表示有無(水平線)
498                tempCreate.setRangeLineColor( rangeLineColor );                 // 4.0.3.0 (2008/01/07) 縦軸のグリッド線の色
499                tempCreate.setCategorySkip( categorySkip );                             // 4.0.3.0 (2008/01/07) 横軸ラベルをスキップする間隔
500                tempCreate.setCategoryCutNo( categoryCutNo );                   // 4.1.1.0 (2008/02/04) 横軸ラベルの文字位置指定のキーブレイク
501                tempCreate.setCategoryAnchor( categoryAnchor );                 // 4.1.1.0 (2008/02/04) 横軸ラベルの文字位置指定のキーブレイク
502//              tempCreate.setDomainLineOffset( lineOffset );                   // 4.1.1.0 (2008/02/14) 横軸のグリッド(垂直線)の書き出し位置(START,MIDDLE,END)
503                tempCreate.setRangeSkip( rangeSkip );                                   // 4.1.1.0 (2008/02/04) 縦軸のグリッド線(水平線)をスキップする間隔
504                tempCreate.setUseToolTip( useToolTip );                                 // 4.3.1.0 (2008/08/09) ツールチップスの利用
505                tempCreate.setDateAxisFormat( dateAxisFormat );                 // 5.6.1.0 (2013/02/01) Time,XYTime Polt関係の時間軸を表す場合のフォーマット指定
506                tempCreate.setSegmentedTimelineInfo( dateSegSize,dateSegIncluded,dateSegExcluded,dateStartTime );       // 5.9.16.2 (2017/1/28) 6.7.3.0 (2017/01/27) SegmentedTimeline 関係
507
508
509                if( isDebug() ) { tempCreate.setDebug( true );  }               // 4.0.2.0 (2007/12/20)
510
511                tempCreate.setDatasetList( chartDataset );
512
513                return tempCreate ;
514        }
515
516        /**
517         * テンポラリFile を取得します。
518         *
519         * ここでは、一般的なファイル出力を考慮した テンポラリFile を作成します。
520         * 
521         * @og.rev 5.9.16.2 (2017/1/28) 6.3.5.0 (2015/08/08) チャートの画像ファイル名指定に対応。
522         *
523         * @param       fileURL ファイルを作成するディレクトリ
524         *
525         * @return      テンポラリFile
526         */
527        private File getTempFile( final String fileURL ) {
528                final File file ;
529
530                String directory = HybsSystem.url2dir( fileURL );
531                File dir = new File( directory );
532                if( ! dir.exists() && ! dir.mkdirs() ) {
533                        String errMsg = "ディレクトリの作成に失敗しました。[" + directory + "]";
534                        throw new HybsSystemException( errMsg );
535                }
536
537                try {
538//                      file = File.createTempFile( "JFree",".png",dir );
539//                      file.deleteOnExit();
540                        // 5.9.16.2 (2017/1/28) 画像ファイル指定 (6.3.5.0 (2015/08/08))
541                        if( chartFile == null ) {
542                                file = File.createTempFile( "JFree",".png",dir );
543                                file.deleteOnExit();
544                        }
545                        else {
546                                file = new File( dir , chartFile );
547                        }
548                        
549                }
550                catch( IOException ex ) {
551                        String errMsg = "ファイル名がオープン出来ませんでした。"
552                                + HybsSystem.CR
553                                        + "Url:" + fileURL ;
554                        throw new HybsSystemException( errMsg,ex );
555                }
556
557                return file ;
558        }
559
560        /**
561         * 【TAG】コマンド[NEW/RENEW]をセットします(初期値:NEW)。
562         *
563         * @og.tag
564         * コマンドは,HTMLから(get/post)指定されますので,CMD_xxx で設定される
565         * フィールド定数値のいづれかを、指定できます。
566         * command が、NEW または、RENEW の場合のみ、新規にオブジェクトの構築を行います。
567         *
568         * @param       cmd コマンド(public static final 宣言されている文字列)
569         * @see         <a href="../../../../constant-values.html#org.opengion.hayabusa.taglib.ChartCreateTag.CMD_NEW">コマンド定数</a>
570         */
571//      public void setCommand( String cmd ) {
572//              String cmd2 = getRequestParameter( cmd );
573//              if( cmd2 != null && cmd2.length() != 0 ) { command = cmd2.toUpperCase(Locale.JAPAN); }
574//      }
575
576        /**
577         * 【TAG】チャートのタイトルをセットします。
578         *
579         * @og.tag チャートのタイトルをセットします。
580         *
581         * @param   ttl タイトル
582         */
583        public void setTitle( final String ttl ) {
584                title = nval( getRequestParameter( ttl ),title );
585        }
586
587        /**
588         * 【TAG】チャートの横幅をセットします(初期値:200)。
589         *
590         * @og.tag
591         * タイトルや凡例も含んだ大きさです。データ領域は自動計算されます。
592         *
593         * @og.rev 4.0.1.0 (2007/12/13) 引数に "px" を使用できるようにする。
594         *
595         * @param   wd 横幅
596         */
597        public void setWidth( final String wd ) {
598                // 引数に、"px" が使用されていた場合は、それを取り除く。
599                if( wd != null && wd.length() >= 3 && wd.endsWith( "px" ) ) {
600                        width = Integer.valueOf( wd.substring( 0,wd.length()-2 ) );
601                }
602                else {
603                        width = nval( getRequestParameter( wd ),width );
604                }
605        }
606
607        /**
608         * 【TAG】チャートの縦幅をセットします(初期値:200)。
609         *
610         * @og.tag
611         * タイトルや凡例も含んだ大きさです。データ領域は自動計算されます。
612         *
613         * @og.rev 4.0.1.0 (2007/12/13) 引数に "px" を使用できるようにする。
614         *
615         * @param   ht 縦幅
616         */
617        public void setHeight( final String ht ) {
618                // 引数に、"px" が使用されていた場合は、それを取り除く。
619                if( ht != null && ht.length() >= 3 && ht.endsWith( "px" ) ) {
620                        height = Integer.valueOf( ht.substring( 0,ht.length()-2 ) );
621                }
622                else {
623                        height = nval( getRequestParameter( ht ),height );
624                }
625        }
626
627        /**
628         * 【TAG】チャートのドメインラベルを指定します。
629         *
630         * @og.tag
631         * チャートのドメインラベルを指定します。
632         *
633         * @param   dmLbl チャートのドメインラベル
634         */
635        public void setDomainLabel( final String dmLbl ) {
636                domainLabel = nval( getRequestParameter( dmLbl ),domainLabel );
637        }
638
639        /**
640         * 【TAG】チャートの凡例の表示可否[true/false]をセットします(初期値:true[表示する])。
641         *
642         * @og.tag
643         * 初期値は、表示する(true) です。
644         *
645         * @param   swLegend 凡例の表示可否 [true:表示する/それ以外:しない]
646         */
647        public void setShowLegend( final String swLegend ) {
648                showLegend = nval( getRequestParameter( swLegend ),showLegend );
649        }
650
651        /**
652         * 【TAG】チャートの表示箇所を、[TOP/BOTTOM/RIGHT/LEFT]で指定します(初期値:BOTTOM)。
653         *
654         * @og.tag
655         * 表示箇所は、org.jfree.ui.RectangleEdge クラスの設定値を使用します。
656         * 指定できるのは、TOP、BOTTOM、RIGHT、LEFT で、各文字の頭一文字で
657         * 判定してます。つまり、T,B,R,L で、判定を行い、それ以外はエラーになります。
658         * 初期値は、BOTTOM です。
659         *
660         * @param   rectEdge 凡例表示方向 : (TOP、BOTTOM、RIGHT、LEFT)
661         */
662        public void setRectangleEdge( final String rectEdge ) {
663                rectangleEdge = nval( getRequestParameter( rectEdge ),rectangleEdge );
664        }
665
666        /**
667         * 【TAG】チャートのプロット(Plot)表示方向を、[VERTICAL(or V),HORIZONTAL(or H)]で指定します(初期値:VERTICAL)。
668         *
669         * @og.tag
670         * 軸表示方向は、org.jfree.chart.plot.PlotOrientation クラスの設定値を使用します。
671         * 指定できるのは、VERTICAL、HORIZONTALで、各文字の頭一文字で
672         * 判定してます。つまり、V,H で、判定を行い、それ以外はエラーになります。
673         * 初期値は、VERTICAL です。
674         *
675         * @param   orientation プロット表示方向 : VERTICAL(or V) , HORIZONTAL(or H)
676         */
677        public void setPlotOrientation( final String orientation ) {
678                plotOrientation = nval( getRequestParameter( orientation ),plotOrientation );
679        }
680
681        /**
682         * 【TAG】チャートの背景色を指定します。
683         *
684         * @og.tag
685         * 指定文字列は、java.awt.Color クラスのstatic フィールド名で指定します。
686         * BLACK , BLUE , CYAN , DARK_GRAY , GRAY , GREEN , LIGHT_GRAY ,
687         * MAGENTA , ORANGE , PINK , RED , WHITE , YELLOW , (PURPLE) が指定できます。
688         * また、#XXXXXX形式の16bitRGB表記 でも指定可能です。
689         *
690         * @param   chBackClr チャートの背景色
691         * @see         java.awt.Color#BLACK
692         */
693        public void setChartBackColor( final String chBackClr ) {
694                chartBackColor = nval( getRequestParameter( chBackClr ),chartBackColor );
695        }
696
697        /**
698         * 【TAG】チャートの描画領域の色を指定します。
699         *
700         * @og.tag
701         * 指定文字列は、java.awt.Color クラスのstatic フィールド名で指定します。
702         * BLACK , BLUE , CYAN , DARK_GRAY , GRAY , GREEN , LIGHT_GRAY ,
703         * MAGENTA , ORANGE , PINK , RED , WHITE , YELLOW , (PURPLE) が指定できます。
704         * また、#XXXXXX形式の16bitRGB表記 でも指定可能です。
705         *
706         * @param   plBackClr チャートの描画領域色
707         * @see         java.awt.Color#BLACK
708         */
709        public void setPlotBackColor( final String plBackClr ) {
710                plotBackColor = nval( getRequestParameter( plBackClr ),plotBackColor );
711        }
712
713        /**
714         * 【TAG】チャートのカテゴリーラベルの方向を指定します(3:60度)。
715         *
716         * @og.tag
717         * 方向は、上方向に対して、(PI / 指示数) で求まる値に設定します。
718         * この指示数に相当する値を設定します。
719         * 1:180度 、2:90度 、3:60度 、4:45度 、6:30度 ・・・
720         * マイナスは、した方向に回転させます。
721         * 0 を指定した場合は、何も設定しません。
722         * 初期値は、3:60度です。
723         *
724         * @param       rttLabel        カテゴリーラベルの方向
725         */
726        public void setRotationLabel( final String rttLabel ) {
727                rotationLabel = nval( getRequestParameter( rttLabel ),rotationLabel );
728        }
729
730        /**
731         * 【TAG】ラベルの表示向きを縦にするかどうか[false/true]を指定します(初期値:false)。
732         *
733         * @og.tag
734         * ChartCreate の rotationLabel は、角度を指定できましたが、NumberAxis,DateAxis では、
735         * 縦にするかどうかの指定しかできません。
736         * ここでは、true を指定するとラベルは、縦書きになります。
737         * 初期値は、false(横書き)です。
738         *
739         * @og.rev 5.6.4.3 (2013/05/24)) 新規追加
740         *
741         * @param       useVLavels      ラベルの表示向き [false:横書き/true:縦書き]
742         */
743        public void setUseVerticalLabels( final String useVLavels ) {
744                useVerticalLabels = nval( getRequestParameter( useVLavels ),useVerticalLabels );
745        }
746
747        /**
748         * 【TAG】チャートの横軸の値(ドメイン)に合致する位置にマーカーラインを設定します。
749         *
750         * @og.tag
751         * この属性には、マーカーラインを設定する値を記述します。
752         *
753         * @param   marker ドメインのマーカーライン
754         */
755        public void setDomainMarker( final String marker ) {
756                domainMarker = nval( getRequestParameter( marker ),domainMarker );
757        }
758
759        /**
760         * 【TAG】横軸ラベルのラベルを表示するかどうか[true/false]を指定します(初期値:true)。
761         *
762         * @og.tag
763         * ドメイン(横軸)が、多数存在する場合、ドメインラベルが見えにくくなります。
764         * そのようなケースで、横軸のラベルそのものを表示しない場合に、false を
765         * 設定します。
766         * 初期値は、表示する(true)です。
767         *
768         * @param   flag 横軸ラベルの表示有無 [true:表示する/false:表示しない]
769         */
770        public void setUseDomainLabel( final String flag ) {
771                useDomainLabel = nval( getRequestParameter( flag ),useDomainLabel );
772        }
773
774        /**
775         * 【TAG】マーカーラインに、その設定値を表示するかどうか[true/false]を指定します(初期値:true)。
776         *
777         * @og.tag
778         * ドメイン(横軸)が、多数存在する場合、ドメインラベルが見えない場合があります。
779         * そのようなケースで、見たい値にマーカーラインを設定し、その横に、ドメインラベル
780         * を表示する事で、ピックアップしている軸の値を容易に知ることが可能です。
781         * 初期値は、表示する(true)です。
782         *
783         * @param   flag マーカーラインの設定値表示 true:表示する/false:表示しない]
784         */
785        public void setUseMarkerLabel( final String flag ) {
786                useMarkerLabel = nval( getRequestParameter( flag ),useMarkerLabel );
787        }
788
789        /**
790         * 【TAG】JFreeChart オブジェクトをキャッシュするかどうか[true/false]を指定します(初期値:false)。
791         *
792         * @og.tag
793         * useCache="true" を設定すると、session に、HybsSystem.JF_CHART_CACHE_KEY
794         * キーで、キャッシュされます。
795         * そのときに、domainMarker 属性と、seriesPikup 属性だけ、再設定可能になっています。
796         *
797         * 初期値は、キャッシュしない(false)です。
798         *
799         * @param   flag JFreeChartをキャッシュするかどうか true:キャッシュする/false:キャッシュしない]
800         * @see     #setDomainMarker( String )
801         * @see     #setSeriesPikup( String )
802         */
803        public void setUseCache( final String flag ) {
804                useCache = nval( getRequestParameter( flag ),useCache );
805        }
806
807        /**
808         * 【TAG】複数シリーズのピックアップを行う場合のシリーズ番号を指定します。
809         *
810         * @og.tag
811         * 複数シリーズ(検索時に複数項目を同時に検索する場合)では、チャート上に
812         * 複数のグラフが表示されますが、その中の一つをピックアップする場合に、
813         * シリーズ番号を指定します。
814         * シリーズ番号は、0 から始まる数字です。
815         * ここでは、ピックアップされたシリーズは、赤色で表示されます。
816         * それ以外は、グレー色での表示になります。
817         * seriesPikup を使用すると、chartDataset タグの useValueVisible 属性が
818         * 影響を受けます。この属性は、データの値(itemText)を表示しますが、
819         * seriesPikup が指定された場合は、そのシリーズのみにラベル表示します。
820         *
821         * @param       pikup   シリーズ番号
822         */
823        public void setSeriesPikup( final String pikup ) {
824                seriesPikup = nval( getRequestParameter( pikup ),seriesPikup );
825        }
826
827        /**
828         * 【TAG】キャッシュ用マスタキーを指定します。
829         *
830         * @og.tag
831         * useCache="true" に設定した場合、キャッシュを使用できるか確認します。
832         * この場合、seriesPikup 違いの場合は、JFreeChart オブジェクトそのものを
833         * キャッシュしておけば、データベースアクセスなしで、グラフを再描画
834         * させることが可能です。
835         * この、同一 JFreeChart を指定するためのキーを、ここで設定します。
836         * このキーの個数だけ、JFreeChart がキャッシュされます。
837         * なお、キャッシュ保持時間は、5分固定です。
838         *
839         * @param       mkey    キャッシュ用マスタキー
840         */
841        public void setMasterKey( final String mkey ) {
842                masterKey = nval( getRequestParameter( mkey ),masterKey );
843        }
844
845        /**
846         * 【TAG】クリッカブル・マップ用URLを指定します。
847         *
848         * @og.tag
849         * 画像に、クリッカブル・マップを作成する場合の、URL を指定します。
850         * これは、画像上にエリア指定でリンク引数を作成することが可能です。
851         * URL 自身は、? 付きで固定値の引数を連結することが可能です。
852         * クリックしたエリアのカテゴリやインデックスの値(引数)は、自動的に
853         * 設定されます。(指定しない場合はチャートによって異なります)
854         * <pre>
855         * ・Pie      :category、pieIndex
856         * ・XY       :series、item
857         * ・Category :series、category
858         * </pre>
859         * この引数の URL の名称を変更したい場合は、URL に続けて、カンマ(,) で、
860         * 名称を記述してください。
861         * 例:link.jsp,BLOCK
862         *
863         * @param       imap    クリッカブル・マップ用URL
864         * @see #setImageMapTarget( String )
865         */
866        public void setImageMapUrl( final String imap ) {
867                imageMapUrl = nval( getRequestParameter( imap ),imageMapUrl );
868        }
869
870        /**
871         * 【TAG】クリッカブル・マップ用TARGETを指定します。
872         *
873         * @og.tag
874         * 画像に、クリッカブル・マップを作成する場合の、TARGET を指定します。
875         * これは、画像上にエリア指定でリンクを作成する場合のフレーム指定です。
876         *
877         * @param       target  クリッカブル・マップ用TARGET
878         * @see #setImageMapUrl( String )
879         */
880        public void setImageMapTarget( final String target ) {
881                imageMapTarget = nval( getRequestParameter( target ),imageMapTarget );
882        }
883
884        /**
885         * 【TAG】カテゴリマージン(0.0〜1.0)を指定します。
886         *
887         * @og.tag
888         * カテゴリ(グラフの横軸に相当)の表示間隔(マージン)の比率を指定します。
889         * この比率は、% ではなく、数字(double)での設定になります。
890         * 何も指定しない場合は、デフォルトで自動調整されます。
891         *
892         * @og.rev 4.0.2.0 (2007/12/20) 新規追加
893         *
894         * @param       margin  カテゴリマージン(0.0〜1.0)
895         */
896        public void setCategoryMargin( final String margin ) {
897                categoryMargin = nval( getRequestParameter( margin ),categoryMargin );
898        }
899
900        /**
901         * 【TAG】下方マージン(0.0〜1.0)を指定します。
902         *
903         * @og.tag
904         * カテゴリ(グラフの横軸に相当)の下方側(左側)のマージンの比率を指定します。
905         * この比率は、% ではなく、数字(double)での設定になります。
906         * 何も指定しない場合は、デフォルトで自動調整されます。
907         *
908         * @og.rev 4.0.2.0 (2007/12/20) 新規追加
909         *
910         * @param       margin  下方マージン(0.0〜1.0)
911         */
912        public void setLowerMargin( final String margin ) {
913                lowerMargin = nval( getRequestParameter( margin ),lowerMargin );
914        }
915
916        /**
917         * 【TAG】上方マージン(0.0〜1.0)を指定します。
918         *
919         * @og.tag
920         * カテゴリ(グラフの横軸に相当)の上方側(右側)のマージンの比率を指定します。
921         * この比率は、% ではなく、数字(double)での設定になります。
922         * 何も指定しない場合は、デフォルトで自動調整されます。
923         *
924         * @og.rev 4.0.2.0 (2007/12/20) 新規追加
925         *
926         * @param       margin  上方マージン(0.0〜1.0)
927         */
928        public void setUpperMargin( final String margin ) {
929                upperMargin = nval( getRequestParameter( margin ),upperMargin );
930        }
931
932        /**
933         * 【TAG】横軸のグリッド表示有無(垂直線)を指定します(初期値:false)。
934         *
935         * @og.tag
936         * ドメイン(横軸)に対する、グリッドラインを表示するかどうか指定します。
937         *
938         * 何も指定しない場合は、表示しません。(false)
939         *
940         * @og.rev 4.0.3.0 (2008/01/07) 新規追加
941         *
942         * @param       useLine 横軸のグリッド表示有無(垂直線)
943         */
944        public void setUseDomainLine( final String useLine ) {
945                useDomainLine = nval( getRequestParameter( useLine ),useDomainLine );
946        }
947
948        /**
949         * 【TAG】横軸のグリッド線の色を指定します。
950         *
951         * @og.tag
952         * ドメイン(横軸)に対する、グリッドラインの表示色を指定します。
953         * 何も指定しない場合は、デフォルトで自動設定されます。
954         *
955         * @og.rev 4.0.3.0 (2008/01/07) 新規追加
956         *
957         * @param       color   横軸のグリッド線の色
958         */
959        public void setDomainLineColor( final String color ) {
960                domainLineColor = nval( getRequestParameter( color ),domainLineColor );
961        }
962
963        /**
964         * 【TAG】横軸ラベルをスキップする間隔を指定します。
965         *
966         * @og.tag
967         * 横軸ラベル(カテゴリラベル表示)する際に、スキップする間隔を指定します。
968         * "1" (初期値)では、1つづつ表示(つまり、すべて表示する)します。
969         * "2" とすると、1つおきに、"3" とすると、2つおきに表示します。
970         * 初期値は、"1" (すべて表示)です。
971         * なお、先頭から表示を開始します。
972         *
973         * 注意:これとは別に、ラベル先頭に "_" を付けた場合は、ラベルを表示しません。
974         * また、categoryCutNo が指定された場合は、categorySkip は使用されません。
975         *
976         * @param       step    スキップする間隔
977         * @see         #setCategoryCutNo( String )
978         */
979        public void setCategorySkip( final String step ) {
980                categorySkip = nval( getRequestParameter( step ),categorySkip );
981        }
982
983        /**
984         * 【TAG】横軸ラベルの文字位置指定のキーブレイクを指定します。
985         *
986         * @og.tag
987         * 横軸ラベル(カテゴリラベル表示)する際に、ラベルの先頭から、この指定文字数だけ
988         * カットして、表示します。
989         * その際、前回作成したカットラベルと、同一ラベルの場合は、表示しません。
990         * 例えば、データは、年月日で、年と月のみ(先頭6文字)を指定すると、
991         * 日のデータは、ラベルが表示されません。
992         * 指定される数字は、1以上の整数としてください。
993         * 初期値は、すべて表示です。
994         *
995         * 注意:これとは別に、ラベル先頭に "_" を付けた場合は、ラベルを表示しません。
996         *
997         * @og.rev 4.1.1.0 (2008/02/04) 新規追加
998         *
999         * @param       cutNo   キーブレイク位置
1000         * @see         #setCategorySkip( String )
1001         */
1002        public void setCategoryCutNo( final String cutNo ) {
1003                categoryCutNo = nval( getRequestParameter( cutNo ),categoryCutNo );
1004        }
1005
1006        /**
1007         * 【TAG】横軸のグリッド(垂直線)の書き出し位置(START,MIDDLE,END)を指定します。
1008         *
1009         * @og.tag
1010         * 横軸のグリッド(垂直線)を、グラフのどの位置に記述するかを指定します。
1011         * 具体的な値は、CategoryAnchor オブジェクトの値になります。
1012         * ここでは、文字列で(START,MIDDLE,END)を指定します。(先頭一文字で判定)
1013         * 何も指定しない場合は、デフォルト(MIDDLE)です。
1014         *
1015         * @og.rev 4.1.1.0 (2008/02/14) 新規追加
1016         *
1017         * @param       anchor  横軸のグリッド(垂直線)の書き出し位置(START,MIDDLE,END)
1018         */
1019        public void setCategoryAnchor( final String anchor ) {
1020                categoryAnchor = nval( getRequestParameter( anchor ),categoryAnchor );
1021
1022                if( categoryAnchor != null && categoryAnchor.length() > 0 ) {
1023                        if( ! "START".equals( categoryAnchor )  &&
1024                                ! "MIDDLE".equals( categoryAnchor ) &&
1025                                ! "END".equals( categoryAnchor ) ) {
1026                                        String errMsg = "指定のAnchorは適用できません。[" + anchor + "]"
1027                                                        + HybsSystem.CR
1028                                                        + "START,MIDDLE,END の中から、指定してください。" ;
1029                                        throw new HybsSystemException( errMsg );
1030                        }
1031                }
1032        }
1033
1034        /**
1035         * 【TAG】DomainLineの書き出し位置Offsetを指定します。
1036         *
1037         * @og.tag
1038         * 横軸ライン(カテゴリライン表示)する際に、ラインの描画位置を、
1039         * 先頭から、この指定数だけずらします。
1040         * プラスの場合は、右へ、マイナスの場合は、左へずらします。
1041         *
1042         * これにより、ライン(縦線)の位置を、グラフの中心から、ずらす事が
1043         * 可能になります。
1044         *
1045         * @og.rev 4.1.1.0 (2008/02/04) 新規追加
1046         *
1047         * @param       domainLineOffset        DomainLineの書き出し位置Offset
1048         */
1049//      public void setDomainLineOffset( final String domainLineOffset ) {
1050//              String offset = StringUtil.nval( getRequestParameter( domainLineOffset ),null );
1051//              if( offset != null ) {
1052//                      lineOffset = Double.parseDouble( offset );
1053//              }
1054//      }
1055
1056        /**
1057         * 【TAG】縦軸のグリッド表示有無(水平線)を指定します(初期値:true)。
1058         *
1059         * @og.tag
1060         * レンジ(縦軸)に対する、グリッドラインを表示するかどうか指定します。
1061         *
1062         * 何も指定しない場合は、表示しません。(false)
1063         *
1064         * @og.rev 4.0.3.0 (2008/01/07) 新規追加
1065         *
1066         * @param       useLine 横軸のグリッド表示有無(垂直線)
1067         */
1068        public void setUseRangeLine( final String useLine ) {
1069                useRangeLine = nval( getRequestParameter( useLine ),useRangeLine );
1070        }
1071
1072        /**
1073         * 【TAG】縦軸のグリッド線の色を指定します。
1074         *
1075         * @og.tag
1076         * レンジ(縦軸)に対する、グリッドラインの表示色を指定します。
1077         * 何も指定しない場合は、デフォルトで自動設定されます。
1078         *
1079         * @og.rev 4.0.3.0 (2008/01/07) 新規追加
1080         *
1081         * @param       color   縦軸のグリッド線の色
1082         */
1083        public void setRangeLineColor( final String color ) {
1084                rangeLineColor = nval( getRequestParameter( color ),rangeLineColor );
1085        }
1086
1087        /**
1088         * 【TAG】縦軸のグリッド線(水平線)をスキップする間隔を指定します。
1089         *
1090         * @og.tag
1091         * 縦軸のグリッド線(水平線)を表示する際に、スキップする間隔を指定します。
1092         * 通常は、ラベルと同じだけのグリッド線が掛かれますが、ラベルよりも
1093         * 少ない数のグリッド線(例えば、2つおき)を出す場合に、値を設定します。
1094         * "1" (初期値)では、1つづつ表示(つまり、すべて表示する)します。
1095         * "2" とすると、1つおきに、"3" とすると、2つおきに表示します。
1096         * 初期値は、"1" (すべて表示)です。
1097         * なお、先頭から表示を開始します。
1098         *
1099         * @og.rev 4.1.1.0 (2008/02/04) 新規追加
1100         *
1101         * @param       rngSkip 縦軸のグリッド線(水平線)をスキップする間隔
1102         */
1103        public void setRangeSkip( final String rngSkip ) {
1104                rangeSkip = nval( getRequestParameter( rngSkip ),rangeSkip );
1105        }
1106
1107        /**
1108         * 【TAG】ツールチップスの使用可否[true:利用する/false:利用しない]を指定します(初期値:false)。
1109         *
1110         * @og.tag
1111         * ラベルを利用する際に、ラベルと図面、隣のラベル同士が重なることがあります。
1112         * この場合、ツールチップスの利用をお勧めします。
1113         * 初期値は'false'です。
1114         *
1115         * @og.rev 4.3.1.0 (2008/08/09) 新規追加
1116         *
1117         * @param   toolTip ツールチップス [true:利用/false:利用しない]
1118         */
1119        public void setUseToolTip( final String toolTip ) {
1120                useToolTip = nval( getRequestParameter( toolTip ), useToolTip );
1121        }
1122
1123        /**
1124         * 【TAG】Time,XYTime Polt関係の時間軸を表す場合のフォーマットを指定します(初期値:MM/dd)。
1125         *
1126         * @og.tag
1127         * TimeSeries 関連のデータを扱う場合の横軸の日付フォーマットを指定します。
1128         * 日付フォーマットは、java.text.SimpleDateFormat で使われる yyyy/MM/dd HH:mm:ss 表記です。
1129         * 
1130         * 初期値は、"MM/dd" です。
1131         *
1132         * @og.rev 5.6.1.0 (2013/02/01) 新規追加
1133         * @og.rev 5.6.1.0 (2013/02/01) 新規追加
1134         *
1135         * @param       dtFormat        Time,XYTime Polt関係の時間軸を表す場合のフォーマット
1136         */
1137        public void setDateAxisFormat( final String dtFormat ) {
1138                dateAxisFormat = nval( getRequestParameter( dtFormat ), dateAxisFormat );
1139//              if( dtFormat != null && dtFormat.length() > 0 ) {
1140//                      dateAxisFormat  = dtFormat;
1141//              }
1142        }
1143        
1144        /**
1145         * 【TAG】Time,XYTime Polt関係の時間軸で、SegmentedTimelineのsegment size を、分単位で指定します。
1146         *
1147         * @og.tag
1148         * 日単位を指定する場合は、24*60 = 1440 を指定します。
1149         * 0 または、何も指定しない場合は、SegmentedTimeline を使用しません。
1150         * <pre>
1151         *   start time
1152         *     |
1153         *     v
1154         *     0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 ...
1155         *   +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+...
1156         *   |  |  |  |  |  |EE|EE|  |  |  |  |  |EE|EE|  |  |  |  |  |EE|EE|
1157         *   +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+...
1158         *   [_____________] [___]            [_]
1159         *          |          |               |
1160         *       included   excluded        segment
1161         *       segments   segments         size
1162         *   [___________________]
1163         *              |
1164         *         segment group
1165         * </pre>
1166         *
1167         * @og.rev 5.9.16.2 (2017/1/28) 6.7.3.0 (2017/01/27) 新規追加
1168         *
1169         * @param       segSize SegmentedTimelineのsegment size を、分単位で指定
1170         */
1171        public void setDateSegSize( final String segSize ) {
1172                dateSegSize = nval( getRequestParameter( segSize ), dateSegSize );
1173        }
1174
1175        /**
1176         * 【TAG】Time,XYTime Polt関係の時間軸で、SegmentedTimelineのincluded segments(スペース)を数値で指定します。
1177         *
1178         * @og.tag
1179         * segment group内で、スペース(空ける) になる segment数 を指定します。
1180         * この値は、dateSegSize を指定しない限り、使用されません。
1181         *
1182         * @og.rev 5.9.16.2 (2017/1/28) 6.7.3.0 (2017/01/27) 新規追加
1183         *
1184         * @param       segIncluded     SegmentedTimelineのincluded segments(スペース)を数値で指定
1185         * @see         #setDateSegSize( String )
1186         */
1187        public void setDateSegIncluded( final String segIncluded ) {
1188                dateSegIncluded = nval( getRequestParameter( segIncluded ), dateSegIncluded );
1189        }
1190
1191        /**
1192         * 【TAG】Time,XYTime Polt関係の時間軸で、SegmentedTimelineのexcluded segments(EE)を数値で指定します。
1193         *
1194         * @og.tag
1195         * segment group内で、excluded する segment数 を指定します。
1196         * この値は、dateSegSize を指定しない限り、使用されません。
1197         *
1198         * @og.rev 5.9.16.2 (2017/1/28) 6.7.3.0 (2017/01/27) 新規追加
1199         *
1200         * @param       segExcluded     SegmentedTimelineのexcluded segments(EE)を数値で指定
1201         * @see         #setDateSegSize( String )
1202         */
1203        public void setDateSegExcluded( final String segExcluded ) {
1204                dateSegExcluded = nval( getRequestParameter( segExcluded ), dateSegExcluded );
1205        }
1206
1207        /**
1208         * 【TAG】Time,XYTime Polt関係の時間軸で、SegmentedTimelineのStartTime(segment groupの開始位置) を、yyyyMMddHHmmss形式で指定します。
1209         *
1210         * @og.tag
1211         * TimeSeries 関連のデータを扱う場合の横軸に、SegmentedTimelineを指定します。
1212         * 日付フォーマットは、yyyyMMddHHmmss形式で指定します。
1213         * 
1214         * この値は、dateSegSize を指定しない限り、使用されません。
1215         * 初期値は、null(自動設定) です。
1216         *
1217         * @og.rev 5.9.16.2 (2017/1/28) 6.7.3.0 (2017/01/27) 新規追加
1218         *
1219         * @param       startTime       SegmentedTimelineのStartTime(segment groupの開始位置)
1220         * @see         #setDateSegSize( String )
1221         */
1222        public void setDateStartTime( final String startTime ) {
1223                dateStartTime = nval( getRequestParameter( startTime ), dateStartTime );
1224        }
1225        
1226        /**
1227         * 【TAG】チャートの画像ファイル名を指定します(初期値:自動)。
1228         *
1229         * @og.tag
1230         * チャートは、png 形式のファイルとして作成されます。そのファイル名を指定します。
1231         * ファイルは、CHART_TEMP_DIR 以下に、作成されます。
1232         * 原仕様では、作成するフォルダを指定できません。
1233         * 何も指定しない場合は、JFreeXXXXX.png 形式のテンポラリファイル名で作成されます。
1234         * この場合は、File#deleteOnExit() を付与するので、Tomcat停止時に自動的に削除されます。
1235         * chartFile 属性で指定した場合は、自動削除されませんので、ご注意ください。
1236         * 
1237         * 初期値は、自動( File.createTempFile( "JFree",".png" , CHART_TEMP_DIR ) ) です。
1238         *      (CHART_TEMP_DIR[={@og.value SystemData#CHART_TEMP_DIR}])。
1239         *
1240         * @og.rev 5.9.16.2 (2017/1/28) 6.3.5.0 (2015/08/08) チャートの画像ファイル名指定に対応。
1241         *
1242         * @param       file    時間軸を表すフォーマット
1243         */
1244        public void setChartFile( final String file ) {
1245                chartFile = nval( getRequestParameter( file ), chartFile );
1246        }
1247
1248        /**
1249         * BODY要素に記述した、chartDataset タグの属性設定クラスをListに追加します。
1250         *
1251         * BODY部に記述された、chartDataset タグの属性は、チャートのデータ取得Queryや、
1252         * チャートの種類などの情報を管理しています。
1253         * チャートの種類(Category系)によっては、チャートを合成して表示させることが可能です。
1254         * それらの複数のチャートの指定が、chartDataset タグ で行われます。
1255         *
1256         * @param       chDataset       chartDatasetタグの属性設定クラス
1257         */
1258        protected void addChartDataset( final ChartDataset chDataset ) {
1259                if( chartDataset == null ) { chartDataset = new ArrayList<ChartDataset>(); }
1260                chartDataset.add( chDataset );
1261        }
1262
1263        /**
1264         * シリアライズ用のカスタムシリアライズ書き込みメソッド
1265         *
1266         * @og.rev 4.0.0.0 (2007/11/29) 新規追加
1267         * @serialData 一部のオブジェクト(Map&lt;String,ChartCache&gt;,ChartCache)は、シリアライズされません。
1268         *
1269         * @param       strm    ObjectOutputStreamオブジェクト
1270         * @throws IOException  シリアライズに関する入出力エラーが発生した場合
1271         */
1272        private void writeObject( final ObjectOutputStream strm ) throws IOException {
1273                strm.defaultWriteObject();
1274        }
1275
1276        /**
1277         * シリアライズ用のカスタムシリアライズ読み込みメソッド
1278         *
1279         * ここでは、transient 宣言された内部変数の内、初期化が必要なフィールドのみ設定します。
1280         *
1281         * @og.rev 4.0.0.0 (2007/11/29) 新規追加
1282         * @serialData 一部のオブジェクト(Map&lt;String,ChartCache&gt;,ChartCache)は、読み込まれません。
1283         *
1284         * @param       strm    ObjectInputStreamオブジェクト
1285         * @see #release2()
1286         * @throws IOException  シリアライズに関する入出力エラーが発生した場合
1287         * @throws ClassNotFoundException       クラスを見つけることができなかった場合
1288         */
1289        private void readObject( final ObjectInputStream strm ) throws IOException , ClassNotFoundException {
1290                strm.defaultReadObject();
1291        }
1292
1293        /**
1294         * このオブジェクトの文字列表現を返します。
1295         * 基本的にデバッグ目的に使用します。
1296         *
1297         * @return このクラスの文字列表現
1298         */
1299        @Override
1300        public String toString() {
1301                StringBuilder rtn = new StringBuilder( HybsSystem.BUFFER_MIDDLE );
1302
1303                rtn.append( "[" ).append( this.getClass().getName() ).append( "]" ).append( HybsSystem.CR );
1304                rtn.append( "title           [" ).append( title           ).append( "]" ).append( HybsSystem.CR );
1305                rtn.append( "width           [" ).append( width           ).append( "]" ).append( HybsSystem.CR );
1306                rtn.append( "height          [" ).append( height          ).append( "]" ).append( HybsSystem.CR );
1307                rtn.append( "domainLabel     [" ).append( domainLabel     ).append( "]" ).append( HybsSystem.CR );
1308                rtn.append( "showLegend      [" ).append( showLegend      ).append( "]" ).append( HybsSystem.CR );
1309                rtn.append( "rectangleEdge   [" ).append( rectangleEdge   ).append( "]" ).append( HybsSystem.CR );
1310                rtn.append( "plotOrientation [" ).append( plotOrientation ).append( "]" ).append( HybsSystem.CR );
1311                rtn.append( "chartBackColor  [" ).append( chartBackColor  ).append( "]" ).append( HybsSystem.CR );
1312                rtn.append( "plotBackColor   [" ).append( plotBackColor   ).append( "]" ).append( HybsSystem.CR );
1313
1314                return rtn.toString();
1315        }
1316
1317        /**
1318         * JFreeChart や 画像ファイルのアドレスをキャッシュするクラスです。
1319         * このキャッシュは、JFreeChart 単位に保持されます。
1320         * JFreeChart と、画像ファイルのキャッシュを行います。
1321         * JFreeChart オブジェクトをキャッシュしなおしたタイミングで、
1322         * 画像ファイルのキャッシュは初期化(クリア)されます。
1323         * キャッシュの有効期間は、システムリソースの CHART_CACHE_TIME で定義します。
1324         */
1325        private static final class ChartCache {
1326                private static final int CACHE_TIME = HybsSystem.sysInt( "CHART_CACHE_TIME" );
1327                private static final long       MAX_CACHE_TIME = CACHE_TIME * 1000L;
1328
1329                private final Map<String,String> fileAdrs = new HashMap<String,String>();
1330                private final String            mkey ;
1331                private           long                  createLimitTime = 0L;
1332                private           JFreeChart    chart                   = null ;
1333
1334                /**
1335                 * コンストラクター
1336                 * JFreeChart オブジェクトをキャッシュするキーを指定します。
1337                 * 内部的には、このキー(mkey)で、比較や hashCode が計算されています。
1338                 *
1339                 * @param       mkey    キャッシュするキー
1340                 */
1341                public ChartCache( final String mkey ) {
1342                        this.mkey = mkey;
1343                }
1344
1345                /**
1346                 * JFreeChart オブジェクトをキャッシュします。
1347                 * 画像ファイルのキャッシュは初期化(クリア)されます。
1348                 * このキャッシュのタイミングで、キャッシュ時間を初期化します。
1349                 *
1350                 * @param       chart   JFreeChartオブジェクト
1351                 */
1352                public void setJFreeChart( final JFreeChart chart ) {
1353                        this.chart = chart;
1354                        fileAdrs.clear();
1355                        createLimitTime = System.currentTimeMillis() + MAX_CACHE_TIME;
1356                }
1357
1358                /**
1359                 * JFreeChart オブジェクトを返します。
1360                 * キャッシュされていれば、そのキャッシュを、そうでなければ、null を
1361                 * 返します。
1362                 * キャッシュの有効期間は、システムリソースの CHART_CACHE_TIME で定義します。
1363                 * オブジェクトの作成時間が、それを超える場合は、キャッシュを初期化します。
1364                 *
1365                 * @return   JFreeChart JFreeChartオブジェクト
1366                 */
1367                public JFreeChart getJFreeChart() {
1368                        return chart;
1369                }
1370
1371                /**
1372                 * 画像ファイルをキャッシュします。
1373                 * 画像ファイルのキャッシュはサブキー単位に行われます。
1374                 * つまり、このオブジェクトの中に、複数の画像ファイルのアドレスが
1375                 * キャッシュされています。
1376                 *
1377                 * @param       chart   JFreeChartオブジェクト
1378                 */
1379                public void putFileAddress( final String skey,final String adrs ) {
1380                        fileAdrs.put( skey,adrs );
1381                }
1382
1383                /**
1384                 * 画像ファイルのアドレスを返します。
1385                 * キャッシュされていれば、そのキャッシュを、そうでなければ、null を
1386                 * 返します。
1387                 * キャッシュの有効期間は、システムリソースの CHART_CACHE_TIME で定義します。
1388                 * オブジェクトの作成時間が、それを超える場合は、キャッシュを初期化します。
1389                 *
1390                 * @return   JFreeChart JFreeChartオブジェクト
1391                 */
1392                public String getFileAddress( final String skey ) {
1393                        return fileAdrs.get( skey ) ;
1394                }
1395
1396                /**
1397                 * キャッシュが、有効かどうかを返します。(有効:true)
1398                 * キャッシュは、システムリソースの CHART_CACHE_TIME (秒)パラメータ
1399                 * 指定された時間が経過すると、無効と判断されます。
1400                 * 有効であれば、true を返します。
1401                 *
1402                 * @return      有効かどうか(有効:true/無効:false)
1403                 */
1404                public boolean isAvailable() {
1405                        return ( System.currentTimeMillis() < createLimitTime ) ;
1406                }
1407
1408                /**
1409                 * このオブジェクトと他のオブジェクトが等しいかどうかを示します。
1410                 * キャッシュのキーが等しいかどうかで判断します。
1411                 *
1412                 * @param   object 比較対象の参照オブジェクト
1413                 * @return  obj 引数に指定されたオブジェクトとこのオブジェクトが等しい場合は true、そうでない場合は false
1414                 */
1415                public boolean equals( final Object object ) {
1416                        if( object instanceof ChartCache ) {
1417                                return this.mkey.equals( ((ChartCache)object).mkey );
1418                        }
1419                        return false ;
1420                }
1421
1422                /**
1423                 * オブジェクトのハッシュコード値を返します。
1424                 * このメソッドは、java.util.Hashtable によって提供されるような
1425                 * ハッシュテーブルで使用するために用意されています。
1426                 * equals( Object ) メソッドをオーバーライトした場合は、hashCode() メソッドも
1427                 * 必ず 記述する必要があります。
1428                 * この実装では、mkey.hashCode() と同値を返します。
1429                 *
1430                 * @return  このオブジェクトのハッシュコード値
1431                 */
1432                public int hashCode() {
1433                        return mkey.hashCode() ;
1434                }
1435        }
1436}