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