    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.ArrayList;
    019import java.util.List;
    020import java.util.Set;                                                                                   // 6.4.3.4 (2016/03/11)
    021import java.util.Iterator;                                                                              // 6.7.7.0 (2017/03/31)
    022import java.util.function.IntFunction;                                                  // 7.0.1.3 (2018/11/12)
    023
    024// import org.opengion.fukurou.system.BuildNumber;                                      // 7.0.1.2 (2018/11/04)
    025import org.opengion.hayabusa.common.HybsSystem;
    026import org.opengion.hayabusa.common.HybsSystemException;
    027import org.opengion.hayabusa.db.DBTableModelSorter;
    028import org.opengion.hayabusa.db.DBTableModel;
    029import org.opengion.hayabusa.db.DBColumn;                                               // 6.8.3.1 (2017/12/01)
    030import org.opengion.hayabusa.io.JsChartDataV3;                                  // 7.0.1.1 (2018/10/22)
    031
    032import org.opengion.fukurou.util.ArraySet;                                              // 6.4.3.4 (2016/03/11)
    033import org.opengion.fukurou.util.ToString;
    034import org.opengion.fukurou.util.StringUtil;                                    // 6.8.3.1 (2017/12/01)
    035import org.opengion.fukurou.util.ColorMap;                                              // 7.0.1.3 (2018/11/12)
    036import static org.opengion.fukurou.util.StringUtil.nval ;
    037
    038/**
    039 * JsChartV3 は、JavascriptのjsChart用のｽｸﾘﾌﾟﾄを出力するクラスです。
    040 * 複数の JsChartDataV3 オブジェクトを合成することも、ここで行っています。
    041 * ChartJSのVer3を利用しているため、標準属性以外の項目をセットする場合はoptionAttributesで行ってください。
    042 *
    043 * 出力されるスクリプトでは、idを指定しない場合はhybscanvas[tableId]が利用されます。
    044 * 複数のグラフを同一画面で出力する場合はidかtableIdを変えてください。
    045 * チャートオブジェクトはchart_[id]という名前で作成されるため、ajax等でコントロールが必要な場合は利用してください。
    046 *
    047 * <a href="https://www.tohoho-web.com/ex/chartjs-params.html">とほほのChart.js入門</a>
    048 *
    049 * ChartのGlobal Configurationとして、Chart.defaults.**** が指定できる。これは本ﾀｸﾞでは
    050 * 用意していないが、グローバルなので、タグの前に個別に記述しておくことで適用される。
    051 *
    052 * <a href="https://www.chartjs.org/docs/latest/configuration/">Configuration</a>
    053 *
    054 * @og.formSample
    055 * ●形式：&lt;og:jsChartV3 chartType="…" ... /&gt;
    056 * ●body：あり(EVAL_BODY_BUFFERED:BODYを評価し、{$#064;XXXX} を解析します)
    057 *
    058 * ●Tag定義：
    059 *  &lt;og:jsChartV3
    060 *      chartType       ○【TAG】ﾁｬｰﾄの種類(type属性)を指定します[line/bar/radar/polarArea/pie/doughnut/bubble/scatter](必須)
    061 *                                  horizontalBar 廃止 → indexAxis="y" 指定verticalLine 相当の表示も indexAxis="y" 指定
    062 *      labelColumn     ○【TAG】ﾗﾍﾞﾙのｶﾗﾑ名(data:labels属性)を指定します(表示名称）(必須)
    063 *      id                【TAG】canvasﾀｸﾞのidを指定します(初期値:hybscanvas)
    064 *      height            【TAG】ﾁｬｰﾄ(canvasﾀｸﾞ)の高さを指定します(初期値:400px)
    065 *      width             【TAG】ﾁｬｰﾄ(canvasﾀｸﾞ)の幅を指定します(初期値:400px)
    066 *      plugins           【TAG】プラグイン定義された関数を指定します(plugins)      // 6.9.9.2 (2018/09/18)
    067 *  =================== options: 以下の属性
    068 * (V3) indexAxis         【TAG】"y" を指定することで、horizontalBar や verticalLine を実現する(options:indexAxis)       8.0.0.0 (2021/08/31) 新規追加
    069 *      barWidthPer       【TAG】棒線の横幅を指定します(初期値:0.8, typeがbar の場合に有効)(option:categoryPercentage)
    070 *      animation         【TAG】簡易的にアニメーションのON/OFFを設定(true/false)します(初期値::null=true)(options:animation)
    071 *      onClick           【TAG】ﾁｬｰﾄｸﾘｯｸ時のｲﾍﾞﾝﾄを指定します(options:onClick)
    072 *      optOptions        【TAG】optionsの要素に、その他ｵﾌﾟｼｮﾝを追加します
    073 *  =================== options:scales:x: 以下の属性
    074 *      xscaleType        【TAG】x軸のｽｹｰﾙﾀｲﾌﾟ[category/linear/time/realtime]を指定します(type[初期値:category])
    075 *      xposition         【TAG】x軸の表示位置[top/right/bottom/left]を指定します(初期値:bottom)(position)
    076 *      xmax              【TAG】x軸の最大値を指定します(xscaleTypeがlinearの場合に有効)(max)
    077 *      xmin              【TAG】x軸の最小値を指定します(xscaleTypeがlinearの場合に有効)(min)
    078 *      xlabel            【TAG】x軸のラベルを指定します(title:text)
    079 *      xscaleCallback    【TAG】x軸ｺｰﾙﾊﾞｯｸを指定します(ticks:callback)
    080 *      xbeginAtZero      【TAG】x軸を０から書き始まるかどうか(xscaleTypeがlinearの場合に有効)(beginAtZero[初期値:null(=false)])
    081 *      xstepSize         【TAG】x軸のメモリ幅を指定します(xscaleTypeがlinearの場合に有効)(ticks:stepSize)
    082 *      optAxis           【TAG】その他options:scales:x のｵﾌﾟｼｮﾝを追加します
    083 *      optTicks          【TAG】その他options:scales:x:ticksのｵﾌﾟｼｮﾝを追加します
    084 * (V3) optTitle          【TAG】その他options:scales:x:titleのｵﾌﾟｼｮﾝを追加します   8.0.0.0 (2021/08/31) 新規追加
    085 * (V3) optGrid           【TAG】その他options:scales:x:gridのｵﾌﾟｼｮﾝを追加します    8.0.0.0 (2021/08/31) 新規追加
    086 *  =================== options:scales:x:time: 以下の属性(xscaleTypeがtimeの場合に有効)
    087 *      timeUnit          【TAG】x軸のﾀｲﾑの単位[year/quarter/month/week/day/hour/minute/second/millisecond]を指定(unit)します(指定しない場合は自動)
    088 *      timeUnitStepSize  【TAG】x軸のﾀｲﾑの単位幅を指定します(stepSize)
    089 * (V3) timeParser        【TAG】x軸の設定するﾀｲﾑ(入力ﾃﾞｰﾀ)のﾌｫｰﾏｯﾄを指定します ･･･ 廃止 → time.parser になったが使い方不明  8.0.0.0 (2021/08/31) 新規追加
    090 *      timeLblFormat     【TAG】x軸の表示するﾀｲﾑのﾌｫｰﾏｯﾄを指定します(time:displayFormats:year～secondまで同じ値を設定) → displayFormats
    091 *      tooltipFormat     【TAG】時間のﾂｰﾙﾁｯﾌﾟに使用するﾌｫｰﾏｯﾄ(tooltipFormat)
    092 *  =================== options:plugins: 以下の属性
    093 *      title             【TAG】ﾀｲﾄﾙ、またはﾀｲﾄﾙ要素を指定します(title:text)
    094 *      titlePosition     【TAG】ﾀｲﾄﾙの表示位置[top/right/bottom/left]を指定します(title:position:初期値 top)
    095 *      legendDisplay     【TAG】凡例を表示するか[true/false]を指定します(legend:display)
    096 *      legendPosition    【TAG】凡例の表示位置[top/right/bottom/left]を指定します(legend:position)
    097 *      usePointStyle     【TAG】凡例のスタイル属性を使用するかどうか[true/false]を指定します(legend:labels:usePointStyle)
    098 * (V3) optPlugins        【TAG】options:pluginsの要素に、その他ｵﾌﾟｼｮﾝを追加します
    099 * (V3) optTooltip        【TAG】options:plugins:tooltip の要素に、その他ｵﾌﾟｼｮﾝを追加します
    100 * (V3) optLegend         【TAG】options:plugins:legend の要素に、その他ｵﾌﾟｼｮﾝを追加します
    101 *  =================== options:plugins:annotation:annotations:(CSVで指定した分のline0): 以下の属性
    102 *      markValues        【TAG】y軸に横マーカーラインの設定値をCSV形式で複数指定します(yMin:値,yMax:値)
    103 *      markColors        【TAG】y軸に横マーカーラインの色をCSV形式で複数指定します(borderColor)
    104 *      markLbls          【TAG】y軸に横マーカーラインのラベルをCSV形式で複数指定します(未指定時はラベルを表示しません)(label:content)
    105 *      markAdjust        【TAG】y軸に横マーカーラインのラベル表示位置の上(－)下(＋)方向を調整します(yAdjust:初期値 -6)
    106 *      xmarkLbls         【TAG】x軸に横マーカーラインのラベルをCSV形式で複数指定します(未指定時はラベルを表示しません)(label:content)
    107 *      xmarkValues       【TAG】x軸に縦マーカーラインの設定値をCSV形式で複数指定します(xMin:値,xMax:値)
    108 *      xmarkColors       【TAG】x軸に縦マーカーラインの色をCSV形式で複数指定します              // 7.0.1.1 (2018/10/22)
    109 *      markWidth         【TAG】x軸,y軸全マーカーライン共通のラインの幅を指定します(borderWidth:初期値 2)                                   // 7.0.1.1 (2018/10/22)
    110 *      markDash          【TAG】x軸,y軸全マーカーライン共通のラインに点線を指定([5,2]など)します:(borderDash:初期値 null)      // 7.0.1.1 (2018/10/22)
    111 *      markFontSize      【TAG】x軸,y軸全マーカーライン共通のラベルのフォントサイズを指定します:(label:font:size:初期値 10)
    112 *  =================== options:plugins:zoom: 以下の属性
    113 *      useZoom           【TAG】WheelZoom処理を使用するかどうか[true/false]を指定します(options:plugins:zoom:zoom:)
    114 *      useDragZoom       【TAG】DragZoom処理を使用するかどうか[true/false]を指定します(options:plugins:zoom:zoom:)
    115 *  ===================
    116 *      useZeroDataOmit   【TAG】ﾃﾞｰﾀが０の場合、使用しない（除外する）かどうかを指定します[true:０ﾃﾞｰﾀを除外する](初期値:false)
    117 *      useRenderer       【TAG】データ出力でレンデラを利用するかどうか[true/false]を指定します(初期値:false)
    118 *      sortColumn        【TAG】検索結果をこのカラムでソートしなおします(初期値:null)
    119 *      valueQuot         【TAG】値の前後にクオートをはさむかどうか[true/false]指定します
    120 *      varColumns        【TAG】TableModelの指定のカラムをconstの配列変数として出力します     // 7.0.1.2 (2018/11/04)
    121 *  ===================
    122 *      optChart          【廃止】chartの属性に、TLDで未定義の属性を追加します                8.0.0.0 (2021/08/31) 廃止(代替えはありません)
    123 *      optScaleLabel     【廃止】optTitle を使用してください(旧 scaleLabel)          8.0.0.0 (2021/08/31) 廃止
    124 *      optGridLines      【廃止】optGrid を使用してください(旧 gridLines)                    8.0.0.0 (2021/08/31) 廃止
    125 *      timeMax           【廃止】廃止 → xmaxを使用してください                8.0.0.0 (2021/08/31) 廃止
    126 *      timeMin           【廃止】廃止 → xminを使用してください                8.0.0.0 (2021/08/31) 廃止
    127 *      timeSetFormat     【廃止】廃止 → timeParserを使用してください          8.0.0.0 (2021/08/31) 廃止
    128 *  ===================
    129 *      tableId           【TAG】(通常は使いません)sessionから所得する DBTableModelオブジェクトの ID
    130 *      scope             【TAG】キャッシュする場合のスコープ[request/page/session/application]を指定します(初期値:session)
    131 *      caseKey           【TAG】このタグ自体を利用するかどうかの条件キーを指定します(初期値:null)
    132 *      caseVal           【TAG】このタグ自体を利用するかどうかの条件値を指定します(初期値:null)
    133 *      caseNN            【TAG】指定の値が、null/ゼロ文字列 でない場合(Not Null=NN)は、このタグは使用されます(初期値:判定しない)
    134 *      caseNull          【TAG】指定の値が、null/ゼロ文字列 の場合は、このタグは使用されます(初期値:判定しない)
    135 *      caseIf            【TAG】指定の値が、true/TRUE文字列の場合は、このタグは使用されます(初期値:判定しない)
    136 *      debug             【TAG】デバッグ情報を出力するかどうか[true/false]を指定します(初期値:false)
    137 *  &gt;   ... Body ...
    138 *  &lt;/og:jsChartV3&gt;
    139 *
    140 * ●使用例
    141 *      &lt;og:jsChartV3
    142 *          chartType      = "[line/bar/radar/polarArea/pie/doughnut/bubble/scatter]"
    143 *          labelColumn    = "LDATA"
    144 *          id             = "hybscanvas"
    145 *          height         = "400px"
    146 *          width          = "400px"
    147 *          title          = "タイトル" または "{display:true,text:'ﾀｲﾄﾙ',color:'blue',font:{size:15},}" 形式
    148 *          titlePosition  = "top"                              [top/right/bottom/left]
    149 *          xlabel         = "名称"
    150 *          legendPosition = "right"                    [top/right/bottom/left]
    151 *          legendDisplay  = "true"                             [true/false]
    152 *          xsclaeCallback = "function(value){return value + ' 様';}"
    153 *          xscaleType     = "linear"
    154 *          xmax           = "1000000"
    155 *          xmin           = "100000"
    156 *          xstepSize      = "10000"
    157 *          barWidthPer    = "0.4"
    158 *      &gt;
    159 *          &lt;og:jsChartDataV3 ... /&gt;
    160 *      &lt;/og:jsChartV3&gt;
    161 *
    162 * @og.rev 8.0.0.0 (2021/08/31) Ver3対応 大幅見直し
    163 * @og.group 画面表示
    164 *
    165 * @version     8.0
    166 * @author   Kazuhiko Hasegawa
    167 * @since       JDK11.0
    168 */
    169public class JsChartV3Tag extends CommonTagSupport {
    170        /** このプログラムのVERSION文字列を設定します。{@value} */
    171        private static final String VERSION = "8.0.2.1 (2021/12/10)" ;
    172        private static final long serialVersionUID = 802120211210L ;
    173
    174        private static final String IE_CHECK
    175                        = "<script>{"
    176                                + "let userAgent = window.navigator.userAgent.toLowerCase();"                   + CR
    177                                + "if(userAgent.indexOf('msie') != -1 ||"                                                               + CR
    178                                + "   userAgent.indexOf('trident') != -1 ) {"                                                   + CR
    179                                + "    document.write('Internet Explorer では表示できません<br />');"    + CR
    180                                + "}}</script>"                                                                                                                 + CR ;
    181
    182        /** chartType 引数に渡す事の出来る タイプ 折れ線 {@value} */
    183        public static final String              CTYPE_LINE                      = "line";
    184        /** chartType 引数に渡す事の出来る タイプ 棒線 {@value} */
    185        public static final String              CTYPE_BAR                       = "bar";
    186//      /** chartType 引数に渡す事の出来る タイプ 横棒線 {@value} */
    187//      public static final String              CTYPE_HBAR                      = "horizontalBar";
    188        /** chartType 引数に渡す事の出来る タイプ レイダー {@value} */
    189        public static final String              CTYPE_RADAR                     = "radar";
    190        /** chartType 引数に渡す事の出来る タイプ ポーラエリア {@value} */
    191        public static final String              CTYPE_POLAR                     = "polarArea";
    192        /** chartType 引数に渡す事の出来る タイプ 円 {@value} */
    193        public static final String              CTYPE_PIE                       = "pie";
    194        /** chartType 引数に渡す事の出来る タイプ ドーナツ {@value} */
    195        public static final String              CTYPE_DOUGHNUT          = "doughnut";
    196        /** chartType 引数に渡す事の出来る タイプ バブル {@value} 8.0.0.0 (2021/08/20) 追加 */
    197        public static final String              CTYPE_BUBBLE                    = "bubble";
    198        /** chartType 引数に渡す事の出来る タイプ 散乱図 {@value} 8.0.0.0 (2021/08/20) 追加 */
    199        public static final String              CTYPE_SCATTER           = "scatter";
    200
    201        /** chartType 引数に渡す事の出来る タイプ リスト {@value} */
    202        private static final Set<String> CTYPE_SET
    203                = new ArraySet<>( CTYPE_LINE,CTYPE_BAR,CTYPE_RADAR,CTYPE_POLAR,
    204                                                        CTYPE_PIE,CTYPE_DOUGHNUT,CTYPE_BUBBLE,CTYPE_SCATTER );
    205
    206        // 6.9.9.4 (2018/10/01) String配列から、Set に変更
    207        /** chartType が円形のリスト */
    208        private static final Set<String> SET_CI_TYPE    = new ArraySet<>( CTYPE_RADAR, CTYPE_POLAR, CTYPE_PIE, CTYPE_DOUGHNUT );
    209
    210        private static final String TYPE_CATEGORY               = "category";
    211        private static final String TYPE_LINEAR                 = "linear";
    212        private static final String TYPE_TIME                   = "time";
    213        private static final String TYPE_REALTIME               = "realtime";           // 7.0.1.2 (2018/11/04)
    214
    215        private static final Set<String> SET_POSITION   = new ArraySet<>("top","right","bottom","left");
    216        private static final Set<String> SET_TIMEUNIT   = new ArraySet<>("year","quarter","month","week","day","hour","minute","second","millisecond"); // 8.0.0.0 (2021/08/31)
    217        private static final Set<String> SET_XSCALE             = new ArraySet<>( TYPE_CATEGORY, TYPE_TIME, TYPE_LINEAR, TYPE_REALTIME );
    218        private static final Set<String> SET_BOOLEAN    = new ArraySet<>( "true", "false" );
    219
    220        private static final String     CANVAS_NAME             = "hybscanvas";
    221
    222        private static final String             MARK_DEF_ADJUST = "-6";                 // 6.8.5.0 (2018/01/09) y軸に横マーカーラインの位置調整の初期値
    223
    224        // 7.0.1.3 (2018/11/12) バッファキー検索処理追加
    225        // 8.0.0.0 (2021/08/31) Moment.js の依存関係が切れ、openGionV8では、date-fns を使用します。
    226        private static final String             TIME_FORMAT_JA  = "{year:'yyyy年',quarter:'yyyy年M月',month:'yyyy年M月',week:'M月d日',day:'M月d日',hour:'d日 h時',minute:'h時m分',second:'m分s秒'}" ;
    227        private static final String             TIME_FORMAT             = "{year:'yyyy',quarter:'yyyy/M',month:'yyyy/M',week:'M/d',day:'M/d',hour:'d HH',minute:'HH:mm',second:'HH:mm:ss'}" ;
    228
    229        // 7.0.1.3 (2018/11/12) true/false なので、記号化します。
    230        private static final boolean    USE_QUOTE               = false;
    231        private static final boolean    NO_QUOTE                = true;         // IS_NUMBER か、!USE_QUOTE か、
    232
    233        // JSON形式をそれなりに成形するためのタブと改行
    234        private static final String[]   CR_TAB = new String[10] ;
    235        static {
    236                final StringBuilder tabs = new StringBuilder().append( CR );
    237                for( int i=0; i<CR_TAB.length; i++ ) {
    238                        CR_TAB[i] = tabs.toString();
    239                        tabs.append( '\t' );
    240                }
    241        }
    242
    243        private static final String WHEEL_ZOOM = "zoom:{zoom:{mode:'xy',wheel:{enabled:true,},pinch:{enabled:true,},},pan:{mode:'xy',enabled:true,},}," ;
    244        private static final String DRAG_ZOOM  = "zoom:{zoom:{drag:{enabled:true,borderColor:'rgb(54,162,235)',borderWidth:1,backgroundColor:'rgba(54,162,235,0.3)',},},pan:{mode:'xy',enabled:true,modifierKey:'ctrl',},},";
    245
    246        // 変数宣言
    247        // 6.9.8.0 (2018/05/28) FindBugs:直列化可能クラスの非 transient で非直列化可能なインスタンスフィールド
    248        private final transient List<JsChartDataV3>     jsChartData = new ArrayList<JsChartDataV3>() ;          // 6.7.5.0 (2017/03/10) jsChartDataのﾘｽﾄ
    249
    250        private transient       JsChartDataV3 jsXAxis  = new JsChartDataV3();   // xAxes の設定用(datasetは使いません)
    251
    252        private String  chartBody                       ;                                                       // ﾁｬｰﾄタグのBODY部分に書かれた文字列
    253
    254        private String  chartType                       ;                                                       // ﾁｬｰﾄﾀｲﾌﾟ(必須)
    255        private String  labelColumn                     ;                                                       // ﾗﾍﾞﾙｶﾗﾑ(必須)
    256        private String  indexAxis                       ;                                                       // horizontalBarや、verticalLine を実現 8.0.0.0 (2021/08/31)
    257        private String  id                                      ;                                                       // canvasﾀｸﾞのid
    258        private String  height                          = "400px";                                      // canvasﾀｸﾞのheight
    259        private String  width                           = "400px";                                      // canvasﾀｸﾞのwidth
    260        private String  title                           ;                                                       // ﾀｲﾄﾙ
    261        private String  titlePosition           = "top";                                        // ﾀｲﾄﾙ位置
    262        private String  legendPosition          ;                                                       // 凡例位置
    263        private String  legendDisplay           ;                                                       // 凡例表示ﾌﾗｸﾞ
    264        private boolean usePointStyle           ;                                                       // 6.8.5.0 (2018/01/09) 点のスタイル属性を使用するかどうか(初期値:false)
    265        private boolean useLegend                       ;                                                       // Legend関連属性(legendPosition,legendDisplay,usePointStyle) のどれかがセットされれば、true
    266        private String  barWidthPer                     = "0.8";                                        // 棒線の横幅(ﾊﾟｰｾﾝﾄ)
    267        private String  animation                       ;                                                       // 簡易的なアニメーションのON/OFF
    268        private String  onClick                         ;                                                       // ｸﾘｯｸｲﾍﾞﾝﾄ
    269        private String  plugins                         ;                                                       // 6.9.9.2 (2018/09/18) プラグイン定義された関数を指定します。
    270        private String  xscaleType                      = TYPE_CATEGORY ;                       // x軸のｽｹｰﾙﾀｲﾌﾟ
    271        private String  xposition                       ;                                                       // x軸の表示位置[top/right/bottom/left]        // 7.0.1.2 (2018/11/04)
    272        private boolean valueQuot                       ;                                                       // 値の前後にクオートをはさむかどうか[true/false]指定します。
    273        private String  tableId                         = HybsSystem.TBL_MDL_KEY;       // ﾃｰﾌﾞﾙid
    274        private String  markValues                      ;                                                       // 6.8.5.0 (2018/01/09) y軸に横マーカーラインの設定値をCSV形式で複数指定します
    275        private String  markColors                      ;                                                       // 6.8.5.0 (2018/01/09) y軸に横マーカーラインの色をCSV形式で複数指定します
    276        private String  markLbls                        ;                                                       // 6.8.5.0 (2018/01/09) y軸に横マーカーラインのラベルをCSV形式で複数指定します(未指定時はラベルを表示しません)
    277        private String  markAdjust                      ;                                                       // 6.8.5.0 (2018/01/09) y軸に横マーカーラインのラベル表示位置の上下方向を調整します(初期値:-6)。
    278        private String  xmarkLbls                       ;                                                       // 8.0.0.0 (2021/09/30) x軸に横マーカーラインのラベルをCSV形式で複数指定
    279        private String  xmarkValues                     ;                                                       // 7.0.1.1 (2018/10/22) x軸に縦マーカーラインの設定値をCSV形式で複数指定します
    280        private String  xmarkColors                     ;                                                       // 7.0.1.1 (2018/10/22) x軸に縦マーカーラインの色をCSV形式で複数指定します
    281        private String  markWidth                       = "2";                                          // 7.0.1.1 (2018/10/22) マーカーライン共通のラインの幅を指定します:borderWidth(初期値:2)
    282        private String  markDash                        ;                                                       // 7.0.1.1 (2018/10/22) マーカーライン共通のラインに点線を指定([5,2]など)します:borderDash(初期値:null)
    283        private String  markFontSize            = "10";                                         // 7.0.1.1 (2018/10/22) マーカーライン共通のラベルのフォントサイズを指定します:fontSize(初期値:10)
    284        private boolean useZoom                         ;                                                       // 6.8.5.0 (2018/01/09) ズーム処理を使用するかどうか(初期値:false)
    285        private boolean useDragZoom                     ;                                                       // 6.8.5.0 (2018/01/09) ズーム処理を使用するかどうか(初期値:false)
    286        private String  varColumns              ;                                                       // 7.0.1.2 (2018/11/04) TableModelの指定のカラムをconstの配列変数として出力します。
    287//      / *      useVarCheck       【TAG】const定義するJavaScript変数に使用できるかどうか[true/false]指定します
    288//      private boolean useVarCheck                     ;                                                       // 8.0.0.0 (2021/09/30) JavaScript変数に使用できるかどうか[true/false]指定します
    289        private boolean useZeroDataOmit         ;                                                       // 6.7.7.0 (2017/03/31) ﾃﾞｰﾀが０の場合、使用しない（除外する）かどうか
    290        private boolean useRenderer                     ;                                                       // 6.7.9.0 (2017/04/28) useRenderer 追加
    291        private String  sortColumn                      ;                                                       // 6.8.0.0 (2017/06/02) 検索結果をこのカラムでソートしなおします(初期値:null)。
    292//      private String  optChart                        ;                                                       // 7.0.1.2 (2018/11/04) chartの属性に、TLDで未定義の属性を追加指定します。
    293        private String  optOptions                      ;                                                       // 7.0.1.2 (2018/11/04) optionsの属性に、その他ｵﾌﾟｼｮﾝを追加指定します。
    294        private String  optPlugins                      ;                                                       // 8.0.0.0 (2021/09/30) options:pluginsの属性に、その他ｵﾌﾟｼｮﾝを追加します
    295        private String  optTooltip                      ;                                                       // 8.0.0.0 (2021/09/30) options:plugins:tooltip の属性に、その他ｵﾌﾟｼｮﾝを追加します
    296        private String  optLegend                       ;                                                       // 8.0.0.0 (2021/09/30) options:plugins:legend の属性に、その他ｵﾌﾟｼｮﾝを追加します
    297
    298//      private List<String> options = new ArrayList<>() ;                              // 8.0.0.0 (2021/08/31) optionsの属性に、ｵﾌﾟｼｮﾝを追加設定します。
    299
    300        /**
    301         * デフォルトコンストラクター
    302         *
    303         * @og.rev 6.9.7.0 (2018/05/14) PMD Each class should declare at least one constructor
    304         */
    305        public JsChartV3Tag() { super(); }              // これも、自動的に呼ばれるが、空のメソッドを作成すると警告されるので、明示的にしておきます。
    306
    307        /**
    308         * タグリブオブジェクトをリリースします。
    309         * キャッシュされて再利用されるので、フィールドの初期設定を行います。
    310         *
    311         * @og.rev 6.7.5.0 (2017/03/10) jsChartData属性の初期化もれ
    312         * @og.rev 5.9.19.0 (2017/04/07) T.OTA 61200-170316-02  ﾁｬｰﾄｻｲｽﾞ・max・minの動的変更対応
    313         * @og.rev 6.7.7.0 (2017/03/31) useZeroDataOmit属性の追加
    314         * @og.rev 6.7.9.0 (2017/04/28) useRenderer 追加
    315         * @og.rev 6.8.0.0 (2017/06/02) sortColumn 追加
    316         * @og.rev 6.8.3.0 (2017/11/27) useEqValOmit属性の追加
    317         * @og.rev 6.8.5.0 (2018/01/09) xbeginAtZero,ybeginAtZero,markValues,markColors,markLbls,markAdjust,rangeMin,rangeMax,usePointStyle属性の追加
    318         * @og.rev 6.9.9.2 (2018/09/18) plugins,chartAttributes属性の追加
    319         * @og.rev 6.9.9.3 (2018/09/25) xscaleType の time 属性廃止。
    320         * @og.rev 6.9.9.4 (2018/10/01) ﾘﾆｱ対応,time 属性復活
    321         * @og.rev 6.9.9.4 (2018/10/01) 7.0.1.0 (2018/10/15) time 属性修正、tooltipFormat属性の追加
    322         * @og.rev 7.0.1.1 (2018/10/22) xmarkValues,xmarkColors属性の追加
    323         * @og.rev 7.0.1.1 (2018/10/22) ylabelColor,y2label,y2labelColor属性の追加
    324         * @og.rev 7.0.1.2 (2018/11/04) ylabelColor,y2label,y2labelColor属性の追加
    325         * @og.rev 8.0.0.0 (2021/08/31) horizontalBar 廃止 → indexAxis="y" 指定
    326         */
    327        @Override
    328        protected void release2() {
    329                super.release2();
    330                jsChartData.clear();                    // 6.7.5.0 (2017/03/10)
    331                jsXAxis                         = new JsChartDataV3();                          // xAxes の設定用(datasetは使いません)
    332
    333                chartBody                       = null;         // 7.0.1.1 (2018/10/22) ﾁｬｰﾄタグのBODY部分に書かれた文字列
    334                chartType                       = null;
    335                id                                      = null;
    336                height                          = "400px";
    337                width                           = "400px";
    338                labelColumn                     = null;
    339                indexAxis                       = null;         // 8.0.0.0 (2021/08/31)
    340                title                           = null;
    341                titlePosition           = "top";
    342                legendPosition          = null;
    343                legendDisplay           = null;
    344                usePointStyle           = false;        // 6.8.5.0 (2018/01/09) 点のスタイル属性を使用するかどうか
    345                useLegend                       = false;        // 7.0.1.1 (2018/10/22) Legend関連属性(legendPosition,legendDisplay,usePointStyle) のどれかがセットされれば、true
    346                barWidthPer                     = "0.8";
    347                animation                       = null;         // 8.0.0.0 (2021/08/31) 簡易的なアニメーションのON/OFF
    348                onClick                         = null;
    349                plugins                         = null;         // 6.9.9.2 (2018/09/18) プラグイン定義された関数を指定します。
    350                xscaleType                      = TYPE_CATEGORY;
    351                xposition                       = null;         // 7.0.1.2 (2018/11/04) x軸の表示位置[top/right/bottom/left]
    352                valueQuot                       = false;        // 7.0.1.1 (2018/10/22) 値の前後にクオートをはさむかどうか[true/false]指定します。
    353                tableId                         = HybsSystem.TBL_MDL_KEY;
    354                markValues                      = null;         // 6.8.5.0 (2018/01/09) y軸に横マーカーラインの設定値をCSV形式で複数指定します
    355                markColors                      = null;         // 6.8.5.0 (2018/01/09) y軸に横マーカーラインの色をCSV形式で複数指定します
    356                markLbls                        = null;         // 6.8.5.0 (2018/01/09) y軸に横マーカーラインのラベルをCSV形式で複数指定します(未指定時はラベルを表示しません)
    357                markAdjust                      = null;         // 6.8.5.0 (2018/01/09) y軸に横マーカーラインのラベル表示位置の上下方向を調整します(初期値:-6)。
    358                xmarkLbls                       = null;         // 8.0.0.0 (2021/09/30) x軸に横マーカーラインのラベルをCSV形式で複数指定
    359                xmarkValues                     = null;         // 7.0.1.1 (2018/10/22) x軸に縦マーカーラインの設定値をCSV形式で複数指定します
    360                xmarkColors                     = null;         // 7.0.1.1 (2018/10/22) x軸に縦マーカーラインの色をCSV形式で複数指定します
    361                markWidth                       = "2";          // 7.0.1.1 (2018/10/22) マーカーライン共通のラインの幅を指定します:borderWidth(初期値:2)
    362                markDash                        = null;         // 7.0.1.1 (2018/10/22) マーカーライン共通のラインに点線を指定([5,2]など)します:borderDash(初期値:null)
    363                markFontSize            = "10";         // 7.0.1.1 (2018/10/22) マーカーライン共通のラベルのフォントサイズを指定します:fontSize(初期値:10)
    364                useZoom                         = false;        // 6.8.5.0 (2018/01/09) ズーム処理を使用するかどうか(初期値:false)
    365                useDragZoom                     = false;        // 6.8.5.0 (2018/01/09) ズーム処理を使用するかどうか(初期値:false)
    366                varColumns              = null;         // 7.0.1.2 (2018/11/04) TableModelの指定のカラムをconstの配列変数として出力します。
    367//              useVarCheck                     = false;        // 8.0.0.0 (2021/09/30) JavaScript変数に使用できるかどうか[true/false]指定します
    368                useZeroDataOmit         = false;        // 6.7.7.0 (2017/03/31) ﾃﾞｰﾀが０の場合、使用しない（除外する）かどうか
    369                useRenderer                     = false;        // 6.7.9.0 (2017/04/28) useRenderer 追加
    370                sortColumn                      = null;         // 6.8.0.0 (2017/06/02) 検索結果をこのカラムでソートしなおします(初期値:null)。
    371//              optChart                        = null;         // 7.0.1.2 (2018/11/04) chartの属性に、TLDで未定義の属性を追加指定します。
    372                optOptions                      = null;         // 7.0.1.2 (2018/11/04) optionsの属性に、その他ｵﾌﾟｼｮﾝを追加指定します。
    373                optPlugins                      = null;         // 8.0.0.0 (2021/09/30) options:pluginsの属性に、その他ｵﾌﾟｼｮﾝを追加します
    374                optTooltip                      = null;         // 8.0.0.0 (2021/09/30) options:plugins:tooltip の属性に、その他ｵﾌﾟｼｮﾝを追加します
    375                optLegend                       = null;         // 8.0.0.0 (2021/09/30) options:plugins:legend の属性に、その他ｵﾌﾟｼｮﾝを追加します
    376        }
    377
    378        /**
    379         * Taglibの開始タグが見つかった時に処理する doStartTag() を オーバーライドします。
    380         *
    381         * @og.rev 6.7.5.0 (2017/03/10) タグの使用を決める共通属性の追加
    382         *
    383         * @return 後続処理の指示
    384         */
    385        @Override
    386        public int doStartTag() {
    387                if( !useTag() ) { return SKIP_BODY ; }          // 6.7.5.0 (2017/03/10)
    388
    389                return EVAL_BODY_BUFFERED; // Bodyを評価する
    390        }
    391
    392        /**
    393         * Taglibのタグ本体を処理する doAfterBody() を オーバーライドします。
    394         *
    395         * @og.rev 7.0.1.1 (2018/10/22) このスクリプトの中に入れたい文字があれば、登録できるようにします。
    396         *
    397         * @return      後続処理の指示(SKIP_BODY)
    398         */
    399        @Override
    400        public int doAfterBody() {
    401                chartBody = getBodyString();
    402
    403                if( chartBody != null ) {
    404                        chartBody = chartBody.trim();
    405                }
    406
    407                return SKIP_BODY ;
    408        }
    409
    410        /**
    411         * Taglibの終了タグが見つかったときに処理する doEndTag() を オーバーライドします。
    412         *
    413         * @og.rev 6.7.5.0 (2017/03/10) タグの使用を決める共通属性の追加
    414         * @og.rev 6.9.9.4 (2018/10/01) idの振り方、データの持ち方変更
    415         * @og.rev 8.0.0.0 (2021/08/31) ｴﾗｰﾒｯｾｰｼﾞを画面に返します。
    416         *
    417         * @return 後続処理の指示
    418         */
    419        @Override
    420        public int doEndTag() {
    421                debugPrint();
    422                if( !useTag() ) { return EVAL_PAGE ; }                  // 6.7.5.0 (2017/03/10)
    423
    424                id = (id==null ? tableId : id );                                // 6.9.9.4 (2018/10/01) id指定なしの場合はtableId
    425
    426                // jsChart出力
    427                jspPrint( jsChartOutput() );
    428
    429                // 8.0.0.0 (2021/08/31) ｴﾗｰﾒｯｾｰｼﾞを画面に表示する。
    430                final StringBuilder errBuf = new StringBuilder( BUFFER_MIDDLE );
    431                final String axisErr = jsXAxis.getErrorMessage();
    432                if( !axisErr.isEmpty() ) {
    433                        errBuf.append( "X軸の設定でエラーがあります" ).append( CR )
    434                                        .append( axisErr ).append( CR );
    435                }
    436
    437                // jsChartDataﾀｸﾞの変数宣言
    438                for( int i=0; i<jsChartData.size(); i++ ) {
    439                        final String dataErr = jsChartData.get(i).getErrorMessage();
    440                        if( !dataErr.isEmpty() ) {
    441                                errBuf.append( "Y軸[" ).append( i ) .append( "]の設定でエラーがあります" ).append( CR )
    442                                                .append( dataErr ).append( CR );
    443                        }
    444                }
    445
    446                if( errBuf.length() > 0 ) {                             // 一応、設定されているかどうか確認する。
    447                        errBuf.insert( 0,"<pre>" ).append( "</pre>" );
    448                        jspPrint( errBuf.toString() );
    449                }
    450
    451                return EVAL_PAGE;
    452        }
    453
    454        /**
    455         * jsChart出力用
    456         * jsChartTag と jsChartData を使用して、jsChart情報を出力します。
    457         *
    458         * @og.rev 5.9.19.0 (2017/04/07) T.OTA 61200-170316-02  ﾁｬｰﾄｻｲｽﾞ・max・minの動的変更対応
    459         * @og.rev 6.7.7.0 (2017/03/31) ﾁｬｰﾄﾃﾞｰﾀで、ｾﾞﾛ、null カラムを非表示にします。
    460         * @og.rev 6.7.9.0 (2017/04/28) useRenderer 追加
    461         * @og.rev 6.8.0.0 (2017/06/02) sortColumn 追加
    462         * @og.rev 6.8.3.0 (2017/11/27) useZeroDataOmit属性で、nullOmit属性もセットします。
    463         * @og.rev 6.8.3.0 (2017/11/27) useEqValOmit属性の追加
    464         * @og.rev 6.8.3.1 (2017/12/01) 不要なデータを出力しないようにします。
    465         * @og.rev 5.9.27.0 2017/12/01  T.OTA 61200-170831-04   max,minの小数点対応
    466         * @og.rev 6.8.5.0 (2018/01/09) xbeginAtZero,ybeginAtZero,markValues,markColors,markLbls,markAdjust,rangeMin,rangeMax,usePointStyle属性の追加
    467         * @og.rev 6.9.9.2 (2018/09/18) chart.jsが2.4.0から2.7.2にバージョンアップにより、廃止された属性対応
    468         * @og.rev 6.9.9.2 (2018/09/18) plugins,chartAttributes属性の追加
    469         * @og.rev 6.9.9.3 (2018/09/25) xscaleType の time 属性廃止。
    470         * @og.rev 6.9.9.4 (2018/10/01) ﾘﾆｱ対応,time 属性復活
    471         * @og.rev 6.9.9.4 (2018/10/01) idの振り方、データの持ち方変更
    472         * @og.rev 7.0.1.1 (2018/10/22) xmarkValues,xmarkColors属性の追加
    473         * @og.rev 7.0.1.3 (2018/11/12) バッファキー検索処理追加、markColors,xmarkColors属性に、VIVID,PASTELカラー指定に対応します。
    474         * @og.rev 8.0.0.0 (2021/08/31) BUBBLEとSCATTERの追加
    475         * @og.rev 8.0.0.0 (2021/08/31) horizontalBar 廃止 → indexAxis="y" 指定
    476         *
    477         * @return jsChert用文字列
    478         */
    479        private String jsChartOutput() {
    480//              // 各JavaScriptの変数名
    481//              final String cd                 = "cd_" + id;           //chartData
    482//              final String myChart    = "chart_"+id;
    483
    484                // JSON形式でﾃｰﾌﾞﾙ情報を取得
    485                // ﾃｰﾌﾞﾙ情報の取得
    486                // 6.8.0.0 (2017/06/02) sortColumn 追加
    487                DBTableModel table = (DBTableModel)getObject( tableId ) ;
    488                if( StringUtil.isNotNull( sortColumn ) ) {                                              // 6.8.5.0 (2018/01/09)
    489                        final int clmNo = table.getColumnNo( sortColumn );                      // エラーを出す。
    490
    491                        final DBTableModelSorter temp = new DBTableModelSorter();
    492                        temp.setModel( (DBTableModel)getObject( tableId ) );
    493                        temp.sortByColumn( clmNo,true );                                                        // 順方向のソート
    494                        table = temp;
    495                }
    496
    497                final int rowCount = table.getRowCount();                                               // 6.9.2.0 (2018/03/05)
    498
    499                // 7.0.1.3 (2018/11/12) DBTableModelに存在しないカラムのChartDataは無視します。
    500                // これは、動的にグラフを生成する場合に、カラムの増減に合わせて、JsChartDataV3Tagを生成しなおすのが手間だからです。
    501                final Iterator<JsChartDataV3> itr = jsChartData.iterator();             // 個々のグラフ
    502                while( itr.hasNext() ) {
    503                        final JsChartDataV3 jcData = itr.next();
    504                        final String chtClm = jcData.getChartColumn();
    505                        final int    clmNo  = table.getColumnNo( chtClm );      // エラーを出す。
    506
    507                        if( clmNo < 0 ) {
    508                                itr.remove();                                                                                   // 7.0.1.3 (2018/11/12) カラムがDBTableModelに存在しない。
    509                        }
    510                        else if( useZeroDataOmit ) {    // ｾﾞﾛﾃﾞｰﾀを使用しない設定
    511                                // 6.8.3.1 (2017/12/01) ループ処理の判定は、ChartColumn のみでよい。
    512                                boolean isRemove = true;
    513                                for( int row=0; row<rowCount; row++ ) {
    514                                        final String val = table.getValue( row,clmNo );
    515                                        if( StringUtil.isNotNull( val ) && !"0".equals( val ) && !"0.0".equals( val ) && !"0.00".equals( val )  ) {     // 6.8.5.0 (2018/01/09)
    516                                                isRemove = false;
    517                                                break;          // 判定処理打ち切り
    518                                        }
    519                                }
    520
    521                                if( isRemove ) {
    522                                        itr.remove();                                                                           // すべてが、ｾﾞﾛ、null カラムを、削除します。
    523                                }
    524                        }
    525                }
    526
    527                // 6.8.3.1 (2017/12/01) 不要なデータを出力しないようにします。
    528                final int clmSize = jsChartData.size();                                                         // JsChartV3Tag の 値部分のみの配列
    529
    530                final String[] clmNms = new String[clmSize];                                            // 6.9.9.4 (2018/10/01) カラム名の配列
    531                final int[]    clmNos = new int[clmSize];
    532                final int      lblNos = table.getColumnNo( labelColumn );                       // エラーを出す
    533                final DBColumn dbClm  = table.getDBColumn( lblNos );                            // 6.9.2.0 (2018/03/05)
    534
    535                // jsChartDataﾀｸﾞの変数宣言
    536                for( int j=0; j<clmSize; j++ ) {
    537                        final String chtClm = jsChartData.get(j).getChartColumn();
    538//                      clmNms[j] = chtClm;                                                                                                     // 6.9.9.4 (2018/10/01) カラム名の配列 8.0.0.0 (2021/09/30) Delete
    539                        clmNos[j] = table.getColumnNo( chtClm );                                                        // エラーを出す
    540
    541                        final String clmRnm = "CLM" + j;                                                                        // 8.0.0.0 (2021/09/30) JavaScript変数名対応
    542                        jsChartData.get(j).setChartColumn(clmRnm);
    543                        clmNms[j] = clmRnm;
    544                }
    545
    546                //      8.0.0.0 (2021/08/31) chartJs V3 以降は、timeもrealtimeも表示するようになった…らしい
    547                final StringBuilder rtn = new StringBuilder( BUFFER_MIDDLE )
    548                        .append( IE_CHECK )                                                                                                     // IE 警告
    549                        .append( "<canvas class=\""     ).append( CANVAS_NAME )                                 // canvasﾀｸﾞの設定
    550                        .append( "\" id=\""                     ).append( id            )
    551                        .append( "\" width=\""          ).append( width         )
    552                        .append( "\" height=\""         ).append( height        )
    553                        .append( "\"><!-- --></canvas>" ).append( CR    )
    554                        .append( "<script>{" ).append( CR )                                                                     // 8.0.0.0 (2021/08/31) スコープ限定の '{' を追加
    555                        .append( chartBody );                                                                                           // 7.0.1.1 (2018/10/22) BODY部分の文字列の組み込み
    556
    557                final boolean isXcateType  = TYPE_CATEGORY.equals(      xscaleType );           // 6.9.9.4 (2018/10/01)
    558                final boolean isXlinerType = TYPE_LINEAR.equals(        xscaleType );           // 6.8.5.0 (2018/01/09) xscaleType が linear かどうか。
    559                final boolean isXtimeType  = TYPE_TIME.equals(          xscaleType );           // 6.8.5.0 (2018/01/09) xscaleType が time かどうか。
    560
    561                // 7.0.1.3 (2018/11/12) const 変数に設定する配列情報を、bufに追加します。
    562                final DBTableModel fcTable = table;                     // ラムダ式で使えるのは、final宣言された変数のみ。根本は、Sorterを組み込んでfinalすべき。
    563                final IntFunction<String> lcFunc = (row) -> {
    564                                final String lval = fcTable.getValue( row,lblNos );
    565                                return useRenderer && !isXlinerType
    566                                                        ? StringUtil.jsonFilter( dbClm.getRendererValue(row,lval) ) : lval ;
    567                };
    568                setVarArray( rtn,labelColumn,rowCount,isXcateType || isXtimeType || useRenderer,lcFunc );
    569
    570                // 6.9.9.4 (2018/10/01) データ部の出力
    571                for( int j=0; j<clmSize; j++ ) {
    572                        final int clmNo = clmNos[j];            // finalしか参照できないため。
    573                        setVarArray( rtn,clmNms[j],rowCount,valueQuot,(row) -> fcTable.getValue( row,clmNo ) );
    574                }
    575
    576                // x軸がlinearｽｹｰﾙの場合
    577                // [{x:値1,y:値2},{x:値1,y:値2},･･･] 形式のデータが必要
    578                if( isXlinerType ) {
    579                        for( int j=0; j<clmSize; j++ ) {
    580                                final String chtClm = clmNms[j];
    581                                rtn.append( "const LI_" ).append( chtClm ).append( "=[];" ).append( CR );
    582
    583                                // 6.9.9.4 (2018/10/01) x軸がlinearｽｹｰﾙの場合、カラム名が、変わるので、再設定している。(超特殊処理)
    584                                jsChartData.get(j).setChartColumn( "LI_" + chtClm );
    585                        }
    586
    587                        rtn.append( "for(var i=0; i<").append( labelColumn ).append( ".length; i++){" );
    588                        for( int j=0; j<clmSize; j++ ) {
    589                                final String chtClm = clmNms[j];
    590                                        // {x:ﾗﾍﾞﾙ, y:値}の形式で値を設定
    591                                rtn.append( "LI_" ).append( chtClm ).append( "[i]={x:" ).append( labelColumn )
    592                                        .append( "[i],y:" ).append( chtClm ).append( "[i]};" );
    593                        }
    594                        rtn.append( "};" ).append( CR );
    595                }
    596
    597                // 7.0.1.2 (2018/11/04) varColumns 追加
    598                final String[] varClms  = StringUtil.csv2Array( varColumns );   // 独自に出力しておきたいカラム列の値
    599                for( int j=0; j<varClms.length; j++ ) {
    600                        final int varNos = table.getColumnNo( varClms[j] );     // エラーを出す
    601                        final boolean isNumType = table.getDBColumn( varNos ).isNumberType();                   // 6.4.6.0 (2016/05/27)
    602
    603                        setVarArray( rtn,varClms[j],rowCount,!isNumType,(row) -> fcTable.getValue( row,varNos ) );
    604                }
    605
    606                // 8.0.0.0 (2021/08/31) BUBBLEとSCATTERの追加
    607                // chartType が BUBBLE の場合、chtClmが x:、varColumns の最初が、y: 次が r: になる。
    608                // SCATTERの場合は、r: がないだけ。
    609                if( CTYPE_BUBBLE.equals( chartType ) || CTYPE_SCATTER.equals( chartType ) ) {
    610                        if( CTYPE_BUBBLE.equals( chartType ) && varClms.length < 2 ||
    611                                CTYPE_SCATTER.equals( chartType ) && varClms.length < 1 ) {
    612                                        final StringBuilder errMsg = new StringBuilder( BUFFER_MIDDLE )
    613                                                .append( "chartTypeが、" ).append( chartType )
    614                                                .append( "の場合は、varColumns で、y: データ、r:データを指定してください。" );
    615                                        throw new HybsSystemException( errMsg.toString() );
    616                        }
    617
    618                        final String chtClm = clmNms[0];                // chartDataの1個目決め打ち
    619                        rtn.append( "const LI_" ).append( chtClm ).append( "=[];" ).append( CR );
    620
    621                        // x軸が[{x: , y: , r: }…} のカラム名が変わるので、再設定している。(超特殊処理)
    622                        jsChartData.get(0).setChartColumn( "LI_" + chtClm );
    623
    624                        rtn.append( "for(var i=0; i<").append( chtClm ).append( ".length; i++){" )
    625                                .append( "LI_" ).append( chtClm ).append( "[i]={x:" ).append( chtClm )
    626                                .append( "[i],y:" ).append( varClms[0] );
    627
    628                        // 切れ切れで分かりにくいかもしれないが、BUBBLEのみ、r: を出す。
    629                        if( CTYPE_BUBBLE.equals( chartType ) ) {
    630                                rtn.append( "[i],r:" ).append( varClms[1] );
    631                        }
    632
    633                        rtn.append( "[i]};}" ).append( CR );
    634                }
    635
    636                // ==================================================================================
    637                // 7.0.1.1 (2018/10/22) jsChartData(X軸)の設定
    638                if( !SET_CI_TYPE.contains( chartType ) ) {
    639                        jsXAxis.setId( "x0" );                                          // X軸のid
    640                        jsXAxis.setUseTime( isXtimeType );                      // x軸の時間表示を使用するかどうか
    641
    642                        // 7.0.1.3 (2018/11/12) バッファキー検索処理追加
    643                        if( isXtimeType && !jsXAxis.contains( JsChartDataV3.TIME , "displayFormats" ) ) {               // ｷｰﾜｰﾄﾞが無ければ追加
    644                                // ほんとはリソースに入れるべきでしょう。
    645                                if( "ja".equalsIgnoreCase( getLanguage() ) ) {                                          // 'ja' なら日本
    646                                        jsXAxis.addTime( "displayFormats" , TIME_FORMAT_JA , NO_QUOTE );        // 標準ﾀｲﾑﾌｫｰﾏｯﾄ適用。ｵﾌﾞｼﾞｪｸﾄなので、クオートなし
    647                                }
    648                                else {
    649                                        jsXAxis.addTime( "displayFormats" , TIME_FORMAT , NO_QUOTE );           // 標準ﾀｲﾑﾌｫｰﾏｯﾄ適用。ｵﾌﾞｼﾞｪｸﾄなので、クオートなし
    650                                }
    651                        }
    652
    653                        // x軸にﾘﾆｱｽｹｰﾙを設定した場合(これは残す)
    654                        final String xpos = xposition != null ? xposition
    655                                                                                                  : isXlinerType ? "bottom"
    656                                                                                                                                 : null ;       // horizontalBar 廃止
    657                        jsXAxis.addAxis( "position" , xpos , USE_QUOTE );       // 文字
    658
    659                        rtn.append( jsXAxis.getAxis() ).append( CR );
    660                }
    661
    662                // ==================================================================================
    663                // jsChartData(Y軸)の設定
    664
    665                // 各JavaScriptの変数名
    666                final String cd                 = "cd_" + id;           //chartData
    667                final String myChart    = "chart_"+id;
    668
    669                // 7.0.1.1 (2018/10/22) data:dataset と、options:scales:yAxes: を変数化して出力します。
    670                for( final JsChartDataV3 chData : jsChartData ) {
    671                        rtn.append(  chData.getDataset( 'y' )   ).append( CR )          // 横棒線の場合は、'x'が、それ以外は、'y'
    672                                .append( chData.getAxis()                       ).append( CR );
    673                }
    674
    675                rtn.append( "const ").append( cd ).append( "={labels:" ).append( labelColumn ).append( ",datasets:[" );
    676                for( final JsChartDataV3 chData : jsChartData ) {
    677                        rtn.append( chData.getDatasetKey() ).append( ',' );
    678                }
    679                rtn.append( "]};" ).append( CR )
    680                        // jsChartの生成(グローバル変数定義の var)
    681                        .append( "var " ).append( myChart ).append( "=new Chart(" ).append( id )
    682                        .append( ",{" )
    683                        .append( CR_TAB[1] ).append( "type:'" ).append( chartType ).append( "'," )
    684                        .append( CR_TAB[1] ).append( "data:"  ).append( cd ).append( ',' );
    685
    686                // 6.9.9.2 (2018/09/18) plugins,chartAttributes属性の追加
    687                setProp( rtn, CR_TAB[1],"plugins:["  , plugins   , "]," );
    688
    689                rtn.append( CR_TAB[1] ).append( "options:{responsive:false," );                 // ﾚｽﾎﾟﾝｼﾌﾞ OFF
    690
    691                // 8.0.0.0 (2021/08/31)
    692                setProp( rtn, CR_TAB[2],"indexAxis:'"  , indexAxis   , "'," );          // "y" を指定することで、horizontalBar や verticalLine を実現
    693                setProp( rtn, CR_TAB[2],"categoryPercentage:" , barWidthPer , ","  );   // 棒線の横幅
    694                setProp( rtn, CR_TAB[2],"animation:" , animation , ","  );                      // 簡易的なアニメーションのON/OFFを設定
    695
    696                // ｸﾘｯｸｲﾍﾞﾝﾄの設定
    697                // clickLink 変数を使用する場合、内部でﾏｽﾀﾃﾞｰﾀを使用します。ｷｰとして、渡しておく必要があります。
    698                setProp( rtn, CR_TAB[2],"onClick:function(event,obj){",CR_TAB[3], onClick,CR_TAB[2],"}," );
    699
    700                // 8.0.0.0 (2021/08/31) options:plugins:
    701                rtn.append( CR_TAB[2] ).append( "plugins:{" );
    702
    703                setProp( rtn, CR_TAB[3], optPlugins , "," );                            // 8.0.0.0 (2021/09/30) 属性はマージされる
    704                setProp( rtn, CR_TAB[3],"tooltip:{" , optTooltip , "}," );      // 8.0.0.0 (2021/09/30)
    705
    706                // ﾀｲﾄﾙ属性の設定(ﾀｲﾄﾙ要素も処理できるように変更))
    707                if( title != null && title.length() > 0 ) {
    708                        if( title.charAt(0) == '{' ) {
    709                                rtn.append( CR_TAB[3] ).append( "title:" ).append( title ).append( ',' );
    710                        }
    711                        else if( title.charAt(0) == '[' ) {
    712                                // タイトルに配列を渡すと、改行表示する。
    713                                setProp( rtn, CR_TAB[3],"title:{display:true,text:",title,",position:'", titlePosition, "',}," );
    714                        }
    715                        else {
    716                                // タイトルを文字列として処理する。
    717                                setProp( rtn, CR_TAB[3],"title:{display:true,text:'",title,"',position:'", titlePosition, "',}," );
    718                        }
    719                }
    720
    721                // 凡例属性の設定(
    722                if( useLegend ) {                                                                                       // 7.0.1.1 (2018/10/22)
    723                        rtn.append( CR_TAB[3] ).append( "legend:{" );
    724                        setProp( rtn, optLegend  , ","  );                                              // 8.0.0.0 (2021/09/30) 属性はマージされる
    725                        setProp( rtn, "display:"   , legendDisplay  , ","  );
    726                        setProp( rtn, "position:'" , legendPosition , "'," );
    727
    728                        // 凡例のスタイルを、pointStyle にあわせるかどうか
    729                        if( usePointStyle ) {                                                                   // 7.0.1.1 (2018/10/22)
    730                                rtn.append( "labels:{usePointStyle:true}," );
    731                        }
    732                        rtn.append( "}," );
    733                }
    734
    735                // 8.0.0.0 (2021/08/31) zoom は、文法も変わり、options:plugins: 以下の属性になった。
    736                // 6.8.5.0 (2018/01/09) ズーム処理を使用するかどうか
    737                if( useZoom ) {         // useZoom を優先する。
    738                        rtn.append( CR_TAB[3] ).append( WHEEL_ZOOM );
    739                }
    740                else if( useDragZoom ) {
    741                        rtn.append( CR_TAB[3] ).append( DRAG_ZOOM );
    742                }
    743
    744                // 8.0.0.0 (2021/08/31) annotation は、options:plugins: 以下の属性になった。
    745                final String[] mkVals  = StringUtil.csv2Array( markValues );    // y軸の値で、横のﾏｰｶｰ
    746                final String[] xmkVals = StringUtil.csv2Array( xmarkValues );   // x軸の値で、縦のﾏｰｶｰ
    747                final int vCnt = mkVals.length;
    748                final int xCnt = xmkVals.length;
    749                if( vCnt > 0 || xCnt > 0 ) {
    750                        rtn.append( CR_TAB[3] ).append( "annotation:{annotations:{" );  // 8.0.0.0 (2021/08/31) 配列からｵﾌﾞｼﾞｪｸﾄへ
    751
    752                        // 従来の markValues,markColors,markLbls,markAdjust 属性対応
    753                        if( vCnt > 0 ) {
    754                                final String[] mkLbls = StringUtil.csv2Array( markLbls          , ',' , vCnt );
    755                                final String[] mkAjst = StringUtil.csv2Array( markAdjust        , ',' , vCnt , MARK_DEF_ADJUST );
    756                                final String[] mkCols = colorCsv( markColors ,  vCnt );                                                 // 7.0.1.3 (2018/11/12)
    757
    758                                // 7.0.1.1 (2018/10/22) 'y-axis-0' → 'y0Ax' これは、JsChartDataV3#getAxisKey() で取得できる値だが、決め打ち
    759                                for( int i=0; i<vCnt; i++ ) {
    760                                        rtn.append( CR_TAB[4] ).append( "yline" ).append(i).append( ":{" )      // V3で、名前付きになった。
    761                                                .append( CR_TAB[5] ).append( "type:'line'," );
    762                                        setProp( rtn, "borderWidth:"            , markWidth     , ","   );
    763                                        setProp( rtn, "borderDash:"                     , markDash      , ","   );
    764                                        setProp( rtn, "borderColor:'"           , mkCols[i] , "',"      );
    765                                        setProp( rtn, CR_TAB[5],"yMin:"         , mkVals[i]     , ","   );                      // V3 → V2 で、valueから、yMin,yMax に変更
    766                                        setProp( rtn,                   "yMax:"         , mkVals[i]     , ","   );
    767                                        if( !mkLbls[i].isEmpty() ) {
    768                                                rtn.append( CR_TAB[5] ).append( "label:{" )
    769                                                        .append( CR_TAB[6] )
    770                                                        .append( "enabled:'true',position:'start',backgroundColor:'rgba(0,0,0,0)'," )   // position:left → start に変更
    771                                                        .append( CR_TAB[6] );
    772                                                setProp( rtn, "content:'"               , mkLbls[i] , "'," );
    773                                                setProp( rtn, "color:'"                 , mkCols[i] , "'," );
    774                                                setProp( rtn, "yAdjust:"                , mkAjst[i]     , ","   );
    775                                                setProp( rtn, CR_TAB[6],"font:{size:" , markFontSize , "},"     );      // fontSize:XX → font:{size:XX} に変更
    776                                                rtn.append( CR_TAB[5] ).append( "}," );         // label:{
    777                                        }
    778                                        rtn.append( CR_TAB[4] ).append( "}," );         // type:
    779                                }
    780                        }
    781
    782                        // 7.0.1.1 (2018/10/22) xmarkValues,markLbls,xmarkColors属性対応
    783                        if( xCnt > 0 ) {
    784                                final String[] xmkLbls = StringUtil.csv2Array( xmarkLbls        , ',' , xCnt ); // 8.0.0.0 (2021/09/30)
    785                                final String[] xmkCols = colorCsv( xmarkColors ,  xCnt );                       // 7.0.1.3 (2018/11/12)
    786
    787                                // 7.0.1.1 (2018/10/22) 'x-axis-0' → 'x0Ax' これは、JsChartDataV3#getAxisKey() で取得できる値だが、決め打ち
    788                                for( int i=0; i<xCnt; i++ ) {
    789                                        rtn.append( CR_TAB[4] ).append( "xline" ).append(i).append( ":{" )
    790                                                .append( CR_TAB[5] ).append( "type:'line'," );                          // V3で、名前付きになった。
    791                                        setProp( rtn, "borderWidth:"            , markWidth     , ","   );
    792                                        setProp( rtn, "borderDash:"                     , markDash      , ","   );
    793                                        setProp( rtn, "borderColor:'"           , xmkCols[i] , "'," );
    794                                        setProp( rtn, CR_TAB[5],"xMin:'"        , xmkVals[i] , "',"     );              // V3 → V2 で、valueから、xMin,xMax に変更
    795                                        setProp( rtn,                   "xMax:'"        , xmkVals[i] , "',"     );              //カテゴリで文字列のケース有り
    796                                        if( !xmkLbls[i].isEmpty() ) {                                                                   // 8.0.0.0 (2021/09/30)
    797                                                rtn.append( CR_TAB[5] ).append( "label:{" )
    798                                                        .append( CR_TAB[6] )
    799                                                        .append( "enabled:'true',position:'end',backgroundColor:'white'," )     // position:left → start に変更
    800                                                        .append( CR_TAB[6] );
    801                                                setProp( rtn, "content:'"               , xmkLbls[i] , "'," );
    802                                                setProp( rtn, "color:'"                 , xmkCols[i] , "'," );
    803                                                setProp( rtn, CR_TAB[6],"font:{size:" , markFontSize , "},"     );      // fontSize:XX → font:{size:XX} に変更
    804                                                rtn.append( CR_TAB[5] ).append( "}," );         // label:{
    805                                        }
    806                                        rtn.append( CR_TAB[4] ).append( "}," );         // type:
    807                                }
    808                        }
    809                        rtn.append( CR_TAB[3] ).append( "}}," );                // annotation:{annotations:{
    810                }
    811                rtn.append( CR_TAB[2] ).append( "}," );         // plugins:{
    812
    813                // 6.9.9.2 (2018/09/18) chart.jsが2.4.0から2.7.2にバージョンアップにより、廃止された属性対応
    814                if( !SET_CI_TYPE.contains( chartType ) ) {
    815                        // 円形以外の場合はscales属性に設定
    816                        rtn.append( CR_TAB[2] ).append( "scales:{x:" )
    817                                .append( jsXAxis.getAxisKey() ).append( ',' );
    818
    819                        // 7.0.1.1 (2018/10/22) options:scales:yAxes: を変数化して出力しているので、その設定のみでよい。
    820                        // 最初の一つだけ、"y:" を付ける(何か方法があるはず)。
    821                        boolean isFirst = true;
    822                        for( final JsChartDataV3 chData : jsChartData ) {
    823                                if( chData.isUseAxis() ) {
    824                                        if( isFirst ) { rtn.append( "y:" ); isFirst=false; }
    825                                        rtn.append( chData.getAxisKey() ).append( ',' );
    826                                }
    827                        }
    828
    829                        rtn.append( "}," );             // 7.0.1.1 (2018/10/22)
    830                }
    831
    832                setProp( rtn, CR_TAB[2] , optOptions , "," );           // 7.0.1.2 (2018/11/04)
    833                rtn.append( CR_TAB[1] ).append( "}," )
    834                        .append( CR_TAB[0] ).append( "});" ).append( CR );
    835
    836                // 8.0.0.0 (2021/08/31) zoom を使った場合は、ダブルクリックで元に戻す処理を入れておく
    837                if( useZoom || useDragZoom ) {
    838                        rtn.append( "const cv_" ).append( id ).append( "=document.getElementById('" )
    839                                .append( id ).append( "');" ).append( CR )
    840                                .append( "cv_" ).append( id ).append( ".addEventListener( 'dblclick',function(){" )
    841                                .append( myChart )                                                              // Chart オブジェクト
    842                                .append( ".resetZoom();});" ).append( CR );
    843                }
    844
    845                rtn.append( "}</script>" );     // 8.0.0.0 (2021/08/31) スコープ限定の '}' を追加
    846
    847                return rtn.toString();
    848        }
    849
    850        /**
    851         * s引数のすべての文字列が null か、長さゼロ文字列でない場合は、連結した結果を返します。
    852         *
    853         * @param buf   ベースとなるStringBuilder
    854         * @param str   連結対象の文字列群(可変長引数)
    855         */
    856        private void setProp( final StringBuilder buf, final String... strs ) {
    857                if( !StringUtil.isEmpty( strs ) ) {             // null か、長さゼロ文字列が、一つもない場合
    858                        for( final String str : strs ) {
    859                                buf.append( str );
    860                        }
    861                }
    862        }
    863
    864        /**
    865         * const 変数に設定する配列情報を、bufに追加します。
    866         *
    867         * const 変数名が key で、cnt分の繰返しで、IntFunction を呼びます。
    868         * isQuote=trueの場合は、前後にクォーテーションをつけます。
    869         *
    870         * @og.rev 7.0.1.3 (2018/11/12) const 変数に設定する配列情報を、bufに追加します。
    871         * @og.rev 8.0.2.1 (2021/12/10) 空文字列の場合は、クォーテーションを付けない。
    872         *
    873         * @param buf   ベースとなるStringBuilder
    874         * @param key   キー
    875         * @param cnt   ループする個数(通常は行数：rowCount)
    876         * @param isQuote       クォーテーションで括るかどうか [true:括る/false:括らない]
    877         * @param func  数値を引数に取る関数型インタフェース
    878         */
    879        private void setVarArray( final StringBuilder buf, final String key, final int cnt,
    880                                                                final boolean isQuote, final IntFunction<String> func ) {
    881                buf.append( "const " ).append( key ).append( "=[" );
    882                for( int row=0; row<cnt; row++ ) {
    883                        final String val = nval( func.apply( row ),"" );        // null 文字列が append されるのを避ける
    884
    885                        if( val.isEmpty() ) {                   // 8.0.2.1 (2021/12/10)
    886                                buf.append( ',' );
    887                        }
    888                        else if( isQuote ) {
    889                                buf.append( '"' ).append( val ).append( "\"," );
    890                        }
    891                        else {
    892                                buf.append( val ).append( ',' );
    893                        }
    894                }
    895                buf.append( "];" ).append( CR );
    896        }
    897
    898        /**
    899         * ﾊﾟﾗﾒｰﾀﾁｪｯｸ用ﾒｿｯﾄﾞ。
    900         *
    901         * @param trg           ターゲット
    902         * @param set           使用可能なキーワードのSet
    903         * @param trgStr        ターゲットの名称
    904         */
    905        private void checkPara( final String trg, final Set<String> set, final String trgStr ) {
    906                if( StringUtil.isNotNull( trg ) && !check( trg, set ) ) {                                               // 6.8.5.0 (2018/01/09)
    907                        final StringBuilder errMsg = new StringBuilder( BUFFER_MIDDLE )
    908                                .append( "指定の" ).append( trgStr ).append( "は指定できません。" ).append( CR )
    909                                .append( trgStr ).append( "=[" ).append( trg ).append( ']' ).append( CR )
    910                                .append( set );         // org.opengion.fukurou.util.ArraySet の toStringメソッド
    911                        throw new HybsSystemException( errMsg.toString() );
    912                }
    913        }
    914
    915//      /**
    916//       * JavaScript変数ﾁｪｯｸ用ﾒｿｯﾄﾞ。
    917//       *
    918//       * 1文字目は数字と、特殊記号(アンダーバー(_)、ドル記号($)を除く)、をチェックします。
    919//       * 厳密には、予約文字が使えなかったりするが、簡易ﾁｪｯｸとする。
    920//       * 前後の空白文字は除外、それ以外の特殊記号は、アンダーバー(_)に変換します。
    921//       *
    922//       * @og.rev 8.0.0.0 (2021/09/30) JavaScriptの変数名ﾁｪｯｸと置換
    923//       *
    924//       * @param key           ﾁｪｯｸする変数
    925//       * @param trgStr        変数置換後の変数
    926//       */
    927//      private String checkPara( final String key ) {
    928//              if( !useVarCheck ) { return key; }                              // useVarCheck が false の場合は、何もしない。
    929//
    930//              if( key == null || key.isEmpty() ) { return "_"; }
    931//
    932//              final StringBuilder buf = new StringBuilder(key.trim());
    933//              for( int i=0; i<buf.length(); i++ ) {
    934//                      final char ch = buf.charAt(i);
    935//                      if( i==0 && '0'<=ch && ch<='9'                  ||
    936//                              ' '<=ch && ch<='/' && '$'!=ch           ||
    937//                              ':'<=ch && ch<='@'                                      ||
    938//                              '['<=ch && ch<='`' && '_'!=ch           ||
    939//                              '{'<=ch && ch<='~' ) { buf.setCharAt( i,'_' ); }
    940//              }
    941//
    942//              return buf.toString();
    943//      }
    944
    945        /**
    946         * 色コードの配列を返すメソッドです。
    947         *
    948         * これは、普通のCSV形式のﾃﾞｰﾀなら、そのまま分割します。
    949         * 配列は、lenの数だけ作成します。
    950         * nullやゼロ文字列の場合は、ColorMapのOLOR_KEYすべてを対象にします。
    951         * 1色の場合も、すべて同じ色をlen の数だけセットします。
    952         *
    953         * VIVIDとPASTEL はｷｰﾜｰﾄﾞで、org.opengion.fukurou.util.ColorMap のビビッドカラーと
    954         * パステルカラーの配列を指定したことと同じになります。
    955         * また、色番号として、ビビッドを、(V0～V11) , パステルを、(P0～P11)
    956         * に割当てていますので、配列に分解後一旦すべてのｷｰﾜｰﾄﾞを色番号検索に使用します。
    957         *
    958         * @og.rev 7.0.1.3 (2018/11/12) 色コードの配列を返すメソッド追加
    959         *
    960         * @param colCsv        色コードのCSV形式文字列
    961         * @param len           作成する配列の個数
    962         * @return      色コードに変換後の配列
    963         */
    964        private String[] colorCsv( final String colCsv, final int len ) {
    965                // 色の数を、len にあわせる必要があります。
    966                final String[] mkCols = new String[len];
    967
    968                // cols を元に、ColorMap から色配列を取得します。
    969                final String[] cols = ColorMap.getColorKeys( colCsv );
    970
    971                // 色配列に順番に割り当てますが、色が足りない場合は、初期値の色をセットします。
    972                final int min = Math.min( mkCols.length , cols.length );
    973                for( int i=0; i<min; i++ ) {
    974                        mkCols[i] = cols[i];
    975                }
    976                for( int i=min; i<mkCols.length; i++ ) {
    977                        mkCols[i] = cols[0];                                    // 色コードの最初の色
    978                }
    979
    980                return mkCols ;
    981        }
    982
    983        /**
    984         * jsChartData情報をﾘｽﾄに追加します。
    985         *
    986         * @og.rev 6.7.5.0 (2017/03/10) ﾘｽﾄの初期化方法を変更します。
    987         *
    988         * @param jsData jsChartData情報
    989         */
    990        protected void addJsChartData( final JsChartDataV3 jsData ) {
    991                jsChartData.add( jsData );
    992        }
    993
    994        /**
    995         * 登録済みのjsChartData情報の個数を返します。
    996         *
    997         * @og.rev 6.7.7.0 (2017/03/31) 新規登録
    998         *
    999         * @return 登録済みのjsChartData情報の個数
    1000         */
    1001        protected int getJsChartDataSize() {
    1002                return jsChartData.size();
    1003        }
    1004
    1005        /**
    1006         * borderColorとbackgroundColorに色を１色しか使用できないかどうかを返します。
    1007         *
    1008         * chartType に応じて、色配列が使用できないタイプがあります。
    1009         *    line/radar が true  （１色しか使用できない）
    1010         *    それ以外（bar/horizontalBar/polarArea/pie/doughnut）が false （色配列が使用できる）
    1011         *
    1012         * @og.rev 7.0.1.1 (2018/10/22) 新規登録
    1013         *
    1014         * @return 登録済みのjsChartData情報の個数
    1015         */
    1016        protected boolean isOneColor() {
    1017                // line/radar が true  （１色しか使用できない）
    1018                return CTYPE_LINE.equalsIgnoreCase( chartType ) || CTYPE_RADAR.equalsIgnoreCase( chartType );
    1019        }
    1020
    1021        // =================================================================================
    1022
    1023        /**
    1024         * 【TAG】ﾁｬｰﾄの種類を指定します[line/bar/radar/polarArea/pie/doughnut/bubble/scatter](必須)。
    1025         *
    1026         * @og.tag
    1027         * コンフィグ属性の type 定義です。
    1028         * なお、複合グラフ時には、この値を、"bar" にしておかないと、きちんと表示しないようです。
    1029         *
    1030         * 8.0.0.0 (2021/08/31)
    1031         *  chartTypeが、bubbleとscatterの場合は、y:データ、r:データを varColumns で
    1032         *  指定します。詳細は、varColumns の説明をご確認ください。
    1033         *
    1034         *  horizontalBar 廃止 → indexAxis="y" 指定 (当面は互換性の関係で残しますが、廃止予定です)
    1035         *  verticalLine 相当の表示も indexAxis="y" 指定
    1036         *
    1037         * @og.rev 8.0.0.0 (2021/08/31) BUBBLEとSCATTERの追加
    1038         *
    1039         * @param cType ﾁｬｰﾄﾀｲﾌﾟ [line/bar/radar/polarArea/pie/doughnut/bubble/scatter]
    1040         */
    1041        public void setChartType( final String cType ) {
    1042                chartType = nval( getRequestParameter( cType ) , null );
    1043
    1044                // 8.0.0.0 (2021/08/31) 互換性の関係で、少し残す。
    1045                if( "horizontalBar".equalsIgnoreCase( chartType ) ) {
    1046                        indexAxis = "y";
    1047                        chartType = CTYPE_BAR ;
    1048        // いちいち表示がうるさいので、ﾒｯｾｰｼﾞを出すのを当面やめておきます。
    1049        //              final String errMsg = "chartTypeのhorizontalBarは廃止されました。代わりに、indexAxis='y'を指定してください。" ;
    1050        //              System.err.println( errMsg );
    1051                        return ;
    1052                }
    1053
    1054                if( !check( chartType, CTYPE_SET ) ) {
    1055                        final StringBuilder errMsg = new StringBuilder( BUFFER_MIDDLE )
    1056                                .append( "指定のチャートタイプは実行できません。"        ).append( CR )
    1057                                .append( "chartType=[" ).append( chartType ).append( ']' ).append( CR )
    1058                                .append( CTYPE_SET );   // org.opengion.fukurou.util.ArraySet の toStringメソッド
    1059                        throw new HybsSystemException( errMsg.toString() );
    1060                }
    1061        }
    1062
    1063        /**
    1064         * 【TAG】ﾗﾍﾞﾙのｶﾗﾑ名を指定します(表示名称）(必須)。
    1065         *
    1066         * @og.tag
    1067         * 表示名称に使用するﾃﾞｰﾀﾍﾞｰｽの検索時のカラムを指定します。
    1068         *
    1069         * @param lblclm ﾗﾍﾞﾙｶﾗﾑ
    1070         */
    1071        public void setLabelColumn( final String lblclm ) {
    1072                labelColumn = nval( getRequestParameter( lblclm ),labelColumn );
    1073        }
    1074
    1075        /**
    1076         * 【TAG】canvasﾀｸﾞのidを指定します(初期値:hybscanvas)。
    1077         *
    1078         * @og.tag
    1079         * canvasﾀｸﾞのidに設定します。
    1080         *
    1081         * @param id canvasﾀｸﾞのid
    1082         */
    1083        @Override
    1084        public void setId( final String id ) {
    1085                this.id = nval( getRequestParameter( id ),this.id );
    1086        }
    1087
    1088        /**
    1089         * 【TAG】ﾁｬｰﾄの高さを指定します(初期値:400px)。
    1090         *
    1091         * @og.tag
    1092         * canvasﾀｸﾞの高さに設定します。
    1093         *
    1094         * @param hei 設定する高さ
    1095         */
    1096        public void setHeight( final String hei ) {
    1097                height = nval( getRequestParameter( hei ),height );
    1098        }
    1099
    1100        /**
    1101         * 【TAG】ﾁｬｰﾄの幅を指定します(初期値:400px)。
    1102         *
    1103         * @og.tag
    1104         * canvasﾀｸﾞの横幅を設定します。
    1105         *
    1106         * @param wid 設定する横幅
    1107         */
    1108        public void setWidth( final String wid ) {
    1109                width = nval( getRequestParameter( wid ),width );
    1110        }
    1111
    1112        /**
    1113         * 【TAG】プラグイン定義された関数を指定します。
    1114         *
    1115         * @og.tag
    1116         * コンフィグ属性の type 定義です。
    1117         *
    1118         * プラグインは、plugins: [pinFunc], 形式で追加されます。
    1119         * この属性での指定時は、[]は、不要で、CSV形式の関数名を並べます。
    1120         * 外部に、const pinFunc = { afterDatasetsDraw: function(chart, options) { ･･･ } };
    1121         * 形式のプラグインを指定することで、個別に読ませることが可能です。
    1122         * なお、すべてのチャートに、同一のプラグインを指定する場合は、この属性ではなく、
    1123         * Chart.plugins.register({ afterDatasetsDraw: function(chart, options) { ･･･ } });
    1124         * 形式で、プラグイン登録
    1125         *
    1126         * ※ options:plugins: 属性とは異なります。
    1127         *
    1128         * @og.rev 6.9.9.2 (2018/09/18) プラグイン定義された関数を指定します。
    1129         *
    1130         * @param attri 追加属性の値
    1131         */
    1132        public void setPlugins( final String attri ) {
    1133                plugins = nval( getRequestParameter( attri ),plugins );
    1134        }
    1135
    1136        // =================================================================================
    1137
    1138        /**
    1139         * 【TAG】"y" を指定することで、horizontalBar や verticalLine を実現する。
    1140         *
    1141         * @og.tag
    1142         * options: 以下の属性
    1143         *  horizontalBar が廃止され、同様の機能は、indexAxis="y" 指定で実現できます。
    1144         *  verticalLine 相当の表示も indexAxis="y" 指定で実現します。
    1145         *
    1146         * @og.rev 8.0.0.0 (2021/08/31) horizontalBar 廃止 → indexAxis="y" 指定
    1147         *
    1148         * @param indx 軸の方向('x','y')
    1149         */
    1150        public void setIndexAxis( final String indx ) {
    1151                indexAxis = nval( getRequestParameter( indx ),null );
    1152        }
    1153
    1154        /**
    1155         * 【TAG】棒線の横幅を指定します(初期値:0.8, typeがbarの場合に有効)。
    1156         *
    1157         * @og.tag
    1158         * options: 以下の属性
    1159         *  options:xAxes:categoryPercentage → option:categoryPercentage の 要素の属性です。
    1160         *
    1161         * ※ 階層変更による対応のため、chartType による属性の出力制御は廃止しました。
    1162         *
    1163         * @og.rev 6.9.9.3 (2018/09/25) nvalを入れて、初期値を設定します。
    1164         *
    1165         * @param widthPer 棒線の横幅
    1166         */
    1167        public void setBarWidthPer( final String widthPer ) {
    1168                barWidthPer = nval( getRequestParameter( widthPer ),barWidthPer );
    1169        }
    1170
    1171        /**
    1172         * 【TAG】簡易的にアニメーションのON/OFFを設定(true/false)します(初期値::null=true)(options:animation)。
    1173         *
    1174         * @og.tag
    1175         * options: 以下の属性
    1176         *  options:animation の 要素の属性です。
    1177         *
    1178         * ※ 簡易的に、false を指定すると、アニメーションが OFF になります。
    1179         *    各種属性が登録できるように、文字列を自由に登録できます。
    1180         *
    1181         * @og.rev 8.0.0.0 (2021/08/31) optionAttributesで設定していた項目を属性追加
    1182         *
    1183         * @param flag アニメーションのON/OFFを設定(true/false)
    1184         */
    1185        public void setAnimation( final String flag ) {
    1186                animation = nval( getRequestParameter( flag ), animation );
    1187        }
    1188
    1189        /**
    1190         * 【TAG】ﾁｬｰﾄｸﾘｯｸ時のｲﾍﾞﾝﾄを指定します。
    1191         *
    1192         * @og.tag
    1193         * options: 以下の属性
    1194         * 下記の値が引数として渡されます。
    1195         * " onClick:function(event,obj){" +  onClick + '}'
    1196         * に変換されてセットされます。
    1197         *   event:ｲﾍﾞﾝﾄ情報
    1198         *   obj:ｸﾘｯｸされたｵﾌﾞｼﾞｪｸﾄの情報
    1199         *
    1200         * 例)
    1201         *   onClick="clickLink( event,obj,'result_sample2.jsp?command=RENEW&amp;CLM={CLM}&amp;VAL={VAL}&amp;IDX={IDX}' );"
    1202         *   onClick="updatechart(obj,'SubChart');"
    1203         *   onClick="clickLink( event, obj,'index.jsp?chartTitle={LBL}&amp;markValues={CLM}' , parent );"
    1204         *
    1205         * 基本的には、外部関数を呼び出す設定を行い、実際の動作は外部関数側で行います。
    1206         *
    1207         * @param click チャートクリック時のイベントを指定
    1208         */
    1209        public void setOnClick( final String click ) {
    1210                onClick = nval( getRequestParameter( click ),null );
    1211        }
    1212
    1213        // =================================================================================
    1214
    1215        /**
    1216         * 【TAG】ﾀｲﾄﾙ、またはﾀｲﾄﾙ要素を指定します。
    1217         *
    1218         * @og.tag
    1219         * options:title:text → options:plugins:title:text の 要素の属性です。
    1220         * "タイトル" または "{display:true,text:'ﾀｲﾄﾙ',color:'blue',font:{size:15},}" 形式で指定します。
    1221         * options:plugins:titleの属性に、その他ｵﾌﾟｼｮﾝを追加するのと同じ動きになります。
    1222         * 判定方法は、先頭に 『{』が存在するかどうかです。
    1223         * タイトルに配列を渡すと、改行表示します。
    1224         * ['タイトル','改行','するのか？'] の形式なので、先頭に 『[』が存在するか判定します。
    1225         *
    1226         * <pre>
    1227         *   display:true/false,   初期値:false
    1228         *   text   :チャートタイトル(string |,string[])
    1229         *   color  :タイトルの色
    1230         *   font   :{ family:フォント,size:サイズ,style:スタイル,weight:太さ,lineHeight:1行の高さ }
    1231         *   padding:パディング
    1232         *   align  :表示位置。'start'(開始側), 'center'(中央), 'end'(終了側)のいずれか。デフォルトは 'center'
    1233         *   position:表示位置。'top'(上部), 'left'(左側), 'bottom'(下部), 'right'(右側)のいずれか。デフォルトは 'top'
    1234         *   fullSize:フルサイズで表示するか否か。デフォルトは true
    1235         *
    1236         * </pre>
    1237         *
    1238         * @og.rev 6.9.9.3 (2018/09/25) nvalを入れて、初期値を設定します。
    1239         * @og.rev 8.0.0.0 (2021/09/30) タイトル要素も指定できるように変更
    1240         *
    1241         * @param title ﾀｲﾄﾙ
    1242         */
    1243        public void setTitle( final String title ) {
    1244                this.title = nval( getRequestParameter( title ),this.title );
    1245        }
    1246
    1247        /**
    1248         * 【TAG】ﾀｲﾄﾙの表示位置[top/right/bottom/left]を指定します(初期値:top)。
    1249         *
    1250         * @og.tag
    1251         *  options:title:position → options:plugins:title:position の 要素の属性です。
    1252         * title 属性に、ﾀｲﾄﾙ要素({…}書式)を設定した場合は、positionは無効です。
    1253         *
    1254         * <a href="https://www.tohoho-web.com/ex/chartjs-params.html#title">とほほ → チャートタイトル </a>
    1255         *
    1256         * @og.rev 6.9.9.3 (2018/09/25) nvalを入れて、初期値を設定します。
    1257         *
    1258         * @param position ﾀｲﾄﾙの表示位置 [top/right/bottom/left]
    1259         */
    1260        public void setTitlePosition( final String position ) {
    1261                titlePosition = nval( getRequestParameter( position ),titlePosition );
    1262
    1263                checkPara( titlePosition, SET_POSITION, "titlePosition" );
    1264        }
    1265
    1266        /**
    1267         * 【TAG】凡例を表示するか[true/false]を指定します。
    1268         *
    1269         * @og.tag
    1270         * options:legend:display → options:plugins:legend:display の 要素の属性です。
    1271         *
    1272         * @og.rev 6.9.9.3 (2018/09/25) nvalを入れて、初期値を設定します。
    1273         *
    1274         * @param display 凡例を表示するか [true/false]
    1275         */
    1276        public void setLegendDisplay( final String display ) {
    1277                legendDisplay = nval( getRequestParameter( display ),legendDisplay );
    1278
    1279                if( legendDisplay != null ) {
    1280                        checkPara( legendDisplay, SET_BOOLEAN, "legendDisplay" );
    1281                        useLegend = true;
    1282                }
    1283        }
    1284
    1285        /**
    1286         * 【TAG】凡例の表示位置[top/right/bottom/left]を指定します(初期値:top)。
    1287         *
    1288         * @og.tag
    1289         *  options:legend:position → options:plugins:legend:position の 要素の属性です。
    1290         *
    1291         * @og.rev 6.9.9.3 (2018/09/25) nvalを入れて、初期値を設定します。
    1292         *
    1293         * @param position 凡例の表示位置 [top/right/bottom/left]
    1294         */
    1295        public void setLegendPosition( final String position ) {
    1296                legendPosition = nval( getRequestParameter( position ),legendPosition );
    1297
    1298                if( legendPosition != null ) {
    1299                        checkPara( legendPosition, SET_POSITION, "legendPosition" );
    1300                        useLegend = true;
    1301                }
    1302        }
    1303
    1304        /**
    1305         * 【TAG】凡例のスタイル属性を使用するかどうか[true/false]を指定します(初期値:false)。
    1306         *
    1307         * @og.tag
    1308         * 凡例のスタイルを、jsChartDataタグのpointStyle属性で指定した形状に変更します。
    1309         * 複数データの場合、片方だけ指定したい場合は、usePointStyle="true" にしておき、
    1310         * 指定したいほうだけ、jsChartDataタグ側で、pointStyle属性を設定してください。
    1311         * <del>options:legend:labels属性のusePointStyle です。</del>
    1312         * options:legend:labels:usePointStyle → options:plugins:legend:labels:usePointStyle の 要素の属性です。
    1313         *
    1314         * @og.rev 6.8.5.0 (2018/01/09) 新規登録
    1315         *
    1316         * @param usePstyle 凡例のスタイル属性を使用するかどうか [true:使用する/false:使用しない]
    1317         */
    1318        public void setUsePointStyle( final String usePstyle ) {
    1319                final String useStyle = nval( getRequestParameter( usePstyle ),null );
    1320
    1321                if( useStyle != null ) {
    1322                        usePointStyle = Boolean.parseBoolean( useStyle );
    1323                        useLegend = true;               // パラメータの設定が行われた場合のみ、設定します。
    1324                }
    1325        }
    1326
    1327        //========================================================================================
    1328
    1329        /**
    1330         * 【TAG】x軸のｽｹｰﾙﾀｲﾌﾟ[category/linear/time]を指定します(初期値:category)。
    1331         *
    1332         * @og.tag
    1333         *  8.0.0.0 (2021/08/31)
    1334         *  chartTypeが、bubbleとscatterの場合は、xscaleType は、初期値:category に
    1335         *  しておいてください。内部で、x: y: r: 等のﾃﾞｰﾀの割り当てを行います。
    1336         * options:scales:xAxes:type → options:scales:x:type の 要素の属性です。
    1337         *
    1338         * @og.rev 6.9.9.3 (2018/09/25) nvalを入れて、初期値を設定します。
    1339         * @og.rev 7.0.1.1 (2018/10/22) JsChartDataV3ｵﾌﾞｼﾞｪｸﾄを使用。
    1340         *
    1341         * @param xscaleType x軸のｽｹｰﾙﾀｲﾌﾟ [category/linear/time]
    1342         */
    1343        public void setXscaleType( final String xscaleType ) {
    1344                this.xscaleType = nval( getRequestParameter( xscaleType ) , this.xscaleType );
    1345
    1346                // プラグインなどで独自の type を指定することがあるため、警告だけにします。
    1347                try {
    1348                        checkPara( this.xscaleType, SET_XSCALE, "xscaleType" );
    1349                }
    1350                catch( final HybsSystemException ex ) {
    1351                        System.err.println( ex.getMessage() );
    1352                }
    1353
    1354                jsXAxis.addAxis( "type" , this.xscaleType , USE_QUOTE );                // 文字
    1355        }
    1356
    1357        /**
    1358         * 【TAG】x軸の表示位置[top/right/bottom/left]を指定します(初期値:bottom)。
    1359         *
    1360         * @og.tag
    1361         * <del>horizontalBar を指定した場合は、left になります。</del>
    1362         * 8.0.0.0 (2021/08/31) horizontalBar は廃止
    1363         * 初期値(null)は、下(bottom)に表示されます。
    1364         * <del>options:scales:xAxes の 要素の属性です。</del>
    1365         * options:scales:xAxes:position → options:scales:x:position の 要素の属性です。
    1366         *
    1367         * @og.rev 7.0.1.2 (2018/11/04) 新規登録
    1368         *
    1369         * @param pos x軸の表示位置 [top/right/bottom/left]
    1370         */
    1371        public void setXposition( final String pos ) {
    1372                xposition = nval( getRequestParameter( pos ),null );
    1373
    1374                checkPara( xposition, SET_POSITION, "position" );
    1375        }
    1376
    1377        /**
    1378         * 【TAG】x軸の最大値を指定します(xscaleTypeがlinearの場合に有効)。
    1379         *
    1380         * @og.tag
    1381         *  options:scales:xAxes:ticks:max → options:scales:x:max の 要素の属性です。
    1382         *
    1383         * @og.rev 6.9.9.3 (2018/09/25) nvalを入れて、初期値を設定します。
    1384         * @og.rev 7.0.1.1 (2018/10/22) JsChartDataV3ｵﾌﾞｼﾞｪｸﾄを使用。
    1385         *
    1386         * @param xmax x軸の最大値
    1387         */
    1388        public void setXmax( final String xmax ) {
    1389                jsXAxis.addAxis( "max" , nval( getRequestParameter( xmax ),null ) , NO_QUOTE );         // 数値
    1390        }
    1391
    1392        /**
    1393         * 【TAG】x軸の最小値を指定します(xscaleTypeがlinearの場合に有効)。
    1394         *
    1395         * @og.tag
    1396         *  options:scales:xAxes:ticks:min → options:scales:x:min の 要素の属性です。
    1397         *
    1398         * @og.rev 6.9.9.3 (2018/09/25) nvalを入れて、初期値を設定します。
    1399         * @og.rev 7.0.1.1 (2018/10/22) JsChartDataV3ｵﾌﾞｼﾞｪｸﾄを使用。
    1400         *
    1401         * @param xmin x軸の最小値
    1402         */
    1403        public void setXmin( final String xmin ) {
    1404                jsXAxis.addAxis( "min" , nval( getRequestParameter( xmin ),null ) , NO_QUOTE );         // 数値
    1405        }
    1406
    1407        /**
    1408         * 【TAG】x軸のラベルを指定します。
    1409         *
    1410         * @og.tag
    1411         *  options:scales:xAxes:scaleLabel:labelString → options:scales:x:title:text の 要素の属性です。
    1412         *
    1413         * @og.rev 6.9.9.3 (2018/09/25) nvalを入れて、初期値を設定します。
    1414         * @og.rev 7.0.1.1 (2018/10/22) JsChartDataV3ｵﾌﾞｼﾞｪｸﾄを使用。
    1415         *
    1416         * @param xlabel x軸のラベル
    1417         */
    1418        public void setXlabel( final String xlabel ) {
    1419                final String lbl = nval( getRequestParameter( xlabel ),null );
    1420                if( lbl != null ) {
    1421                        final String scLbl = "display:true,text:'" + lbl + "'" ;                // ラストの ',' は、addAxis 側で付ける。
    1422                        jsXAxis.addAxis( JsChartDataV3.TITLE , scLbl );
    1423                }
    1424        }
    1425
    1426        /**
    1427         * 【TAG】x軸ｺｰﾙﾊﾞｯｸを指定します。
    1428         *
    1429         * @og.tag
    1430         * x軸のメモリ編集用スケールバックを設定します。
    1431         *  options:scales:xAxes:ticks:callback → options:scales:x:ticks:callback の 要素の属性です。
    1432         *  callback:function(value,index,[tick objects]) {
    1433         *    return '$' + value;
    1434         *  }
    1435         *
    1436         * @og.rev 6.9.9.3 (2018/09/25) nvalを入れて、初期値を設定します。
    1437         * @og.rev 7.0.1.1 (2018/10/22) JsChartDataV3ｵﾌﾞｼﾞｪｸﾄを使用。
    1438         *
    1439         * @param callback x軸ｺｰﾙﾊﾞｯｸ
    1440         */
    1441        public void setXscaleCallback( final String callback ) {
    1442                jsXAxis.addTicks( "callback" , nval( getRequestParameter( callback ),null ) , NO_QUOTE );       // ファンクションは、クオートしない
    1443        }
    1444
    1445        /**
    1446         * 【TAG】x軸を０から書き始まるかどうか(xscaleTypeがlinearの場合に有効)(初期値:null)。
    1447         *
    1448         * @og.tag
    1449         * options:scales:xAxes:ticks:beginAtZero → options:scales:x:beginAtZero の 要素の属性です。
    1450         *
    1451         * @og.rev 6.8.5.0 (2018/01/09) 新規登録
    1452         * @og.rev 7.0.1.1 (2018/10/22) JsChartDataV3ｵﾌﾞｼﾞｪｸﾄを使用。
    1453         *
    1454         * @param xZero x軸のゼロ開始
    1455         */
    1456        public void setXbeginAtZero( final String xZero ) {
    1457                final String beginAtZero =  nval( getRequestParameter( xZero ),null );
    1458                checkPara( beginAtZero, SET_BOOLEAN, "xbeginAtZero" );
    1459                jsXAxis.addAxis( "beginAtZero" , beginAtZero , NO_QUOTE );              // 数値(boolean)
    1460        }
    1461
    1462        /**
    1463         * 【TAG】x軸のメモリ幅を指定します(xscaleTypeがlinearの場合に有効)。
    1464         *
    1465         * @og.tag
    1466         *  options:scales:xAxes:ticks:stepSize → options:scales:x:ticks:stepSize の 要素の属性です。
    1467         *
    1468         * @og.rev 6.9.9.3 (2018/09/25) nvalを入れて、初期値を設定します。
    1469         * @og.rev 7.0.1.1 (2018/10/22) JsChartDataV3ｵﾌﾞｼﾞｪｸﾄを使用。
    1470         *
    1471         * @param xstepSize x軸のメモリ幅
    1472         */
    1473        public void setXstepSize( final String xstepSize ) {
    1474                jsXAxis.addTicks( "stepSize" , nval( getRequestParameter( xstepSize ),null ) , NO_QUOTE );              // 数値
    1475        }
    1476
    1477        /**
    1478         * 【TAG】optionsの属性に、その他ｵﾌﾟｼｮﾝを追加します。
    1479         *
    1480         * @og.tag
    1481         * optionsの属性に、その他ｵﾌﾟｼｮﾝを追加します。
    1482         * 指定する際の、前後の『{}』は、不要です。
    1483         *
    1484         * <a href="https://www.tohoho-web.com/ex/chartjs-params.html#options">とほほ → オプション </a>
    1485         *
    1486         * @og.rev 7.0.1.2 (2018/11/04) 属性名変更
    1487         *
    1488         * @param attri オプションの値
    1489         */
    1490        public void setOptOptions( final String attri ) {
    1491                optOptions = nval( getRequestParameter( attri ),null );
    1492        }
    1493
    1494        /**
    1495         * 【TAG】options:pluginsの要素に、その他ｵﾌﾟｼｮﾝを追加します。
    1496         *
    1497         * @og.tag
    1498         * options:pluginsの要素に、その他ｵﾌﾟｼｮﾝを追加します
    1499         * 指定する際の、前後の『{}』は、不要です。
    1500         * plugins には、legend(凡例),title(ﾀｲﾄﾙ),tooltip(ﾂｰﾙﾁｯﾌﾟ),decimation(間引き),filler(塗りつぶし)
    1501         * の属性を指定できるが、元々のこれらを単独で設定できる属性も持っており、
    1502         * データ的にはマージされますが、同じキーを指定した場合にどのような動きになるかは保証できません。
    1503         *
    1504         * <a href="https://www.tohoho-web.com/ex/chartjs-params.html#plugins">とほほ → プラグイン </a>
    1505         *
    1506         * @og.rev 8.0.0.0 (2021/09/30) 新規追加
    1507         *
    1508         * @param attri plugins要素
    1509         */
    1510        public void setOptPlugins( final String attri ) {
    1511                optPlugins = nval( getRequestParameter( attri ),null );
    1512        }
    1513
    1514        /**
    1515         * 【TAG】options:plugins:tooltipの要素に、その他ｵﾌﾟｼｮﾝを追加します。
    1516         *
    1517         * @og.tag
    1518         * options:plugins:tooltipの属性に、その他ｵﾌﾟｼｮﾝを追加します
    1519         * 指定する際の、前後の『{}』は、不要です。
    1520         * tooltip には、多数の要素が設定可能なので、外部で定義したｵﾌﾞｼﾞｪｸﾄを
    1521         * 指定するのが良いと思います。
    1522         *
    1523         * <a href="https://www.tohoho-web.com/ex/chartjs-params.html#tooltip">とほほ → ツールチップ </a>
    1524         *
    1525         * @og.rev 8.0.0.0 (2021/09/30) 新規追加
    1526         *
    1527         * @param attri tooltip要素
    1528         */
    1529        public void setOptTooltip( final String attri ) {
    1530                optTooltip = nval( getRequestParameter( attri ),null );
    1531        }
    1532
    1533        /**
    1534         * 【TAG】options:plugins:legendの要素に、その他ｵﾌﾟｼｮﾝを追加します。
    1535         *
    1536         * @og.tag
    1537         * options:plugins:legendの属性に、その他ｵﾌﾟｼｮﾝを追加します
    1538         * 指定する際の、前後の『{}』は、不要です。
    1539         * legend には、多数の要素が設定可能なので、外部で定義したｵﾌﾞｼﾞｪｸﾄを
    1540         * 指定するのが良いと思います。
    1541         *
    1542         * legend 関係の属性として、legendDisplay、legendPosition、usePointStyle を定義しています。
    1543         * optLegend属性を設定した場合、これらの属性とマージされるため、同じキーワードが存在した場合の
    1544         * 動作は、不明です。
    1545         *
    1546         * <a href="https://www.tohoho-web.com/ex/chartjs-params.html#legend">とほほ → 凡例(レジェンド) </a>
    1547         *
    1548         * @og.rev 8.0.0.0 (2021/09/30) 新規追加
    1549         *
    1550         * @param attri legend要素
    1551         */
    1552        public void setOptLegend( final String attri ) {
    1553                optLegend = nval( getRequestParameter( attri ),null );
    1554                if( optLegend != null ) {
    1555                        useLegend = true;
    1556                }
    1557        }
    1558
    1559        /**
    1560         * 【TAG】その他options:scales:xのｵﾌﾟｼｮﾝを追加します。
    1561         *
    1562         * @og.tag
    1563         * <del>options:scales:xAxes の 要素の属性です。</del>
    1564         * options:scales:xAxes → options:scales:x の 要素の属性です。
    1565         *  ※ chartJS上は、Axes(axisの複数形)と、Axis を使い分けていますが、属性は、axis で統一します。
    1566         *
    1567         * @og.rev 7.0.1.2 (2018/11/04) 属性の追加。
    1568         *
    1569         * @param attri その他options:scales:xAxesのｵﾌﾟｼｮﾝ
    1570         */
    1571        public void setOptAxis( final String attri ) {
    1572                jsXAxis.addAxis( JsChartDataV3.AXIS , nval( getRequestParameter( attri ),null ) );
    1573        }
    1574
    1575        /**
    1576         * 【TAG】その他options:scales:x:ticksのｵﾌﾟｼｮﾝを追加します。
    1577         *
    1578         * @og.tag
    1579         * <del>options:scales:xAxes:ticks の 要素の属性です。</del>
    1580         * options:scales:xAxes:ticks → options:scales:x:ticks の 要素の属性です。
    1581         *
    1582         * @og.rev 7.0.1.2 (2018/11/04) 属性の追加。
    1583         *
    1584         * @param attri その他options:scales:xAxes:ticksのｵﾌﾟｼｮﾝ
    1585         */
    1586        public void setOptTicks( final String attri ) {
    1587                jsXAxis.addAxis( JsChartDataV3.TICKS , nval( getRequestParameter( attri ),null ) );
    1588        }
    1589
    1590        /**
    1591         * 【TAG】その他options:scales:x:titleのｵﾌﾟｼｮﾝを追加します。
    1592         *
    1593         * @og.tag
    1594         * <del>options:scales:xAxes:scaleLabel の 要素の属性です。</del>
    1595         * options:scales:xAxes:scaleLabel → options:scales:x:title の 要素の属性です。
    1596         *
    1597         * @og.rev 7.0.1.2 (2018/11/04) 属性の追加。
    1598         *
    1599         * @param title options:scales:x:title要素
    1600         */
    1601        public void setOptTitle( final String title ) {
    1602                jsXAxis.addAxis( JsChartDataV3.TITLE , nval( getRequestParameter( title ),null ) );
    1603        }
    1604
    1605        /**
    1606         * 【TAG】その他options:scales:x:gridのｵﾌﾟｼｮﾝを追加します。
    1607         *
    1608         * @og.tag
    1609         * <del>options:scales:xAxes:gridLines の 要素の属性です。</del>
    1610         *  options:scales:xAxes:gridLines → options:scales:x:grid の 要素の属性です。
    1611         *
    1612         * @og.rev 7.0.1.2 (2018/11/04) 属性の追加。
    1613         *
    1614         * @param grid options:scales:x:gridの属性
    1615         */
    1616        public void setOptGrid( final String grid ) {
    1617                jsXAxis.addAxis( JsChartDataV3.GRID , nval( getRequestParameter( grid ),null ) );
    1618        }
    1619
    1620        /**
    1621         * 【TAG】x軸のﾀｲﾑの単位[year/quarter/month/week/day/hour/minute/second/millisecond]を指定します。
    1622         *
    1623         * @og.tag
    1624         * (xscaleTypeがtimeの場合に有効。指定しない場合は自動)
    1625         * options:scales:x:unit
    1626         *
    1627         * @og.rev 6.9.9.3 (2018/09/25) xscaleType の time 属性廃止。
    1628         * @og.rev 6.9.9.4 (2018/10/01) nvalを入れて、属性復活。
    1629         * @og.rev 7.0.1.1 (2018/10/22) JsChartDataV3ｵﾌﾞｼﾞｪｸﾄを使用。
    1630         *
    1631         * @param tunit x軸のﾀｲﾑの単位 [year/quarter/month/week/day/hour/minute/second/millisecond]
    1632         */
    1633        public void setTimeUnit( final String tunit ) {
    1634                final String timeUnit = nval( getRequestParameter( tunit ),null );
    1635
    1636                checkPara( timeUnit, SET_TIMEUNIT, "timeUnit" );
    1637
    1638                jsXAxis.addTime( "unit" , timeUnit , USE_QUOTE );       // 文字列
    1639        }
    1640
    1641        /**
    1642         * 【TAG】x軸のﾀｲﾑの単位幅を指定します(xscaleTypeがtimeの場合に有効)。
    1643         *
    1644         * @og.tag
    1645         *  options:scales:x:time:unitStepSize → options:scales:x:time:stepSize の 要素の属性です。
    1646         *
    1647         * @og.rev 6.9.9.3 (2018/09/25) xscaleType の time 属性廃止。
    1648         * @og.rev 6.9.9.4 (2018/10/01) nvalを入れて、属性復活。
    1649         * @og.rev 7.0.1.1 (2018/10/22) JsChartDataV3ｵﾌﾞｼﾞｪｸﾄを使用。
    1650         *
    1651         * @param tunitStepSize x軸のﾀｲﾑの単位幅
    1652         */
    1653        public void setTimeUnitStepSize( final String tunitStepSize ) {
    1654                jsXAxis.addTime( "stepSize" , nval( getRequestParameter( tunitStepSize ),null ) , NO_QUOTE );   // 数値
    1655        }
    1656
    1657        /**
    1658         * 【TAG】x軸の設定するﾀｲﾑ(入力ﾃﾞｰﾀ)のﾌｫｰﾏｯﾄを指定します(xscaleTypeがtimeの場合に有効)。
    1659         *
    1660         * @og.tag
    1661         * ﾌｫｰﾏｯﾄは、chartjs-adapter-date-fns.bundle.min.js の定義を使用します。
    1662         * <a href="https://github.com/chartjs/chartjs-adapter-date-fns">chartjs-adapter-date-fns</a>
    1663         * <a href="https://zenn.dev/snjssk/articles/f05d1bcfeb9604#format">date-fns format</a>
    1664         * 例：yyyyMMddHHmmss
    1665         *
    1666         * 8.0.0.0 (2021/08/31)
    1667         *  代わりに、options:scales:x:time.parser で指定します。
    1668         *
    1669         * @og.rev 6.9.9.3 (2018/09/25) xscaleType の time 属性廃止。
    1670         * @og.rev 6.9.9.4 (2018/10/01) nvalを入れて、属性復活。
    1671         * @og.rev 7.0.1.1 (2018/10/22) JsChartDataV3ｵﾌﾞｼﾞｪｸﾄを使用。
    1672         * @og.rev 8.0.0.0 (2021/08/31) timeSetFormat → timeParser 変更
    1673         *
    1674         * @param tFormat x軸の設定するﾀｲﾑのﾌｫｰﾏｯﾄ処理
    1675         */
    1676        public void setTimeParser( final String tFormat ) {
    1677                jsXAxis.addTime( "parser" , nval( getRequestParameter( tFormat ),null ) , USE_QUOTE );  // 文字列
    1678        }
    1679
    1680        /**
    1681         * 【TAG】x軸の表示するﾀｲﾑのﾌｫｰﾏｯﾄを指定します(xscaleTypeがtimeの場合に有効)。
    1682         *
    1683         * @og.tag
    1684         * 8.0.0.0 (2021/08/31)
    1685         *   Moment.js の依存関係が切れ、openGionV8では、date-fns を使用します。
    1686         *  <a href="https://date-fns.org/v2.23.0/docs/format">date-fns format</a>
    1687         *  ※ yyyy が、YYYY になっているが、よく分からない。
    1688         *
    1689         * 基本形：yyyyMMddHHmmss
    1690         * options:scales:x:time:displayFormats
    1691         *
    1692         * <table class="plain">
    1693         *   <caption>ﾀｲﾑのﾌｫｰﾏｯﾄ(抜粋)</caption>
    1694         *       <tr><th>Pattern        </th><th>Result examples                                        </th><th>Unit                           </th></tr>
    1695         *       <tr><td>yyyy           </td><td>0044, 0001, 1900, 2017                         </td><td>Calendar year          </td></tr>
    1696         *       <tr><td>M                      </td><td>1, 2, ..., 12                                          </td><td>Month (formatting) </td></tr>
    1697         *       <tr><td>MM                     </td><td>01, 02, ..., 12                                        </td><td>Month (formatting) </td></tr>
    1698         *       <tr><td>MMM            </td><td>Jan, Feb, ..., Dec                                     </td><td>Month (formatting) </td></tr>
    1699         *       <tr><td>MMMM           </td><td>January, February, ..., December       </td><td>Month (formatting) </td></tr>
    1700         *       <tr><td>d                      </td><td>1, 2, ..., 31                                          </td><td>Day of month           </td></tr>
    1701         *       <tr><td>dd                     </td><td>01, 02, ..., 31                                        </td><td>Day of month           </td></tr>
    1702         *       <tr><td>H                      </td><td>0, 1, 2, ..., 23                                       </td><td>Hour [0-23]            </td></tr>
    1703         *       <tr><td>HH                     </td><td>00, 01, 02, ..., 23                            </td><td>                                       </td></tr>
    1704         *       <tr><td>m                      </td><td>0, 1, ..., 59                                          </td><td>Minute                         </td></tr>
    1705         *       <tr><td>mm                     </td><td>00, 01, ..., 59                                        </td><td>                                       </td></tr>
    1706         *       <tr><td>s                      </td><td>0, 1, ..., 59                                          </td><td>Second                         </td></tr>
    1707         *       <tr><td>ss                     </td><td>00, 01, ..., 59                                        </td><td>                                       </td></tr>
    1708         *       <tr><td>S                      </td><td>0, 1, ..., 9                                           </td><td>Fraction of second </td></tr>
    1709         *       <tr><td>SS                     </td><td>00, 01, ..., 99                                        </td><td>                                       </td></tr>
    1710         *       <tr><td>SSS            </td><td>000, 001, ..., 999                                     </td><td>                                       </td></tr>
    1711         * </table>
    1712         *
    1713         * timeLblFormatが指定されている場合、全てのdisplayFormatsにtimeLblFormatを設定する
    1714         *
    1715         * @og.rev 6.9.9.3 (2018/09/25) xscaleType の time 属性廃止。
    1716         * @og.rev 6.9.9.4 (2018/10/01) nvalを入れて、属性復活。
    1717         * @og.rev 7.0.1.1 (2018/10/22) JsChartDataV3ｵﾌﾞｼﾞｪｸﾄを使用。
    1718         *
    1719         * @param tLblFormat x軸の表示するﾀｲﾑのﾌｫｰﾏｯﾄ
    1720         * @see         #setTimeParser(String)
    1721         */
    1722        public void setTimeLblFormat( final String tLblFormat ) {
    1723                final String timeFmt = nval( getRequestParameter( tLblFormat ),null );
    1724                if( timeFmt != null ) {
    1725                        final StringBuilder buf = new StringBuilder( BUFFER_MIDDLE )
    1726                                        .append(  "{year:'"             ).append( timeFmt )
    1727                                        .append( "',quarter:'"  ).append( timeFmt )
    1728                                        .append( "',month:'"    ).append( timeFmt )
    1729                                        .append( "',week:'"             ).append( timeFmt )
    1730                                        .append( "',day:'"              ).append( timeFmt )
    1731                                        .append( "',hour:'"             ).append( timeFmt )
    1732                                        .append( "',minute:'"   ).append( timeFmt )
    1733                                        .append( "',second:'"   ).append( timeFmt )
    1734                                        .append( "'}" );
    1735
    1736                        jsXAxis.addTime( "displayFormats" , buf.toString() , NO_QUOTE );        // ｵﾌﾞｼﾞｪｸﾄなので、クオートなし
    1737                }
    1738        }
    1739
    1740        /**
    1741         * 【TAG】x軸の時間のﾂｰﾙﾁｯﾌﾟに使用するﾌｫｰﾏｯﾄ(ﾀｲﾑｽｹｰﾙ用)を指定します(xscaleTypeがtimeの場合に有効)。
    1742         *
    1743         * @og.tag
    1744         * 8.0.0.0 (2021/08/31)
    1745         *   Moment.js の依存関係が切れ、openGionV8では、date-fns を使用します。
    1746         *  <a href="https://date-fns.org/v2.23.0/docs/format">date-fns format</a>
    1747         *
    1748         * 基本形：yyyyMMddHHmmss
    1749         * options:scales:x:time:tooltipFormat
    1750         *
    1751         * ﾌｫｰﾏｯﾄは、timeLblFormat (内部的には、time:displayFormats)と同じ
    1752         *
    1753         * @og.rev 7.0.1.0 (2018/10/15) 時間のﾂｰﾙﾁｯﾌﾟに使用するﾌｫｰﾏｯﾄ(ﾀｲﾑｽｹｰﾙ用)
    1754         * @og.rev 7.0.1.1 (2018/10/22) JsChartDataV3ｵﾌﾞｼﾞｪｸﾄを使用。
    1755         *
    1756         * @param tipFormat x軸の表示するﾀｲﾑのﾌｫｰﾏｯﾄ
    1757         * @see         #setTimeParser(String)
    1758         */
    1759        public void setTooltipFormat( final String tipFormat ) {
    1760                jsXAxis.addTime( "tooltipFormat" , nval( getRequestParameter( tipFormat ),null ) , USE_QUOTE ); // 文字列
    1761        }
    1762
    1763        //========================================================================================
    1764
    1765        /**
    1766         * 【TAG】y軸に横マーカーラインの設定値をCSV形式で複数指定します。
    1767         *
    1768         * @og.tag
    1769         * X軸に平行に固定値の線を引きます。線の値を、CSV形式で指定します。
    1770         * annotation:annotations オプションに名前付きで設定した中に yMin,yMax を定義します。
    1771         * 以前は、value に値をセットしていましたが、,yMin:値,yMax:値 にセットします。
    1772         *
    1773         * 8.0.0.0 (2021/08/31)
    1774         *      chartjs-plugin-annotation を使用します。
    1775         *      配列ではなく、名前付きの設定になります。(下記の例では、ymark0:)
    1776         *  options::plugins:annotation:annotations:ymark0:{
    1777         *      type:'line',                    ← 固定です。
    1778         *      borderWidth:2,                  ← markWidthの値(ﾗｲﾝ共通 初期値="2")
    1779         *      borderDash:[5,2],               ← markDashの値(ﾗｲﾝ共通  初期値=null)
    1780         *      yMin:値,yMax:値,                ← markValuesの値
    1781         *      borderColor: '#FF0000',         ← markColorsの値
    1782         *      label:{
    1783         *          enabled:'true',position:'start',    ← 固定です。
    1784         *          backgroundColor:'rgba(0,0,0,0)',    ← 固定です。
    1785         *          font:{ size:10 },                   ← markFontSizeの値(ﾗｲﾝ共通  初期値=10)
    1786         *          content:'基準値',       ← markLblsの値
    1787         *          yAdjust:-6,             ← markAdjustの値
    1788         *          color:'#FF0000',        ← markColorsの値
    1789         *          … ,
    1790         *      },
    1791         *  },
    1792         *
    1793         * @og.rev 6.8.5.0 (2018/01/09) 新規登録
    1794         * @og.rev 8.0.0.0 (2021/08/31) chartJs V3 で大きく変更されています。
    1795         *
    1796         * @param mkVals y軸に横マーカーラインの設定値(CSV形式)
    1797         */
    1798        public void setMarkValues( final String mkVals ) {
    1799                markValues = nval( getRequestParameter( mkVals ) , markValues );
    1800        }
    1801
    1802        /**
    1803         * 【TAG】y軸に横マーカーラインの色をCSV形式で複数指定します。
    1804         *
    1805         * @og.tag
    1806         * annotation:annotations オプションに名前付きで設定した中に borderColor を定義します。
    1807         *
    1808         * X軸に平行に固定値の線を引きます。線の色を、CSV形式で指定します。
    1809         * markValues が指定されており、markColorsが指定されていない場合は、青色(BLUE)になります。
    1810         * 色指定に、VIVID,PASTEL を使えるようにします。
    1811         *
    1812         * 詳細は、markValues の説明をご確認願います。
    1813         *
    1814         * @og.rev 6.8.5.0 (2018/01/09) 新規登録
    1815         * @og.rev 7.0.1.3 (2018/11/12) 色指定に、VIVID,PASTEL を使えるようにします。
    1816         *
    1817         * @param mkCols y軸に横マーカーラインの色(CSV形式)
    1818         * @see #setMarkValues(String)
    1819         */
    1820        public void setMarkColors( final String mkCols ) {
    1821                markColors = nval( getRequestParameter( mkCols ) , markColors );
    1822        }
    1823
    1824        /**
    1825         * 【TAG】y軸に横マーカーラインのラベルをCSV形式で複数指定します。
    1826         *
    1827         * @og.tag
    1828         * annotation:annotations オプションに名前付きで設定した中に
    1829         * label:content を定義します。
    1830         *
    1831         * label 属性の enabled:'true',position:'start',backgroundColor:'rgba(0,0,0,0)',
    1832         * font:{ size:10 } は固定で、color は、markColors 属性で指定した
    1833         * y軸に横マーカーラインの色を使用します。
    1834         * 色指定に、VIVID,PASTEL を使えるようにします。
    1835         *
    1836         * 詳細は、markValues の説明をご確認願います。
    1837         *
    1838         * @og.rev 6.8.5.0 (2018/01/09) 新規登録
    1839         *
    1840         * @param mklbls y軸に横マーカーラインのラベル(CSV形式)
    1841         * @see #setMarkValues(String)
    1842         */
    1843        public void setMarkLbls( final String mklbls ) {
    1844                markLbls = nval( getRequestParameter( mklbls ) , markLbls );
    1845        }
    1846
    1847        /**
    1848         * 【TAG】y軸に横マーカーラインのラベル表示位置の上下方向を調整します(初期値:-6)。
    1849         *
    1850         * @og.tag
    1851         * annotation:annotations オプションに名前付きで設定した中に
    1852         * label:yAdjust を定義します。
    1853         *
    1854         * これは、ラインに対するラベルの位置を表します。＋で、下側、－で上側に表示します。
    1855         * 初期値は、－６ で、ラインの上側に来るように調整しています。
    1856         *
    1857         * 詳細は、markValues の説明をご確認願います。
    1858         *
    1859         * @og.rev 6.8.5.0 (2018/01/09) 新規登録
    1860         *
    1861         * @param mkAjst y軸に横マーカーラインのラベル表示位置の上下方向調整
    1862         * @see #setMarkValues(String)
    1863         */
    1864        public void setMarkAdjust( final String mkAjst ) {
    1865                markAdjust = nval( getRequestParameter( mkAjst ) , markAdjust );
    1866        }
    1867
    1868        /**
    1869         * 【TAG】x軸に横マーカーラインのラベルをCSV形式で複数指定します。
    1870         *
    1871         * @og.tag
    1872         * annotation:annotations オプションに名前付きで設定した中に
    1873         * label:content を定義します。
    1874         *
    1875         * label 属性の enabled:'true',position:'end',backgroundColor:'white',
    1876         * font:{ size:10 } は固定で、color は、markColors 属性で指定した
    1877         * x軸に横マーカーラインの色を使用します。
    1878         * 色指定に、VIVID,PASTEL を使えるようにします。
    1879         *
    1880         * 詳細は、xmarkValues の説明をご確認願います。
    1881         *
    1882         * @og.rev 8.0.0.0 (2021/09/30) 新規追加
    1883         *
    1884         * @param mklbls x軸に横マーカーラインのラベル(CSV形式)
    1885         * @see #setMarkValues(String)
    1886         */
    1887        public void setXmarkLbls( final String mklbls ) {
    1888                xmarkLbls = nval( getRequestParameter( mklbls ) , xmarkLbls );
    1889        }
    1890
    1891        /**
    1892         * 【TAG】x軸に縦マーカーラインの設定値をCSV形式で複数指定します。
    1893         *
    1894         * @og.tag
    1895         * annotation:annotations オプションに名前付きで設定した中に xMin,xMax を定義します。
    1896         *
    1897         * Y軸に平行に固定値の縦線を引きます。線の値を、CSV形式で指定します。
    1898         * 以前は、value に値をセットしていましたが、,xMin:値,xMax:値 にセットします。
    1899         *
    1900         * type:'line',borderWidth:2,scaleID:'x0Ax', 固定です。
    1901         *      chartjs-plugin-annotation を使用します。
    1902         *      配列ではなく、名前付きの設定になります。(下記の例では、xmark0:)
    1903         *
    1904         *  options:plugins:annotation:annotations:xmark0:{
    1905         *      type:'line',                    ← 固定です。
    1906         *      borderWidth:2,                  ← markWidthの値(ﾗｲﾝ共通 初期値="2")
    1907         *      borderDash:[5,2],               ← markDashの値(ﾗｲﾝ共通  初期値=null)
    1908         *      xMin:値,xMax:値,                ← xmarkValuesの値
    1909         *      borderColor:'#FF0000',          ← xmarkColorsの値
    1910         *  },
    1911         *
    1912         * @og.rev 7.0.1.1 (2018/10/22) xmarkValues,xmarkColors属性の追加
    1913         *
    1914         * @param mkVals x軸に縦マーカーラインの設定値(CSV形式)
    1915         * @see #setMarkValues(String)
    1916         */
    1917        public void setXmarkValues( final String mkVals ) {
    1918                xmarkValues = nval( getRequestParameter( mkVals ) , xmarkValues );
    1919        }
    1920
    1921        /**
    1922         * 【TAG】x軸に縦マーカーラインの色をCSV形式で複数指定します。
    1923         *
    1924         * @og.tag
    1925         * annotation:annotations オプションに名前付きで設定した中に borderColor を定義します。
    1926         *
    1927         * Y軸に平行に固定値の縦線を引きます。線の色を、CSV形式で指定します。
    1928         * xmarkValues が指定されており、xmarkColorsが指定されていない場合は、青色(BLUE)になります。
    1929         *
    1930         * @og.rev 7.0.1.1 (2018/10/22) xmarkValues,xmarkColors属性の追加
    1931         * @og.rev 7.0.1.3 (2018/11/12) 色指定に、VIVID,PASTEL を使えるようにします。
    1932         *
    1933         * @param mkCols x軸に縦マーカーラインの色(CSV形式)
    1934         * @see #setXmarkValues(String)
    1935         */
    1936        public void setXmarkColors( final String mkCols ) {
    1937                xmarkColors = nval( getRequestParameter( mkCols ) , xmarkColors );
    1938        }
    1939
    1940        /**
    1941         * 【TAG】x軸,y軸全マーカーライン共通のラインの幅を指定します:borderWidth(初期値:2)。
    1942         *
    1943         * @og.tag
    1944         * annotation:annotations オプションに名前付きで設定した中に borderWidth を定義します。
    1945         *
    1946         * この値は、x軸,y軸関係なく、マーカーラインの順番も関係なく、共通設定になります。
    1947         *
    1948         * @og.rev 7.0.1.1 (2018/10/22) markWidth,markDash,markFontSize属性の追加
    1949         *
    1950         * @param width マーカーライン共通のラインの幅
    1951         * @see #setMarkValues(String)
    1952         */
    1953        public void setMarkWidth( final String width ) {
    1954                markWidth = nval( getRequestParameter( width ) , markWidth );
    1955        }
    1956
    1957        /**
    1958         * 【TAG】x軸,y軸全マーカーライン共通のラインに点線を指定([5,2]など)します:borderDash(初期値:null)。
    1959         *
    1960         * @og.tag
    1961         * annotation:annotations オプションに名前付きで設定した中に borderDash を定義します。
    1962         *
    1963         * この値は、x軸,y軸関係なく、マーカーラインの順番も関係なく、共通設定になります。
    1964         * markDash="[5,2]" とすれば、線の長さが5px , 線と線の間が2px になります。
    1965         *
    1966         * @og.rev 7.0.1.1 (2018/10/22) markWidth,markDash,markFontSize属性の追加
    1967         *
    1968         * @param dash マーカーライン共通のラインの点線の形状
    1969         * @see #setMarkValues(String)
    1970         */
    1971        public void setMarkDash( final String dash ) {
    1972                markDash = nval( getRequestParameter( dash ) , markDash );
    1973        }
    1974
    1975        /**
    1976         * 【TAG】x軸,y軸全マーカーライン共通のラベルのフォントサイズを指定します:label:font:size(初期値:10)。
    1977         *
    1978         * @og.tag
    1979         * annotation:annotations オプションに名前付きで設定した中に
    1980         * label:font:size を定義します。
    1981         *
    1982         * この値は、x軸,y軸関係なく、マーカーラインの順番も関係なく、共通設定になります。
    1983         *
    1984         * @og.rev 7.0.1.1 (2018/10/22) markWidth,markDash,markFontSize属性の追加
    1985         *
    1986         * @param size マーカーライン共通のフォントサイズ
    1987         * @see #setMarkValues(String)
    1988         */
    1989        public void setMarkFontSize( final String size ) {
    1990                markFontSize = nval( getRequestParameter( size ) , markFontSize );
    1991        }
    1992
    1993        //========================================================================================
    1994
    1995        /**
    1996         * 【TAG】すべてのﾃﾞｰﾀが０の場合、使用しないかどうか[true:除外する/false:除外しない]を指定します(初期値:false)。
    1997         *
    1998         * @og.tag
    1999         * JSON データを作成して、JsChartV3に渡しますが、このフラグを true に設定すると
    2000         * 0 または、null（空文字列）のデータを出力しません。  6.8.3.0 (2017/11/27)
    2001         * グラフ系で、0 が、ありえない値として設定されている場合に、使用すると、
    2002         * 出力するデータ量を抑えることが出来ます。
    2003         *
    2004         * @og.rev 6.7.7.0 (2017/03/31) useZeroDataOmit属性の追加
    2005         *
    2006         * @param useZeroOmit ﾃﾞｰﾀが０の場合の使用可否 [true:除外する/false:除外しない]
    2007         */
    2008        public void setUseZeroDataOmit( final String useZeroOmit ) {
    2009                useZeroDataOmit = nval( getRequestParameter( useZeroOmit ) , useZeroDataOmit );
    2010        }
    2011
    2012        /**
    2013         * 【TAG】JSON出力で、値出力にレンデラを利用するかどうか[true/false]を指定します(初期値:false)。
    2014         *
    2015         * @og.tag
    2016         * JSONのデータのレンデラー変換を行うかどうか。
    2017         * 数値部分にはレンデラー変換は行いません。ラベル文字に行います。
    2018         * 指定しない場合は使用しない(false)です。
    2019         *
    2020         * @og.rev 6.7.9.0 (2017/04/28) useRenderer 追加
    2021         *
    2022         * @param       usernd レンデラーを利用するかどうか [true/false]
    2023         */
    2024        public void setUseRenderer( final String usernd ) {
    2025                useRenderer = nval( getRequestParameter( usernd ) , useRenderer );
    2026        }
    2027
    2028        /**
    2029         * 【TAG】検索結果をこのカラムでソートし直します(初期値:null)。
    2030         *
    2031         * @og.tag
    2032         * query で検索した結果を、JsChartV3で利用する場合、チャート上のソート順と、
    2033         * リストや、別のチャートでの表示準が異なる場合に、このカラムで、ソートしなおします。
    2034         * 通常は、labelColumn と同じ値でソートすることで、X軸の順番に表示されます。
    2035         *
    2036         * @og.rev 6.8.0.0 (2017/06/02) sortColumn 追加
    2037         *
    2038         * @param       sortClm このカラムでソートし直す
    2039         */
    2040        public void setSortColumn( final String sortClm ) {
    2041                sortColumn = nval( getRequestParameter( sortClm ) , sortColumn );
    2042        }
    2043
    2044        /**
    2045         * 【TAG】値の前後にクオートをはさむかどうか[true/false]指定します(初期値:false)。
    2046         *
    2047         * @og.tag
    2048         * 以前は、yscaleType="category" のときに、値が、文字列のため、クオートで囲う判断をしていました。
    2049         * その属性は、JsChartDataV3Tag に移ったため、新たなパラメータを用意します。
    2050         * 将来的に、自動判定にするか、JsChartDataV3Tag から情報を取得するかもしれません。
    2051         *
    2052         * @og.rev 7.0.1.1 (2018/10/22) 新規登録
    2053         *
    2054         * @param flag 値の前後にクオートをはさむかどうか [true/false]
    2055         */
    2056        public void setValueQuot( final String flag ) {
    2057                valueQuot = nval( getRequestParameter( flag ),valueQuot );
    2058        }
    2059
    2060        /**
    2061         * 【TAG】WheelZoom処理を使用するかどうか[true/false]を指定します(初期値:false)。
    2062         *
    2063         * @og.tag
    2064         * plugins:zoom に、zoom:{wheel,pinch} と pan を定義します。(chartJs V3 の変更点)
    2065         * これは、chartjs-plugin-zoom.js を使用します。
    2066         * マウスホイールで、zoom処理、右クリックで移動(pan)します。
    2067         * ダブルクリックで元の状態に戻します。
    2068         * useDragZoom と同時指定した場合は、useZoom が優先されます。
    2069         *
    2070         * 初期値は、false:使用しないです。
    2071         *
    2072         * <ul>
    2073         *   <li>zoom:{mode:'xy',wheel:{enabled:true,},pinch:{enabled:true,},},</li>
    2074         *   <li>pan:{mode:'xy',enabled:true,},</li>
    2075         *   <li>canvasをクリックでzoomリセット   </li>
    2076         * </ul>
    2077         *
    2078         *  options:plugins:zoom:{
    2079         *      zoom:{mode:'xy',wheel:{enabled:true,},pinch:{enabled:true,},},
    2080         *      pan:{mode:'xy',enabled:true,},
    2081         *  },
    2082         *
    2083         * @og.rev 6.8.5.0 (2018/01/09) 新規登録
    2084         *
    2085         * @param flag WheelZoom処理を使用するかどうか [true:使用する/false:使用しない]。
    2086         */
    2087        public void setUseZoom( final String flag ) {
    2088                useZoom = nval( getRequestParameter( flag ) , useZoom );
    2089        }
    2090
    2091        /**
    2092         * 【TAG】DragZoom処理を使用するかどうか[true/false]を指定します(初期値:false)。
    2093         *
    2094         * @og.tag
    2095         * plugins:zoom に zoom:{drag} と pan:{modifierKey: 'ctrl',} を定義します。(chartJs V3 の変更点)
    2096         * これは、chartjs-plugin-zoom.js を使用します。
    2097         * 右クリックで範囲指定で、zoom処理、CTRLボタンを押しながら、右クリックで移動(pan)します。
    2098         * ダブルクリックで元の状態に戻します。
    2099         * useDragZoom と同時指定した場合は、useZoom が優先されます。
    2100         *
    2101         * 初期値は、false:使用しないです。
    2102         *
    2103         * <ul>
    2104         *   <li>zoom:{drag:{enabled:true,borderColor:'rgb(54,162,235)',borderWidth:1,backgroundColor:'rgba(54,162,235,0.3)'},},</li>
    2105         *   <li>pan:{mode:'xy',enabled:true,modifierKey: 'ctrl',},</li>
    2106         *   <li>canvasをクリックでzoomリセット   </li>
    2107         * </ul>
    2108         *
    2109         *  options:plugins:zoom:{
    2110         *      zoom:{drag:{enabled:true,borderColor:'rgb(54,162,235)',borderWidth:1,backgroundColor:'rgba(54,162,235,0.3)'},},
    2111         *      pan:{mode:'xy',enabled:true,modifierKey: 'ctrl',},
    2112         *  },
    2113         *
    2114         * @og.rev 6.8.5.0 (2018/01/09) 新規登録
    2115         *
    2116         * @param flag DragZoom処理を使用するかどうか [true:使用する/false:使用しない]。
    2117         */
    2118        public void setUseDragZoom( final String flag ) {
    2119                useDragZoom = nval( getRequestParameter( flag ) , useDragZoom );
    2120        }
    2121
    2122        /**
    2123         * 【TAG】TableModelの指定のカラム(CSV形式)をconstの配列変数として出力します。
    2124         *
    2125         * @og.tag
    2126         * これは、指定のカラムのデータをJavaScriptのconst変数定義で配列として出力します。
    2127         * labelColumn や、JsChartDataV3Tag の chartColumn と同じ方法です。
    2128         *
    2129         * 例えば、TableModelを、sortColumn でソートすると、JsChartDataV3Tag の pointBGColor
    2130         * の配列順も変わりますので、ソートされた状態で出力したいことがあると思います。
    2131         *
    2132         * 8.0.0.0 (2021/08/31)
    2133         *  chartTypeが、bubble の場合、
    2134         *    x:は、jsChartData の chartColumn
    2135         *    y:は、varColumns で指定した1番目のカラム
    2136         *    r:は、varColumns で指定した2番目のカラム
    2137         *  scatter の場合は、y:の1番目のカラムのみ使用します。
    2138         *
    2139         * @og.rev 7.0.1.2 (2018/11/04) 新規登録
    2140         * @og.rev 8.0.0.0 (2021/08/31) BUBBLEとSCATTERの追加
    2141         *
    2142         * @param clms 指定のカラム(CSV形式)をconstの配列変数として出力
    2143         */
    2144        public void setVarColumns( final String clms ) {
    2145                varColumns = nval( getRequestParameter( clms ) , varColumns );
    2146        }
    2147
    2148//      /**
    2149//       * 【TAG】const定義するJavaScript変数に使用できるかどうか[true/false]指定します。
    2150//       *
    2151//       * @og.tag
    2152//       * const定義するJavaScript変数に使用できる文字は、決まっています。
    2153//       *
    2154//       * 1文字目は数字と、特殊記号(アンダーバー(_)、ドル記号($)を除く)、をチェックします。
    2155//       * 厳密には、予約文字が使えなかったりするが、簡易ﾁｪｯｸとする。
    2156//       * 前後の空白文字は除外、それ以外の特殊記号は、アンダーバー(_)に変換します。
    2157//       * 初期値[false]
    2158//       *
    2159//       * @og.rev 8.0.0.0 (2021/09/30) 新規登録
    2160//       *
    2161//       * @param flag JavaScript変数に使用できるかどうか[true/false]指定
    2162//       */
    2163//      public void setUseVarCheck( final String flag ) {
    2164//              useVarCheck = nval( getRequestParameter( flag ) , useVarCheck );
    2165//      }
    2166
    2167        //========================================================================================
    2168
    2169        /**
    2170         * 【TAG】(通常は使いません)sessionから所得する DBTableModelオブジェクトの ID。
    2171         *
    2172         * @og.tag
    2173         * (通常は使いません)sessionから所得する DBTableModelオブジェクトの ID。
    2174         *
    2175         * @og.rev 6.9.9.3 (2018/09/25) nvalを入れて、初期値を設定します。
    2176         *
    2177         * @param tableId テーブルID
    2178         */
    2179        public void setTableId( final String tableId ) {
    2180                this.tableId = nval( getRequestParameter( tableId ) , this.tableId );
    2181        }
    2182
    2183        /**
    2184         * このオブジェクトの文字列表現を返します。
    2185         * 基本的にデバッグ目的に使用します。
    2186         *
    2187         * @return このクラスの文字列表現
    2188         */
    2189        @Override
    2190        public String toString() {
    2191                final StringBuilder buf = new StringBuilder( BUFFER_MIDDLE )
    2192                                .append( "X_AXIS=" ).append( jsXAxis ).append( CR );
    2193
    2194                jsChartData.forEach( js -> buf.append( "Y_AXIS=" ).append( jsXAxis ).append( CR ) );
    2195
    2196                return ToString.title( this.getClass().getName() )
    2197                        .println( "VERSION"                             , VERSION                               )
    2198                        .println( "id"                                  , id                                    )
    2199                        .println( "tableId"                             , tableId                               )
    2200                        .println( "chartType"                   , chartType                             )
    2201                        .println( "width"                               , width                                 )
    2202                        .println( "height"                              , height                                )
    2203                        .println( "barWidthPer"                 , barWidthPer                   )
    2204                        .println( "title"                               , title                                 )
    2205                        .println( "titlePosition"               , titlePosition                 )
    2206                        .println( "legendPosition"              , legendPosition                )
    2207                        .println( "legendDisplay"               , legendDisplay                 )
    2208                        .println( "xscaleType"                  , xscaleType                    )
    2209                        .println( "optOptions"                  , optOptions                    )       // 7.0.1.2 (2018/11/04)
    2210//                      .println( "optChart"                    , optChart                              )       // 7.0.1.2 (2018/11/04)
    2211                        .fixForm().println()
    2212                        .println( buf ).toString();
    2213        }
    2214}