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 * 出来ませんので、ご注意くã�?�•ã�??
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画像化しますã?
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) 短縮ラベルなどã€?lt;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 }