001 /* 002 * Copyright (c) 2009 The openGion Project. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 013 * either express or implied. See the License for the specific language 014 * governing permissions and limitations under the License. 015 */ 016 package org.opengion.plugin.view; 017 018 import org.opengion.hayabusa.common.HybsSystem; 019 import org.opengion.hayabusa.common.HybsSystemException; 020 import org.opengion.fukurou.util.StringUtil; 021 022 import java.util.Calendar; 023 import java.util.Map; 024 import java.util.TreeMap; 025 import java.util.Collection; 026 import java.util.Locale ; 027 import java.util.Date; 028 import java.text.DateFormat; 029 import java.text.SimpleDateFormat; 030 031 import java.awt.Graphics2D; 032 import java.awt.Color; 033 import java.awt.FontMetrics; 034 import java.awt.Stroke; 035 import java.awt.BasicStroke; 036 import java.awt.image.BufferedImage; 037 038 import javax.imageio.ImageIO; 039 import java.io.File; 040 import java.io.IOException; 041 042 043 /** 044 * キー、日時?状況コードを持つ稼働状況?表示を行うクラスです? 045 * 046 * パラメータが?な場合?、ViewTimeBarParamTag を使用してください? 047 * 048 * パラメータが設定されて???合?、ViewForm_ImageTimeBar の初期値が使用されます? 049 * (パラメータを使用するには、viewタグのuseParam 属?をtrueに設定する?があります?) 050 * 051 * SELECT??、キー、日時?状況コードが、???で、カラ??並び??、完?に固定です? 052 * よって、カラ?置を指定する??ありませんが?SELECT?自由に設定すること? 053 * 出来ませんので、ご注意く???<br/> 054 * こ?固定化に伴??WRITABLE ?も使用できません。(そもそも書き込み不可です? 055 * それ以降?カラ?つ?は、?部処?しては、使用して?せん? 056 * ただし?パラメータで、カラー色??ラベル表記部、イメージ重?合わせ? 057 * ポップア??表記?リンク表記に使えます? 058 * 059 * ??タの並び?ORDER BY)も?キー、日時?にしてください? 060 * ??タは、キー単位に?レコード作?されます??キーブレイク?その間?日時?に 061 * ??タを??ます? 062 * 063 * ??タの表示は、今?レコード?日時から?次のレコード?日時までを?の状態と 064 * して表します?今?レコードを表示するには、次のレコードが?になります? 065 * 画面表示は、表示開始日?minStartTime) から 表示期間(timeSpan)?表示します? 066 * 通常?始時刻は、表示開始時刻より前より始まり?次のレコードで、終?刻が決? 067 * されます?????タは、期間??で続いて?と仮定されます? 068 * ??タが存在しな??であれば、?存在しな?ータ」を作?してください? 069 * 070 * ImageTimeBar では、キーでまとめた値につ?、各状況コードをカラー化し、積み上げ 071 * 帯グラフ形式でPNG画像化します?<br/> 072 * こ?画像を、読み込?HTML を?力することで、画面上に、積み上げ帯グラフを表示します? 073 * 状況コードに対応する色は、標準では自動作?ですが、外部から色??(colorClm)を与えることで 074 * 自由に?する事も可能です? 075 * 076 * ポップア??表?tipsClm)、リンク表?linkClm)は、この画像に対するエリア?タグを?力する事で実現します? 077 * 画像ファイルは、???タに対して?画像だけなので、サイズは大きくなりますが?レコー? 078 * 単位に画像を作?しな?め?レスポンスは向上します? 079 * それぞれ、viewMarker , viewLink を利用することが可能です?特に、リンク表?linkClm) につ?は? 080 * linkタグの hrefTarget 属??true に設定することで適用できます? 081 * 082 * 画像ファイルは、java.io.File.createTempFile( File ) で作?するため、JavaVM(=Tomcat)? 083 * 正常終?るときに、削除されます?異常終?には残りますが、temp フォル?定期? 084 * 整?れ?、それほど大量?ファイルが残ることはな?思われます? 085 * 086 * ??タは、イベント発生時に作?されると仮定して?す?つまり?書き込まれた日時から? 087 * 状況コードに対応する状況が発生し、次の状???レコードまで継続して?と?ます? 088 * よって、データを?中で?出す?合??出す?の前?状態が?になります? 089 * ???の状態??不?" として扱?す??空?白色?? 090 * 091 * @og.rev 5.5.5.6 (2012/08/31) 新規追? 092 * @og.group 画面表示 093 * 094 * @version 4.0 095 * @author Kazuhiko Hasegawa 096 * @since JDK5.0, 097 */ 098 public class ViewForm_ImageTimeBar extends ViewForm_HTMLTable { 099 //* こ?プログラ??VERSION??を設定します? {@value} */ 100 private static final String VERSION = "5.6.5.0 (2013/06/07)" ; 101 102 private static final Color LABEL_COLOR = Color.BLACK; // ラベル記述時?色 103 private static final Color NULL_COLOR = Color.WHITE; // 5.6.1.1 (2013/02/08) 不?(空?時?色 104 105 private long startDate ; // タイ?ーブルの表示開始日時から求め?long 値(1=?? 106 private long timeSpan ; // タイ?ーブルの表示期間。?は時間?であるが??位で持つ?1=?? 107 108 private boolean useLegend ; // カラーの凡例を使用するかど?[true/false] 109 private int maxLabelWidth ; // ラベル表記部の?サイズをpxで??何もなければ、可変長サイズ 110 private int maxTimeWidth ; // タイ?記部の?サイズをpxで?? 111 private int chartHeight ; // ?レコード?チャート?間隔をpxで??実際の??、CHART_HEIGHT?MARGIN?? 112 private int chartPadding ; // イメージ作?の 全体テーブルの隙間 113 private int recodeMargin ; // ?コード??等??の間隔 114 private boolean useLastData ; // 5.6.1.1 (2013/02/08) 行?????が?継続して?として使?ど?[true/false] 115 116 private String tempDir ; // 画像ファイルを作?する?ポラリ?レクトリ(相対パス) 117 private String tempUrl ; // 作?した画像ファイルを取得するときに使用するURL(コン?ス?相対パス) 118 119 // SELECT??、キー、日時?状況コードが、??? 120 private static final int keyClmNo = 0; // ヘッ??1?キーカラ?o 121 private static final int dyClmNo = 1; // ヘッ??2?日時カラ?o 122 private static final int fgjClmNo = 2; // ヘッ??3?状況コードカラ?o 123 124 private int[] labelClmsNo = null; // 初期値は、キーカラ? 125 private int[] maxClmWidth = null; // labelClms 単位????長 126 private int colClmNo = -1; // カラーコード直接?する?合に色??を指定するカラ?o 127 private int tipsClmNo = -1; // マウスオーバ?時?Tips表示を行うカラ?o 128 private int linkClmNo = -1; // クリ?ブルリンクを設定するカラ?o 129 130 private int str2DateTime ; // getStr2Date(String)処?おこなった時の、引数の時刻??(??をセ?する?ポラリ変数? 131 private int startTime ; // startDate の時刻??。上記??、startDate ?getStr2Date(String) 処?たとき?値を持っておくための変数? 132 133 private int MAX_X ; // イメージの?横?X)方向?サイズpx。chartPadding*2 + maxLabelWidth + maxTimeWidth 134 private int MAX_Y ; // イメージの?縦?Y)方向?サイズpx。chartPadding*2 + (chartHeight+recodeMargin*2)*(レコード数???ー数) 135 136 /** 137 * ?をクリア(初期?します? 138 * 139 */ 140 // @Override 141 // public void clear() { 142 // super.clear(); 143 // } 144 145 /** 146 * DBTableModel から HTML??を作?して返します? 147 * startNo(表示開始位置)から、pageSize(表示件数)までのView??を作?します? 148 * 表示残り??タ?pageSize 以下?場合?,残りの??タをすべて出力します? 149 * 150 * @og.rev 5.6.1.0 (2013/02/01) tips ?link は、?とつ前???タで作?する?がる為、最初?1件目は、??な??修正 151 * @og.rev 5.6.1.1 (2013/02/08) 初期値の色を?直接の値ではなく?static final で定義された色を使用する。色自体?変えて?せん 152 * @og.rev 5.6.1.1 (2013/02/08) useLastData 追? 153 * @og.rev 5.6.3.0 (2013/04/01) tipsのシングルクォー??ション のエスケー? 154 * @og.rev 5.6.3.1 (2013/04/05) 短縮ラベルなど?span>タグが付与される値から、spanタグを削除します? 155 * 156 * @param startNo 表示開始位置 157 * @param pageSize 表示件数 158 * 159 * @return DBTableModelから作?され?HTML?? 160 */ 161 @Override 162 public String create( final int startNo, final int pageSize ) { 163 if( getRowCount() == 0 ) { return ""; } // 暫定?置 164 165 // パラメータの??を?期化??得します? 166 paramInit(); 167 168 int lastNo = getLastNo( startNo, pageSize ); 169 170 // イメージの ???サイズを求め、結果を?MAX_X,MAX_Y 変数に設定する? 171 calcImageSize( startNo,lastNo ); 172 173 BufferedImage img = new BufferedImage( MAX_X, MAX_Y, BufferedImage.TYPE_INT_ARGB); 174 Graphics2D g2 = img.createGraphics(); 175 176 // chartPadding を?慮した領域のクリ???クリ??外にDrowされても無視されます??? 177 g2.setClip( chartPadding , chartPadding , MAX_X-chartPadding*2+1 , MAX_Y-chartPadding*2+1 ); // ?? 座?y 座??高さ) ?1?罫線?? 178 179 StringBuilder out = new StringBuilder( HybsSystem.BUFFER_LARGE ); 180 181 String oldKeyVal = ""; // 初期値。1回目にキーブレイクさせる? 182 long oldTime = 0L; // 日付?目の?前?値 183 184 // Color oldColor = Color.WHITE; // 色の?前?値(初期値) 185 Color oldColor = NULL_COLOR; // 5.6.1.1 (2013/02/08) 不?(空?時?色(初期値) 186 187 ColorMap colMap = new ColorMap(); // 状況コード?ラベル、カラーを管?るクラス 188 189 int rowCnt = (useLegend) ? 2 : 1; // 凡?useLegend)を使?true)場合??行?、使わな??合?、??ーの?行が初期値 190 int imgX = 0; // イメージ出力時の X軸の左端 px数 191 int imgY = 0; // イメージ出力時の Y軸の上端 px数 192 int imgW = 0; // イメージ出力時の ?fillRectで使用) 193 int imgH = chartHeight; // イメージ出力時の 高さ(fillRectで使用) 194 int rowH = chartHeight+recodeMargin*2; // 罫線?力時の高さ(drawRectで使用) 195 196 double timeScale = (double)maxTimeWidth/(double)timeSpan; 197 boolean useTipsLink = (tipsClmNo >= 0 || linkClmNo >= 0) ; // tipsClm ?linkClm かどちらかを使用する場合?true 198 for( int row=startNo; row<lastNo; row++ ) { 199 // キーブレイクの判? 200 String keyVal = getValue( row,keyClmNo ); 201 String dyVal = getValue( row,dyClmNo ); 202 203 // キーブレイク判定?キーブレイクは、?初めから来る? 204 if( !oldKeyVal.equals( keyVal ) ) { 205 // キーブレイクで??に行うのは、前のレコード?未出力?の処???行目は、??? 206 if( row > startNo ) { 207 imgX = chartPadding + maxLabelWidth + (int)(oldTime*timeScale); 208 imgW = (int)((timeSpan-oldTime)*timeScale) ; 209 210 // ?0以上?場合?み描画する? 211 if( imgW > 0 ) { 212 // 5.6.1.1 (2013/02/08) useLastData 追? 213 if( useLastData ) { g2.setColor( oldColor ); } // 色の設定?、旧色を使? 214 else { g2.setColor( NULL_COLOR ); } // NULL色を使? 215 g2.fillRect( imgX , imgY+recodeMargin , imgW, imgH ); // (実際の状?左端x,上端y,?,高さh 216 217 // tipsClm ?linkClm を使用する? 218 // 5.6.1.0 (2013/02/01) tips ?link は、?とつ前???タで作?する?がる為、最初?1件目は、??な??修正 219 // if( useTipsLink ) { 220 // if( useTipsLink && row > 0 ) { 221 if( useLastData && useTipsLink && row > 0 ) { // 5.6.1.1 (2013/02/08) useLastData 追? 222 // tips ?link は、?とつ前???タで作?する?がある?row-1) 223 String tips = (tipsClmNo >= 0) ? getValueLabel( row-1,tipsClmNo ) : getValueLabel( row-1,fgjClmNo ) ; 224 if( tips != null && tips.indexOf( "'" ) >= 0 ) { // 5.6.3.0 (2013/04/01) シングルクォー??ション のエスケー? 225 tips = tips.replaceAll( "'","'" ); 226 } 227 tips = StringUtil.spanCut( tips ); // 5.6.3.1 (2013/04/05) spanタグを削除 228 229 out.append( "<area shape='rect' alt='" ).append( tips ).append( "'" ); 230 if( linkClmNo >= 0 ) { 231 String hrefVal = getValueLabel( row-1,linkClmNo ); 232 if( hrefVal != null && hrefVal.startsWith( "href" ) ) { // linkClmの値の先?が?html の場合?み追?る? 233 out.append( hrefVal ); 234 } 235 } 236 out.append( " coords='" ).append( imgX ).append( "," ).append( imgY+recodeMargin ).append( "," ); // 左端x1,上端y1 237 out.append( imgX+imgW ).append( "," ).append( imgY+recodeMargin+chartHeight ).append( "' />" ); // 右端x2,下段y2 238 } 239 } 240 } 241 242 // 次に、新しい行?出力(ラベルは、ブレイク時に出力しておきます??? 243 oldKeyVal = keyVal; // null は来な??? 244 imgY = chartPadding+(rowH)*rowCnt ; 245 rowCnt++ ; 246 247 // レコード?ラベル?け?繰返し描画する? 248 int clmSu = labelClmsNo.length; 249 int posX = chartPadding ; // ラベル??の書き?し位置の初期値 250 int posY2 = imgY+chartHeight+recodeMargin ; // ラベルのY軸基準? 251 g2.setColor( LABEL_COLOR ); 252 for( int col=0; col<clmSu; col++ ) { 253 String lbl = getValueLabel( row,labelClmsNo[col] ); // そ?行?値のRenderer値 254 lbl = StringUtil.spanCut( lbl ); // 5.6.3.1 (2013/04/05) spanタグを削除 255 g2.drawString( lbl , posX + recodeMargin, posY2 ); // ??,ベ?スラインのx座?y座? 256 posX += recodeMargin*2 + maxClmWidth[col] ; // 次の書き?し位置は、文字最大長??ージン 257 } 258 259 // レコード??? 260 g2.drawRect( chartPadding , imgY , MAX_X-chartPadding*2 , rowH ); // (レコード枠)左端x,上端y,?,高さh 261 262 oldTime = 0L; // キーブレイクによる初期? 263 // oldColor= Color.WHITE; // キーブレイクによる初期? 264 oldColor= NULL_COLOR; // 5.6.1.1 (2013/02/08) キーブレイクによる初期?不?(空?時?色 265 } 266 267 long newTime = getStr2Date( dyVal ) - startDate; // 次の時刻 268 if( newTime < oldTime ) { newTime = oldTime; } // 前?時刻より小さ??合?、前の時刻まで??めておく? 269 270 imgX = chartPadding + maxLabelWidth + (int)(oldTime*timeScale); // old時刻から書き始め?左端x) 271 imgW = (int)((newTime-oldTime)*timeScale) ; // 差??け描画する? 272 273 // ?0以上?場合?み描画する? 274 if( imgW > 0 ) { 275 g2.setColor( oldColor ); // 色の設? 276 g2.fillRect( imgX , imgY+recodeMargin , imgW, chartHeight ); // (実際の状?左端x,上端y,?,高さh 277 278 // tipsClm ?linkClm を使用する? 279 // 5.6.1.0 (2013/02/01) tips ?link は、?とつ前???タで作?する?がる為、最初?1件目は、??な??修正 280 // if( useTipsLink ) { 281 if( useTipsLink && row > 0 ) { 282 // tips ?link は、?とつ前???タで作?する?がある?row-1) 283 String tips = (tipsClmNo >= 0) ? getValueLabel( row-1,tipsClmNo ) : getValueLabel( row-1,fgjClmNo ) ; 284 if( tips != null && tips.indexOf( "'" ) >= 0 ) { // 5.6.3.0 (2013/04/01) シングルクォー??ション のエスケー? 285 tips = tips.replaceAll( "'","'" ); 286 } 287 tips = StringUtil.spanCut( tips ); // 5.6.3.1 (2013/04/05) spanタグを削除 288 289 out.append( "<area shape='rect' alt='" ).append( tips ).append( "'" ); 290 if( linkClmNo >= 0 ) { 291 String hrefVal = getValueLabel( row-1,linkClmNo ); 292 if( hrefVal != null && hrefVal.startsWith( "href" ) ) { // linkClmの値の先?が?html の場合?み追?る? 293 out.append( hrefVal ); 294 } 295 } 296 out.append( " coords='" ).append( imgX ).append( "," ).append( imgY+recodeMargin ).append( "," ); // 左端x1,上端y1 297 out.append( imgX+imgW ).append( "," ).append( imgY+recodeMargin+chartHeight ).append( "' />" ); // 右端x2,下段y2 298 } 299 } 300 301 oldTime = newTime ; 302 303 String fgjVal = getValue( row,fgjClmNo ); // 状況コード?キー 304 String fgjLbl = getValueLabel( row,fgjClmNo ); // 状況コード?ラベル 305 if( colClmNo >= 0 ) { 306 oldColor = colMap.getColor( fgjVal,fgjLbl,getValue( row,colClmNo ) ); // 色??を指定する?? 307 } 308 else { 309 oldColor = colMap.getColor( fgjVal,fgjLbl ); // 色??を指定しな??動設? 310 } 311 } 312 313 // レコード??ばん最後?出力???ジャスト?場?oldTime == maxEdTime)は、??な? 314 // 5.6.1.1 (2013/02/08) レコード??ばん最後?出力?、NULL色を使??変更 315 if( oldTime < timeSpan ) { 316 imgX = chartPadding + maxLabelWidth + (int)(oldTime*timeScale); 317 imgW = (int)((timeSpan-oldTime)*timeScale) ; 318 // 5.6.1.1 (2013/02/08) useLastData 追? 319 if( useLastData ) { g2.setColor( oldColor ); } // 色の設定?、旧色を使? 320 else { g2.setColor( NULL_COLOR ); } // NULL色を使? 321 g2.fillRect( imgX , imgY+recodeMargin , imgW, chartHeight ); // (実際の状?左端,上端,?高さ 322 323 // tipsClm ?linkClm を使用する? 324 // if( useTipsLink ) { 325 if( useLastData && useTipsLink ) { // 5.6.1.1 (2013/02/08) useLastData 追? 326 // tips ?link ??出力?、最後???タなので、lastNo-1 となる? 327 String tips = (tipsClmNo >= 0) ? getValueLabel( lastNo-1,tipsClmNo ) : getValueLabel( lastNo-1,fgjClmNo ) ; 328 if( tips != null && tips.indexOf( "'" ) >= 0 ) { // 5.6.3.0 (2013/04/01) シングルクォー??ション のエスケー? 329 tips = tips.replaceAll( "'","'" ); 330 } 331 tips = StringUtil.spanCut( tips ); // 5.6.3.1 (2013/04/05) spanタグを削除 332 333 out.append( "<area shape='rect' alt='" ).append( tips ).append( "'" ); 334 if( linkClmNo >= 0 ) { 335 String hrefVal = getValueLabel( lastNo-1,linkClmNo ); 336 if( hrefVal != null && hrefVal.startsWith( "href" ) ) { // linkClmの値の先?が?html の場合?み追?る? 337 out.append( hrefVal ); 338 } 339 } 340 out.append( " coords='" ).append( imgX ).append( "," ).append( imgY+recodeMargin ).append( "," ); // 左端x1,上端y1 341 out.append( imgX+imgW ).append( "," ).append( imgY+recodeMargin+chartHeight ).append( "' />" ); // 右端x2,下段y2 342 } 343 } 344 345 // ヘッ????のイメージを作?します? 346 imageHeaderPaint( g2 , timeScale , colMap ); 347 348 // イメージファイルを?力し、URLを返します? 349 File file = null; 350 try { 351 File dir = new File( tempDir ); // 画像ファイル出力?のフォル? 352 dir.mkdirs(); // なければ作?する? 353 354 file = File.createTempFile( "Img",".png", dir ); // ?ポラリファイルの作? 355 file.deleteOnExit(); // JavaVM 停止時に?ポラリファイルの削除 356 357 ImageIO.write(img, "PNG", file ); 358 g2.dispose(); 359 } 360 catch( IOException ex ) { 361 System.out.println( "エラー:" + ex ); 362 } 363 364 // imgタグを作?します? 365 int width = MAX_X; 366 int height = MAX_Y; 367 368 StringBuilder out2 = new StringBuilder( HybsSystem.BUFFER_LARGE ); 369 out2.append( "<img id='ImageTimeBar' alt='ImageTimeBar' border='0'" ); 370 out2.append( " width='" ).append( width ).append( "px' height='" ).append( height ).append( "px'" ); 371 out2.append( " src='" ).append( tempUrl ).append( file.getName() ).append( "'" ); 372 373 // area タグの??タが作?されて?ば、?力します? 374 if( out.length() > 0 ) { 375 out2.append( " usemap='#TimeBarMap' />" ); // img タグにusemap 属?を追?て、終??追? 376 377 out2.append( "<map name='TimeBarMap'>" ); 378 out2.append( out ); 379 out2.append( "</map>" ); 380 } 381 else { 382 out2.append( " />" ); // img タグの終??追? 383 } 384 385 return out2.toString(); 386 } 387 388 /** 389 * パラメータ?を?期化します? 390 * 391 * @og.rev 5.6.1.1 (2013/02/08) useLastData 追? 392 */ 393 private void paramInit() { 394 String s_startDate = getParam( "START_DATE" ); // タイ?ーブルの表示開始日時をセ?しま?初期値:??タの?日?? 395 int timeSpanHour = getIntParam( "TIME_SPAN" ); // タイ?ーブルの表示期間を時間で?しま?初期値:{@og.value TIME_SPAN})? 396 397 String[] s_labelClms = StringUtil.csv2Array( getParam( "LABEL_CLMS" ) ); // ?表のラベル表示部に表示するカラ?をCSV形式で?します? 398 String s_colClm = getParam( "COLOR_CLM" ); // レコードに付ける色を色??で?する?合?カラ?を指定します? 399 String s_tipsClm = getParam( "TIPS_CLM" ); // レコード単位に、?ウスオーバ?時?Tips表示を行うカラ?を指定します? 400 String s_linkClm = getParam( "LINK_CLM" ); // レコード単位に、クリ?ブルリンクを設定するカラ?を指定します? 401 402 useLegend = getBoolParam( "USE_LEGEND" ); // カラーの凡例を使用するかど?[true/false] 403 maxLabelWidth = getIntParam( "MAX_LABEL_WIDTH" ); // ラベル表記部の?サイズをpxで??何もなければ、可変長サイズ 404 maxTimeWidth = getIntParam( "MAX_TIME_WIDTH" ); // タイ?記部の?サイズをpxで?? 405 chartHeight = getIntParam( "CHART_HEIGHT" ); // ?レコード?チャート?間隔をpxで??実際の??、CHART_HEIGHT?MARGIN?? 406 chartPadding = getIntParam( "CHART_PADDING" ); // イメージ作?の 全体テーブルの隙間 407 recodeMargin = getIntParam( "RECODE_MARGIN" ); // ?コード??等??の間隔 408 useLastData = getBoolParam( "USE_LAST_DATA" ); // 5.6.1.1 (2013/02/08) 行?????が?継続して?として使?ど?[true/false] 409 410 tempDir = getParam( "TEMP_DIR" ); // 画像ファイルを作?する?ポラリ?レクトリ(相対パス) 411 tempUrl = getParam( "TEMP_URL" ); // 作?した画像ファイルを取得するときに使用するURL(コン?ス?相対パス) 412 413 startDate = getStr2Date( s_startDate ); // ?位に変換する? 414 startTime = str2DateTime ; // 開始日時?時刻??(??の値。str2DateTime は、getStr2Date(String)メソ?実行後にセ?される? 415 timeSpan = timeSpanHour * 60L ; // ?位に変換する? 416 417 int len = s_labelClms.length; 418 if( len > 0 ) { 419 labelClmsNo = new int[len]; 420 for( int i=0; i<len; i++ ) { 421 labelClmsNo[i] = getColumnNo( s_labelClms[i] ); 422 } 423 } 424 else { 425 labelClmsNo = new int[] { keyClmNo }; // 初期値は、キーカラ? 426 } 427 428 // ??カラ?に対するカラ?号を取得?なければ?1 を設定しておく? 429 if( s_colClm != null ) { colClmNo = getColumnNo( s_colClm ); } // レコードに付ける色を色??で?する?合?カラ?o 430 if( s_tipsClm != null ) { tipsClmNo = getColumnNo( s_tipsClm ); } // レコード単位に、?ウスオーバ?時?Tips表示を行うカラ?o 431 if( s_linkClm != null ) { linkClmNo = getColumnNo( s_linkClm ); } // レコード単位に、クリ?ブルリンクを設定するカラ?o 432 } 433 434 /** 435 * イメージの ??サイズを求め、結果を?MAX_X,MAX_Y 変数に設定します? 436 * 437 * また?ラベル??の?長が指定されて???合?axLabelWidth == -1?最大長を?動計算し、maxLabelWidth変数にセ?します? 438 * 439 * maxLabelWidth : -1 の場合?、ラベル??の?長を求めて、この値を計算する?= (recodeMargin*2 + ラベル??の?長) 440 * MAX_X : イメージの?横?X)方向?サイズpx。chartPadding*2 + maxLabelWidth + maxTimeWidth 441 * MAX_Y : イメージの?縦?Y)方向?サイズpx。chartPadding*2 + (chartHeight+recodeMargin*2)*(レコード数???ー数) 442 * 443 * @og.rev 5.6.3.1 (2013/04/05) 短縮ラベルなど?span>タグが付与される値から、spanタグを削除します? 444 * 445 * @param startNo 計算?開始?番号 446 * @param lastNo 計算?終??番号 447 */ 448 private void calcImageSize( final int startNo , final int lastNo ) { 449 String oldKeyVal = ""; // 初期値。1回目にキーブレイクさせる? 450 451 int clmSu = labelClmsNo.length; 452 maxClmWidth = new int[clmSu]; 453 454 int rowCnt = (useLegend) ? 2 : 1; // 凡?useLegend)を使?true)場合??行?、使わな??合?、??ーの?行が初期値 455 456 // ラベル領域の長さを?ベル長を積み上げて計算する? 457 if( maxLabelWidth < 0 ) { 458 // FontMetrics を取得する為?の BufferedImage 459 BufferedImage img = new BufferedImage( 1, 1, BufferedImage.TYPE_INT_ARGB); 460 Graphics2D g2 = img.createGraphics(); 461 FontMetrics fontM = g2.getFontMetrics(); 462 463 // 初期値の計算?、??ーのラベルの?使用する? 464 for( int col=0; col<clmSu; col++ ) { 465 String lbl = getColumnLabel( labelClmsNo[col] ); // ヘッ??のラベル 466 lbl = StringUtil.spanCut( lbl ); // 5.6.3.1 (2013/04/05) spanタグを削除 467 maxClmWidth[col] = fontM.stringWidth( lbl ); // ?値の初期値として、??ーラベルの?セ?しておく? 468 } 469 470 for( int row=startNo; row<lastNo; row++ ) { 471 // キーブレイク判定?キーブレイクは、?初めから来る? 472 String keyVal = getValue( row,keyClmNo ); 473 if( !oldKeyVal.equals( keyVal ) ) { 474 oldKeyVal = keyVal; 475 rowCnt++; // レコード数 476 477 // ラベルは、キーブレイク時?値のみ採用する? 478 for( int col=0; col<clmSu; col++ ) { 479 String lbl = getValueLabel( row,labelClmsNo[col] ); // そ?行?値のRenderer値 480 lbl = StringUtil.spanCut( lbl ); // 5.6.3.1 (2013/04/05) spanタグを削除 481 int fontW = fontM.stringWidth( lbl ); 482 if( maxClmWidth[col] < fontW ) { maxClmWidth[col] = fontW; } 483 } 484 } 485 } 486 g2.dispose(); 487 488 // ?ラベル??、各ラベルの?値?(?ージン?2)*カラ? 489 maxLabelWidth = recodeMargin * 2 * clmSu ; 490 for( int col=0; col<clmSu; col++ ) { 491 maxLabelWidth += maxClmWidth[col]; 492 } 493 } 494 else { 495 for( int row=startNo; row<lastNo; row++ ) { 496 // キーブレイク判定?キーブレイクは、?初めから来る? 497 String keyVal = getValue( row,keyClmNo ); 498 if( !oldKeyVal.equals( keyVal ) ) { 499 oldKeyVal = keyVal; 500 rowCnt++; // レコード数 501 } 502 } 503 504 // ?ラベル??、均等割り付け。端数は無視(ど?、ラベル部は、maxLabelWidth で計算する?で。? 505 int clmWidth = ( maxLabelWidth - recodeMargin * 2 * clmSu ) / clmSu ; 506 for( int col=0; col<clmSu; col++ ) { 507 maxClmWidth[col] = clmWidth; 508 } 509 } 510 511 MAX_X = chartPadding*2 + maxLabelWidth + maxTimeWidth ; 512 MAX_Y = chartPadding*2 + (chartHeight+recodeMargin*2)*rowCnt ; 513 } 514 515 /** 516 * ヘッ????のイメージを作?します? 517 * 518 * 全体??ここで作?しておきます? 519 * イメージは、キーカラ??ラベルと、時間軸になります?時間軸は縦方向にすべて線を引きます? 520 * 時間軸の間隔は、timeScale によって、?り替わります? 521 * 凡例を使??合?seLegend=true??、引数の ColorMap を利用して作?します? 522 * 523 * @og.rev 5.6.3.1 (2013/04/05) 短縮ラベルなど?span>タグが付与される値から、spanタグを削除します? 524 * @og.rev 5.6.5.0 (2013/06/07) 年月日??を表示します?なお?日単位?場合?、年月?省略します? 525 * 526 * @param g2 描画するGraphics2Dオブジェク? 527 * @param timeScale 時間(?当たり?ピクセル数 528 * @param colMap 状況コードに対応したカラーマッ? 529 */ 530 private void imageHeaderPaint( final Graphics2D g2 , final double timeScale , final ColorMap colMap ) { 531 532 int posY1 = chartPadding ; 533 int posY2 = chartPadding+chartHeight+recodeMargin ; 534 535 // 凡例を使??? 536 if( useLegend && colMap != null ) { 537 // 凡例を並べる間隔を求める? 538 FontMetrics fontM = g2.getFontMetrics(); 539 int maxSize = fontM.stringWidth( colMap.getMaxLengthLabel() ) ; // ??の?長ラベルの? 540 int imgW = chartHeight ; // 凡例■の?高さと同じにして?ので真四? 541 int mgnW = recodeMargin ; // 凡例■から?までの? 542 int spanW = maxSize + recodeMargin ; // 凡例■から凡例■までの間隔。文字最大長?α 543 544 int legX = chartPadding ; 545 for( Object[] obj : colMap.values() ) { 546 String lbl = (String)obj[0]; 547 Color col = (Color)obj[1]; 548 549 g2.setColor( col ); // 凡例■の色 550 g2.fillRect( legX , posY1+recodeMargin , imgW , chartHeight ); // (実際の状?左端x,上端y,?,高さh 551 552 legX += imgW + mgnW ; 553 g2.setColor( LABEL_COLOR ); 554 g2.drawString( lbl , legX , posY2 ); // ??,ベ?スラインのx座?y座? 555 556 legX += spanW ; 557 } 558 posY1 += chartHeight+recodeMargin*2 ; // ?レコード?の高さを加算しておく? 559 posY2 += chartHeight+recodeMargin*2 ; // ?レコード?の高さを加算しておく? 560 } 561 562 // まず?、?体???描画 563 g2.setColor( LABEL_COLOR ); 564 g2.drawRect( chartPadding, posY1, MAX_X-chartPadding*2, MAX_Y-posY1-chartPadding ); // 左端,上端,?高さ 565 566 // ヘッ??のラベル?け?繰返し描画する? 567 int clmSu = labelClmsNo.length; 568 int posX = chartPadding ; // ラベル??の書き?し位置の初期値 569 for( int col=0; col<clmSu; col++ ) { 570 String lbl = getColumnLabel( labelClmsNo[col] ); // ヘッ??のラベル 571 lbl = StringUtil.spanCut( lbl ); // 5.6.3.1 (2013/04/05) spanタグを削除 572 g2.drawString( lbl , posX + recodeMargin, posY2 ); // ??,ベ?スラインのx座?y座? 573 posX += recodeMargin*2 + maxClmWidth[col] ; // 次の書き?し位置は、文字最大長??ージン*2 574 g2.drawLine( posX, posY1, posX, MAX_Y-chartPadding ); // 始点(x 座?y 座?,終点(x 座?y 座? 575 } 576 577 int step = TimeScaleStep.getStep( timeScale ); // 時間スケールに対応したSTEP数 578 579 // 日付??ー部の描画のためのカレン?? 580 Calendar cal = Calendar.getInstance(); 581 cal.setTimeInMillis( startDate * 60000L ); 582 583 int week = cal.get( Calendar.DAY_OF_WEEK ); // 開始曜日 584 585 String fmt = ( step < 1440 ) ? "yyyy/MM/dd(EE)" : "dd" ; // 上段フォーマット?、時間?ースの場合??yyyy/MM/dd(EE)" 、日ベ?スの場合??dd" 586 DateFormat format1 = new SimpleDateFormat( fmt,Locale.JAPAN ); 587 588 // グラフ?域?日付??ー部の描画 589 g2.setStroke( DSAH_STROK ); // 日付部は、?? 590 posX = chartPadding+maxLabelWidth ; // グラフ?域?、chartPadding+maxLabelWidth から? 591 for( int tm = 0; tm < timeSpan; tm+=step ) { 592 593 int offset = chartHeight / 2 + recodeMargin; // ヘッ??の表示基準?オフセ??チャート??半??? 594 595 // 上段???ー出? 596 if( ( tm % 1440 ) == 0 ) { 597 Date dt = new Date( (startDate + tm) * 60000L ); 598 g2.drawString( format1.format( dt ) , posX + recodeMargin , posY2-offset ); // ??,ベ?スラインのx座?y座? 599 offset = 0; // ヘッ??を表示する場合?み上まで線を引く? 600 } 601 602 g2.drawString( getTime2Str(startTime+tm,step,week) , posX + recodeMargin , posY2 ); // ??,ベ?スラインのx座?y座? 603 g2.drawLine( posX, posY1+offset, posX, MAX_Y-chartPadding ); // 始点(x 座?y 座?,終点(x 座?y 座? 604 605 // g2.drawString( getTime2Str(startTime+tm,step) , posX + recodeMargin , posY2 ); // ??,ベ?スラインのx座?y座? 606 // g2.drawLine( posX, posY1-10, posX, MAX_Y-chartPadding-10 ); // 始点(x 座?y 座?,終点(x 座?y 座? 607 posX += (int)(step*timeScale); 608 } 609 } 610 611 // imageHeaderPaintメソ?で使用する 破線?定義 612 private static final Stroke DSAH_STROK = new BasicStroke( 613 1.0f , // BasicStroke の? 614 BasicStroke.CAP_BUTT , // 両端の? 615 BasicStroke.JOIN_MITER , // 輪郭線セグメント?接合部の? 616 1.0f , // 接合トリミングの制限? 617 new float[] {2.0f, 1.0f} , // 破線パターンを表す?? 618 0.0f // 破線パターン開始位置のオフセ? 619 ); 620 621 /** 622 * 時間スケールに対応したSTEP数を管?るため??クラス 623 * 624 * 時間ヘッ??を表示する場合?ある程度意味のある間隔でラベル表示した?思います? 625 * 全体?描画領域の長さと、時間当たり?スケールファクター?ピクセル数?から? 626 * ラベルの描画間隔を求めます? 627 * 意味のある間隔は、STEPS で定義し?10?30?60?1/4日,1/2日,1日 まで定義して?す? 628 * ?大きな単位以上?場合?、その?単位?整数倍を返します? 629 * 630 * ?間当たり?表示?、MIN_PX として?す?で、この値以下?間隔では描画されません? 631 * 初期値は?00px ?24時間表示できる 600px/24h = 25px にして?す? 632 */ 633 private static final class TimeScaleStep { 634 // ? ? ? 1/4 1/2 ?日 635 private static final int[] STEPS = new int[] { 10 , 30 , 60 , 360 , 720 , 1440 }; 636 private static final int MIN_PX = 25; // スケールに対する?? 637 638 /** 639 * 時間を意味のある?の整数として返します? 640 * 641 * 全体?描画領域の長さと、時間当たり?スケールファクター?ピクセル数?から? 642 * 10?30?60?1/4日,1/2日,1日 までの整数値で返します? 643 * ?大きな単位以上?場合?、その?単位?整数倍を返します? 644 * 645 * @param timeScale 時間(?当たり?ピクセル数 646 * @return 時間スケールに対応した意味のある?の整数 647 */ 648 public static final int getStep( final double timeScale ) { 649 int tmStep = (int)Math.ceil(MIN_PX/(timeScale)); // 整数?上げ 650 651 for( int i=0; i<STEPS.length; i++ ) { 652 if( tmStep <= STEPS[i] ) { return STEPS[i]; } // 配?の数字に?上げ 653 } 654 655 // 未設定?場合?、最上位?値の整数倍に?上げ 656 return (int)Math.ceil( tmStep / STEPS[STEPS.length-1] ) * STEPS[STEPS.length-1]; 657 } 658 } 659 660 /** 661 * 状況コード?ラベル、色を管?るため??クラス 662 * 663 * 状況に応じたコード?ラベル、色を管?ます? 664 * これは、getColor(状況コー?ラベル) また?、getColor(状況コー?ラベル,色??) で 665 * 要求された??を?部で管?、同じコード?場合に同じ色を返します? 666 * また?凡例作?用に、最も文字数が長?ベルを管?ます? 667 * 色??を指定した?合でも???に要求された状況コードに対応する色を返します? 668 * これは、同?況コードで色違いを作?することができな?とを意味します? 669 * 色??を指定しな??合?、?部の色配?から??番に色を割り当てます? 670 * 色を割り当てる?番は、状況コード?発生?です?よって、検索条件によって? 671 * 状況コード?現れる?が異なると、色も毎回異なることになります? 672 * 673 * 自動割り当ての色は、BLUE,CYAN,GRAY,GREEN,LIGHT_GRAY,MAGENTA,DARK_GRAY,ORANGE,PINK,RED,YELLOW 674 * となっており、それを?ると、RGBをラン?に発生させて色を作?します? 675 * よって、どのような色になるかは全くわかりません? 676 */ 677 private static final class ColorMap { 678 private static final Color[] CLR_ARY = new Color[] { 679 Color.BLUE ,Color.CYAN ,Color.GRAY ,Color.GREEN ,Color.LIGHT_GRAY ,Color.MAGENTA , 680 Color.DARK_GRAY ,Color.ORANGE ,Color.PINK ,Color.RED ,Color.YELLOW 681 }; 682 private int lastCnt = 0; 683 private final Map<String,Object[]> colMap = new TreeMap<String,Object[]>(); 684 private String maxLabel = "" ; // ?長のラベル 685 private int maxlen = -1 ; // ?長のラベルのlength() 686 687 /** 688 * 状況コードに対応した色オブジェクトを返します? 689 * 690 * 状況コードが初めて?された場合???番に?の色を割り当てます? 691 * また?そ?時?ラベルも管?ます?ラベルと色のセ?は、?例作?時に利用されます? 692 * 693 * 自動割り当ての色は、BLUE,CYAN,GRAY,GREEN,LIGHT_GRAY,MAGENTA,DARK_GRAY,ORANGE,PINK,RED,YELLOW 694 * となっており、それを?ると、RGBをラン?に発生させて色を作?します? 695 * よって、どのような色になるかは全くわかりません? 696 * 697 * @param fgj 状況コー? 698 * @param lbl 状況コード?ラベル 699 * @return 状況コードに対応した色オブジェク? 700 */ 701 public Color getColor( final String fgj,final String lbl ) { 702 return getColor( fgj,lbl,null ); 703 } 704 705 /** 706 * 状況コードに対応した色オブジェクトを返します? 707 * 708 * 状況コードが初めて?された場合?、引数の色??の色を割り当てます? 709 * また?そ?時?ラベルも管?ます?ラベルと色のセ?は、?例作?時に利用されます? 710 * 711 * 色??を指定した?合でも???に要求された状況コードに対応する色を返します? 712 * これは、同?況コードで色違いを作?することができな?とを意味します? 713 * 色?? ?null の場合?、?動割り当てのメソ?と同じです? 714 * よって、色??の?と、?動割り当てが同時に発生すると、異なる状況コードで 715 * 同じ色が指定される可能性があります?で、混在して使用しな?ください? 716 * 717 * @param fgj 状況コー? 718 * @param lbl 状況コード?ラベル 719 * @param colStr 状況コードに対応した色??(nullの場合?、?動割り当て) 720 * @return 状況コードに対応した色オブジェク? 721 */ 722 public Color getColor( final String fgj,final String lbl,final String colStr ) { 723 if( fgj == null ) { return LABEL_COLOR; } 724 if( lbl != null ) { 725 int len = lbl.length(); 726 if( len > maxlen ) { maxLabel = lbl; maxlen = len; } 727 } 728 729 Object[] obj = colMap.get( fgj ); 730 if( obj == null ) { 731 obj = new Object[2]; 732 obj[0] = lbl; 733 obj[1] = (colStr != null) ? StringUtil.getColorInstance( colStr ) : uniqColor(); 734 735 colMap.put( fgj,obj ); 736 } 737 738 return (Color)obj[1] ; 739 } 740 741 /** 742 * ?のシーケンスに対応した?ユニ?クな色オブジェクトを返します? 743 * 744 * ?カウンターを+?しながら、?部の色オブジェクトを返します? 745 * 746 * 自動割り当ての色は、BLUE,CYAN,GRAY,GREEN,LIGHT_GRAY,MAGENTA,DARK_GRAY,ORANGE,PINK,RED,YELLOW 747 * となっており、それを?ると、RGBをラン?に発生させて色を作?します? 748 * よって、どのような色になるかは全くわかりません? 749 * 750 * @return ユニ?クな色オブジェク? 751 */ 752 public Color uniqColor() { 753 Color col = null; 754 if( lastCnt < CLR_ARY.length ) { 755 col = CLR_ARY[lastCnt++]; 756 } 757 else { 758 int R=(int)(Math.random()*256); 759 int G=(int)(Math.random()*256); 760 int B=(int)(Math.random()*256); 761 col = new Color(R,G,B); 762 } 763 764 return col; 765 } 766 767 /** 768 * ?で管?て?、ラベル(String)と色オブジェク?Color)の コレクションを返します? 769 * 770 * ?で管?て?コレクションです? 771 * こ?コレクションは、状況コードでソートされて?す? 772 * コレクションの中身は、オブジェクト?列となっており、[0]は、String型?ラベル、[1]は? 773 * Color型?色です? 774 * 775 * @return ラベル(String)と色オブジェク?Color)の コレクション 776 */ 777 public Collection<Object[]> values() { 778 return colMap.values(); 779 } 780 781 /** 782 * 登録されたラベル??で、最も文字数が長?ベルを返します? 783 * 784 * 凡例で、ラベルの?長を求める?に利用できます? 785 * ただし?簡易的に、length() 計算して??なので、英語?日本語混在?? 786 * プロポ?ショナルフォント使用時?厳??長の??ではありません? 787 * 788 * @return ??数が長?ベル 789 */ 790 public String getMaxLengthLabel() { return maxLabel; } 791 } 792 793 /** 794 * 時間??を数字に変換します? 795 * 796 * "0800" は?80に?2100" は?260 に変換します? 797 * つまり??位?値に変換します?秒?単位?、?り捨てます? 798 * ここでは、時間文字?が?08:00 の様に?:" を含??合?、削除し? 799 * ?ケタ以上?場合?、前から?ケタ?使?す? 800 * ?ケタ以下(1,2,3ケタ?でも?先?に 0 埋めで、時間文字?にします? 801 * ?ケタ、およ?、null の場合?、defTm 初期値 を返します? 802 * 803 * @param val 時間??の値(0800 など) 804 * @param defTm 引数の時間???null の場合?初期値 805 * 806 * @return 時間??を数字に変換した結果( 80 など) 807 */ 808 private int getStr2Time( final String val , final int defTm ) { 809 if( val == null || val.isEmpty() ) { return defTm; } 810 811 // 桁数によって、???仕方が変わるため? 812 int rtnInt = 0; 813 switch( val.length() ) { 814 case 1: 815 case 2: rtnInt = Integer.parseInt( val ); break; 816 case 3: rtnInt = Integer.parseInt( val.substring( 0,1 ) )*60 + Integer.parseInt( val.substring( 1,3 ) ); break; 817 default : rtnInt = Integer.parseInt( val.substring( 0,2 ) )*60 + Integer.parseInt( val.substring( 2,4 ) ); break; 818 } 819 820 return rtnInt ; 821 } 822 823 /** 824 * 日時文字?を数字に変換します? 825 * 826 * 日時文字?は、yyyyMMdd また?、yyyyMMddhhmmss 形式とします? 827 * これを?エポックタイ?ら?経過時間の ?位?値を求めます? 828 * 具体的には、Calendar オブジェクト? getTimeInMillis() の結果を? 829 * 60000 で割り算した?を作?します? 830 * よって、Calendar オブジェクト作?時も、秒?単位??捨てます? 831 * 引数?null の場合?、現在時刻より、作?します? 832 * 833 * @param val 日時文字?の値(yyyyMMdd また?、yyyyMMddhhmmss 形?など) 834 * 835 * @return 日時文字?を?換算した数? 836 */ 837 private long getStr2Date( final String val ) { 838 Calendar cal = Calendar.getInstance(); 839 str2DateTime = 0; 840 if( val == null ) { 841 cal.set( Calendar.HOUR_OF_DAY, 0 ); // 5.3.5.0 (2011/05/01) 時間の解決規則が適用されるため??時」?は、setメソ?で 0 にセ?する? 842 cal.clear( Calendar.MINUTE ); 843 cal.clear( Calendar.SECOND ); 844 cal.clear( Calendar.MILLISECOND ); 845 } 846 else if( val.length() == 8 ) { 847 cal.clear(); 848 cal.set( Integer.parseInt( val.substring( 0,4 ) ) , // 年 849 Integer.parseInt( val.substring( 4,6 ) ) - 1, // ?0から始ま? 850 Integer.parseInt( val.substring( 6,8 ) ) // 日 851 ); 852 } 853 else { 854 cal.clear(); 855 cal.set( Integer.parseInt( val.substring( 0,4 ) ) , // 年 856 Integer.parseInt( val.substring( 4,6 ) ) - 1, // ?0から始ま? 857 Integer.parseInt( val.substring( 6,8 ) ) , // 日 858 Integer.parseInt( val.substring( 8,10 ) ) , // ? 859 Integer.parseInt( val.substring( 10,12 ) ) // ? 860 ); 861 str2DateTime = Integer.parseInt( val.substring( 8,10 ) ) * 60 + Integer.parseInt( val.substring( 10,12 ) ) ; 862 } 863 return (cal.getTimeInMillis() / 60000L); // ?位に変換する? 864 } 865 866 // 5.6.5.0 (2013/06/07) 曜日??タを?列で持っておきます? 867 private static final String[] DAY_OF_WEEK_ja = new String[] { "?,"日","?,"火","水","木","?,"? }; // [0]="? は??? の余計算で?7=0 になる為? 868 869 /** 870 * 数??を時間文字?に変換します? 871 * 872 * 480 は?08" に?260 は?21" に変換します? 873 * 引数の時間は、?を表す整数です??4時間表記であれば? ??1440 の?で収まりますが? 874 * 期間が長??合?、その値を?ます?また??4時間を?る?合?? に戻ります? 875 * ??にする場合??単位???なので?0(?で割り算して、余?、?り捨てます? 876 * step は?0(?単位?表示時に飛?す数です?step=1 なら?60(?単位?step=2 なら?120(? 877 * 単位となります?stepが?24 以下?場合?、そのまま?4時間表記で構いませんが? 878 * それを?ると時間ではなく?日数表記に?替わります? 879 * 880 * @og.rev 5.6.5.0 (2013/06/07) 月単位?場合?、曜日を表示します? 881 * 882 * @param timeVal 引数の時間整数(? 883 * @param step 60?位?ス?プ数( 10,30,60,720,1440 単位となるよ?調整) 884 * @param week カレン?ラスの曜日フィール?DAY_OF_WEEK) 885 * 886 * @return 数字を時間??に変換した結果( "08" など) 887 */ 888 // private String getTime2Str( final int timeVal, final int step ) { 889 private String getTime2Str( final int timeVal, final int step, final int week ) { 890 891 int dtm = (timeVal / 60 / 24 ); // 日 892 int htm = ((timeVal / 60) % 24 ); // ??4時間制) 893 int mtm = (timeVal % 60 ); // ??0?制) 894 895 StringBuilder rtn = new StringBuilder(); 896 897 if( step >= 1440 ) { 898 // rtn.append( dtm ).append( "d" ); // 5.6.5.0 (2013/06/07) 相対日付? 899 rtn.append( DAY_OF_WEEK_ja[ ( dtm + week ) % 7 ] ); // 曜日を表示 900 } 901 else { 902 if( htm < 10 ) { rtn.append( "0" ); } 903 rtn.append( htm ); 904 905 if( step < 60 ) { 906 rtn.append( ":" ); 907 if( mtm < 10 ) { rtn.append( "0" ); } 908 rtn.append( mtm ); 909 } 910 } 911 912 return rtn.toString(); 913 } 914 915 // 引数に?を追?る? 916 917 /** 918 * 表示?の編?並び替?が可能かど?を返しま? 919 * 920 * @return 表示?の編?並び替?が可能かど?(false:不可能) 921 */ 922 @Override 923 public boolean isEditable() { 924 return false; 925 } 926 }