2017年4月3日月曜日

時間帯を色分けするhta

毎日の活動内容をざっくり分類して、各活動の種類ごとに色を設定して、活動内容が変わるタイミングで対応する色を選択していき、最終的に各色ごとの合算時間を表示するHTAプログラムを作成しました。




起動画面


色はカラーコード(RGB)を変更すれば任意の色に変えられます。
各色に対応する内容を入力して以下のようにします。
足りない場合は「色追加」ボタンで追加することもできます。



「開始」ボタンを押すとカウントが始まり、切り替え用ラジオボックスが表示されます。



ラジオボックスを切り替えると、切り替える前までの活動の終了時刻が記録されると共に次の活動の開始時刻も記録されます。



「終了」ボタンを押すと以下のようにリザルトが表示されます。



カラーバーの各色にマウスカーソルを乗せると、そのバーに対応する情報が表示されます。
「コメント」はバーごとに個別の文字列を記録できます。



以下ソース
<html>
<head>
<title>時間帯の色分け</title>
<style type="text/css">
.max{width:100%;height:100%}
.w-max{width:100%}
.nowrap{white-space:nowrap}
.ta-c{text-align:center}
.bc{border-collapse:collapse}
.of-auto{overflow:auto}
.of-hidden{overflow:hidden}
.border1{border:solid 1px #000}
</style>
</head>
<body>
<table class="bc max" border=1>
<tr height=1>
<td>色の種類</td>
<td>
<table id=tbl色 class="w-max bc" border=1>
<td width=100><input class=w-max></td>
<td><input class=w-max></td>
</table>
<button id=btn色追加>色追加</button>
</td>
</tr>
<tr height=1>
<td>カウント</td>
<td>
<button id=btn開始>開始</button>
<button id=btn終了 style="display:none">終了</button>
</td>
</tr>
<tr height=1><td>切り替え</td><td id=td切り替え><label style="float:left"><input type=radio name=rad><span></span></label></td></tr>
<tr height=1><td>スケール</td><td><select id=sel></select></td></tr>
<tr height=1><td>カラーバー</td><td><div id=div0 class="of-auto nowrap border1" style="width:100%;height:40px"></div></td></tr>
<tr height=1><td width=120>内容</td><td id=td内容></td></tr>
<tr><td width=120>コメント</td><td><textarea id=ta class=max wrap=off></textarea></td></tr>
<tr height=1><td>開始</td><td id=td開始></td></tr>
<tr height=1><td>終了</td><td id=td終了></td></tr>
<tr height=1><td>期間</td><td id=td期間></td></tr>
<tr height=1><td>リザルト</td><td id=tdリザルト></td></tr>
</table>
</body>
<script>
resizeTo(400,750)
FI='firstChild', iB='insertBefore', CN='childNodes', LEN='length', iT='innerText', iH='innerHTML'
for0L = function(arr,fun){for(var i=0,L=arr[LEN],res;i<L;i++){if(res=fun(i,arr[i])){return res}}}
forIn = function(obj,fun){var name,res; for(name in obj){if(res=fun(name, obj[name])){return res}}}
me=function(){return arguments.callee.caller}
onload=function(){
var ops=sel.options, i=0
ops[i++] = new Option('全体',0)
ops[i++] = new Option('分' ,1000*60)
ops[i++] = new Option('時間',1000*60*60)
ops[i++] = new Option('日' ,1000*60*60*24)
ops[i++] = new Option('週' ,1000*60*60*24*7)
ops[i++] = new Option('月' ,1000*60*60*24*31)
ops[i++] = new Option('年' ,1000*60*60*24*365)
var tbo=tbl色[FI], tr=tbo[FI].removeNode(true), newTR
var fun色=function(i,str){
tbo[iB](newTR=tr.cloneNode(true))
var cn=newTR[CN], inp0=cn[0][FI], inp1=cn[1][FI]
inp0.style.backgroundColor = '#' + (inp0.value = str)
arr色[i] = {code:arr色[i]}
;(inp0.onchange=function(){
var str=this.value, i=me().i, obj=arr色[i]
if(!str){
if(!confirm('['+obj.code+']を削除しますか?')){ return this.value = obj.code }
arr色 = arr色.slice(0,i).concat(arr色.slice(i+1,arr色.length))
return 色の種類表示を初期化()
}
this.style.backgroundColor = '#' + (obj.code = str)
}).i = i
;(inp1.onchange=function(){ arr色[me().i].内容 = this.value }).i = i
}
var 色の種類表示を初期化=function(){
while(tbo[FI]){ tbo[FI].removeNode(true) }
for0L(arr色,fun色)
}
色の種類表示を初期化()
btn色追加.onclick=function(){
var code='cccccc'
fun色(arr色.push(code)-1, code)
}
var lbl=td切り替え[FI].removeNode(true), newL
radio初期化=function(){
td切り替え[iT] = ''
for0L(arr色,function(i,obj){
td切り替え[iB](newL=lbl.cloneNode(true))
var cn=newL[CN], rad=cn[0], span=cn[1]
rad.value = i
newL.style.backgroundColor = '#' + (span[iT] = obj.code)
;(newL.onclick=function(){ chg(me().i) }).i = i
})
}
}
arr記録 = []
arr色 = ['E60012', 'F39800', 'FFF100', '009944', '0068B7', '1D2088', '920783']
インターバル={
開始:function(){ this.クリア用obj = setInterval(帯を表示, this.間隔) },
終了:function(){ clearInterval(this.クリア用obj); 帯を表示() },
クリア用obj:null,
間隔:1000
}
sel.onchange=function(){ 帯を表示() }
ms2日時=function(ms){with(new Date(ms)){return [getFullYear(), getMonth()+1,getDate()].join('/')+' '+[getHours(),getMinutes(),getSeconds()].join(':')}}
帯を表示=function(){
var 単位=sel.options[sel.selectedIndex].value-0, d=document.createElement('span'), newD
var 今=gt(), 最後=arr記録[arr記録.length-1], 期間=(最後.str=='終了' ? 最後.t : 今) - arr記録[0].t
div0.innerText = ''
d.height='20px'
var f=function(i){
var 開始=arr記録[i].t, 終了=arr記録[i+1] ? arr記録[i+1].t : 今
div0.insertBefore(newD=d.cloneNode(true))
newD.style.backgroundColor = '#'+arr記録[i].色
;(newD.onmouseover = function(){
ta.onchange()
var obj=arguments.callee.obj, 長さ=obj.終了-obj.開始
ta.value = arr記録[i].コメント || ''
td内容[iT] = arr記録[i].内容 || ''
td開始.innerText = ms2日時(obj.開始)
td終了.innerText = ms2日時(obj.終了)
td期間.innerText = (Math.round(長さ * 10 / (単位 || 1000)) / 10) +' '+ (単位 ? sel.options[sel.selectedIndex].text : '秒')
ta.onchange.i = i
}).obj = {開始:開始, 終了:終了}
newD.style.width = ((終了-開始) / (単位 || 期間) * 100) + '%'
}
for(var i=0,L=arr記録.length-1;i<L;i++){ f(i) }
最後.str!='終了' && f(i)
}
ta.onchange=function(){
var i=arguments.callee.i
if(!isFinite(i)){return}
arr記録[i].コメント = this.value
}
btn開始.onclick = function(){
btn終了.style.display = 'block'
this.style.display = 'none'
arr記録.push({t:gt(), str:'開始', 色:'ccc'})
インターバル.開始()
radio初期化()
}
btn終了.onclick = function(){
this.style.display = 'none'
btn開始.style.display = 'block'
arr記録.push({t:gt(), str:'終了', 色:'ccc'})
インターバル.終了()
リザルト表示()
}
リザルト表示=function(){
var obj結果={}, 最後=arr記録.length-1
for0L(arr記録,function(i,obj){
if(i==最後){return}
if(!obj結果[obj.色]){ obj結果[obj.色] = 0 }
obj結果[obj.色] += arr記録[i+1].t - obj.t
})
tdリザルト[iH] = '<table><td></td><td></td></table>'
var tbo=tdリザルト[FI][FI], tr=tbo[FI].removeNode(true), newTR
forIn(obj結果,function(code,num){
tbo[iB](newTR=tr.cloneNode(true))
with(newTR[CN][0]){style.backgroundColor='#'+(innerText=code)}
newTR[CN][1][iT] = time単位(num)
})
}
time単位=function(ミリ秒){
// 値の大きさに応じて「秒」「分」「時間」などの単位に直した文字列を返す。
var f=function(){return Math.round(ミリ秒/1000/num*10)/10}, num=1
if(ミリ秒 < 1000 * 60){return f()+'秒'}
if(ミリ秒 < 1000 * 60 * (num=60)){return f()+'分'}
if(ミリ秒 < 1000 * (num=60 * 60) * 24){return f()+'時間'}
if(ミリ秒 < 1000 * (num=60 * 60 * 24) * 7){return f()+'日'}
if(ミリ秒 < 1000 * (num=60 * 60 * 24) * 31){return f(num*=7)+'週'}
if(ミリ秒 < 1000 * (num=60 * 60 * 24) * 365){return f(num*=31)+'月'}
num = 60 * 60 * 24 * 365
return f()+'年'
}
chg=function(i){ arr記録.push({t:gt(), 色:arr色[i].code, 内容:arr色[i].内容}) }
gt=function(d){return (d || new Date()).getTime()}
</script>
</html>


0 件のコメント:

コメントを投稿