001package org.opengion.hayabusa.taglib;
002
003import java.util.ArrayList;
004import java.util.Arrays;
005import java.util.List;
006import java.util.concurrent.ConcurrentHashMap;
007import java.util.concurrent.ConcurrentMap;
008import java.util.regex.Matcher;
009import java.util.regex.Pattern;
010
011import org.opengion.hayabusa.common.HybsSystem;
012import org.opengion.hayabusa.common.HybsSystemException;
013import org.opengion.hayabusa.db.DBTableModel;
014import org.opengion.hayabusa.html.ViewForm;
015import org.opengion.hayabusa.html.ViewFormFactory;
016import org.opengion.hayabusa.html.ViewJsonParam;
017import org.opengion.hayabusa.io.JsChartData;
018import static org.opengion.fukurou.util.StringUtil.nval;
019
020/**
021 * JsChart は、JavascriptのjsChart用のスクリプトを出力するクラスです。
022 * 複数の JsChartData オブジェクトを合成することも、ここで行っています。
023 * ChartJSを利用しているため、標準属性以外の項目をセットする場合はoptionAttributesで行ってください。
024 * 例えばアニメーションをOFFにする場合はanimation:falseをセットします。
025 * 
026 * 出力されるスクリプトでは、idを指定しない場合はhybscanvas[tableId]が利用されます。
027 * 複数のグラフを同一画面で出力する場合はidかtableIdを変えてください。
028 * チャートオブジェクトはchart_[id]という名前で作成されるため、ajax等でコントロールが必要な場合は利用してください。
029 * 
030 * @og.formSample
031 * ●形式:<og:column chartType="…" ... />
032 * ●body:あり(EVAL_BODY_BUFFERED:BODYを評価し、{$#064;XXXX} を解析します)
033 * 
034 * ●Tag定義:
035 *  <og:jsChart
036 *      chartType       ○【TAG】チャートの種類を指定します。(必須)
037 *      id                【TAG】canvasタグのidを指定します。(初期値:hybscanvas)
038 *      height            【TAG】チャートの高さを指定します。(初期値:400)
039 *      width             【TAG】チャートの幅を指定します。(初期値:400)
040 *      labelColumn       【TAG】ラベルのカラム名を指定します。(表示名称)
041 *      title             【TAG】タイトルを指定します。
042 *      titlePosition     【TAG】タイトルの表示位置[top/right/bottom/left]を指定します。(初期値:top)
043 *      ylabel            【TAG】x軸のラベルを指定します。
044 *      xlabel            【TAG】y軸のラベルを指定します。
045 *      legendPosition    【TAG】凡例の表示位置[top/right/bottom/left]を指定します。(初期値:top)
046 *      legendDisplay     【TAG】凡例を表示するか[true/false]を指定します。
047 *      xscaleCallback    【TAG】x軸コールバックを指定します。
048 *      yscaleCallback    【TAG】y軸コールバックを指定します。
049 *      xscaleType        【TAG】x軸のスケールタイプ[category/time/linear]を指定します。(初期値:category)
050 *      xmax              【TAG】x軸の最大値を指定します。(xscaleTypeがlinearの場合に有効)
051 *      xmin              【TAG】x軸の最小値を指定します。(xscaleTypeがlinearの場合に有効)
052 *      xstepSize         【TAG】x軸のメモリ幅を指定します。(xscaleTypeがlinearの場合に有効)
053 *      timeUnit          【TAG】x軸のタイムの単位[year/quarter/month/week/day/hour/minute/second/millsecond]を指定します。(xscaleTypeがtimeの場合に有効。指定しない場合は自動)
054 *      timeUnitStepSize  【TAG】x軸のタイムの単位幅を指定します。(xscaleTypeがtimeの場合に有効)
055 *      timeSetFormat     【TAG】x軸の設定するタイムのフォーマットを指定します。(xscaleTypeがtimeの場合に有効)
056 *      timeLblFormat     【TAG】x軸の表示するタイムのフォーマットを指定します。(xscaleTypeがtimeの場合に有効)
057 *      timeMax           【TAG】x軸のタイムの最大値を指定します。(xscaleTypeがtimeの場合に有効)
058 *      timeMin           【TAG】x軸のタイムの最小値を指定します。(xscaleTypeがtimeの場合に有効)
059 *      yscaleType        【TAG】y軸のスケールタイプ[linear/category]を指定します。(初期値:linear)
060 *      ycategoryList     【TAG】y軸のメモリリストをカンマ区切りで指定します。(xscaleTypeがlinearの場合に有効)
061 *      max               【TAG】y軸の最大値を指定します。(xscaleTypeがlinearの場合に有効)
062 *      min               【TAG】y軸の最小値を指定します。(xscaleTypeがlinearの場合に有効)
063 *      stepSize          【TAG】y軸のメモリ幅を指定します。(xscaleTypeがlinearの場合に有効)
064 *      barWidthPer       【TAG】棒線の横幅を指定します。(初期値:0.8, typeがbar,horizontalBarの場合に有効)
065 *      onClick           【TAG】チャートクリック時のイベントを指定します。
066 *      tableid           【TAG】(通常使いません)sessionから所得する DBTableModelオブジェクトの ID
067 *      scope             【TAG】キャッシュする場合のスコープ[request/page/session/applicaton]を指定します(初期値:session)
068 *      widthEventColumn  【TAG】横幅を動機に設定するカラムのIDを指定します。
069 *      heightEventColumn 【TAG】縦幅を動的に設定するカラムのIDを指定します。
070 *      minEventColumn    【TAG】minを動的に設定するカラムのIDを指定します。 
071 *      maxEventColumn    【TAG】maxを動的に設定するカラムのIDを指定します。 
072 *      optionAttributes  【TAG】その他オプションを指定します。
073 *  >   ... Body ...
074 *  </og:jsChart>
075 * ●使用例
076 *      <og:jsChart
077 *          chartType      = "bar"
078 *          labelColumn    = "LDATA"
079 *          id             = "canvasid"
080 *          height         = "500"
081 *          width          = "800"
082 *          labelColumn    = "LCLM"
083 *          title          = "タイトル"
084 *          titlePosition  = "bottom"
085 *          ylabel         = "給料"
086 *          xlabel         = "名称"
087 *          legendPosition = "right"
088 *          legendDisplay  = "true"
089 *          xsclaeCallback = "function(value){return value + ' 様';}"
090 *          ysclaeCallback = "function(value){return value.toLocaleString();}"
091 *          xscaleType     = "time"
092 *          max            = "1000000"
093 *          min            = "100000"
094 *          stepSize       = "10000"
095 *          barWidthPer    = "0.4"
096 *      >
097 *          <og:jsChartData ... />
098 *      </og:jsChart>
099 *      
100 * @og.group 画面表示
101 * 
102 * @version     5.9.17.2        2017/02/08
103 * @og.rev 5.9.19.0             2017/04/07      T.OTA 61200-170316-02   チャートサイズ・max・minの動的変更対応
104 * 
105 * @author      T.OTA
106 * @since       JDK7.0
107 *
108 */
109public class JsChartTag extends CommonTagSupport {
110        //* このプログラムのVERSION文字列を設定します。{@value} */
111        private static final String             VERSION                         = "5.9.17.2 (2017/02/07)";
112        private static final long               serialVersionUID        = 1631345224410617801L;
113        /** chartType 引数に渡す事の出来る アクション 折れ線 **/
114        public static final String              CTYPE_LINE                      = "line";
115        /** chartType 引数に渡す事の出来る アクション 棒線 **/
116        public static final String              CTYPE_BAR                       = "bar";
117        /** chartType 引数に渡す事の出来る アクション 横棒線 **/
118        public static final String              CTYPE_HBAR                      = "horizontalBar";
119        /** chartType 引数に渡す事の出来る アクション レイダー **/
120        public static final String              CTYPE_RADAR                     = "radar";
121        /** chartType 引数に渡す事の出来る アクション ポーラエリア **/
122        public static final String              CTYPE_PA                        = "polarArea";
123        /** chartType 引数に渡す事の出来る アクション 円 **/
124        public static final String              CTYPE_PIE                       = "pie";
125        /** chartType 引数に渡す事の出来る アクション ドーナツ **/
126        public static final String              CTYPE_DOUGHNUT          = "doughnut";
127        /** chartType 引数に渡す事の出来る アクション リスト */
128        private static final String[]   CTYPE_LIST                      = new String[] { CTYPE_LINE, CTYPE_BAR, CTYPE_HBAR, CTYPE_RADAR, CTYPE_PA, CTYPE_PIE, CTYPE_DOUGHNUT };
129        /** chartType が円形のリスト */
130        private static final String[]   CTYPE_CI                        = new String[] { CTYPE_RADAR, CTYPE_PA, CTYPE_PIE, CTYPE_DOUGHNUT };
131        private static final String[]   TYPE_POSITION           = new String[] { "top", "right", "bottom", "left" };
132        private static final String[]   TYPE_TIMEUNIT           = new String[] { "year", "quarter", "month", "week", "day", "hour", "minute", "second", "millsecond" };
133        private static final String[]   TYPE_XSCALE                     = new String[] { "category", "time", "linear" };
134        private static final String[]   TYPE_YSCALE                     = new String[] { "linear", "category" };
135        private static final String[]   TYPE_BOOLEAN            = new String[] { "true", "false" };
136        
137        private static final String     CANVAS_NAME                     = "hybscanvas";
138        
139        // 変数宣言
140        private String                                  id                                      = null;                                                                                                                                                                         // canvasタグのid
141        private String                                  height                          = "400";                                                                                                                                                                                                // canvasタグのheight
142        private String                                  width                           = "400";                                                                                                                                                                                                // canvasタグのwidth
143        private String                                  chartType                       = null;                                                                                                                                                                                         // チャートタイプ
144        private String                                  labelColumn                     = null;                                                                                                                                                                                         // ラベルカラム
145        private String                                  ylabel                          = null;                                                                                                                                                                                         // y軸ラベル
146        private String                                  xlabel                          = null;                                                                                                                                                                                         // x軸ラベル
147//      private String                                  scope                           = "session";                                                                                                                                                                                    // スコープ
148        private String                                  tableId                         = HybsSystem.TBL_MDL_KEY;                                                                                                                                                               // テーブルid
149        private List<JsChartData>         jsChartData                     = null;                                                                                                                                                                                         // jsChartDataのリスト
150        private transient DBTableModel  table                           = null;                                                                                                                                                                                         // DBTableModelクラス
151        private String                                  onClick                         = null;                                                                                                                                                                                         // クリックイベント
152        private String                                  title                           = null;                                                                                                                                                                                         // タイトル
153        private String                                  titlePosition           = null;                                                                                                                                                                                         // タイトル位置
154        private String                                  legendPosition          = null;                                                                                                                                                                                         // 凡例位置
155        private String                                  legendDisplay           = null;                                                                                                                                                                                         // 凡例表示フラグ
156        private String                                  barWidthPer                     = null;                                                                                                                                                                                         // 棒線の横幅(パーセント)
157        private String                                  xscaleCallback          = null;                                                                                                                                                                                         // x軸のメモリ編集用コールバック
158        private String                                  yscaleCallback          = null;                                                                                                                                                                                         // y軸のメモリ編集用コールバック
159        private String                                  xscaleType                      = null;                                                                                                                                                                                         // x軸のスケールタイプ
160        private String                                  xmax                            = null;                                                                                                                                                                                         // x軸の最大値(リニアスケール用)
161        private String                                  xmin                            = null;                                                                                                                                                                                         // x軸の最小値(リニアスケール用)
162        private String                                  xstepSize                       = null;                                                                                                                                                                                         // x軸のメモリ幅(リニアスケール用)
163        private String                                  yscaleType                      = null;                                                                                                                                                                                         // y軸のスケールタイプ
164        private String                                  ycategoryList           = null;                                                                                                                                                                                         // y軸のカテゴリーリスト(カテゴリースケール用)
165        private String                                  max                                     = null;                                                                                                                                                                                         // y軸の最大値(リニアスケール用)
166        private String                                  min                                     = null;                                                                                                                                                                                         // y軸の最小値(リニアスケール用)
167        private String                                  stepSize                        = null;                                                                                                                                                                                         // y軸のメモリ幅(リニアスケール用)
168        private String                                  timeUnit                        = null;                                                                                                                                                                                         // 時間の単位(タイムスケール用)
169        private String                                  timeUnitStepSize        = null;                                                                                                                                                                                         // 時間のメモリ幅(タイムスケール用)
170        private String                                  timeSetFormat           = null;                                                                                                                                                                                         // 時間の入力フォーマット(タイムスケール用)
171        private String                                  timeLblFormat           = null;                                                                                                                                                                                         // 時間の表示フォーマット(タイムスケール用)
172        private String                                  timeMax                         = null;                                                                                                                                                                                         // 最大の時間(タイムスケール用)
173        private String                                  timeMin                         = null;                                                                                                                                                                                         // 最小の時間(タイムスケール用)
174        private String                                  widthEventColumn        = null;                                                                                                                                                                                         // 横幅の動的参照カラム   2017/03/28 ADD
175        private String                                  heightEventColumn       = null;                                                                                                                                                                                         // 縦幅の動的参照カラム   2017/03/28 ADD
176        private String                                  minEventColumn          = null;                                                                                                                                                                                         // 最小値の動的参照カラム  2017/03/28 ADD
177        private String                                  maxEventColumn          = null;                                                                                                                                                                                         // 最大値の動的参照カラム  2017/03/28 ADD
178        private boolean useRenderer                     ;                                                       // 5.9.20.1 (2017/05/12) useRenderer 追加(6.7.7.0)
179        private String                                  optionAttributes        = null;                                                                                                                                                                                         // オプション
180
181        /**
182         * タグリブオブジェクトをリリースします。
183         * キャッシュされて再利用されるので、フィールドの初期設定を行います。
184         * 
185         * @og.rev 5.9.19.0 (2017/04/07) T.OTA 61200-170316-02  チャートサイズ・max・minの動的変更対応
186         * @og.rev 5.9.20.1 (2017/05/12) useRenderer追加  
187         */
188        @Override
189        protected void release2() {
190                super.release2();
191                id = null;
192                height = "400";
193                width = "400";
194                chartType = null;
195                labelColumn = null;
196//              scope = "session";
197                tableId = HybsSystem.TBL_MDL_KEY;
198                jsChartData = null;
199                table = null;
200                optionAttributes = null;
201                onClick = null;
202                title = null;
203                titlePosition = null;
204                xlabel = null;
205                ylabel = null;
206                legendPosition = null;
207                legendDisplay = null;
208                barWidthPer = null;
209                xscaleCallback = null;
210                yscaleCallback = null;
211                xscaleType = null;
212                yscaleType = null;
213                ycategoryList = null;
214                max = null;
215                min = null;
216                stepSize = null;
217                timeUnit = null;
218                timeUnitStepSize = null;
219                timeSetFormat = null;
220                timeLblFormat = null;
221                timeMax = null;
222                timeMin = null;
223                xmax = null;
224                xmin = null;
225                xstepSize = null;
226                widthEventColumn = null;                // 5.9.19.0     
227                heightEventColumn = null;               // 5.9.19.0     
228                maxEventColumn = null;                  // 5.9.19.0     
229                minEventColumn = null;                  // 5.9.19.0     
230                useRenderer                     = false;        // 5.9.20.1 (2017/05/12) useRenderer 追加(6.7.9.0)
231        }
232
233        /**
234         * Taglibの開始タグが見つかった時に処理する doStartTag() を オーバーライドします。
235         * 
236         * @og.rev 5.9.20.1 (2017/05/12) タグの使用を決める共通属性の追加(6.7.5.0)
237         * 
238         * @return 後続処理の指示
239         */
240        @Override
241        public int doStartTag() {
242                if( !useTag() ) { return SKIP_BODY ; }          // 5.9.20.1 (2017/05/12)
243                
244                // チェック処理の実行
245                checkData();
246
247//              // スコープの設定
248//              super.setScope( scope );
249
250                // テーブル情報の取得
251                table = (DBTableModel) getObject( tableId );
252
253                return EVAL_BODY_BUFFERED; // Bodyを評価する
254        }
255
256        /**
257         * チェック処理
258         */
259        private void checkData() {
260                // xscaleTypeに「linear」、yscaleTypeに「category」を指定した場合は、エラー
261                if( "linear".equals( xscaleType ) && "category".equals( yscaleType ) ) {
262                        StringBuilder errMsg = new StringBuilder( HybsSystem.BUFFER_MIDDLE );
263                        errMsg.append( "指定のスケールタイプの組み合わせは実行できません。" );
264                        errMsg.append( HybsSystem.CR );
265                        errMsg.append( "xscaleType:" ).append( xscaleType ).append( " yscaleType:" ).append( yscaleType );
266                        throw new HybsSystemException( errMsg.toString() );
267                }
268        }
269
270        /**
271         * Taglibの終了タグが見つかったときに処理する doEndTag() を オーバーライドします。
272         * 
273         * @return 後続処理の指示
274         */
275        @Override
276        public int doEndTag() {
277                debugPrint();
278
279                id = (id==null ? CANVAS_NAME + tableId : id );  // id指定なしの場合はCANVAS_NAME+tableId
280                
281                // jsChart出力
282                jspPrint( jsChartOutput() );
283
284                return EVAL_PAGE;
285        }
286
287        /**
288         * jsChart出力用
289         * jsChartTag と jsChartData を使用して、jsChart情報を出力します。
290         * 
291         * @og.rev 5.9.19.0 (2017/04/07) T.OTA 61200-170316-02  チャートサイズ・max・minの動的変更対応
292         * @og.rev 5.9.20.1 (2017/05/12) useRenderer対応
293         * 
294         * @return jsChert用文字列
295         */
296        private String jsChartOutput() {
297                StringBuilder rtn = new StringBuilder( HybsSystem.BUFFER_MIDDLE );
298                
299                // 各JavaScriptの変数名
300                String qd = "qd_" + id; //queryData
301                String cd = "cd_" + id; //chartData
302                String myChart = "chart_"+id;
303                String lblClm = labelColumn + id;
304                
305
306                // JSON形式でテーブル情報を取得
307                ViewForm form = ViewFormFactory.newInstance( "JSON" );
308                form.init( table );
309                
310                // 5.9.20.1 (2017/05/12) form にパラメータMapを与えるようにする
311                final ConcurrentMap<String,String> cMap = new ConcurrentHashMap<String,String>();
312                if( useRenderer ) {
313                        cMap.put( ViewJsonParam.JSON_RENDERER_KEY , "true" );
314                }
315                if( !cMap.isEmpty() ) {
316                        form.setParam( cMap );
317                }
318
319                // canvasタグの設定
320                rtn.append( "<canvas class=\"").append( CANVAS_NAME).append( "\" id=\"" ).append( id ).append( "\" width=\"" ).append( width ).append( "\" height=\"" ).append( height ).append( "\"><!-- --></canvas>" );
321
322                rtn.append( "<script>" );
323                // query情報の取得(JSON)
324                rtn.append( "var ").append( qd ).append(" = " ).append( form.create() );
325
326                // jsChartDataタグの変数宣言
327                for( int i = 0; i < jsChartData.size(); i++ ) {
328                        rtn.append( " var " ).append( jsChartData.get( i ).getChartColumn() ).append( " = [];" );
329                }
330                rtn.append( "var " ).append( lblClm ).append( " = [];" );
331
332                // query情報をjsChartDataの変数に入れ替え 
333                rtn.append( "for(var i=0; i < ").append( qd ).append( ".DATA.length; i++){" );
334                for( int i = 0; i < jsChartData.size(); i++ ) {
335                        String chartColumn = jsChartData.get( i ).getChartColumn();
336
337                        // x軸がlinearスケールの場合
338                        if( "linear".equals( xscaleType ) ) {
339                                // {x:ラベル, y:値}の形式で値を設定
340                                rtn.append( chartColumn ).append( "[i] = {x:").append(qd).append(".DATA[i]." ).append( labelColumn ).append( ",y:").append(qd).append(".DATA[i]." ).append( chartColumn ).append( "};" );
341                        }
342                        else {
343                                // その他は値を設定
344                                rtn.append( chartColumn ).append( "[i] = ").append(qd).append( ".DATA[i]." ).append( chartColumn ).append( ";" );
345                        }
346                }
347                rtn.append( lblClm ).append( "[i] = ").append( qd ).append( ".DATA[i]." ).append( labelColumn ).append( ";" );
348                rtn.append( "}" );
349
350                // y軸にカテゴリースケールを設定した場合
351                if( "category".equals( yscaleType ) ) {
352                        rtn.append( "var ycateList = [];" );
353                        if( ycategoryList != null && ycategoryList.length() > 0 ) {
354                                // 「,」を「','」に変換して設定。(,前後の半角スペースは除去する)
355                                String regex = " *, *";
356                                Pattern p = Pattern.compile( regex );
357
358                                Matcher m = p.matcher( ycategoryList );
359                                // y軸カテゴリーリストの設定
360                                rtn.append( "ycateList = ['" ).append( m.replaceAll( "','" ) ).append( "'];" );
361                        }
362                }
363
364                // jsChartDataの設定
365                rtn.append( "var ").append( cd ).append(" = {" );
366                rtn.append( "labels:" ).append( lblClm );
367                // y軸にカテゴリースケールを設定した場合
368                if( "category".equals( yscaleType ) ) {
369                        rtn.append( ",yLabels:ycateList" );
370                }
371                rtn.append( ",datasets:[" );
372                for( int i = 0; i < jsChartData.size(); i++ ) {
373                        if( i != 0 ) {
374                                rtn.append( "," );
375                        }
376                        rtn.append( jsChartData.get( i ).getParameter() );
377                }
378                rtn.append( "]};" );
379
380                // jsChartの生成
381                rtn.append( "var ").append( myChart ).append(" = new Chart(" ).append( id ).append( ",{" );
382                rtn.append( "type:'" ).append( chartType ).append( "'" );
383                rtn.append( ",data:").append(cd);
384                rtn.append( ",options:{" );
385                rtn.append( "responsive:false" ); // レスポンシブ OFF
386//              rtn.append( ",animation:false" ); // アニメーション OFF
387
388                // クリックイベントの設定
389                if( onClick != null && onClick.length() > 0 ) {
390                        rtn.append( ",onClick:function(event,obj){" ).append( onClick ).append( "}" );
391                }
392
393                // タイトル属性の設定
394                if( title != null && title.length() > 0 ) {
395                        rtn.append( ",title:{" );
396                        rtn.append( "display:true" );
397                        setProp( rtn, ",text:'", title, "'" );
398                        setProp( rtn, ",position:'", titlePosition, "'" );
399                        rtn.append( "}" );
400                }
401
402                // メモリ属性の設定
403                rtn.append( ",legend:{" );
404                setProp( rtn, "display:", legendDisplay, "," );
405                setProp( rtn, "position:'", legendPosition, "'" );
406                rtn.append( "}" );
407
408                // chartTypeの円形チェック
409                List<String> list = Arrays.asList( CTYPE_CI );
410                if( list.contains( chartType ) ) {
411                        // 円形の場合はscale属性に値を設定
412                        rtn.append( ",scale: {ticks:{beginAtZero:true" );
413                        setProp( rtn, ",max:", max );
414                        setProp( rtn, ",min:", min );
415                        setProp( rtn, ",stepSize:", stepSize );
416                        rtn.append( "}}" );
417                }
418                else {
419                        // 円形以外の場合はscales属性に設定
420                        rtn.append( ",scales:{" );
421                        if( CTYPE_HBAR.equals( chartType ) ) {
422                                // 横棒線の場合はx軸の設定
423                                rtn.append( "xAxes" );
424                        }
425                        else {
426                                // それ以外はy軸の設定
427                                rtn.append( "yAxes" );
428                        }
429                        rtn.append( ":[{" );
430                        setProp( rtn, "type:'", yscaleType, "'," );
431                        // y軸にカテゴリースケールを設定した場合
432                        if( "category".equals( yscaleType )) {
433                                rtn.append( "position:'left'," );
434                        }
435                        if(ylabel != null && ylabel.length() > 0 ){
436                                rtn.append( "scaleLabel: {" );
437                                rtn.append( "display: true," );
438                                rtn.append( "labelString: '").append( ylabel ).append("'");
439                                rtn.append( "}," );
440                        }
441                        rtn.append( "ticks:{beginAtZero:true" );
442                        setProp( rtn, ",max:", max );
443                        setProp( rtn, ",min:", min );
444                        setProp( rtn, ",stepSize:", stepSize );
445                        setProp( rtn, ",callback:", yscaleCallback );
446                        rtn.append( "}}]," );
447
448                        if( CTYPE_HBAR.equals( chartType ) ) {
449                                // 横棒線の場合はy軸の設定
450                                rtn.append( "yAxes" );
451                        }
452                        else {
453                                // それ以外はx軸の設定
454                                rtn.append( "xAxes" );
455                        }
456                        rtn.append( ":[{" );
457                        setProp( rtn, "type:'", xscaleType, "'," );
458                        setProp( rtn, "categoryPercentage:", barWidthPer, "," );
459                        // x軸にリニアスケールを設定した場合
460                        if( "linear".equals( xscaleType ) ) {
461                                rtn.append( "position:'bottom'," );
462                        }
463                        // チャートタイプが横棒線の場合
464                        if(  CTYPE_HBAR.equals( chartType )){
465                                rtn.append( "position:'left'," );
466                        }
467                        
468                        if(xlabel != null && xlabel.length() > 0 ){
469                                rtn.append( "scaleLabel: {" );
470                                rtn.append( "display: true," );
471                                rtn.append( "labelString: '").append( xlabel ).append("'");
472                                rtn.append( "}," );
473                        }
474                        rtn.append( "time:{" );
475                        setProp( rtn, "format:'", timeSetFormat, "'," );
476                        // timeLblFormatが指定されている場合、全てのdisplayFormatsにtimeLblFormatを設定する
477                        if( timeLblFormat != null && timeLblFormat.length() > 0 ) {
478                                rtn.append( "displayFormats:{year:'" ).append( timeLblFormat ).append( "',quarter:'" ).append( timeLblFormat ).append( "',month:'" ).append( timeLblFormat ).append( "',week:'" ).append( timeLblFormat ).append( "',day:'" ).append( timeLblFormat ).append( "',hour:'" ).append( "',minute:'" ).append( timeLblFormat ).append( "',second:'" ).append( timeLblFormat ).append( "',millisecond:'" ).append( "'}," );
479                        }
480                        setProp( rtn, "max:'", timeMax, "'," );
481                        setProp( rtn, "min:'", timeMin, "'," );
482                        setProp( rtn, "unit:'", timeUnit, "'," );
483                        setProp( rtn, "unitStepSize:", timeUnitStepSize );
484                        rtn.append( "}," );
485
486                        rtn.append( "ticks:{" );
487                        setProp( rtn, "callback:", xscaleCallback, "," );
488                        // x軸にリニアスケールを設定した場合
489                        if( "linear".equals( xscaleType ) ) {
490                                rtn.append( "beginAtZero:true," );
491                                setProp( rtn, "max:", xmax, "," );
492                                setProp( rtn, "min:", xmin, "," );
493                                setProp( rtn, "stepSize:", xstepSize );
494                        }
495                        rtn.append( "}}]" );
496
497                        rtn.append( "}" );
498                }
499                setProp( rtn, ",", optionAttributes );
500
501                rtn.append( "}});" );
502                
503                // イベント設定用 5.9.19.0
504                // widthEventColumn設定
505                if( widthEventColumn != null && widthEventColumn.length() > 0){
506                        rtn.append( "$(document).delegate('#").append( widthEventColumn ).append( "','mouseup',function(){")
507                                .append( "var width = $(this).val();")
508                                .append( "$('#" ).append( id ).append( "').attr('width',width);")
509                                .append( myChart ).append( ".chart.width=width;")
510                                .append( myChart ).append( ".update();")
511                                .append( "} );")
512                                .append( "$(function( ){")
513                                .append( "var chartWidth = $('#" ).append( id ).append("').attr('width');")
514                                .append( "$('#").append( widthEventColumn ).append( "').val(chartWidth);")              // 初期値を設定
515                                .append( "});");
516                }
517                // heightEventColumn設定
518                if( heightEventColumn != null && heightEventColumn.length() > 0){
519                        rtn.append( "$(document).delegate('#").append( heightEventColumn ).append( "','mouseup',function(){")
520                                .append( "var height = $(this).val();")
521                                .append( "$('#" ).append( id ).append( "').attr('height',height);")
522                                .append( myChart ).append( ".chart.height=height;")
523                                .append( myChart ).append( ".update();")
524                                .append( "} );")
525                                .append( "$(function( ){")
526                                .append( "var chartHeight = $('#" ).append( id ).append("').attr('height');")
527                                .append( "$('#").append( heightEventColumn ).append( "').val(chartHeight);")    // 初期値を設定
528                                .append( "});");
529                }
530                // minEventColumn設定
531                if( minEventColumn != null && minEventColumn.length() > 0){
532                        rtn.append( "$(document).delegate('#").append( minEventColumn ).append( "','mouseup',function(){")
533                                .append( "var min = parseInt($(this).val());")
534                                .append( myChart ).append( ".options.scales.yAxes[0].ticks.min = min;")
535                                .append( myChart ).append( ".update();")
536                                .append( "} );")
537                                .append( "$(function( ){")
538                                .append( "var chartMin = ").append( myChart ).append( ".scales['y-axis-0'].min;")
539                                .append( "$('#").append( minEventColumn ).append( "').val(chartMin);")                  // 初期値を設定
540                                .append( "});");
541                }
542                // maxEventColumn設定
543                if( maxEventColumn != null && maxEventColumn.length() > 0){
544                        rtn.append( "$(document).delegate('#").append( maxEventColumn ).append( "','mouseup',function(){")
545                                .append( "var max = parseInt($(this).val());")
546                                .append( myChart ).append( ".options.scales.yAxes[0].ticks.max = max;")
547                                .append( myChart ).append( ".update();")
548                                .append( "} );")
549                                .append( "$(function(){")               
550                                .append( "var chartMax = ").append( myChart ).append( ".scales['y-axis-0'].max;")
551                                .append( "$('#").append( maxEventColumn ).append( "').val(chartMax);")                  // 初期値を設定
552                                .append("});");
553                }
554                
555                rtn.append( "</script>" );
556
557                return rtn.toString();
558        }
559
560        /**
561         * setに値が存在する場合,
562         * sbにstr + setの形で値を追加する。
563         * 
564         * @param sb
565         * @param str
566         * @param set
567         */
568        private void setProp( StringBuilder sb, String str, String set ) {
569                if( set != null && set.length() > 0 ) {
570                        sb.append( str ).append( set );
571                }
572        }
573
574        /**
575         * setに値が存在する場合,
576         * sbにstr + set + endの形で値を追加する。
577         * 
578         * @param sb
579         * @param str
580         * @param set
581         * @param end
582         */
583        private void setProp( StringBuilder sb, String str, String set, String end ) {
584                if( set != null && set.length() > 0 ) {
585                        sb.append( str ).append( set ).append( end );
586                }
587        }
588
589        /**
590         * id を設定します。
591         * canvasタグのidに設定します。
592         * 
593         * @param id
594         */
595        public void setId( String id ) {
596                String temp = getRequestParameter( id );
597                if( temp != null && temp.length() > 0 ) {
598                        this.id = temp;
599                }
600        }
601
602        /**
603         * 高さ を設定します。
604         * canvasタグの高さに設定します。
605         * 
606         * @param hei
607         */
608        public void setHeight( final String hei ) {
609                String temp = getRequestParameter( hei );
610                if( temp != null && temp.length() > 0 ) {
611                        height = temp;
612                }
613        }
614
615        /**
616         * 横幅 を設定します。
617         * canvasタグの横幅を設定します。
618         * 
619         * @param wid
620         */
621        public void setWidth( final String wid ) {
622                String temp = getRequestParameter( wid );
623                if( wid != null && wid.length() > 0 ) {
624                        width = temp;
625                }
626        }
627
628        /**
629         * チャートタイプ を設定します。
630         * 
631         * @param cType
632         */
633        public void setChartType( final String cType ) {
634                chartType = getRequestParameter( cType );
635
636                if( chartType != null && !check( chartType, CTYPE_LIST ) ) {
637                        StringBuilder errMsg = new StringBuilder( HybsSystem.BUFFER_MIDDLE );
638                        errMsg.append( "指定のチャートタイプは実行できません。" );
639                        errMsg.append( HybsSystem.CR );
640                        errMsg.append( "chartType=[" ).append( chartType ).append( "]" );
641                        errMsg.append( HybsSystem.CR );
642                        for( int i = 0; i < CTYPE_LIST.length; i++ ) {
643                                errMsg.append( " | " );
644                                errMsg.append( CTYPE_LIST[i] );
645                        }
646                        throw new HybsSystemException( errMsg.toString() );
647                }
648        }
649
650        /**
651         * ラベルカラムを指定します。
652         * 
653         * @param labelColumn ラベルカラム
654         */
655        public void setLabelColumn( String labelColumn ) {
656                this.labelColumn = getRequestParameter( labelColumn );
657        }
658
659//      /**
660//       * テーブルスコープを指定します。
661//       * 
662//       * @param scope テーブルスコープ
663//       */
664//      public void setScope( String scope ) {
665//              this.scope = getRequestParameter( scope );
666//      }
667
668        /**
669         * テーブルIDを指定します。
670         * 
671         * @param tableId テーブルID
672         */
673        public void setTableId( String tableId ) {
674                this.tableId = getRequestParameter( tableId );
675        }
676
677        /**
678         * チャートクリック時のイベントを指定します。
679         * 下記の値が引数として渡されます。
680         * 
681         * event:イベント情報 
682         * obj:クリックされたオブジェクトの情報
683         * 
684         * @param onClick
685         */
686        public void setOnClick( String onClick ) {
687                this.onClick = getRequestParameter( onClick );
688        }
689
690        /**
691         * メモリの最大値を指定します。
692         * 
693         * @param max メモリの最大値
694         */
695        public void setMax( String max ) {
696                this.max = getRequestParameter( max );
697        }
698
699        /**
700         * メモリの最小値を指定します。
701         * 
702         * @param min メモリの最小値
703         */
704        public void setMin( String min ) {
705                this.min = getRequestParameter( min );
706        }
707
708        /**
709         * メモリ幅を設定します。
710         * 
711         * @param stepSize
712         */
713        public void setStepSize( String stepSize ) {
714                this.stepSize = getRequestParameter( stepSize );
715        }
716
717        /**
718         * 時間の単位を設定します。
719         * 
720         * @param timeUnit
721         */
722        public void setTimeUnit( String timeUnit ) {
723                this.timeUnit = getRequestParameter( timeUnit );
724
725                checkPara( this.timeUnit, TYPE_TIMEUNIT, "timeUnit" );
726        }
727
728        /**
729         * 時間のメモリ幅を設定します。
730         * 
731         * @param timeUnitStepSize
732         */
733        public void setTimeUnitStepSize( String timeUnitStepSize ) {
734                this.timeUnitStepSize = getRequestParameter( timeUnitStepSize );
735        }
736
737        /**
738         * 時間の入力フォーマットを設定します。
739         * 
740         * @param timeSetFormat
741         */
742        public void setTimeSetFormat( String timeSetFormat ) {
743                this.timeSetFormat = getRequestParameter( timeSetFormat );
744        }
745
746        /**
747         * 時間の表示フォーマットを設定します。
748         * 
749         * @param timeLblFormat
750         */
751        public void setTimeLblFormat( String timeLblFormat ) {
752                this.timeLblFormat = getRequestParameter( timeLblFormat );
753        }
754
755        /**
756         * 時間の最大値を設定します。
757         * 
758         * @param timeMax
759         */
760        public void setTimeMax( String timeMax ) {
761                this.timeMax = getRequestParameter( timeMax );
762        }
763
764        /**
765         * 時間の最小値を設定します。
766         * 
767         * @param timeMin
768         */
769        public void setTimeMin( String timeMin ) {
770                this.timeMin = getRequestParameter( timeMin );
771        }
772
773        /**
774         * タイトルを設定します。
775         * 
776         * @param title
777         */
778        public void setTitle( String title ) {
779                this.title = getRequestParameter( title );
780        }
781
782        /**
783         * タイトル位置を設定します。
784         * 
785         * @param titlePosition
786         */
787        public void setTitlePosition( String titlePosition ) {
788                this.titlePosition = getRequestParameter( titlePosition );
789
790                checkPara( this.titlePosition, TYPE_POSITION, "titlePosition" );
791        }
792
793        /**
794         * 凡例位置を設定します。
795         * 
796         * @param legendPosition
797         */
798        public void setLegendPosition( String legendPosition ) {
799                this.legendPosition = getRequestParameter( legendPosition );
800
801                checkPara( this.legendPosition, TYPE_POSITION, "legendPosition" );
802        }
803
804        /**
805         * 凡例の表示制御を設定します。
806         * 
807         * @param legendDisplay
808         */
809        public void setLegendDisplay( String legendDisplay ) {
810                this.legendDisplay = getRequestParameter( legendDisplay );
811
812                checkPara( this.legendDisplay, TYPE_BOOLEAN, "legendDisplay" );
813        }
814
815        /**
816         * x軸のメモリ編集用スケールバックを設定します。
817         * 
818         * @param xscaleCallback
819         */
820        public void setXscaleCallback( String xscaleCallback ) {
821                this.xscaleCallback = getRequestParameter( xscaleCallback );
822        }
823
824        /**
825         * y軸のメモリ編集用スケールバックを設定します。
826         * 
827         * @param yscaleCallback
828         */
829        public void setYscaleCallback( String yscaleCallback ) {
830                this.yscaleCallback = getRequestParameter( yscaleCallback );
831        }
832
833        /**
834         * x軸のスケールタイプを設定します。
835         * 
836         * @param xscaleType
837         */
838        public void setXscaleType( String xscaleType ) {
839                this.xscaleType = getRequestParameter( xscaleType );
840
841                checkPara( this.xscaleType, TYPE_XSCALE, "xscaleType" );
842        }
843
844        /**
845         * y軸のスケールタイプを設定します。
846         * 
847         * @param yscaleType
848         */
849        public void setYscaleType( String yscaleType ) {
850                this.yscaleType = getRequestParameter( yscaleType );
851
852                checkPara( this.yscaleType, TYPE_YSCALE, "yscaleType" );
853        }
854
855        /**
856         * y軸のカテゴリー一覧を設定します。
857         * 
858         * @param ycategoryList
859         */
860        public void setYcategoryList( String ycategoryList ) {
861                this.ycategoryList = getRequestParameter( ycategoryList );
862        }
863
864        /**
865         * x軸の最大値を設定します。
866         * 
867         * @param xmax
868         */
869        public void setXmax( String xmax ) {
870                this.xmax = getRequestParameter( xmax );
871        }
872
873        /**
874         * x軸の最小値を設定します。
875         * 
876         * @param xmin
877         */
878        public void setXmin( String xmin ) {
879                this.xmin = getRequestParameter( xmin );
880        }
881
882        /**
883         * x軸のメモリ幅を設定します。
884         * 
885         * @param xstepSize
886         */
887        public void setXstepSize( String xstepSize ) {
888                this.xstepSize = getRequestParameter( xstepSize );
889        }
890
891        /**
892         * 棒線の横幅を設定します。
893         * 
894         * @param barWidthPer
895         */
896        public void setBarWidthPer( String barWidthPer ) {
897                this.barWidthPer = getRequestParameter( barWidthPer );
898        }
899
900        /**
901         * y軸のラベルを設定します。
902         * 
903         * @param ylabel
904         */
905        public void setYlabel( String ylabel ) {
906                this.ylabel = getRequestParameter( ylabel );
907        }
908
909        /**
910         * x軸のラベルを設定します。
911         * 
912         * @param xlabel
913         */
914        public void setXlabel( String xlabel ) {
915                this.xlabel = getRequestParameter( xlabel );
916        }
917        /**
918         * 横幅の動的設定カラムを設定します。
919         * 
920         * @og.rev 5.9.19.0 (2017/04/07) 追加
921         * @param widthEventColumn
922         */
923        public void setWidthEventColumn( String widthEventColumn ) {
924                this.widthEventColumn = getRequestParameter( widthEventColumn );
925        }
926        
927        /**
928         * 縦幅の動的設定カラムを設定します。
929         * 
930         * @og.rev 5.9.19.0 (2017/04/07) 追加
931         * @param heightEventColumn
932         */
933        public void setHeightEventColumn( String heightEventColumn ) {
934                this.heightEventColumn = getRequestParameter( heightEventColumn );
935        }
936        
937        /**
938         * minの動的設定カラムを設定します。
939         * 
940         * @og.rev 5.9.19.0 (2017/04/07) 追加
941         * @param minEventColumn
942         */
943        public void setMinEventColumn( String minEventColumn ) {
944                this.minEventColumn = getRequestParameter( minEventColumn );
945        }
946        
947        /**
948         * maxの動的設定カラムを設定します。
949         * 
950         * @og.rev 5.9.19.0 (2017/04/07) 追加
951         * @param maxEventColumn
952         */
953        public void setMaxEventColumn( String maxEventColumn ) {
954                this.maxEventColumn = getRequestParameter( maxEventColumn );
955        }
956        
957        /**
958         * 【TAG】JSON出力で、値出力にレンデラを利用するかどうかを指定します。
959         *
960         * @og.tag
961         * JSONのデータのレンデラー変換を行うかどうか。
962         * 指定しない場合は使用しない(false)です。
963         * 
964         * @og.rev 5.9.20.1 (2017/05/12) useRenderer 追加(6.7.9.0)
965         *
966         * @param       usernd レンデラーを利用するかどうか
967         */
968        public void setUseRenderer( final String usernd ) {
969                this.useRenderer = nval( getRequestParameter( usernd ) , this.useRenderer );
970        }
971
972        /**
973         * 【TAG】オプション情報を指定します。
974         *
975         * @og.tag
976         *  
977         * @param attri オプションの値
978         */
979        public void setOptionAttributes( final String attri ) {
980                optionAttributes = nval( getRequestParameter( attri ),optionAttributes );
981        }
982
983        /**
984         * jsChartData情報をリストに追加します。
985         * リストが存在しない場合は、新しく作成します。
986         * 
987         * @param jsData
988         */
989//      public void addJsChartData( final JsChartData jsData ) {
990        protected void addJsChartData( final JsChartData jsData ) {
991                if( jsChartData == null ) {
992                        jsChartData = new ArrayList<JsChartData>();
993                }
994                jsChartData.add( jsData );
995        }
996
997        /**
998         * パラメータチェック用メソッド
999         * 
1000         * @param trg
1001         * @param list
1002         * @param trgStr
1003         */
1004        private void checkPara( String trg, String[] list, String trgStr ) {
1005                if( trg != null && trg.length() > 0 && !check( trg, list ) ) {
1006                        StringBuilder errMsg = new StringBuilder( HybsSystem.BUFFER_MIDDLE );
1007                        errMsg.append( "指定の" ).append( trgStr ).append( "は指定できません。" );
1008                        errMsg.append( HybsSystem.CR );
1009                        errMsg.append( trgStr ).append( "=[" ).append( trg ).append( "]" );
1010                        errMsg.append( HybsSystem.CR );
1011                        for( int i = 0; i < list.length; i++ ) {
1012                                errMsg.append( " | " );
1013                                errMsg.append( list[i] );
1014                        }
1015                        throw new HybsSystemException( errMsg.toString() );
1016                }
1017        }
1018
1019        /**
1020         * このオブジェクトの文字列表現を返します。
1021         * 基本的にデバッグ目的に使用します。
1022         * 
1023         * @return このクラスの文字列表現
1024         */
1025        public String toString() {
1026                // JSON形式でテーブル情報を取得
1027                ViewForm form = ViewFormFactory.newInstance( "JSON" );
1028                form.init( table );
1029
1030                // jsChartDataのパラメータ情報
1031                StringBuilder sb = new StringBuilder( HybsSystem.BUFFER_MIDDLE );
1032                for( int i = 0; i < jsChartData.size(); i++ ) {
1033                        sb.append( " jsChartData" ).append( i ).append( ":" ).append( jsChartData.get( i ).getParameter() );
1034                }
1035
1036                // 2017/03/28 widthEventColumn,heightEventColumn,minEventColumn,maxEventColumnを追加
1037                return org.opengion.fukurou.util.ToString.title( this.getClass().getName() )
1038                        .println( "VERSION", VERSION )
1039                        .println( "id", id )
1040                        .println( "tableId", tableId )
1041//                      .println( "scope", scope )
1042                        .println( "chartType", chartType )
1043                        .println( "width", width )
1044                        .println( "height", height )
1045                        .println( "max", max )
1046                        .println( "min", min )
1047                        .println( "stepSize", stepSize )
1048                        .println( "barWidthPer", barWidthPer )
1049                        .println( "timeUnit", timeUnit )
1050                        .println( "timeUnitStepSize", timeUnitStepSize )
1051                        .println( "timeLblFormat", timeLblFormat )
1052                        .println( "timeSetFormat", timeSetFormat )
1053                        .println( "timeMax", timeMax )
1054                        .println( "timeMin", timeMin )
1055                        .println( "title", title )
1056                        .println( "titlePosition", titlePosition )
1057                        .println( "xlabel", xlabel )
1058                        .println( "ylabel", ylabel )
1059                        .println( "legendPosition", legendPosition )
1060                        .println( "legendDisplay", legendDisplay )
1061                        .println( "yscaleCallback", yscaleCallback )
1062                        .println( "xscaleCallback", xscaleCallback )
1063                        .println( "xscaleType", xscaleType )
1064                        .println( "xmax", xmax )
1065                        .println( "xmin", xmin )
1066                        .println( "xstepSize", xstepSize )
1067                        .println( "yscaleType", yscaleType )
1068                        .println( "ycategoryList", ycategoryList )
1069                        .println( "widthEventColumn", widthEventColumn )
1070                        .println( "heightEventColumn", heightEventColumn )
1071                        .println( "minEventColumn", minEventColumn )
1072                        .println( "maxEventColumn", maxEventColumn )
1073                        .println( "optionAttributes", optionAttributes )
1074                        .println( "JSON", form.create() )
1075                        .println( "jsChartDataPara", sb.toString() ).fixForm().toString();
1076        }
1077}