001package org.opengion.hayabusa.taglib; 002 003import java.util.ArrayList; 004import java.util.Arrays; 005import java.util.List; 006import java.util.concurrent.ConcurrentHashMap; 007import java.util.concurrent.ConcurrentMap; 008import java.util.regex.Matcher; 009import java.util.regex.Pattern; 010 011import org.opengion.hayabusa.common.HybsSystem; 012import org.opengion.hayabusa.common.HybsSystemException; 013import org.opengion.hayabusa.db.DBTableModel; 014import org.opengion.hayabusa.html.ViewForm; 015import org.opengion.hayabusa.html.ViewFormFactory; 016import org.opengion.hayabusa.html.ViewJsonParam; 017import org.opengion.hayabusa.io.JsChartData; 018import static org.opengion.fukurou.util.StringUtil.nval; 019 020/** 021 * JsChart は、JavascriptのjsChart用のスクリプトを出力するクラスです。 022 * 複数の JsChartData オブジェクトを合成することも、ここで行っています。 023 * ChartJSを利用しているため、標準属性以外の項目をセットする場合はoptionAttributesで行ってください。 024 * 例えばアニメーションをOFFにする場合はanimation:falseをセットします。 025 * 026 * 出力されるスクリプトでは、idを指定しない場合はhybscanvas[tableId]が利用されます。 027 * 複数のグラフを同一画面で出力する場合はidかtableIdを変えてください。 028 * チャートオブジェクトはchart_[id]という名前で作成されるため、ajax等でコントロールが必要な場合は利用してください。 029 * 030 * @og.formSample 031 * ●形式:<og:column chartType="…" ... /> 032 * ●body:あり(EVAL_BODY_BUFFERED:BODYを評価し、{$#064;XXXX} を解析します) 033 * 034 * ●Tag定義: 035 * <og:jsChart 036 * chartType ○【TAG】チャートの種類を指定します。(必須) 037 * id 【TAG】canvasタグのidを指定します。(初期値:hybscanvas) 038 * height 【TAG】チャートの高さを指定します。(初期値:400) 039 * width 【TAG】チャートの幅を指定します。(初期値:400) 040 * labelColumn 【TAG】ラベルのカラム名を指定します。(表示名称) 041 * title 【TAG】タイトルを指定します。 042 * titlePosition 【TAG】タイトルの表示位置[top/right/bottom/left]を指定します。(初期値:top) 043 * ylabel 【TAG】x軸のラベルを指定します。 044 * xlabel 【TAG】y軸のラベルを指定します。 045 * legendPosition 【TAG】凡例の表示位置[top/right/bottom/left]を指定します。(初期値:top) 046 * legendDisplay 【TAG】凡例を表示するか[true/false]を指定します。 047 * xscaleCallback 【TAG】x軸コールバックを指定します。 048 * yscaleCallback 【TAG】y軸コールバックを指定します。 049 * xscaleType 【TAG】x軸のスケールタイプ[category/time/linear]を指定します。(初期値:category) 050 * xscaleTimeType 【TAG】x軸の型[string/int]を指定します。xscaleTypeにtimeを指定した場合に利用します。(初期値:string) 051 * xmax 【TAG】x軸の最大値を指定します。(xscaleTypeがlinearの場合に有効) 052 * xmin 【TAG】x軸の最小値を指定します。(xscaleTypeがlinearの場合に有効) 053 * xstepSize 【TAG】x軸のメモリ幅を指定します。(xscaleTypeがlinearの場合に有効) 054 * timeUnit 【TAG】x軸のタイムの単位[year/quarter/month/week/day/hour/minute/second/millsecond]を指定します。(xscaleTypeがtimeの場合に有効。指定しない場合は自動) 055 * timeUnitStepSize 【TAG】x軸のタイムの単位幅を指定します。(xscaleTypeがtimeの場合に有効) 056 * timeSetFormat 【TAG】x軸の設定するタイムのフォーマットを指定します。(xscaleTypeがtimeの場合に有効) 057 * timeLblFormat 【TAG】x軸の表示するタイムのフォーマットを指定します。(xscaleTypeがtimeの場合に有効) 058 * timeMax 【TAG】x軸のタイムの最大値を指定します。(xscaleTypeがtimeの場合に有効) 059 * timeMin 【TAG】x軸のタイムの最小値を指定します。(xscaleTypeがtimeの場合に有効) 060 * yscaleType 【TAG】y軸のスケールタイプ[linear/category]を指定します。(初期値:linear) 061 * ycategoryList 【TAG】y軸のメモリリストをカンマ区切りで指定します。(xscaleTypeがlinearの場合に有効) 062 * max 【TAG】y軸の最大値を指定します。(xscaleTypeがlinearの場合に有効) 063 * min 【TAG】y軸の最小値を指定します。(xscaleTypeがlinearの場合に有効) 064 * stepSize 【TAG】y軸のメモリ幅を指定します。(xscaleTypeがlinearの場合に有効) 065 * barWidthPer 【TAG】棒線の横幅を指定します。(初期値:0.8, typeがbar,horizontalBarの場合に有効) 066 * onClick 【TAG】チャートクリック時のイベントを指定します。 067 * tableid 【TAG】(通常使いません)sessionから所得する DBTableModelオブジェクトの ID 068 * scope 【TAG】キャッシュする場合のスコープ[request/page/session/applicaton]を指定します(初期値:session) 069 * widthEventColumn 【TAG】横幅を動機に設定するカラムのIDを指定します。 070 * heightEventColumn 【TAG】縦幅を動的に設定するカラムのIDを指定します。 071 * minEventColumn 【TAG】minを動的に設定するカラムのIDを指定します。 072 * maxEventColumn 【TAG】maxを動的に設定するカラムのIDを指定します。 073 * optionAttributes 【TAG】その他オプションを指定します。 074 * > ... Body ... 075 * </og:jsChart> 076 * ●使用例 077 * <og:jsChart 078 * chartType = "bar" 079 * labelColumn = "LDATA" 080 * id = "canvasid" 081 * height = "500" 082 * width = "800" 083 * labelColumn = "LCLM" 084 * title = "タイトル" 085 * titlePosition = "bottom" 086 * ylabel = "給料" 087 * xlabel = "名称" 088 * legendPosition = "right" 089 * legendDisplay = "true" 090 * xsclaeCallback = "function(value){return value + ' 様';}" 091 * ysclaeCallback = "function(value){return value.toLocaleString();}" 092 * xscaleType = "time" 093 * max = "1000000" 094 * min = "100000" 095 * stepSize = "10000" 096 * barWidthPer = "0.4" 097 * > 098 * <og:jsChartData ... /> 099 * </og:jsChart> 100 * 101 * @og.group 画面表示 102 * 103 * @version 5.9.17.2 2017/02/08 104 * @og.rev 5.9.19.0 2017/04/07 T.OTA 61200-170316-02 チャートサイズ・max・minの動的変更対応 105 * 106 * @author T.OTA 107 * @since JDK7.0 108 * 109 */ 110public class JsChartTag extends CommonTagSupport { 111 //* このプログラムのVERSION文字列を設定します。{@value} */ 112 private static final String VERSION = "5.9.17.2 (2017/02/07)"; 113 private static final long serialVersionUID = 1631345224410617801L; 114 /** chartType 引数に渡す事の出来る アクション 折れ線 **/ 115 public static final String CTYPE_LINE = "line"; 116 /** chartType 引数に渡す事の出来る アクション 棒線 **/ 117 public static final String CTYPE_BAR = "bar"; 118 /** chartType 引数に渡す事の出来る アクション 横棒線 **/ 119 public static final String CTYPE_HBAR = "horizontalBar"; 120 /** chartType 引数に渡す事の出来る アクション レイダー **/ 121 public static final String CTYPE_RADAR = "radar"; 122 /** chartType 引数に渡す事の出来る アクション ポーラエリア **/ 123 public static final String CTYPE_PA = "polarArea"; 124 /** chartType 引数に渡す事の出来る アクション 円 **/ 125 public static final String CTYPE_PIE = "pie"; 126 /** chartType 引数に渡す事の出来る アクション ドーナツ **/ 127 public static final String CTYPE_DOUGHNUT = "doughnut"; 128 /** chartType 引数に渡す事の出来る アクション リスト */ 129 private static final String[] CTYPE_LIST = new String[] { CTYPE_LINE, CTYPE_BAR, CTYPE_HBAR, CTYPE_RADAR, CTYPE_PA, CTYPE_PIE, CTYPE_DOUGHNUT }; 130 /** chartType が円形のリスト */ 131 private static final String[] CTYPE_CI = new String[] { CTYPE_RADAR, CTYPE_PA, CTYPE_PIE, CTYPE_DOUGHNUT }; 132 private static final String[] TYPE_POSITION = new String[] { "top", "right", "bottom", "left" }; 133 private static final String[] TYPE_TIMEUNIT = new String[] { "year", "quarter", "month", "week", "day", "hour", "minute", "second", "millsecond" }; 134 private static final String[] TYPE_XSCALE = new String[] { "category", "time", "linear" }; 135 private static final String[] TYPE_YSCALE = new String[] { "linear", "category" }; 136 private static final String[] TYPE_BOOLEAN = new String[] { "true", "false" }; 137 138 private static final String CANVAS_NAME = "hybscanvas"; 139 140 // 変数宣言 141 private String id = null; // canvasタグのid 142 private String height = "400"; // canvasタグのheight 143 private String width = "400"; // canvasタグのwidth 144 private String chartType = null; // チャートタイプ 145 private String labelColumn = null; // ラベルカラム 146 private String ylabel = null; // y軸ラベル 147 private String xlabel = null; // x軸ラベル 148// private String scope = "session"; // スコープ 149 private String tableId = HybsSystem.TBL_MDL_KEY; // テーブルid 150 private List<JsChartData> jsChartData = null; // jsChartDataのリスト 151 private transient DBTableModel table = null; // DBTableModelクラス 152 private String onClick = null; // クリックイベント 153 private String title = null; // タイトル 154 private String titlePosition = null; // タイトル位置 155 private String legendPosition = null; // 凡例位置 156 private String legendDisplay = null; // 凡例表示フラグ 157 private String barWidthPer = null; // 棒線の横幅(パーセント) 158 private String xscaleCallback = null; // x軸のメモリ編集用コールバック 159 private String yscaleCallback = null; // y軸のメモリ編集用コールバック 160 private String xscaleType = null; // x軸のスケールタイプ 161 private String xmax = null; // x軸の最大値(リニアスケール用) 162 private String xmin = null; // x軸の最小値(リニアスケール用) 163 private String xstepSize = null; // x軸のメモリ幅(リニアスケール用) 164 private String yscaleType = null; // y軸のスケールタイプ 165 private String ycategoryList = null; // y軸のカテゴリーリスト(カテゴリースケール用) 166 private String max = null; // y軸の最大値(リニアスケール用) 167 private String min = null; // y軸の最小値(リニアスケール用) 168 private String stepSize = null; // y軸のメモリ幅(リニアスケール用) 169 private String timeUnit = null; // 時間の単位(タイムスケール用) 170 private String timeUnitStepSize = null; // 時間のメモリ幅(タイムスケール用) 171 private String timeSetFormat = null; // 時間の入力フォーマット(タイムスケール用) 172 private String timeLblFormat = null; // 時間の表示フォーマット(タイムスケール用) 173 private String timeMax = null; // 最大の時間(タイムスケール用) 174 private String timeMin = null; // 最小の時間(タイムスケール用) 175 private String widthEventColumn = null; // 横幅の動的参照カラム 2017/03/28 ADD 176 private String heightEventColumn = null; // 縦幅の動的参照カラム 2017/03/28 ADD 177 private String minEventColumn = null; // 最小値の動的参照カラム 2017/03/28 ADD 178 private String maxEventColumn = null; // 最大値の動的参照カラム 2017/03/28 ADD 179 private boolean useRenderer ; // 5.9.20.1 (2017/05/12) useRenderer 追加(6.7.7.0) 180 private String optionAttributes = null; // オプション 181 182 // 5.10.3.2 (2018/09/28) 183 private static final String TYPE_STRING = "string"; 184 private static final String TYPE_INT = "int"; 185 private static final String[] XSCALEDATATYPE_LIST = new String[] {TYPE_STRING, TYPE_INT}; 186 private String xscaleTimeType = TYPE_STRING; 187 188 /** 189 * タグリブオブジェクトをリリースします。 190 * キャッシュされて再利用されるので、フィールドの初期設定を行います。 191 * 192 * @og.rev 5.9.19.0 (2017/04/07) T.OTA 61200-170316-02 チャートサイズ・max・minの動的変更対応 193 * @og.rev 5.9.20.1 (2017/05/12) useRenderer追加 194 * @og.rev 5.10.3.2 (2018/09/28) xscaleTimeType追加 195 */ 196 @Override 197 protected void release2() { 198 super.release2(); 199 id = null; 200 height = "400"; 201 width = "400"; 202 chartType = null; 203 labelColumn = null; 204// scope = "session"; 205 tableId = HybsSystem.TBL_MDL_KEY; 206 jsChartData = null; 207 table = null; 208 optionAttributes = null; 209 onClick = null; 210 title = null; 211 titlePosition = null; 212 xlabel = null; 213 ylabel = null; 214 legendPosition = null; 215 legendDisplay = null; 216 barWidthPer = null; 217 xscaleCallback = null; 218 yscaleCallback = null; 219 xscaleType = null; 220 yscaleType = null; 221 ycategoryList = null; 222 max = null; 223 min = null; 224 stepSize = null; 225 timeUnit = null; 226 timeUnitStepSize = null; 227 timeSetFormat = null; 228 timeLblFormat = null; 229 timeMax = null; 230 timeMin = null; 231 xmax = null; 232 xmin = null; 233 xstepSize = null; 234 widthEventColumn = null; // 5.9.19.0 235 heightEventColumn = null; // 5.9.19.0 236 maxEventColumn = null; // 5.9.19.0 237 minEventColumn = null; // 5.9.19.0 238 useRenderer = false; // 5.9.20.1 (2017/05/12) useRenderer 追加(6.7.9.0) 239 xscaleTimeType = TYPE_STRING; // 5.10.3.2 (2018/09/28) 240 } 241 242 /** 243 * Taglibの開始タグが見つかった時に処理する doStartTag() を オーバーライドします。 244 * 245 * @og.rev 5.9.20.1 (2017/05/12) タグの使用を決める共通属性の追加(6.7.5.0) 246 * 247 * @return 後続処理の指示 248 */ 249 @Override 250 public int doStartTag() { 251 if( !useTag() ) { return SKIP_BODY ; } // 5.9.20.1 (2017/05/12) 252 253 // チェック処理の実行 254 checkData(); 255 256// // スコープの設定 257// super.setScope( scope ); 258 259 // テーブル情報の取得 260 table = (DBTableModel) getObject( tableId ); 261 262 return EVAL_BODY_BUFFERED; // Bodyを評価する 263 } 264 265 /** 266 * チェック処理 267 */ 268 private void checkData() { 269 // xscaleTypeに「linear」、yscaleTypeに「category」を指定した場合は、エラー 270 if( "linear".equals( xscaleType ) && "category".equals( yscaleType ) ) { 271 StringBuilder errMsg = new StringBuilder( HybsSystem.BUFFER_MIDDLE ); 272 errMsg.append( "指定のスケールタイプの組み合わせは実行できません。" ); 273 errMsg.append( HybsSystem.CR ); 274 errMsg.append( "xscaleType:" ).append( xscaleType ).append( " yscaleType:" ).append( yscaleType ); 275 throw new HybsSystemException( errMsg.toString() ); 276 } 277 } 278 279 /** 280 * Taglibの終了タグが見つかったときに処理する doEndTag() を オーバーライドします。 281 * 282 * @return 後続処理の指示 283 */ 284 @Override 285 public int doEndTag() { 286 debugPrint(); 287 288 id = (id==null ? CANVAS_NAME + tableId : id ); // id指定なしの場合はCANVAS_NAME+tableId 289 290 // jsChart出力 291 jspPrint( jsChartOutput() ); 292 293 return EVAL_PAGE; 294 } 295 296 /** 297 * jsChart出力用 298 * jsChartTag と jsChartData を使用して、jsChart情報を出力します。 299 * 300 * @og.rev 5.9.19.0 (2017/04/07) T.OTA 61200-170316-02 チャートサイズ・max・minの動的変更対応 301 * @og.rev 5.9.20.1 (2017/05/12) useRenderer対応 302 * @og.rev 5.9.27.0 2017/12/01 T.OTA 61200-170831-04 max,minの小数点対応 303 * @og.rev 5.10.3.2 (2018/09/28) のxscaleType対応 304 * 305 * @return jsChert用文字列 306 */ 307 private String jsChartOutput() { 308 StringBuilder rtn = new StringBuilder( HybsSystem.BUFFER_MIDDLE ); 309 310 // 各JavaScriptの変数名 311 String qd = "qd_" + id; //queryData 312 String cd = "cd_" + id; //chartData 313 String myChart = "chart_"+id; 314 String lblClm = labelColumn + id; 315 316 317 // JSON形式でテーブル情報を取得 318 ViewForm form = ViewFormFactory.newInstance( "JSON" ); 319 form.init( table ); 320 321 // 5.9.20.1 (2017/05/12) form にパラメータMapを与えるようにする 322 final ConcurrentMap<String,String> cMap = new ConcurrentHashMap<String,String>(); 323 if( useRenderer ) { 324 cMap.put( ViewJsonParam.JSON_RENDERER_KEY , "true" ); 325 } 326 if( !cMap.isEmpty() ) { 327 form.setParam( cMap ); 328 } 329 330 // canvasタグの設定 331 rtn.append( "<canvas class=\"").append( CANVAS_NAME).append( "\" id=\"" ).append( id ).append( "\" width=\"" ).append( width ).append( "\" height=\"" ).append( height ).append( "\"><!-- --></canvas>" ); 332 333 rtn.append( "<script>" ); 334 // query情報の取得(JSON) 335 rtn.append( "var ").append( qd ).append(" = " ).append( form.create() ); 336 337 // jsChartDataタグの変数宣言 338 for( int i = 0; i < jsChartData.size(); i++ ) { 339 rtn.append( " var " ).append( jsChartData.get( i ).getChartColumn() ).append( " = [];" ); 340 } 341 rtn.append( "var " ).append( lblClm ).append( " = [];" ); 342 343 // query情報をjsChartDataの変数に入れ替え 344 rtn.append( "for(var i=0; i < ").append( qd ).append( ".DATA.length; i++){" ); 345 for( int i = 0; i < jsChartData.size(); i++ ) { 346 String chartColumn = jsChartData.get( i ).getChartColumn(); 347 348 // x軸がlinearスケールの場合 349 if( "linear".equals( xscaleType ) ) { 350 // {x:ラベル, y:値}の形式で値を設定 351 rtn.append( chartColumn ).append( "[i] = {x:").append(qd).append(".DATA[i]." ).append( labelColumn ).append( ",y:").append(qd).append(".DATA[i]." ).append( chartColumn ).append( "};" ); 352 } 353 else { 354 // その他は値を設定 355 rtn.append( chartColumn ).append( "[i] = ").append(qd).append( ".DATA[i]." ).append( chartColumn ).append( ";" ); 356 } 357 } 358 // 5.10.3.2 (2018/09/28) 359// rtn.append( lblClm ).append( "[i] = ").append( qd ).append( ".DATA[i]." ).append( labelColumn ).append( ";" ); 360 rtn.append( lblClm ).append( "[i] = "); 361 // xscaleTimeTypeがint場合は数値型を設定 362 if("time".equals(this.xscaleType) && TYPE_INT.equals(this.xscaleTimeType)) { 363 rtn.append("Number("); 364 } 365 rtn.append( qd ).append( ".DATA[i]." ).append( labelColumn ); 366 // xscaleTimeTypeがint場合は数値型を設定 367 if("time".equals(this.xscaleType) && TYPE_INT.equals(this.xscaleTimeType)) { 368 rtn.append(")"); 369 } 370 rtn.append( ";" ); 371 372 373 rtn.append( "}" ); 374 375 // y軸にカテゴリースケールを設定した場合 376 if( "category".equals( yscaleType ) ) { 377 rtn.append( "var ycateList = [];" ); 378 if( ycategoryList != null && ycategoryList.length() > 0 ) { 379 // 「,」を「','」に変換して設定。(,前後の半角スペースは除去する) 380 String regex = " *, *"; 381 Pattern p = Pattern.compile( regex ); 382 383 Matcher m = p.matcher( ycategoryList ); 384 // y軸カテゴリーリストの設定 385 rtn.append( "ycateList = ['" ).append( m.replaceAll( "','" ) ).append( "'];" ); 386 } 387 } 388 389 // jsChartDataの設定 390 rtn.append( "var ").append( cd ).append(" = {" ); 391 rtn.append( "labels:" ).append( lblClm ); 392 // y軸にカテゴリースケールを設定した場合 393 if( "category".equals( yscaleType ) ) { 394 rtn.append( ",yLabels:ycateList" ); 395 } 396 rtn.append( ",datasets:[" ); 397 for( int i = 0; i < jsChartData.size(); i++ ) { 398 if( i != 0 ) { 399 rtn.append( "," ); 400 } 401 rtn.append( jsChartData.get( i ).getParameter() ); 402 } 403 rtn.append( "]};" ); 404 405 // jsChartの生成 406 rtn.append( "var ").append( myChart ).append(" = new Chart(" ).append( id ).append( ",{" ); 407 rtn.append( "type:'" ).append( chartType ).append( "'" ); 408 rtn.append( ",data:").append(cd); 409 rtn.append( ",options:{" ); 410 rtn.append( "responsive:false" ); // レスポンシブ OFF 411// rtn.append( ",animation:false" ); // アニメーション OFF 412 413 // クリックイベントの設定 414 if( onClick != null && onClick.length() > 0 ) { 415 rtn.append( ",onClick:function(event,obj){" ).append( onClick ).append( "}" ); 416 } 417 418 // タイトル属性の設定 419 if( title != null && title.length() > 0 ) { 420 rtn.append( ",title:{" ); 421 rtn.append( "display:true" ); 422 setProp( rtn, ",text:'", title, "'" ); 423 setProp( rtn, ",position:'", titlePosition, "'" ); 424 rtn.append( "}" ); 425 } 426 427 // メモリ属性の設定 428 rtn.append( ",legend:{" ); 429 setProp( rtn, "display:", legendDisplay, "," ); 430 setProp( rtn, "position:'", legendPosition, "'" ); 431 rtn.append( "}" ); 432 433 // chartTypeの円形チェック 434 List<String> list = Arrays.asList( CTYPE_CI ); 435 if( list.contains( chartType ) ) { 436 // 円形の場合はscale属性に値を設定 437 rtn.append( ",scale: {ticks:{beginAtZero:true" ); 438 setProp( rtn, ",max:", max ); 439 setProp( rtn, ",min:", min ); 440 setProp( rtn, ",stepSize:", stepSize ); 441 rtn.append( "}}" ); 442 } 443 else { 444 // 円形以外の場合はscales属性に設定 445 rtn.append( ",scales:{" ); 446 if( CTYPE_HBAR.equals( chartType ) ) { 447 // 横棒線の場合はx軸の設定 448 rtn.append( "xAxes" ); 449 } 450 else { 451 // それ以外はy軸の設定 452 rtn.append( "yAxes" ); 453 } 454 rtn.append( ":[{" ); 455 setProp( rtn, "type:'", yscaleType, "'," ); 456 // y軸にカテゴリースケールを設定した場合 457 if( "category".equals( yscaleType )) { 458 rtn.append( "position:'left'," ); 459 } 460 if(ylabel != null && ylabel.length() > 0 ){ 461 rtn.append( "scaleLabel: {" ); 462 rtn.append( "display: true," ); 463 rtn.append( "labelString: '").append( ylabel ).append("'"); 464 rtn.append( "}," ); 465 } 466 rtn.append( "ticks:{beginAtZero:true" ); 467 setProp( rtn, ",max:", max ); 468 setProp( rtn, ",min:", min ); 469 setProp( rtn, ",stepSize:", stepSize ); 470 setProp( rtn, ",callback:", yscaleCallback ); 471 rtn.append( "}}]," ); 472 473 if( CTYPE_HBAR.equals( chartType ) ) { 474 // 横棒線の場合はy軸の設定 475 rtn.append( "yAxes" ); 476 } 477 else { 478 // それ以外はx軸の設定 479 rtn.append( "xAxes" ); 480 } 481 rtn.append( ":[{" ); 482 setProp( rtn, "type:'", xscaleType, "'," ); 483 setProp( rtn, "categoryPercentage:", barWidthPer, "," ); 484 // x軸にリニアスケールを設定した場合 485 if( "linear".equals( xscaleType ) ) { 486 rtn.append( "position:'bottom'," ); 487 } 488 // チャートタイプが横棒線の場合 489 if( CTYPE_HBAR.equals( chartType )){ 490 rtn.append( "position:'left'," ); 491 } 492 493 if(xlabel != null && xlabel.length() > 0 ){ 494 rtn.append( "scaleLabel: {" ); 495 rtn.append( "display: true," ); 496 rtn.append( "labelString: '").append( xlabel ).append("'"); 497 rtn.append( "}," ); 498 } 499 rtn.append( "time:{" ); 500 setProp( rtn, "format:'", timeSetFormat, "'," ); 501 // timeLblFormatが指定されている場合、全てのdisplayFormatsにtimeLblFormatを設定する 502 if( timeLblFormat != null && timeLblFormat.length() > 0 ) { 503 rtn.append( "displayFormats:{year:'" ).append( timeLblFormat ).append( "',quarter:'" ).append( timeLblFormat ).append( "',month:'" ).append( timeLblFormat ).append( "',week:'" ).append( timeLblFormat ).append( "',day:'" ).append( timeLblFormat ).append( "',hour:'" ).append( "',minute:'" ).append( timeLblFormat ).append( "',second:'" ).append( timeLblFormat ).append( "',millisecond:'" ).append( "'}," ); 504 } 505 setProp( rtn, "max:'", timeMax, "'," ); 506 setProp( rtn, "min:'", timeMin, "'," ); 507 setProp( rtn, "unit:'", timeUnit, "'," ); 508 setProp( rtn, "unitStepSize:", timeUnitStepSize ); 509 rtn.append( "}," ); 510 511 rtn.append( "ticks:{" ); 512 setProp( rtn, "callback:", xscaleCallback, "," ); 513 // x軸にリニアスケールを設定した場合 514 if( "linear".equals( xscaleType ) ) { 515 rtn.append( "beginAtZero:true," ); 516 setProp( rtn, "max:", xmax, "," ); 517 setProp( rtn, "min:", xmin, "," ); 518 setProp( rtn, "stepSize:", xstepSize ); 519 } 520 rtn.append( "}}]" ); 521 522 rtn.append( "}" ); 523 } 524 setProp( rtn, ",", optionAttributes ); 525 526 rtn.append( "}});" ); 527 528 // イベント設定用 5.9.19.0 529 // 5.9.27.0 (2017/12/01) MODIFY イベントにkeyupを追加 530 // widthEventColumn設定 531 if( widthEventColumn != null && widthEventColumn.length() > 0){ 532 rtn.append( "$(document).delegate('#").append( widthEventColumn ).append( "','mouseup keyup',function(){") 533 .append( "var width = $(this).val();") 534 .append( "$('#" ).append( id ).append( "').attr('width',width);") 535 .append( myChart ).append( ".chart.width=width;") 536 .append( myChart ).append( ".update();") 537 .append( "} );") 538 .append( "$(function( ){") 539 .append( "var chartWidth = $('#" ).append( id ).append("').attr('width');") 540 .append( "$('#").append( widthEventColumn ).append( "').val(chartWidth);") // 初期値を設定 541 .append( "});"); 542 } 543 // heightEventColumn設定 544 if( heightEventColumn != null && heightEventColumn.length() > 0){ 545 rtn.append( "$(document).delegate('#").append( heightEventColumn ).append( "','mouseup keyup',function(){") 546 .append( "var height = $(this).val();") 547 .append( "$('#" ).append( id ).append( "').attr('height',height);") 548 .append( myChart ).append( ".chart.height=height;") 549 .append( myChart ).append( ".update();") 550 .append( "} );") 551 .append( "$(function( ){") 552 .append( "var chartHeight = $('#" ).append( id ).append("').attr('height');") 553 .append( "$('#").append( heightEventColumn ).append( "').val(chartHeight);") // 初期値を設定 554 .append( "});"); 555 } 556 // minEventColumn設定 557 if( minEventColumn != null && minEventColumn.length() > 0){ 558 rtn.append( "$(document).delegate('#").append( minEventColumn ).append( "','mouseup keyup',function(){") 559 // 5.9.27.0 (2017/12/01) MODIFY IntからFloat型に変更 560 // .append( "var min = parseInt($(this).val());") 561 .append( "var min = parseFloat($(this).val());") 562 .append( myChart ).append( ".options.scales.yAxes[0].ticks.min = min;") 563 .append( myChart ).append( ".update();") 564 .append( "} );") 565 .append( "$(function( ){") 566 .append( "var chartMin = ").append( myChart ).append( ".scales['y-axis-0'].min;") 567 .append( "$('#").append( minEventColumn ).append( "').val(chartMin);") // 初期値を設定 568 .append( "});"); 569 } 570 // maxEventColumn設定 571 if( maxEventColumn != null && maxEventColumn.length() > 0){ 572 rtn.append( "$(document).delegate('#").append( maxEventColumn ).append( "','mouseup keyup',function(){") 573 // 5.9.27.0 (2017/12/01) MODIFY IntからFloat型に変更 574 // .append( "var max = parseInt($(this).val());") 575 .append( "var max = parseFloat($(this).val());") 576 .append( myChart ).append( ".options.scales.yAxes[0].ticks.max = max;") 577 .append( myChart ).append( ".update();") 578 .append( "} );") 579 .append( "$(function(){") 580 .append( "var chartMax = ").append( myChart ).append( ".scales['y-axis-0'].max;") 581 .append( "$('#").append( maxEventColumn ).append( "').val(chartMax);") // 初期値を設定 582 .append("});"); 583 } 584 585 rtn.append( "</script>" ); 586 587 return rtn.toString(); 588 } 589 590 /** 591 * setに値が存在する場合, 592 * sbにstr + setの形で値を追加する。 593 * 594 * @param sb 595 * @param str 596 * @param set 597 */ 598 private void setProp( StringBuilder sb, String str, String set ) { 599 if( set != null && set.length() > 0 ) { 600 sb.append( str ).append( set ); 601 } 602 } 603 604 /** 605 * setに値が存在する場合, 606 * sbにstr + set + endの形で値を追加する。 607 * 608 * @param sb 609 * @param str 610 * @param set 611 * @param end 612 */ 613 private void setProp( StringBuilder sb, String str, String set, String end ) { 614 if( set != null && set.length() > 0 ) { 615 sb.append( str ).append( set ).append( end ); 616 } 617 } 618 619 /** 620 * id を設定します。 621 * canvasタグのidに設定します。 622 * 623 * @param id 624 */ 625 public void setId( String id ) { 626 String temp = getRequestParameter( id ); 627 if( temp != null && temp.length() > 0 ) { 628 this.id = temp; 629 } 630 } 631 632 /** 633 * 高さ を設定します。 634 * canvasタグの高さに設定します。 635 * 636 * @param hei 637 */ 638 public void setHeight( final String hei ) { 639 String temp = getRequestParameter( hei ); 640 if( temp != null && temp.length() > 0 ) { 641 height = temp; 642 } 643 } 644 645 /** 646 * 横幅 を設定します。 647 * canvasタグの横幅を設定します。 648 * 649 * @param wid 650 */ 651 public void setWidth( final String wid ) { 652 String temp = getRequestParameter( wid ); 653 if( wid != null && wid.length() > 0 ) { 654 width = temp; 655 } 656 } 657 658 /** 659 * チャートタイプ を設定します。 660 * 661 * @param cType 662 */ 663 public void setChartType( final String cType ) { 664 chartType = getRequestParameter( cType ); 665 666 if( chartType != null && !check( chartType, CTYPE_LIST ) ) { 667 StringBuilder errMsg = new StringBuilder( HybsSystem.BUFFER_MIDDLE ); 668 errMsg.append( "指定のチャートタイプは実行できません。" ); 669 errMsg.append( HybsSystem.CR ); 670 errMsg.append( "chartType=[" ).append( chartType ).append( "]" ); 671 errMsg.append( HybsSystem.CR ); 672 for( int i = 0; i < CTYPE_LIST.length; i++ ) { 673 errMsg.append( " | " ); 674 errMsg.append( CTYPE_LIST[i] ); 675 } 676 throw new HybsSystemException( errMsg.toString() ); 677 } 678 } 679 680 /** 681 * ラベルカラムを指定します。 682 * 683 * @param labelColumn ラベルカラム 684 */ 685 public void setLabelColumn( String labelColumn ) { 686 this.labelColumn = getRequestParameter( labelColumn ); 687 } 688 689// /** 690// * テーブルスコープを指定します。 691// * 692// * @param scope テーブルスコープ 693// */ 694// public void setScope( String scope ) { 695// this.scope = getRequestParameter( scope ); 696// } 697 698 /** 699 * テーブルIDを指定します。 700 * 701 * @param tableId テーブルID 702 */ 703 public void setTableId( String tableId ) { 704 this.tableId = getRequestParameter( tableId ); 705 } 706 707 /** 708 * チャートクリック時のイベントを指定します。 709 * 下記の値が引数として渡されます。 710 * 711 * event:イベント情報 712 * obj:クリックされたオブジェクトの情報 713 * 714 * @param onClick 715 */ 716 public void setOnClick( String onClick ) { 717 this.onClick = getRequestParameter( onClick ); 718 } 719 720 /** 721 * メモリの最大値を指定します。 722 * 723 * @param max メモリの最大値 724 */ 725 public void setMax( String max ) { 726 this.max = getRequestParameter( max ); 727 } 728 729 /** 730 * メモリの最小値を指定します。 731 * 732 * @param min メモリの最小値 733 */ 734 public void setMin( String min ) { 735 this.min = getRequestParameter( min ); 736 } 737 738 /** 739 * メモリ幅を設定します。 740 * 741 * @param stepSize 742 */ 743 public void setStepSize( String stepSize ) { 744 this.stepSize = getRequestParameter( stepSize ); 745 } 746 747 /** 748 * 時間の単位を設定します。 749 * 750 * @param timeUnit 751 */ 752 public void setTimeUnit( String timeUnit ) { 753 this.timeUnit = getRequestParameter( timeUnit ); 754 755 checkPara( this.timeUnit, TYPE_TIMEUNIT, "timeUnit" ); 756 } 757 758 /** 759 * 時間のメモリ幅を設定します。 760 * 761 * @param timeUnitStepSize 762 */ 763 public void setTimeUnitStepSize( String timeUnitStepSize ) { 764 this.timeUnitStepSize = getRequestParameter( timeUnitStepSize ); 765 } 766 767 /** 768 * 時間の入力フォーマットを設定します。 769 * 770 * @param timeSetFormat 771 */ 772 public void setTimeSetFormat( String timeSetFormat ) { 773 this.timeSetFormat = getRequestParameter( timeSetFormat ); 774 } 775 776 /** 777 * 時間の表示フォーマットを設定します。 778 * 779 * @param timeLblFormat 780 */ 781 public void setTimeLblFormat( String timeLblFormat ) { 782 this.timeLblFormat = getRequestParameter( timeLblFormat ); 783 } 784 785 /** 786 * 時間の最大値を設定します。 787 * 788 * @param timeMax 789 */ 790 public void setTimeMax( String timeMax ) { 791 this.timeMax = getRequestParameter( timeMax ); 792 } 793 794 /** 795 * 時間の最小値を設定します。 796 * 797 * @param timeMin 798 */ 799 public void setTimeMin( String timeMin ) { 800 this.timeMin = getRequestParameter( timeMin ); 801 } 802 803 /** 804 * タイトルを設定します。 805 * 806 * @param title 807 */ 808 public void setTitle( String title ) { 809 this.title = getRequestParameter( title ); 810 } 811 812 /** 813 * タイトル位置を設定します。 814 * 815 * @param titlePosition 816 */ 817 public void setTitlePosition( String titlePosition ) { 818 this.titlePosition = getRequestParameter( titlePosition ); 819 820 checkPara( this.titlePosition, TYPE_POSITION, "titlePosition" ); 821 } 822 823 /** 824 * 凡例位置を設定します。 825 * 826 * @param legendPosition 827 */ 828 public void setLegendPosition( String legendPosition ) { 829 this.legendPosition = getRequestParameter( legendPosition ); 830 831 checkPara( this.legendPosition, TYPE_POSITION, "legendPosition" ); 832 } 833 834 /** 835 * 凡例の表示制御を設定します。 836 * 837 * @param legendDisplay 838 */ 839 public void setLegendDisplay( String legendDisplay ) { 840 this.legendDisplay = getRequestParameter( legendDisplay ); 841 842 checkPara( this.legendDisplay, TYPE_BOOLEAN, "legendDisplay" ); 843 } 844 845 /** 846 * x軸のメモリ編集用スケールバックを設定します。 847 * 848 * @param xscaleCallback 849 */ 850 public void setXscaleCallback( String xscaleCallback ) { 851 this.xscaleCallback = getRequestParameter( xscaleCallback ); 852 } 853 854 /** 855 * y軸のメモリ編集用スケールバックを設定します。 856 * 857 * @param yscaleCallback 858 */ 859 public void setYscaleCallback( String yscaleCallback ) { 860 this.yscaleCallback = getRequestParameter( yscaleCallback ); 861 } 862 863 /** 864 * x軸のスケールタイプを設定します。 865 * 866 * @og.tag 867 * timeとした場合はxscaleTimeTypeの設定も確認してください。 868 * 869 * @param xscaleType 870 */ 871 public void setXscaleType( String xscaleType ) { 872 this.xscaleType = getRequestParameter( xscaleType ); 873 874 checkPara( this.xscaleType, TYPE_XSCALE, "xscaleType" ); 875 } 876 877 /** 878 * y軸のスケールタイプを設定します。 879 * 880 * @param yscaleType 881 */ 882 public void setYscaleType( String yscaleType ) { 883 this.yscaleType = getRequestParameter( yscaleType ); 884 885 checkPara( this.yscaleType, TYPE_YSCALE, "yscaleType" ); 886 } 887 888 /** 889 * y軸のカテゴリー一覧を設定します。 890 * 891 * @param ycategoryList 892 */ 893 public void setYcategoryList( String ycategoryList ) { 894 this.ycategoryList = getRequestParameter( ycategoryList ); 895 } 896 897 /** 898 * x軸の最大値を設定します。 899 * 900 * @param xmax 901 */ 902 public void setXmax( String xmax ) { 903 this.xmax = getRequestParameter( xmax ); 904 } 905 906 /** 907 * x軸の最小値を設定します。 908 * 909 * @param xmin 910 */ 911 public void setXmin( String xmin ) { 912 this.xmin = getRequestParameter( xmin ); 913 } 914 915 /** 916 * x軸のメモリ幅を設定します。 917 * 918 * @param xstepSize 919 */ 920 public void setXstepSize( String xstepSize ) { 921 this.xstepSize = getRequestParameter( xstepSize ); 922 } 923 924 /** 925 * 棒線の横幅を設定します。 926 * 927 * @param barWidthPer 928 */ 929 public void setBarWidthPer( String barWidthPer ) { 930 this.barWidthPer = getRequestParameter( barWidthPer ); 931 } 932 933 /** 934 * y軸のラベルを設定します。 935 * 936 * @param ylabel 937 */ 938 public void setYlabel( String ylabel ) { 939 this.ylabel = getRequestParameter( ylabel ); 940 } 941 942 /** 943 * x軸のラベルを設定します。 944 * 945 * @param xlabel 946 */ 947 public void setXlabel( String xlabel ) { 948 this.xlabel = getRequestParameter( xlabel ); 949 } 950 /** 951 * 横幅の動的設定カラムを設定します。 952 * 953 * @og.rev 5.9.19.0 (2017/04/07) 追加 954 * @param widthEventColumn 955 */ 956 public void setWidthEventColumn( String widthEventColumn ) { 957 this.widthEventColumn = getRequestParameter( widthEventColumn ); 958 } 959 960 /** 961 * 縦幅の動的設定カラムを設定します。 962 * 963 * @og.rev 5.9.19.0 (2017/04/07) 追加 964 * @param heightEventColumn 965 */ 966 public void setHeightEventColumn( String heightEventColumn ) { 967 this.heightEventColumn = getRequestParameter( heightEventColumn ); 968 } 969 970 /** 971 * minの動的設定カラムを設定します。 972 * 973 * @og.rev 5.9.19.0 (2017/04/07) 追加 974 * @param minEventColumn 975 */ 976 public void setMinEventColumn( String minEventColumn ) { 977 this.minEventColumn = getRequestParameter( minEventColumn ); 978 } 979 980 /** 981 * maxの動的設定カラムを設定します。 982 * 983 * @og.rev 5.9.19.0 (2017/04/07) 追加 984 * @param maxEventColumn 985 */ 986 public void setMaxEventColumn( String maxEventColumn ) { 987 this.maxEventColumn = getRequestParameter( maxEventColumn ); 988 } 989 990 /** 991 * 【TAG】JSON出力で、値出力にレンデラを利用するかどうかを指定します。 992 * 993 * @og.tag 994 * JSONのデータのレンデラー変換を行うかどうか。 995 * 指定しない場合は使用しない(false)です。 996 * 997 * @og.rev 5.9.20.1 (2017/05/12) useRenderer 追加(6.7.9.0) 998 * 999 * @param usernd レンデラーを利用するかどうか 1000 */ 1001 public void setUseRenderer( final String usernd ) { 1002 this.useRenderer = nval( getRequestParameter( usernd ) , this.useRenderer ); 1003 } 1004 1005 /** 1006 * 【TAG】オプション情報を指定します。 1007 * 1008 * @og.tag 1009 * オプションの指定。 1010 * 1011 * @param attri オプションの値 1012 */ 1013 public void setOptionAttributes( final String attri ) { 1014 optionAttributes = nval( getRequestParameter( attri ),optionAttributes ); 1015 } 1016 1017 /** 1018 * 【TAG】x軸のデータ型を指定します。 1019 * 1020 * @ot.tag 1021 * X軸のデータを文字列として扱うか、数値として扱うかを指定します。(string/int) 1022 * Xが時間軸の場合に数値(UNIX時間)として扱う事で時間に沿ったスケールとなります。 1023 * 1024 * @og.rev 5.10.3.2 (2018/09/28) 新規追加 1025 * 1026 * @param xtt string/int 1027 */ 1028 public void setXscaleTimeType( final String xtt) { 1029 this.xscaleTimeType = nval( getRequestParameter( xtt ), this.xscaleTimeType ).toLowerCase(); 1030 checkPara(xtt, XSCALEDATATYPE_LIST, "xscaleTimeType"); 1031 } 1032 1033 /** 1034 * jsChartData情報をリストに追加します。 1035 * リストが存在しない場合は、新しく作成します。 1036 * 1037 * @param jsData 1038 */ 1039// public void addJsChartData( final JsChartData jsData ) { 1040 protected void addJsChartData( final JsChartData jsData ) { 1041 if( jsChartData == null ) { 1042 jsChartData = new ArrayList<JsChartData>(); 1043 } 1044 jsChartData.add( jsData ); 1045 } 1046 1047 /** 1048 * パラメータチェック用メソッド 1049 * 1050 * @param trg 1051 * @param list 1052 * @param trgStr 1053 */ 1054 private void checkPara( String trg, String[] list, String trgStr ) { 1055 if( trg != null && trg.length() > 0 && !check( trg, list ) ) { 1056 StringBuilder errMsg = new StringBuilder( HybsSystem.BUFFER_MIDDLE ); 1057 errMsg.append( "指定の" ).append( trgStr ).append( "は指定できません。" ); 1058 errMsg.append( HybsSystem.CR ); 1059 errMsg.append( trgStr ).append( "=[" ).append( trg ).append( "]" ); 1060 errMsg.append( HybsSystem.CR ); 1061 for( int i = 0; i < list.length; i++ ) { 1062 errMsg.append( " | " ); 1063 errMsg.append( list[i] ); 1064 } 1065 throw new HybsSystemException( errMsg.toString() ); 1066 } 1067 } 1068 1069 /** 1070 * このオブジェクトの文字列表現を返します。 1071 * 基本的にデバッグ目的に使用します。 1072 * 1073 * @return このクラスの文字列表現 1074 */ 1075 public String toString() { 1076 // JSON形式でテーブル情報を取得 1077 ViewForm form = ViewFormFactory.newInstance( "JSON" ); 1078 form.init( table ); 1079 1080 // jsChartDataのパラメータ情報 1081 StringBuilder sb = new StringBuilder( HybsSystem.BUFFER_MIDDLE ); 1082 for( int i = 0; i < jsChartData.size(); i++ ) { 1083 sb.append( " jsChartData" ).append( i ).append( ":" ).append( jsChartData.get( i ).getParameter() ); 1084 } 1085 1086 // 2017/03/28 widthEventColumn,heightEventColumn,minEventColumn,maxEventColumnを追加 1087 return org.opengion.fukurou.util.ToString.title( this.getClass().getName() ) 1088 .println( "VERSION", VERSION ) 1089 .println( "id", id ) 1090 .println( "tableId", tableId ) 1091// .println( "scope", scope ) 1092 .println( "chartType", chartType ) 1093 .println( "width", width ) 1094 .println( "height", height ) 1095 .println( "max", max ) 1096 .println( "min", min ) 1097 .println( "stepSize", stepSize ) 1098 .println( "barWidthPer", barWidthPer ) 1099 .println( "timeUnit", timeUnit ) 1100 .println( "timeUnitStepSize", timeUnitStepSize ) 1101 .println( "timeLblFormat", timeLblFormat ) 1102 .println( "timeSetFormat", timeSetFormat ) 1103 .println( "timeMax", timeMax ) 1104 .println( "timeMin", timeMin ) 1105 .println( "title", title ) 1106 .println( "titlePosition", titlePosition ) 1107 .println( "xlabel", xlabel ) 1108 .println( "ylabel", ylabel ) 1109 .println( "legendPosition", legendPosition ) 1110 .println( "legendDisplay", legendDisplay ) 1111 .println( "yscaleCallback", yscaleCallback ) 1112 .println( "xscaleCallback", xscaleCallback ) 1113 .println( "xscaleType", xscaleType ) 1114 .println( "xmax", xmax ) 1115 .println( "xmin", xmin ) 1116 .println( "xstepSize", xstepSize ) 1117 .println( "yscaleType", yscaleType ) 1118 .println( "ycategoryList", ycategoryList ) 1119 .println( "widthEventColumn", widthEventColumn ) 1120 .println( "heightEventColumn", heightEventColumn ) 1121 .println( "minEventColumn", minEventColumn ) 1122 .println( "maxEventColumn", maxEventColumn ) 1123 .println( "optionAttributes", optionAttributes ) 1124 .println( "JSON", form.create() ) 1125 .println( "jsChartDataPara", sb.toString() ).fixForm().toString(); 1126 } 1127}