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