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