001/*
002 * Copyright (c) 2009 The openGion Project.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
013 * either express or implied. See the License for the specific language
014 * governing permissions and limitations under the License.
015 */
016package org.opengion.hayabusa.taglib;
017
018import java.util.Set;                                                                                                                   // 6.4.3.4 (2016/03/11)
019import java.util.regex.Matcher;                                                                                                 // 7.0.1.1 (2018/10/22)
020import java.util.regex.Pattern;                                                                                                 // 7.0.1.1 (2018/10/22)
021import java.util.Locale;                                                                                                                // 8.0.0.0 (2021/08/31)
022
023import org.opengion.hayabusa.common.HybsSystemException;
024import org.opengion.hayabusa.io.JsChartData;
025import org.opengion.fukurou.util.ArraySet;                                                                              // 6.4.3.4 (2016/03/11)
026import org.opengion.fukurou.util.ToString;
027import org.opengion.fukurou.util.ColorMap;                                                                              // 6.7.7.0 (2017/03/31)
028import org.opengion.fukurou.util.StringUtil;
029
030import static org.opengion.fukurou.util.StringUtil.nval ;
031
032/**
033 * 設定された値をJsChartDataに設定し、
034 * JsChartTagのJsChartDataリストに追加するタグです。
035 *
036 * @og.formSample
037 * ●形式:<og:jsChartData chartColumn="…" … />
038 * ●body:なし
039 *
040 * ●Tag定義:
041 * <og:jsChartData
042 *      chartColumn     ○【TAG】チャートのカラム名を指定します(必須)。
043 *      useAxis           【TAG】y軸表示を行うかどうか[true/false]を指定します[初期値:null(=false)]
044 *      id                【TAG】y軸のid(自動採番 'y'+連番)
045 *  ===================    data:datasets[idx]: の 要素。y[idx]Ds 変数の最上位にセットします
046 *      label             【TAG】凡例の値を指定します(label)
047 *      type              【TAG】複合チャートの種類を指定します[line/bar](type)
048 *      fill              【TAG】線下を塗りつぶすかどうか[true/false]を指定します(fill[初期値:false])
049 *      tension           【TAG】線の伸張を指定します。0で直線になります(tension[初期値:0.0])
050 * (V3) hidden            【TAG】データを表示OFFの状態にするかどうか[true/false]を指定します(hidden[初期値:false]) 8.0.0.0 (2021/08/31) 追加
051 *      backgroundColor   【TAG】データの背景色を指定します(色,色番号,VIVID,PASTEL,V0~,P0~)(backgroundColor[初期値:自動])
052 *      borderColor       【TAG】線の色を指定します(色,色番号,VIVID,PASTEL,V0~,P0~)(borderColor[初期値:自動])
053 *      borderWidth       【TAG】線の幅を指定します(borderWidth[初期値:null(=3)])
054 *      borderDash        【TAG】点線のスタイルを配列で指定します(borderDash[初期値:null(=[])])
055 *      pointStyle        【TAG】点のスタイル(circle,triangle,rect,…)を指定します(pointStyle[初期値:null(=[])])
056 *      pointRadius       【TAG】点の大きさを指定します(pointRadius[初期値:null(=3)])
057 *      showLine          【TAG】ラインを表示するかどうか[true/false]を指定します(showLine[初期値:null(=true)])
058 *      spanGaps          【TAG】データがないポイント間の処理方法[true/false]を指定します(spanGaps[初期値:null])
059 *      pointBGColor      【TAG】ポイントの色を指定します(色,色番号,VIVID,PASTEL,V0~,P0~)(pointBackgroundColor[初期値:自動])
060 *  ===================    options:scales:y: の 要素を指定する場合に、設定します
061 *      position          【TAG】y軸の表示位置[left,right]を指定します(position[初期値:null(=left)])
062 *      scaleType         【TAG】y軸のスケールタイプ[linear/category/time/…]を指定します(type[初期値:linear])
063 *      categoryList      【TAG】y軸のメモリリストをCSV形式で指定します(scaleTypeがcategoryの場合)(labels)
064 *      ylabel            【TAG】y軸に表示するラベル文字(title:text)
065 *      beginAtZero       【TAG】y軸を0から書き始まるかどうか[true/false]を指定(beginAtZero[初期値:null(=false)])
066 * (V3) grace             【TAG】y軸の最大、最小値から指定分スケールを大きくとる(grace[初期値:null])        8.0.0.0 (2021/08/31) 新規追加
067 *      max               【TAG】y軸の最大値を指定します(scaleTypeがlinearの場合に有効)(max)
068 *      min               【TAG】y軸の最小値を指定します(scaleTypeがlinearの場合に有効)(min)
069 *  ===================    options:scales:y:ticks: の 要素を指定する場合に、設定します
070 *      fontColor         【TAG】y軸のフォントの色(色,色番号,VIVID,PASTEL,V0~,P0~)(ticks:color[初期値:自動])
071 *      scaleCallback     【TAG】y軸コールバックを指定します(ticks:callback)
072 *      stepSize          【TAG】y軸のメモリ幅を指定します(scaleTypeがlinearの場合に有効)(ticks:stepSize)
073 *  ===================    options:scales:y:grid: の 要素を指定する場合に、設定します
074 *      gridColor         【TAG】grid:color属性( grid:{color:'red',} を生成)します(gridLinesと同時使用時は動作不定)
075 *  ===================
076 *      optDataset        【TAG】その他data:datasetのオプションを追加します
077 *      optAxis           【TAG】その他options:scales:yのオプションを追加します
078 *      optTicks          【TAG】その他options:scales:y:ticksのオプションを追加します
079 * (V3) optTitle          【TAG】その他options:scales:y:titleのオプションを追加します 8.0.0.0 (2021/08/31) 追加
080 * (V3) optGrid           【TAG】その他options:scales:y:gridのオプションを追加します 8.0.0.0 (2021/08/31) 追加
081 *  ===================
082 *      ticks             【廃止】optTicks を使用してください                                                8.0.0.0 (2021/08/31) 廃止
083 *      gridLines         【廃止】optGrid を使用してください(旧 gridLines)                    8.0.0.0 (2021/08/31) 廃止
084 *      optScaleLabel     【廃止】optTitle を使用してください(旧 scaleLabel)          8.0.0.0 (2021/08/31) 廃止
085 *      optGridLines      【廃止】optGrid を使用してください(旧 gridLines)                    8.0.0.0 (2021/08/31) 廃止
086 *  ===================
087 *      caseKey           【TAG】このタグ自体を利用するかどうかの条件キーを指定します(初期値:null)
088 *      caseVal           【TAG】このタグ自体を利用するかどうかの条件値を指定します(初期値:null)
089 *      caseNN            【TAG】指定の値が、null/ゼロ文字列 でない場合(Not Null=NN)は、このタグは使用されます(初期値:判定しない)
090 *      caseNull          【TAG】指定の値が、null/ゼロ文字列 の場合は、このタグは使用されます(初期値:判定しない)
091 *      caseIf            【TAG】指定の値が、true/TRUE文字列の場合は、このタグは使用されます(初期値:判定しない)
092 *      debug             【TAG】デバッグ情報を出力するかどうか[true/false]を指定します(初期値:false) 7.0.1.1 (2018/10/22)
093 *  />
094 *
095 * ●使用例
096 * <og:jsChart...>
097 *     <og:jsChartData
098 *         chartColumn ="CLM1"
099 *         label       ="ラベル"
100 *         fill        ="true"
101 *         tension     ="0"
102 *         borderColor ="rbga(150,150,150,0.7)"
103 *         borderWidth ="2"
104 *     />
105 * </og:jsChart>
106 *
107 * @og.rev 8.0.0.0 (2021/08/31) 大幅見直し
108 * @og.group 画面表示
109 *
110 * @version     8.0
111 * @author      Kazuhiko Hasegawa
112 * @since       JDK11.0
113 */
114public class JsChartDataTag extends CommonTagSupport {
115        /** このプログラムのVERSION文字列を設定します。{@VALUE} */
116        private static final String VERSION = "8.0.0.0 (2021/08/31)" ;
117        private static final long serialVersionUID = 800020210831L ;
118
119        private static final boolean    USE_QUOTE               = false;
120        private static final boolean    NO_QUOTE                = true;         // IS_NUMBER か、!USE_QUOTE か、
121
122        private static final Set<String> SET_TYPE               = new ArraySet<>( "line","bar" );
123        private static final Set<String> SET_PSTYLE             = new ArraySet<>( "circle","triangle","rect","rectRot","cross","crossRot","star","line","dash","rectRounded" );
124        private static final Set<String> SET_POSITION   = new ArraySet<>( "left","right" );
125        private static final Set<String> SET_SCALE              = new ArraySet<>( "linear","logarithmic","category","time","timeseries","realtime" );   // 8.0.0.0 (2021/08/31)
126        private static final Set<String> SET_BOOLEAN    = new ArraySet<>( "true","false" );
127
128        private transient JsChartData jsData = new JsChartData();
129
130        private String  yAxisID;                                                                // 7.0.1.1 (2018/10/22) y軸のid(自動採番 'y'+連番)
131
132        // 8.0.0.0 (2021/08/31) chartJS V3 の初期値と同じになったので、直接登録します。
133        private String  borderColor                     ;                                       // borderColor は、colorNo と競合するので、最後に判定します。
134        private String  backgroundColor         ;                                       // backgroundColor が未設定の場合は、borderColor を使用します。
135
136//      private static final String D_TENSION   = "0.4";                // 7.0.1.1 (2018/10/22) 初期値
137        private static final String D_TENSION   = "0.0";                // 8.0.0.0 (2021/08/31) 初期値変更(0.4 → 0.0)
138
139        /**
140         * デフォルトコンストラクター
141         *
142         * @og.rev 6.9.7.0 (2018/05/14) PMD Each class should declare at least one constructor
143         */
144        public JsChartDataTag() { super(); }                                    // これも、自動的に呼ばれるが、空のメソッドを作成すると警告されるので、明示的にしておきます。
145
146        /**
147         * Taglibの終了タグが見つかった時に処理する doEndTag() を オーバーライドします。
148         *
149         * @og.rev 6.7.6.0 (2017/03/17) タグの使用を決める共通属性の追加
150         * @og.rev 6.7.7.0 (2017/03/31) backgroundColor が未設定の場合は、borderColor を使用します。
151         * @og.rev 6.8.5.0 (2018/01/09) pointStyle , pointRadius , showLine 属性の追加。
152         * @og.rev 7.0.1.1 (2018/10/22) rightAxis 属性の追加。
153         *
154         * @return      後続処理の指示
155         */
156        @Override
157        public int doEndTag() {
158                debugPrint();
159                if( !useTag() ) { return EVAL_PAGE ; }                                                                  // 6.7.6.0 (2017/03/17)
160
161                final JsChartTag jsChartTag = (JsChartTag) findAncestorWithClass( this, JsChartTag.class );
162
163                if( jsChartTag == null ) {
164                        final String errMsg = "jsChart タグが見つかりませんでした。";
165                        throw new HybsSystemException( errMsg );
166                }
167
168                final int size = jsChartTag.getJsChartDataSize();                                               // 登録順で、現時点で持っている個数
169                if( yAxisID == null ) { yAxisID = "y" + size ; }                                                // 指定しない場合は、y軸のid(自動採番 'y'+連番)
170
171                if( size == 0 ) { jsData.setUseAxis( true ); }                                                  // 要方法検討。false でもY軸が表示されるが不完全
172                jsData.setId( yAxisID );
173
174                // borderColor と、backgroundColor の設定
175                setBorderOrBackColor( jsChartTag.isOneColor() ? size : -1 );                    // 7.0.1.3 (2018/11/12) 変数の集約
176
177                // 8.0.0.0 (2021/08/31) chartJS V3 の初期値と同じになったので、直接登録します。
178//              // fill は、未設定時に、false をあえて設定する必要がある。
179//              jsData.addDataset( "fill" , String.valueOf( fill ) , NO_QUOTE );                // 数値(boolean)
180
181                jsChartTag.addJsChartData( jsData );
182
183                return EVAL_PAGE;
184        }
185
186        /**
187         * タグリブオブジェクトをリリースします。
188         * キャッシュされて再利用されるので、フィールドの初期設定を行います。
189         *
190         * @og.rev 6.7.7.0 (2017/03/31) jsDataのローカル変数化。
191         * @og.rev 6.8.5.0 (2018/01/09) pointStyle , pointRadius , showLine 属性の追加。
192         * @og.rev 7.0.1.1 (2018/10/22) rightAxis 属性の追加。
193         * @og.rev 7.0.1.1 (2018/10/22) 初期値は、デフォルト(出力しない)に変更。
194         * @og.rev 8.0.0.0 (2021/08/31) chartJS V3 の初期値と同じになったので、直接登録します。
195         */
196        @Override
197        protected void release2() {
198                super.release2();
199                jsData                          = new JsChartData();
200
201                yAxisID                         = null;                                                 // 7.0.1.1 (2018/10/22) y軸のid(自動採番 'y'+連番)
202
203//              fill                            = false;                                                // 7.0.1.1 (2018/10/22) lineチャートの下部塗りつぶし(初期値:falseが、chartJS の初期値と異なるので、後付する)
204                borderColor                     = null;                                                 // borderColor は、colorNo と競合するので、最後に判定します。
205                backgroundColor         = null;                                                 // backgroundColor が未設定の場合は、borderColor を使用します。
206        }
207
208        /**
209         * borderColorとbackgroundColor の設定
210         *
211         * borderColorとbackgroundColor は、どちらか一方が設定されている場合は、
212         * もう片方も、そちらにあわせます。
213         * どちらも設定されていない場合は、チャートの番号から、色コードを自動で割り当てます。
214         * また、キーワード PASTELとVIVID が指定された場合は、グラフごとに、色を変える配列を設定します。
215         *
216         * ※ 引数の先頭が $ の場合は、先に、JsChartTag#varColumns などで、配列のオブジェクトを
217         *    作成している場合に、そのまま使用するように指示します。なお $ は外して設定します。
218         *
219         * @og.rev 7.0.1.3 (2018/11/12) 色情報を返すメソッドを集約します。
220         *
221         * @param       cnt     現在のチャートの番号(マイナスの場合は、JavaScript配列形式で返します。)
222         */
223        private void setBorderOrBackColor( final int cnt ) {
224                // 7.0.1.3 (2018/11/12) 色情報を返すメソッドを集約します。
225                if( borderColor == null ) {                                     // borderColorが未設定
226                        backgroundColor = makeColor( backgroundColor , cnt );
227                        borderColor             = backgroundColor;
228                }
229                else if( backgroundColor == null ) {            // backgroundColorが未設定
230                        borderColor             = makeColor( borderColor         , cnt );
231                        backgroundColor = borderColor;
232                }
233                else {
234                        backgroundColor = makeColor( backgroundColor , cnt );
235                        borderColor             = makeColor( borderColor         , cnt );
236                }
237
238                jsData.addDataset( "borderColor"                , borderColor           , NO_QUOTE );   // 文字はすでにクオート付き、配列の場合はクオート不用
239                jsData.addDataset( "backgroundColor"    , backgroundColor       , NO_QUOTE );   // 文字はすでにクオート付き、配列の場合はクオート不用
240        }
241
242        /**
243         * パラメータチェック用メソッド
244         *
245         * @param       trg             ターゲット
246         * @param       set             使用可能なキーワードのSet
247         * @param       trgStr  ターゲットの名称
248         */
249        private void checkPara( final String trg, final Set<String> set, final String trgStr ) {
250                if( StringUtil.isNotNull( trg ) && !check( trg, set ) ) {                               // 6.8.5.0 (2018/01/09)
251                        final StringBuilder errMsg = new StringBuilder( BUFFER_MIDDLE )
252                                .append( "指定の" ).append( trgStr ).append( "は指定できません。" ).append( CR )
253                                .append( trgStr ).append( "=[" ).append( trg ).append( ']' ).append( CR )
254                                .append( set );         // org.opengion.fukurou.util.ArraySet の toStringメソッド
255
256                        throw new HybsSystemException( errMsg.toString() );
257                }
258        }
259
260        /**
261         * 色情報を返します。
262         *
263         * 通常の、#XXXXXX形式の16bitRGB表記や、rgb(r,g,b)や、rgba(r,g,b,a) などが設定可能です。
264         * 色の代わりに、ColorMapの色番号や色記号を指定できます。
265         *
266         * 特殊キーワードとして、VIVIDとPASTEL やビビッド、0~11 (V0~V11) , パステル、12~23 (P0~P11)
267         * を指定できます。
268         * CSV形式の場合、cnt で指定された番号の色を使用します。-1 の場合は、JavaScriptの配列文字列で返します。
269         *
270         * キーがnull の場合は、色番号から初期設定の値を返します。
271         *
272         * ※ 引数にrgbを含む場合は、無条件の元の値を返します。
273         *    これは、ColorMap.getColorKey で、CSV分解してしまうからです。
274         *
275         * ※ 引数の先頭が $ の場合は、先に、JsChartTag#varColumns などで、配列のオブジェクトを
276         *    作成している場合に、そのまま使用するように指示します。なお $ は外して設定します。
277         *
278         * @og.rev 7.0.1.3 (2018/11/12) 色情報を返すメソッドを集約します。
279         * @og.rev 8.0.0.0 (2021/08/31) 引数にrgbを含む場合は、無条件の元の値を返します。
280         *
281         * @param       colKey  色を表すキーワード(色,色番号,VIVID,PASTEL,V0~,P0~)
282         * @param       cnt             CSV形式か、VIVID,PASTEL の場合、指定の番号の色を使用します。
283         * @return      色文字列
284         */
285        private String makeColor( final String colKey, final int cnt ) {
286                // cnt < 0 の場合、CSV形式なら、JavaScript配列で色を返します。
287                final StringBuilder buf = new StringBuilder( BUFFER_MIDDLE );
288
289                // 8.0.0.0 (2021/08/31) 引数にrgbを含む場合は、無条件の元の値を返します
290                if( colKey != null && colKey.toUpperCase(Locale.JAPAN).contains( "RGB" ) ) {
291                        buf.append( '\'' ).append( colKey ).append( '\'' );
292                }
293                // 先頭が $ で始まる場合は、キーワードそのものを戻す。
294                else if( colKey != null && colKey.startsWith( "$" ) ) {
295                        buf.append( colKey.substring(1) );
296                }
297                else if( cnt < 0 ) {
298                        final String[] cols = ColorMap.getColorKeys( colKey );          // nullの場合は、ビビッドとパステルの全24色
299                        // 配列が1の場合、配列にせず、値をそのまま設定します。
300                        if( cols.length == 1 ) {
301                                buf.append( '\'' ).append( cols[0] ).append( '\'' );
302                        }
303                        else {
304                                buf.append( "['" ).append( String.join( "','", cols ) ).append( "']" );
305                        }
306                }
307                else {
308                        // 色順指定されているので、1色だけ返します。
309                        final String[] cols = StringUtil.csv2Array( colKey );
310                        // 元のcolKeyがnullかゼロ文字列
311                        if( cols.length == 0 ) {
312                                buf.append( '\'' ).append( ColorMap.getColorKey( cnt ) ).append( '\'' );        // cnt に応じた自動設定
313                        }
314                        // オーバーする場合は、繰返しになります。
315                        else {
316                                final String col = cols[cnt % cols.length];
317                                buf.append( '\'' ).append( ColorMap.getColorKey( col , col ) ).append( '\'' );
318                        }
319                }
320
321                return buf.toString();
322        }
323
324        /**
325         * 【TAG】チャートのカラム名を指定します(必須)。
326         *
327         * @og.tag
328         * チャートのカラム名を指定します(必須)。
329         *
330         * @param       clm     チャートのカラム名
331         */
332        public void setChartColumn( final String clm ) {
333                jsData.setChartColumn( nval( getRequestParameter( clm ),null ) );
334        }
335
336        /**
337         * 【TAG】このデータのy軸を表示するかどうか[true/false]を指定します(初期値:false)。
338         *
339         * @og.tag
340         * true にセットした場合、jsChartTag で、yAxis に対して、一連の設定を行います。
341         * 初期値(false)ですが、1つのデータセットは必ず表示されるようです。
342         *
343         * @og.rev 7.0.1.1 (2018/10/22) useAxis 属性の追加。
344         *
345         * @param       use     右側のy軸表示するかどうか [true:表示する/false:表示しない]
346         */
347        public void setUseAxis( final String use ) {
348                jsData.setUseAxis( nval( getRequestParameter( use ), false ) );
349        }
350
351        /**
352         * 【TAG】データチャートのIDを指定します。
353         *
354         * @og.tag
355         * 指定しない場合は、y軸のid(自動採番 'y'+連番) になります。
356         * options:scales:y の 要素の属性です。
357         *
358         * @og.rev 7.0.1.1 (2018/10/22) 属性の追加。
359         *
360         * @param       id      固有の名前
361         */
362        @Override
363        public void setId( final String id ) {
364                yAxisID = nval( getRequestParameter( id ),null );
365        }
366
367        //===================    data:datasets[idx]: の 要素。y[idx]Ds 変数の最上位にセットします
368
369        /**
370         * 【TAG】凡例の値を指定します。
371         *
372         * @og.tag
373         * data:datasets[idx]: の 要素
374         *
375         * @param       lbl     凡例
376         */
377        public void setLabel( final String lbl ) {
378                jsData.addDataset( "label" , nval( getRequestParameter( lbl ),null ) , USE_QUOTE );             // 文字
379        }
380
381        /**
382         * 【TAG】複合チャートの種類を指定します[line/bar]。
383         *
384         * @og.tag
385         * data:datasets[idx]: の 要素
386         *
387         * 通常は、JsChartTagタグのchartTypeで指定しますが、複合グラフの場合は、個々のJsChartDataTag でタイプを指定します。
388         * なお、複合グラフ時には、JsChartTagタグのchartTypeを、"bar" にしておかないと、きちんと表示しないようです。
389         *
390         * @param       type    種類 [line/bar]
391         */
392        public void setType( final String type ) {
393                final String ctype = nval( getRequestParameter( type ),null );
394
395                checkPara( ctype, SET_TYPE, "type" );
396                jsData.addDataset( "type" , ctype , USE_QUOTE );                // 文字
397        }
398
399        /**
400         * 【TAG】線下を塗りつぶすかどうか[true/false]を指定します(fill[初期値:false])。
401         *
402         * @og.tag
403         * data:datasets[idx]: の 要素
404         * フィル(線より下の塗りつぶし) を設定します。
405         *
406         * @og.rev 8.0.0.0 (2021/08/31) chartJS V3 の初期値と同じになったので、直接登録します。
407         *
408         * @param       flag    塗りつぶすかどうか [true/false]
409         */
410        public void setFill( final String flag ) {
411                // 8.0.0.0 (2021/08/31) lineチャートの下部塗りつぶし(初期値:falseが、chartJS V3 の初期値と同じになったので、後付する必要がなくなった。)
412                final String fill = nval( getRequestParameter( flag ),null );
413                checkPara( fill, SET_BOOLEAN, "fill" );
414                jsData.addDataset( "fill" , fill , NO_QUOTE );          // 数値(boolean)
415        }
416
417        /**
418         * 【TAG】線の伸張を指定します。0で直線になります(初期値:0.4 → 0.0)。
419         *
420         * @og.tag
421         * data:datasets[idx]: の 要素
422         * 伸張 を設定します。
423         *
424         * 8.0.0.0 (2021/08/31)
425         *  以前のバージョンでは初期値は、0.4 でしたが、Ver3 では、0.0 になりました。
426         *  互換性は考慮しませんので、必要な場合は、各自で設定してください。
427         *
428         * @og.rev 7.0.1.1 (2018/10/22) 初期値は、デフォルト(出力しない)に変更。
429         * @og.rev 8.0.0.0 (2021/08/31) 初期値変更(0.4 → 0.0)
430         *
431         * @param       tension 線の伸張
432         */
433        public void setTension( final String tension ) {
434                jsData.addDataset( "tension" , nval( getRequestParameter( tension ),D_TENSION ) , NO_QUOTE );   // 数値
435        }
436
437        /**
438         * 【TAG】データを表示OFFの状態にするかどうか[true/false]を指定します(hidden[初期値:false])。
439         *
440         * @og.tag
441         * data:datasets[idx]: の 要素
442         * グラフ表示後に凡例をクリックすると表示がOFFします。これを初期状態に設定します。
443         * 初回表示時に、グラフを非表示にしてあるので、必要都度表示することが可能になります。
444         *
445         * @param       hide    データを表示OFFかどうか [true/false]
446         */
447        public void setHidden( final String hide ) {
448                final String hidden = nval( getRequestParameter( hide ),null );
449
450                checkPara( hidden, SET_BOOLEAN, "hidden" );
451                jsData.addDataset( "hidden" , hidden , NO_QUOTE );                                              // 数値(boolean)
452        }
453
454        /**
455         * 【TAG】データの背景色を指定します(backgroundColor[初期値:自動])。
456         *
457         * @og.tag
458         * data:datasets[idx]: の 要素
459         * 色,色番号,VIVID,PASTEL,V0~,P0~ で指定します。
460         * backgroundColor = "BLUE" とすると、すべての背景色を指定できます。
461         * 配列で指定すると、データの順番に適用されます。
462         * 例:backgroundColor = "['#ffaaaa','#ffffaa','#aaffaa','#aaaaff','#aaaaff']"
463         *
464         * 特殊キーワードとして、PASTELとVIVID を指定することで、パステルカラーやビビッドカラーの色コードを指定できます。
465         *
466         * ※ 引数の先頭が $ の場合は、先に、JsChartTag#varColumns などで、配列のオブジェクトを
467         *    作成している場合に、そのまま使用するように指示します。なお $ は外して設定します。
468         *
469         * 背景色を指定しない場合、線の色(borderColor)を使用します。
470         *
471         * @og.rev 6.9.9.2 (2018/09/18) パステルカラーの色文字列のCSV形式文字列
472         *
473         * @param       bgColor 背景色
474         * @see         #setBorderColor(String)
475         */
476        public void setBackgroundColor( final String bgColor ) {
477                backgroundColor = nval( getRequestParameter( bgColor ),null );
478        }
479
480        /**
481         * 【TAG】線の色を指定します(borderColor[初期値:自動])。
482         *
483         * @og.tag
484         * data:datasets[idx]: の 要素
485         * 色,色番号,VIVID,PASTEL,V0~,P0~ で指定します。
486         * borderColor = "BLUE" とすると、すべての線の色を指定できます。
487         * 配列で指定すると、データの順番に適用されます。
488         * 例:borderColor = "['#ffaaaa','#ffffaa','#aaffaa','#aaaaff','#aaaaff']"
489         *
490         * 色の代わりに、ColorMapの色番号を指定したい場合は、colorNo を指定します。
491         * 両方指定した場合は、borderColor が優先されます。
492         * どちらも指定しない場合は、JsChartTagに登録した順番に色コードで指定されます。
493         *
494         * ※ 引数の先頭が $ の場合は、先に、JsChartTag#varColumns などで、配列のオブジェクトを
495         *    作成している場合に、そのまま使用するように指示します。なお $ は外して設定します。
496         *
497         * 特殊キーワードとして、PASTELとVIVID を指定することで、パステルカラーやビビッドカラーの
498         * 色コード配列を指定できます。
499         *
500         * @param       color   線の色
501         */
502        public void setBorderColor( final String color ) {
503                // colorNo で、初期値設定されている可能性があるので、nval の初期値は、borderColor にしておく。
504                borderColor = nval( getRequestParameter( color ),borderColor );
505        }
506
507        /**
508         * 【TAG】線の幅を指定します(borderWidth[初期値:null(=3)])。
509         *
510         * @og.tag
511         * data:datasets[idx]: の 要素
512         *
513         * @param       width   線の幅
514         */
515        public void setBorderWidth( final String width ) {
516                jsData.addDataset( "borderWidth" , nval( getRequestParameter( width ),null ) , NO_QUOTE );      // 数値
517        }
518
519        /**
520         * 【TAG】点線のスタイルを配列で指定します(borderDash[初期値:null(=[])])。
521         *
522         * @og.tag
523         * data:datasets[idx]: の 要素
524         *
525         * ダッシュ線のスタイルは、配列で指定します。
526         * borderDash="[5,2]" とすれば、線の長さが5px , 線と線の間が2px になります。
527         *
528         * @og.rev 7.0.1.3 (2018/11/12) 点線のスタイル追加
529         *
530         * @param       dash    点線のスタイル
531         */
532        public void setBorderDash( final String dash ) {
533                jsData.addDataset( "borderDash" , nval( getRequestParameter( dash ),null ) , NO_QUOTE );        // 配列
534        }
535
536        /**
537         * 【TAG】点のスタイル[circle,triangle,rect,…]を指定します(pointStyle[初期値:null(=[])])。
538         *
539         * @og.tag
540         * data:datasets[idx]: の 要素
541         * jsChartTag で、usePointStyle = "true" をセットした場合に有効になります。
542         * 点のスタイルは、circle,triangle,rect,rectRot,cross,crossRot,star,line,dash,rectRounded
543         *
544         * @og.rev 6.8.5.0 (2018/01/09) 新規登録
545         *
546         * @param       ptStyle 点のスタイル [circle,triangle,rect,rectRot,cross,crossRot,star,line,dash,rectRounded]
547         */
548        public void setPointStyle( final String ptStyle ) {
549                final String pointStyle = nval( getRequestParameter( ptStyle ),null );
550
551                checkPara( pointStyle, SET_PSTYLE, "pointStyle" );
552                jsData.addDataset( "pointStyle" , pointStyle , USE_QUOTE );             // 文字
553        }
554
555        /**
556         * 【TAG】点の大きさを指定します(pointRadius[初期値:null(=3)])。
557         *
558         * @og.tag
559         * data:datasets[idx]: の 要素
560         * jsChartTag で、usePointStyle = "true" をセットした場合に有効になります。
561         *
562         * @og.rev 6.8.5.0 (2018/01/09) 新規登録
563         *
564         * @param       ptRadius        点の大きさを指定します。
565         */
566        public void setPointRadius( final String ptRadius ) {
567                jsData.addDataset( "pointRadius" , nval( getRequestParameter( ptRadius ),null ) , NO_QUOTE );   // 数値
568        }
569
570        /**
571         * 【TAG】ラインを表示するかどうか[true/false]を指定します(showLine[初期値:null(=true)])。
572         *
573         * @og.tag
574         * data:datasets[idx]: の 要素
575         * jsChartTag で、usePointStyle = "true" をセットした場合に有効になります。
576         * 初期値(null)は、showLine 属性を設定しませんが、chartJS 自体の初期値が true
577         * なので、表示されます。
578         *
579         * @og.rev 6.8.5.0 (2018/01/09) 新規登録
580         *
581         * @param       show    ラインを表示するかどうか [true:表示する/false:表示しない]
582         */
583        public void setShowLine( final String show ) {
584                jsData.addDataset( "showLine" , nval( getRequestParameter( show ),null ) , NO_QUOTE );  // Boolean
585        }
586
587        /**
588         * 【TAG】データがないポイント間の処理方法を指定します[true/false]を指定します(spanGaps[初期値:null])。
589         *
590         * @og.tag
591         * data:datasets[idx]: の 要素
592         * trueの場合、データがないかnullのポイント間に線が引かれます。
593         * falseの場合、データがnullのポイントは、行に切れ目を作成します。
594         *
595         * @og.rev 7.0.1.2 (2018/11/04) 新規登録
596         *
597         * @param       flag    データがないポイント間の処理を行うかどうか [true/false]
598         */
599        public void setSpanGaps( final String flag ) {
600                jsData.addDataset( "spanGaps" , nval( getRequestParameter( flag ),null ) , NO_QUOTE );  // Boolean
601        }
602
603        /**
604         * 【TAG】ポイントの色を指定します(pointBackgroundColor[初期値:自動])。
605         *
606         * @og.tag
607         * data:datasets[idx]: の 要素
608         * 色,色番号,VIVID,PASTEL,V0~,P0~ で指定します。
609         * 点の塗りつぶしの色を指定します。属性名が長いので、短縮しています。
610         * 単独文字列の場合は、すべての点を同じ色で塗ります。配列([]で囲う)の場合は、
611         * 点の並び順に応じて、色付けを行います。
612         *
613         * 配列([]で囲う)か、const定義変数を想定していますので、前後にクオートを付けません。
614         * 単独文字列を指定する場合は、"'red'" のように、クオートを付けてください。
615         * 通常は、backgroundColorが使用されますので、単独文字で色指定は行う必要はありません。
616         *
617         * ポイントの色指定に、ColorMapの色コードは使えません。
618         *
619         * @og.rev 6.8.5.0 (2018/01/09) 新規登録
620         *
621         * @param       cols    点の塗りつぶしの色(単独、配列)
622         */
623        public void setPointBGColor( final String cols ) {
624                // 配列[]か、変数なので、クオート無しにします。
625                jsData.addDataset( "pointBackgroundColor" , nval( getRequestParameter( cols ),null ) , NO_QUOTE );
626        }
627
628        //===================    options:scales:y: の 要素を指定する場合に、設定します
629
630        /**
631         * 【TAG】y軸の表示位置[left,right]を指定します(position[初期値:null(=left)])。
632         *
633         * @og.tag
634         * options:scales:y: の 要素
635         * 複合グラフ表示で、指定のデータのy軸を、右に表示したい場合は、right を指定します。
636         * 初期値(null)は、左に表示されます。
637         *
638         * @og.rev 7.0.1.1 (2018/10/22) 属性の追加。
639         *
640         * @param       pos     y軸の表示位置 [left,right]
641         */
642        public void setPosition( final String pos ) {
643                final String position = nval( getRequestParameter( pos ),null );
644
645                checkPara( position, SET_POSITION, "position" );
646                jsData.addAxis( "position" , position , USE_QUOTE );                                    // 文字
647        }
648
649        /**
650         * 【TAG】y軸のスケールタイプ[linear/category/time/…]を指定します(type[初期値:linear])。
651         *
652         * @og.tag
653         * options:scales:y: の 要素
654         * 未指定(null)の場合は、linear になります。
655         * スケールタイプ[linear/logarithmic/category/time/timeseries/realtime]を指定します。
656         *
657         * realtime は、chartjs-plugin-streaming を使用時の縦スクロール時のみ適用可能です。
658         *
659         * @og.rev 7.0.1.1 (2018/10/22) 属性の追加。
660         *
661         * @param       type    y軸のスケールタイプ [linear/logarithmic/category/time/timeseries/realtime]
662         */
663        public void setScaleType( final String type ) {
664                final String sType = nval( getRequestParameter( type ),null );
665
666                // プラグインなどで独自の type を指定することがあるため、警告だけにします。
667                try {
668                        checkPara( sType, SET_SCALE, "type" );
669                }
670                catch( final HybsSystemException ex ) {
671                        System.err.println( ex.getMessage() );
672                }
673
674                jsData.addAxis( "type" , sType , USE_QUOTE );                                                   // 文字
675        }
676
677        /**
678         * 【TAG】y軸のメモリリストをCSV形式で指定します(scaleTypeがcategoryの場合に有効)。
679         *
680         * @og.tag
681         * ※ 通常のCSVで指定します。
682         * options:scales:y: の 要素の属性です。
683         *
684         * @og.rev 7.0.1.1 (2018/10/22) 属性の追加。
685         *
686         * @param       categoryList    y軸のメモリリスト
687         */
688        public void setCategoryList( final String categoryList ) {
689                final String lbls = nval( getRequestParameter( categoryList ),null );
690
691                if( lbls != null ) {
692                        // 「,」を「','」に変換して設定。(,前後の半角スペースは除去する)
693                        final String regex = " *, *";
694                        final Pattern pttn = Pattern.compile( regex );
695                        final Matcher mtch = pttn.matcher( lbls );
696
697                        // y軸カテゴリーリストの設定
698                        final String labels = "['" + mtch.replaceAll( "','" ) + "']" ;
699
700                        jsData.addAxis( "labels" , labels , NO_QUOTE );                                         // 配列なので、クオート不用
701                }
702        }
703
704        /**
705         * 【TAG】y軸に表示するラベル文字(title:text)を指定します(初期値:null)。
706         *
707         * @og.tag
708         * 横軸に表示する文字を指定します。
709         * options:scales:yAxes:scaleLabel:labelString → options:scales:y:title:text の 要素の属性です。
710         * title:{display:true,text:'ラベル文字',} がセットされます。
711         *
712         * @og.rev 7.0.1.1 (2018/10/22) 属性の追加。
713         *
714         * @param       label   y軸に表示するラベル文字
715         */
716        public void setYlabel( final String label ) {
717                final String lbl = nval( getRequestParameter( label ),null );
718                if( lbl != null ) {
719                        final String scLbl = "display: true,text:'" + lbl + "'" ;
720                        jsData.addAxis( JsChartData.TITLE , scLbl );
721                }
722        }
723
724        /**
725         * 【TAG】y軸を0から書き始まるかどうか[true/false]を指定します(beginAtZero[初期値:null(=false)])。
726         *
727         * @og.tag
728         * <del>ticks と同時には使用できません。</del>
729         * <del>初期値(null)は、0から書き始めます。</del>
730         * 初期値(null)は、false と同じで、最小データから書き始めます。
731         * options:scales:yAxes:ticks:beginAtZero → options:scales:y:beginAtZero の 要素の属性です。
732         *
733         * @og.rev 7.0.1.1 (2018/10/22) 属性の追加。
734         *
735         * @param       atZero  y軸を0から書き始まるかどうか [true/false]
736         */
737        public void setBeginAtZero( final String atZero ) {
738                final String beginAtZero = nval( getRequestParameter( atZero ),null );
739
740                checkPara( beginAtZero, SET_BOOLEAN, "beginAtZero" );
741                jsData.addAxis( "beginAtZero" , beginAtZero , NO_QUOTE );                               // 数値(boolean)
742        }
743
744        /**
745         * 【TAG】y軸の最大、最小値から指定分スケールを大きくとる(grace[初期値:null])。
746         *
747         * @og.tag
748         * 最大値または最小値から指定した数値分、スケールを大きくとる。
749         * '20%' のように最大値(最小値)に対する割合で示すことも可。
750         * ここでは、割合を文字列で指定するのみとします。
751         *
752         * options:scales:y:grace の 要素の属性です。
753         *
754         * @og.rev 8.0.0.0 (2021/08/31) 新規追加
755         *
756         * @param       size    y軸を指定分スケールを大きくとる[初期値:null]
757         */
758        public void setGrace( final String size ) {
759                final String grace = nval( getRequestParameter( size ),null );
760
761                jsData.addAxis( "grace" , grace , USE_QUOTE );                                                  // 文字
762        }
763
764        /**
765         * 【TAG】y軸の最大値を指定します(scaleTypeがlinearの場合に有効)。
766         *
767         * @og.tag
768         * options:scales:yAxes:ticks:max → options:scales:y:max の 要素の属性です。
769         *
770         * @og.rev 7.0.1.1 (2018/10/22) 属性の追加。
771         *
772         * @param       max     メモリの最大値
773         */
774        public void setMax( final String max ) {
775                jsData.addAxis( "max" , nval( getRequestParameter( max ),null ) , NO_QUOTE );   // 数値
776        }
777
778        /**
779         * 【TAG】y軸の最小値を指定します(scaleTypeがlinearの場合に有効)。
780         *
781         * @og.tag
782         * options:scales:yAxes:ticks:max → options:scales:y:max の 要素の属性です。
783         *
784         * @og.rev 7.0.1.1 (2018/10/22) 属性の追加。
785         *
786         * @param       min     メモリの最小値
787         */
788        public void setMin( final String min ) {
789                jsData.addAxis( "min" , nval( getRequestParameter( min ),null ) , NO_QUOTE );   // 数値
790        }
791
792        /**
793         * 【TAG】y軸のフォントの色を指定(ticks:color[初期値:自動])。
794         *
795         * @og.tag
796         * ticks と同時には使用できません。
797         * options:scales:yAxes:ticks:fontColor → options:scales:y:ticks:color の 要素の属性です。
798         *
799         * ColorMapの色コード(色,色番号,VIVID,PASTEL,V0~,P0~)が使えます。
800         *
801         * @og.rev 7.0.1.1 (2018/10/22) 属性の追加。
802         * @og.rev 7.0.1.3 (2018/11/12) 色情報を返すメソッドを集約します。
803         *
804         * @param       fontColor       y軸のフォントの色
805         */
806        public void setFontColor( final String fontColor ) {
807                final String col = nval( getRequestParameter( fontColor ),null );
808                if( col != null ) {
809                        jsData.addTicks( "color" , ColorMap.getColorKey( col , col ) , USE_QUOTE );             // 文字
810                }
811        }
812
813        /**
814         * 【TAG】y軸コールバックを指定します(ticks:callback)。
815         *
816         * @og.tag
817         * options:scales:y:ticks:callback: の 要素
818         * y軸のメモリ編集用スケールバックを設定します。
819         * callback="function(val,index){return val.toLocaleString() + '円';}"
820         * のように登録します。
821         * @og.rev 7.0.1.1 (2018/10/22) 属性の追加。
822         *
823         * @param       callback        y軸コールバック
824         */
825        public void setScaleCallback( final String callback ) {
826                jsData.addTicks( "callback" , nval( getRequestParameter( callback ),null ) , NO_QUOTE );        // ファンクションは、クオートしない
827        }
828
829        /**
830         * 【TAG】y軸のメモリ幅を指定します(scaleTypeがlinearの場合に有効)(ticks:stepSize)。
831         *
832         * @og.tag
833         * options:scales:y:ticks:stepSize の 要素の属性です。
834         *
835         * @og.rev 7.0.1.1 (2018/10/22) 属性の追加。
836         *
837         * @param       stepSize        y軸のメモリ幅
838         */
839        public void setStepSize( final String stepSize ) {
840                jsData.addTicks( "stepSize" , nval( getRequestParameter( stepSize ),null ) , NO_QUOTE );        // 数値
841        }
842
843        /**
844         * 【TAG】gridのcolor属性( grid:{color:'red',} を生成)を設定します(初期値:null)。
845         *
846         * @og.tag
847         * options:scales:yAxes:gridLines:color → options:scales:y:grid:color の 要素の属性です。
848         * この設定と、gridLinesパラメータ を同時に設定した場合の動作は、不定です。
849         * ※ 不定というのは、Tomcat上の属性の設定順で規定されるため、どちらの要素が使用されるのか、実装依存です。
850         *
851         * ColorMapの色コード(色,色番号,VIVID,PASTEL,V0~,P0~)が使えます。
852         *
853         * @og.rev 7.0.1.1 (2018/10/22) 属性の追加。
854         * @og.rev 7.0.1.3 (2018/11/12) 色情報を返すメソッドを集約します。
855         *
856         * @param       gridColor       y軸のフォントの色
857         */
858        public void setGridColor( final String gridColor ) {
859                final String col = nval( getRequestParameter( gridColor ),null );
860                if( col != null ) {
861                        final String color = "color:'" + ColorMap.getColorKey( col , col ) + "'" ;
862                        jsData.addAxis( JsChartData.GRID , color );
863                }
864        }
865
866        //========================================================================================
867
868        /**
869         * 【TAG】その他data:datasetのオプションを追加します。
870         *
871         * @og.tag
872         * その他data:datasetのオプションを追加します。
873         *
874         * @og.rev 7.0.1.2 (2018/11/04) 属性の追加。
875         *
876         * @param       attri   その他data:datasetのオプション
877         */
878        public void setOptDataset( final String attri ) {
879                jsData.addAxis( JsChartData.DATASET , nval( getRequestParameter( attri ),null ) );
880        }
881
882        /**
883         * 【TAG】その他options:scales:yのオプションを追加します。
884         *
885         * @og.tag
886         * options:scales:y の 要素の属性です。
887         *  <del>※ chartJS上は、Axes(axisの複数形)と、Axis を使い分けていますが、属性は、axis で統一します。</del>
888         *
889         * @og.rev 7.0.1.2 (2018/11/04) 属性の追加。
890         *
891         * @param       attri   その他options:scales:yのオプション
892         */
893        public void setOptAxis( final String attri ) {
894                jsData.addAxis( JsChartData.AXIS , nval( getRequestParameter( attri ),null ) );
895        }
896
897        /**
898         * 【TAG】その他options:scales:y:ticksのオプションを追加します。
899         *
900         * @og.tag
901         * options:scales:y:ticks の 要素の属性です。
902         *
903         * @og.rev 7.0.1.2 (2018/11/04) 属性の追加。
904         *
905         * @param       attri   その他options:scales:y:ticksのオプション
906         */
907        public void setOptTicks( final String attri ) {
908                jsData.addAxis( JsChartData.TICKS , nval( getRequestParameter( attri ),null ) );
909        }
910
911        /**
912         * 【TAG】その他options:scales:y:titleのオプションを追加します。
913         *
914         * @og.tag
915         * options:scales:yAxes:scaleLabel → options:scales:y:title の 要素の属性です。
916         *
917         * @og.rev 7.0.1.2 (2018/11/04) 属性の追加。
918         *
919         * @param       attri   その他options:scales:y:titleのオプション
920         */
921        public void setOptTitle( final String attri ) {
922                jsData.addAxis( JsChartData.TITLE , nval( getRequestParameter( attri ),null ) );
923        }
924
925        /**
926         * 【TAG】その他options:scales:y:gridのオプションを追加します。
927         *
928         * @og.tag
929         * options:scales:yAxes:gridLines → options:scales:y:grid の 要素の属性です。
930         *
931         * @og.rev 7.0.1.2 (2018/11/04) 属性の追加。
932         *
933         * @param       attri   その他options:scales:y:gridのオプション
934         */
935        public void setOptGrid( final String attri ) {
936                jsData.addAxis( JsChartData.GRID , nval( getRequestParameter( attri ),null ) );
937        }
938
939        /**
940         * このオブジェクトの文字列表現を返します。
941         * 基本的にデバッグ目的に使用します。
942         *
943         * @return このクラスの文字列表現
944         */
945        @Override
946        public String toString() {
947                return ToString.title( this.getClass().getName() )
948                        .println( "VERSIION"            , VERSION       )
949                        .println( "JsChartData"         , jsData        )
950                        .fixForm().toString();
951        }
952}