require "numru/dcl"
require "numru/misc"
require "date" # needs ruby >= 1.8 for DateTime class
module NumRu
module DCLExt
module_function
@@datetime_ax_options = Misc::KeywordOptAutoHelp.new(
['yax', false, 'true => y-axis, false => x-axis'],
['cside', nil, '"b", "t", "l", "r", nil (=>left/bottom), or false (=>right/top)'],
['dtick1', 1, 'small tick interval in hours'],
['dtick2', nil, 'large tick (with hour labels) interval in hours'],
['year', false, 'true => add year to date label'],
['month', true, 'true => add month to date label']
)
def datetime_ax(date_from, date_to, options=nil)
# date_from [a DateTime] : start on this date&time
# date_to [a DateTime] : end on this date&time
opt = @@datetime_ax_options.interpret(options)
yax = opt['yax']
xax = !yax
if xax
xy='x'
else
xy='y'
end
if opt['cside']
cside = opt['cside']
elsif opt['cside'].nil?
if xax
cside='b'
else
cside='l'
end
else
if xax
cside='t'
else
cside='r'
end
end
if opt['year']
datefmt = '%Y/%m/%d'
elsif opt['month']
datefmt = '%m/%d'
else
datefmt = '%d'
end
# < window parameters >
ux1,ux2,uy1,uy2 = DCL.sgqwnd
if xax
u1, u2 = ux1, ux2
else
u1, u2 = uy1, uy2
end
loffset_save = DCL.uzpget('loffset')
xyfact_save = DCL.uzpget(xy+'fact')
xyoffset_save = DCL.uzpget(xy+'offset')
tu1 = date_from.day_fraction.to_f
range_day = date_to - date_from # time btwn start and end (in days)
tu2 = tu1 + range_day
# < axis in hours >
DCL.uzpset('loffset',true)
DCL.uzpset(xy+'fact',24.0)
DCL.uzpset(xy+'offset',(tu1-u1)*24)
dtick1 = opt['dtick1']
if opt['dtick2']
dtick2 = opt['dtick2']
else
if range_day >= 4
dtick2 = 24
elsif range_day >= 2
dtick2 = 12
elsif range_day >= 1
dtick2 = 6
elsif range_day >= 0.5
dtick2 = 3
elsif range_day >= 0.25
dtick2 = 2
else
dtick2 = 1
end
end
str_hour = (tu1*24).ceil
end_hour = (tu2*24).floor
tick1=Array.new
tick2=Array.new
labels=Array.new
h1 = str_hour + (-str_hour % dtick1)
(h1..end_hour).step(dtick1){|i| tick1.push(i)}
h2 = str_hour + (-str_hour % dtick2)
(h2..end_hour).step(dtick2) do |i|
tick2.push(i)
labels.push((i%24).to_s)
end
if xax
DCL.uxaxlb(cside, tick1, tick2, labels, 2)
else
irotl_save = DCL.uzpget('irotly'+cside)
icent_save = DCL.uzpget('icenty'+cside)
DCL.uzpset('irotly'+cside,1)
DCL.uzpset('icenty'+cside,0)
DCL.uyaxlb(cside, tick1, tick2, labels, 2)
end
# < labels in days >
if DCL.uzpget('label'+xy+cside)
DCL.uzpset(xy+'fact',1.0)
DCL.uzpset(xy+'offset',0.0)
str_day = tu1.floor
end_day = tu2.floor
pos=Array.new
labels=Array.new
(str_day..end_day).step(1) do |i|
u = i.to_f + 0.5 + (u1- tu1)
u = (u1+u+0.5)/2 if u < u1
u = (u2+u-0.5)/2 if u > u2
pos.push(u)
str = (date_from+i).strftime(datefmt)
str.sub!(/^0/,'') if !opt['year'] && opt['month']
labels.push(str)
end
if xax
DCL.uxsaxz(cside,DCL.uzpget('roffx'+cside))
DCL.uxplbl(cside,1,pos,labels,10)
else
DCL.uysaxz(cside,DCL.uzpget('roffy'+cside))
DCL.uyplbl(cside,1,pos,labels,10)
# DCL.uzpset('irotly'+cside,irotl_save)
# DCL.uzpset('icenty'+cside,icent_save)
end
end
if xax
else
DCL.uzpset('irotly'+cside,irotl_save)
DCL.uzpset('icenty'+cside,icent_save)
end
# < to finish >
DCL.uzpset('loffset',loffset_save)
DCL.uzpset(xy+'fact',xyfact_save)
DCL.uzpset(xy+'offset',xyoffset_save)
end
end
end
######## test program ######
if $0 == __FILE__
include NumRu
iws = (ARGV[0] || (puts ' WORKSTATION ID (I) ? ;'; DCL.sgpwsn; gets)).to_i
DCL.swpset('ldump',true) if iws==4
DCL.gropn iws
DCL.sldiv('y',2,1)
date_from = DateTime.parse('2005-06-30 17:00')
date_to = DateTime.parse('2005-07-01 5:00')
date_from2 = DateTime.parse('2005-06-29 17:00')
date_to2 = DateTime.parse('2005-07-02 5:00')
any_offst = 10
DCL.grfrm
DCL.grswnd(0.0, date_to-date_from, any_offst, date_to2-date_from2+any_offst)
DCL.grsvpt(0.2, 0.8, 0.2, 0.8)
DCL.grstrn(1)
DCL.grstrf
DCLExt.datetime_ax(date_from, date_to, 'year'=>true)
DCLExt.datetime_ax(date_from, date_to, 'cside'=>'t', 'year'=>true)
DCLExt.datetime_ax(date_from2, date_to2, 'yax'=>true)
DCLExt.datetime_ax(date_from2, date_to2, 'yax'=>true, 'cside'=>'r')
DCL.uxsttl('b','TIME AND DATE',0.0)
DCL.uysttl('l','TIME AND DATE',0.0)
DCL.grfrm
DCL.grswnd(0.0, date_to-date_from, 0, date_to2-date_from2)
DCL.grsvpt(0.2, 0.8, 0.2, 0.8)
DCL.grstrn(1)
DCL.grstrf
DCL.uzpset('inner',-1)
DCLExt.datetime_ax(date_from, date_to, 'dtick2'=>2)
DCLExt.datetime_ax(date_from, date_to, 'cside'=>'t', 'dtick2'=>2)
DCL.uzpset('inner',1)
DCLExt.datetime_ax(date_from2, date_to2, 'yax'=>true,
'dtick1'=>2, 'dtick2'=>24)
DCLExt.datetime_ax(date_from2, date_to2, 'yax'=>true, 'cside'=>'r',
'dtick1'=>2, 'dtick2'=>24)
DCL.uxsttl('b','TIME AND DATE',0.0)
DCL.uysttl('l','TIME AND DATE',0.0)
DCL.grcls
end
syntax highlighted by Code2HTML, v. 0.9.1