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