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