001package org.opengion.hayabusa.taglib;
002
003import org.opengion.hayabusa.common.HybsSystemException;
004import org.opengion.hayabusa.io.JsChartData;
005
006import java.util.Set;                                                                                   // 6.4.3.4 (2016/03/11)
007import org.opengion.fukurou.util.ArraySet;                                              // 6.4.3.4 (2016/03/11)
008import org.opengion.fukurou.util.ToString;
009import org.opengion.fukurou.util.ColorMap;                                              // 6.7.7.0 (2017/03/31)
010import static org.opengion.fukurou.util.StringUtil.nval ;
011
012/**
013 * 設定された値をJsChartDataに設定し、
014 * JsChartTagのJsChartDataリストに追加するタグです。
015 * 
016 * @og.formSample
017 * ●形式:<og:jsChartData chartColumn="…" … />
018 * ●body:なし
019 * 
020 * ●Tag定義:
021 * <og:jsChartData
022 *      chartColumn     ○【TAG】チャートのカラム名を指定します(必須)。
023 *      label             【TAG】凡例の値を指定します。
024 *      fill              【TAG】線下を塗りつぶすかどうか[true/false]を指定します(初期値:false)。
025 *      tension           【TAG】線の伸張を指定します。0で直線になります(初期値:0.4)。
026 *      borderColor       【TAG】線の色を指定します。
027 *      colorNo           【TAG】線の色(borderColor)をColorMapの色番号で指定します。
028 *      borderWidth       【TAG】線の幅を指定します。
029 *      backgroundColor   【TAG】データの背景色を指定します。
030 *      pointStyle        【TAG】点のスタイル(circle,triangle,rect,rectRot,cross,crossRot,star,line,dash)を指定します。 // 6.8.5.0 (2018/01/09)
031 *      pointRadius       【TAG】点の大きさを指定します。                                                                                                                             // 6.8.5.0 (2018/01/09)
032 *      showLine          【TAG】ラインを表示するかどうか[true/false]を指定します(初期値:null)。                                                // 6.8.5.0 (2018/01/09)
033 *      optionAttributes  【TAG】その他オプションを指定します。
034 *      caseKey           【TAG】このタグ自体を利用するかどうかの条件キーを指定します(初期値:null)
035 *      caseVal           【TAG】このタグ自体を利用するかどうかの条件値を指定します(初期値:null)
036 *      caseNN            【TAG】指定の値が、null/ゼロ文字列 でない場合(Not Null=NN)は、このタグは使用されます(初期値:判定しない)
037 *      caseNull          【TAG】指定の値が、null/ゼロ文字列 の場合は、このタグは使用されます(初期値:判定しない)
038 *      caseIf            【TAG】指定の値が、true/TRUE文字列の場合は、このタグは使用されます(初期値:判定しない)
039 *  > />
040 * 
041 * ●使用例
042 * <og:jsChart...>
043 *     <og:jsChartData
044 *         chartColumn ="CLM1"
045 *         label       ="ラベル"
046 *         fill        ="true"
047 *         tension     ="0"
048 *         borderColor ="rbga(150,150,150,0.7)"
049 *         borderWidth ="2"
050 *     />>
051 * &lt/og:jsChart>
052 * 
053 * @og.group 画面表示
054 * 
055 * @version     5.9.17.2                2017/02/08
056 * @author      T.OTA
057 * @since       JDK7.0
058 * 
059 */
060public class JsChartDataTag extends CommonTagSupport {
061        //* このプログラムのVERSION文字列を設定します。{@VALUE} */
062        private static final String VERSION = "6.9.9.2 (2018/09/18)" ;
063        private static final long serialVersionUID = 699220180918L ;
064
065        private static final Set<String> TYPE_BOOLEAN = new ArraySet<>( "true", "false" );
066
067        // 変数宣言
068        private String  chartColumn                     ;
069        private String  label                           ;
070        private String  fill                            = "false";
071        private String  tension                         = "0.4";
072        private String  borderColor                     ;
073        private String  borderWidth                     ;
074        private String  backgroundColor         ;
075        private String  pointStyle                      ;       // 6.8.5.0 (2018/01/09) 点のスタイル
076        private String  pointRadius                     ;       // 6.8.5.0 (2018/01/09) 点の大きさ
077        private String  showLine                        ;       // 6.8.5.0 (2018/01/09) ラインを表示するかどうか
078        private String  optionAttributes        ;
079
080        /**
081         * デフォルトコンストラクター
082         *
083         * @og.rev 6.9.7.0 (2018/05/14) PMD Each class should declare at least one constructor
084         */
085        public JsChartDataTag() { super(); }            // これも、自動的に呼ばれるが、空のメソッドを作成すると警告されるので、明示的にしておきます。
086
087        /**
088         * Taglibの終了タグが見つかった時に処理する doEndTag() を オーバーライドします。
089         * 
090         * @og.rev 6.7.6.0 (2017/03/17) タグの使用を決める共通属性の追加
091         * @og.rev 6.7.7.0 (2017/03/31) backgroundColor が未設定の場合は、borderColor を使用します。
092         * @og.rev 6.8.5.0 (2018/01/09) pointStyle , pointRadius , showLine 属性の追加。
093         * 
094         * @return 後続処理の指示
095         */
096        @Override
097        public int doEndTag() {
098                debugPrint();
099                if( !useTag() ) { return EVAL_PAGE ; }                  // 6.7.6.0 (2017/03/17)
100
101                final JsChartTag jsChartTag = (JsChartTag) findAncestorWithClass( this, JsChartTag.class );
102
103                if( jsChartTag == null ) {
104                        final String errMsg = "jsChart タグが見つかりませんでした。";
105                        throw new HybsSystemException( errMsg );
106                }
107
108                // 6.7.7.0 (2017/03/31) 各種初期設定を行います。
109                if( borderColor == null || borderColor.isEmpty() ) {
110                        final int size = jsChartTag.getJsChartDataSize();       // 登録順に色番号を設定します。
111                        final String[] cols = ColorMap.getColorKeys();
112                        borderColor = cols[size % cols.length];
113                }
114                if( backgroundColor == null || backgroundColor.isEmpty() ) {
115                        backgroundColor = borderColor;
116                }
117
118                final JsChartData jsData = new JsChartData();   // 6.7.7.0 (2017/03/31) ローカル変数化
119                jsData.setChartColumn(          chartColumn                     );
120                jsData.setLabel(                        label                           );
121                jsData.setFill(                         fill                            );
122                jsData.setTension(                      tension                         );
123                jsData.setBorderColor(          borderColor                     );
124                jsData.setBorderWidth(          borderWidth                     );
125                jsData.setBackgroundColor(      backgroundColor         );
126                jsData.setPointStyle(           pointStyle                      );      // 6.8.5.0 (2018/01/09)
127                jsData.setPointRadius(          pointRadius                     );      // 6.8.5.0 (2018/01/09)
128                jsData.setShowLine(                     showLine                        );      // 6.8.5.0 (2018/01/09)
129                jsData.setOptionAttributes(     optionAttributes        );
130
131                jsChartTag.addJsChartData( jsData );
132
133                return EVAL_PAGE;
134        }
135
136        /**
137         * タグリブオブジェクトをリリースします。
138         * キャッシュされて再利用されるので、フィールドの初期設定を行います。
139         * 
140         * @og.rev 6.7.7.0 (2017/03/31) jsDataのローカル変数化。
141         * @og.rev 6.8.5.0 (2018/01/09) pointStyle , pointRadius , showLine 属性の追加。
142         */
143        @Override
144        protected void release2() {
145                super.release2();
146                chartColumn                     = null;
147                label                           = null;
148                fill                            = "false";
149                tension                         = "0.4";
150                borderColor                     = null;
151                borderWidth                     = null;
152                backgroundColor         = null;
153                pointStyle                      = null;         // 6.8.5.0 (2018/01/09) 点のスタイル
154                pointRadius                     = null;         // 6.8.5.0 (2018/01/09) 点のスタイル
155                showLine                        = null;         // 6.8.5.0 (2018/01/09) ラインを表示するかどうか
156                optionAttributes        = null;
157        }
158
159        /**
160         * 【TAG】チャートのカラム名を指定します(必須)。
161         *
162         * @og.tag
163         * 
164         * @param clm チャートのカラム名
165         */
166        public void setChartColumn( final String clm ) {
167                chartColumn = nval( getRequestParameter( clm ),chartColumn );
168        }
169
170        /**
171         * 【TAG】凡例の値を指定します。
172         *
173         * @og.tag
174         * 
175         * @param lbl 凡例
176         */
177        public void setLabel( final String lbl ) {
178                label = nval( getRequestParameter( lbl ),label );
179        }
180
181        /**
182         * 【TAG】線下を塗りつぶすかどうか[true/false]を指定します(初期値:false)。
183         *
184         * @og.tag
185         * フィル(線より下の塗りつぶし) を設定します。
186         * 
187         * @param fill 塗りつぶすかどうか [true/false]
188         */
189        public void setFill( final String fill ) {
190                this.fill = nval( getRequestParameter( fill ) , this.fill );
191
192                checkPara( this.fill, TYPE_BOOLEAN, "fill" );
193        }
194
195        /**
196         * 【TAG】線の伸張を指定します。0で直線になります(初期値:0.4)。
197         *
198         * @og.tag
199         * 伸張 を設定します。
200         *
201         * @param tension 線の伸張
202         */
203        public void setTension( final String tension ) {
204                this.tension = nval( getRequestParameter( tension ),this.tension );
205        }
206
207        /**
208         * 【TAG】線の色を指定します。
209         *
210         * @og.tag
211         * borderColor = "BLUE" とすると、すべての線の色を指定できます。
212         * 配列で指定すると、データの順番に適用されます。
213         * 例:borderColor = "['#ffaaaa','#ffffaa','#aaffaa','#aaaaff','#aaaaff']"
214         * 
215         * 色の代わりに、ColorMapの色番号を指定した場合でも、borderColor が優先されます。
216         * どちらも指定しない場合は、JsChartTagに登録した順番に色コードで指定されます。
217         * 
218         * @param color 線の色
219         * @see         #setColorNo(String)
220         */
221        public void setBorderColor( final String color ) {
222                borderColor = nval( getRequestParameter( color ),borderColor );
223        }
224
225        /**
226         * 【TAG】線の色(borderColor)をColorMapの色番号で指定します。
227         *
228         * @og.tag
229         * 色の代わりに、ColorMapの色番号を指定した場合でも、borderColor が優先されます。
230         * この引数は、色に変換後、borderColor に設定されます。
231         *
232         * @og.rev 6.7.7.0 (2017/03/31) ColorMapの色番号で指定
233         * 
234         * @param colorNo 線の色の番号
235         * @see         ColorMap#getColorKeys()
236         */
237        public void setColorNo( final String colorNo ) {
238                if( borderColor == null ) {             // borderColor が、未設定の場合のみ、色番号を利用する。
239                        final String colNo = nval( getRequestParameter( colorNo ),null );
240                        if( colNo != null ) {
241                                try {
242                                        final int no = Integer.parseInt( colNo );
243                                        final String[] cols = ColorMap.getColorKeys();
244                                        borderColor = cols[no % cols.length];
245                                }
246                                catch( final NumberFormatException ex ) {
247                                        final String errMsg = "colorNo を数値に変換できません。colorNo=" + colNo ;
248                                        throw new HybsSystemException( errMsg,ex );
249                                }
250                        }
251                }
252        }
253
254        /**
255         * 【TAG】線の幅を指定します。
256         *
257         * @og.tag
258         * 
259         * @param width 線の幅
260         */
261        public void setBorderWidth( final String width ) {
262                borderWidth = nval( getRequestParameter( width ),borderWidth );
263        }
264
265        /**
266         * 【TAG】データの背景色を指定します。
267         *
268         * @og.tag
269         * backgroundColor = "BLUE" とすると、すべての背景色を指定できます。
270         * 配列で指定すると、データの順番に適用されます。
271         * 例:backgroundColor = "['#ffaaaa','#ffffaa','#aaffaa','#aaaaff','#aaaaff']"
272         * 
273         * 特殊キーワードとして、"PASTEL" を指定することで、パステルカラーの色コードを指定できます。
274         * 
275         * 背景色を指定しない場合、線の色(borderColor)を使用します。
276         *
277         * @og.rev 6.9.9.2 (2018/09/18) パステルカラーの色文字列のカンマ区切り文字列
278         * 
279         * @param bgColor 背景色
280         * @see         #setBorderColor(String)
281         */
282        public void setBackgroundColor( final String bgColor ) {
283                backgroundColor = nval( getRequestParameter( bgColor ),backgroundColor );
284
285                if( "PASTEL".equalsIgnoreCase( backgroundColor ) ) {
286                        // ※ 処理速度はともかく、簡単で判り易いので、こちらの方法で、CSV文字列を、作成します。
287                        backgroundColor = "['" + String.join( "','", ColorMap.getPastelColorKeys() ) + "']";
288
289        //              6.9.9.2 (2018/09/18) パステルカラーの色文字列のカンマ区切り文字列
290        //              final String[] PSTL_KEYS = ColorMap.getPastelColorKeys();
291        //              final StringJoiner sj = new StringJoiner( "','", "['", "']" );
292        //              for( int i=0; i<PSTL_KEYS.length; i++ ) {
293        //                      sj.add( PSTL_KEYS[i] );
294        //              }
295        //              backgroundColor = sj.toString();                                // パステルカラーを存在する分だけ CSV文字列で返す。
296                }
297        }
298
299        /**
300         * 【TAG】点のスタイルを指定します。
301         *
302         * @og.tag
303         * jsChartTag で、usePointStyle = "true" をセットした場合に有効になります。
304         * 点のスタイルは、circle,triangle,rect,rectRot,cross,crossRot,star,line,dash が、
305         * 
306         * @og.rev 6.8.5.0 (2018/01/09) 新規追加
307         * 
308         * @param ptStyle 点のスタイルを指定します。
309         */
310        public void setPointStyle( final String ptStyle ) {
311                pointStyle = nval( getRequestParameter( ptStyle ),pointStyle );
312        }
313
314        /**
315         * 【TAG】点の大きさを指定します。
316         *
317         * @og.tag
318         * jsChartTag で、usePointStyle = "true" をセットした場合に有効になります。
319         * 
320         * @og.rev 6.8.5.0 (2018/01/09) 新規追加
321         * 
322         * @param ptRadius 点の大きさを指定します。
323         */
324        public void setPointRadius( final String ptRadius ) {
325                pointRadius = nval( getRequestParameter( ptRadius ),pointRadius );
326        }
327
328        /**
329         * 【TAG】ラインを表示するかどうか[true/false]を指定します(初期値:null)。
330         *
331         * @og.tag
332         * jsChartTag で、usePointStyle = "true" をセットした場合に有効になります。
333         * 初期値(null)は、showLine 属性を設定しませんが、chartJS 自体の初期値が true
334         * なので、表示されます。
335         * 
336         * @og.rev 6.8.5.0 (2018/01/09) 新規追加
337         * 
338         * @param show ラインを表示するかどうか [true:表示する/false:表示しない]
339         */
340        public void setShowLine( final String show ) {
341                showLine = nval( getRequestParameter( show ),showLine );
342        }
343
344        /**
345         * 【TAG】その他オプションを指定します。
346         *
347         * @og.tag
348         * 
349         * @param attri その他オプション
350         */
351        public void setOptionAttributes( final String attri ) {
352                optionAttributes = nval( getRequestParameter( attri ),optionAttributes );
353        }
354
355        /**
356         * パラメータチェック用メソッド。
357         * 
358         * @param trg チェック対象
359         * @param set 設定可能なリスト
360         * @param trgStr チェック対象の文字列(エラー表示用)
361         */
362        private void checkPara( final String trg, final Set<String> set, final String trgStr ) {
363                if( trg != null && trg.length() > 0 && !check( trg, set ) ) {
364                        final StringBuilder errMsg = new StringBuilder( BUFFER_MIDDLE )
365                                .append( "指定の" ).append( trgStr ).append( "は指定できません。" )
366                                .append( CR )
367                                .append( trgStr ).append( "=[" ).append( trg ).append( ']' )
368                                .append( CR );
369                        for( final String lst : set ) {
370                                errMsg.append( " | " )
371                                        .append( lst );
372                        }
373                        throw new HybsSystemException( errMsg.toString() );
374                }
375        }
376
377        /**
378         * このオブジェクトの文字列表現を返します。
379         * 基本的にデバッグ目的に使用します。
380         * 
381         * @return このクラスの文字列表現
382         */
383        @Override
384        public String toString() {
385                return ToString.title( this.getClass().getName() )
386                        .println( "VERSIION"                    , VERSION                       )
387                        .println( "chartColumn"                 , chartColumn           )
388                        .println( "label"                               , label                         )
389                        .println( "fill"                                , fill                          )
390                        .println( "tension"                             , tension                       )
391                        .println( "borderColor"                 , borderColor           )
392                        .println( "borderWidth"                 , borderWidth           )
393                        .println( "backgroundColor"             , backgroundColor       )
394                        .println( "optionAttributes"    , optionAttributes      )
395                        .fixForm().toString();
396        }
397}