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