1# http://pyrocko.org - GPLv3
2#
3# The Pyrocko Developers, 21st Century
4# ---|P------/S----------~Lg----------
6from pyrocko import plot
9ansi_reverse = u'\033[7m'
10ansi_reverse_reset = u'\033[27m'
11ansi_dim = u'\033[2m'
12ansi_dim_reset = u'\033[22m'
14blocks = u'\u2588\u2589\u258a\u258b\u258c\u258d\u258e\u258f '
15bar_right = '\u2595'
16bar_left = '\u258f'
18tri_left = '<' # '\u25c0'
19tri_right = '>' # '\u25b6'
20hmulti = 'X'
21vmulti = '%s%%s%s' % (ansi_reverse, ansi_reverse_reset)
24def time_axis(view_tmin, view_tmax, sx):
26 lines = []
27 for napprox in range(10, 0, -1):
28 tinc, tunit = plot.nice_time_tick_inc(
29 (view_tmax - view_tmin) / napprox)
31 times, labels = plot.time_tick_labels(
32 view_tmin, view_tmax, tinc, tunit)
34 if not labels:
35 # show only ticks?
36 continue
38 delta = (view_tmax - view_tmin) / (sx-2)
40 itimes = [int(round((t - view_tmin) / delta)) for t in times]
41 nlines = len(labels[0].split('\n'))
42 lines = ([bar_right] if itimes[0] != 0 else ['']) * nlines
43 overfull = False
44 for it, lab in zip(itimes, labels):
45 for iline, word in enumerate(lab.split('\n')):
46 if len(lines[iline]) > it and word:
47 overfull = True
48 break
50 if it > sx-1:
51 break
53 lines[iline] += ' ' * (it - len(lines[iline]))
54 if len(lines[iline]) < sx-1 and (it - len(lines[iline])) >= 0:
55 lines[iline] += bar_right
56 if len(word) > 0 and len(lines[iline]) + len(word) + 1 < sx-1:
57 lines[iline] += word + ' '
59 if overfull:
60 break
62 for iline in range(nlines):
63 lines[iline] += ' ' * ((sx-1) - len(lines[iline])) + bar_left
65 if overfull:
66 continue
68 break
70 return lines
73def bar(view_tmin, view_tmax, changes, tmin, tmax, sx):
75 delta = (view_tmax - view_tmin) / (sx-2)
76 out = [ansi_dim]
77 ic = 0
78 while ic < len(changes) and changes[ic][0] < view_tmin:
79 ic += 1
81 if 0 < ic and ic < len(changes):
82 count = changes[ic-1][1]
83 else:
84 count = 0
86 out.append(bar_right if (ic == 0 and view_tmin <= tmin) else tri_left)
88 for i in range(sx-2):
89 block_tmin = view_tmin + i * delta
90 block_tmax = view_tmin + (i+1) * delta
91 ic_start = ic
92 if i < sx-3:
93 while ic < len(changes) and changes[ic][0] < block_tmax:
94 ic += 1
95 else:
96 while ic < len(changes) and changes[ic][0] <= block_tmax:
97 ic += 1
99 nc_block = ic - ic_start
100 if nc_block == 0:
101 if count == 0:
102 out.append(blocks[-1])
103 elif count == 1:
104 out.append(blocks[0])
105 else:
106 out.append(vmulti % ('%i' % count if count <= 9 else 'N'))
108 elif nc_block == 1:
109 t, new_count = changes[ic_start]
110 ib = int(round((t - block_tmin) / delta * (len(blocks) - 1)))
111 if new_count == 1 and count == 0:
112 out.append(
113 '%s%s%s' % (
114 ansi_reverse, blocks[-ib-1], ansi_reverse_reset))
115 elif new_count == 0 and count == 1:
116 out.append(blocks[-ib-1])
117 elif new_count > count:
118 out.append(
119 '%s%s%s' % (
120 ansi_reverse, '+', ansi_reverse_reset))
121 elif new_count < count:
122 out.append(
123 '%s%s%s' % (
124 ansi_reverse, '-', ansi_reverse_reset))
125 elif count == 0 and count == new_count:
126 out.append(blocks[-1])
128 elif count == 1 and count == new_count:
129 out.append(blocks[0])
130 else:
131 out.append('N')
133 count = new_count
135 elif nc_block > 1:
136 _, count = changes[ic_start + nc_block - 1]
137 out.append(hmulti)
138 else:
139 assert False
141 out.append(
142 bar_left if (ic == len(changes) and tmax <= view_tmax) else tri_right)
143 out.append(ansi_dim_reset)
145 return ''.join(out)
148if __name__ == '__main__':
149 from ..get_terminal_size import get_terminal_size
150 sx, _ = get_terminal_size()
152 view_tmin = 0.
153 view_tmax = 100.
155 import numpy as num
157 n = 20
158 phis = num.linspace(-0.1, 1., n)
160 for phi in phis:
161 tmin = view_tmin + 0.2 * phi * (view_tmax - view_tmin)
162 tmin2 = view_tmin + 0.3 * phi * (view_tmax - view_tmin)
163 tmax2 = view_tmax - 0.3 * phi * (view_tmax - view_tmin)
164 tmax = view_tmax - 0.2 * phi * (view_tmax - view_tmin)
165 print(bar(
166 view_tmin, view_tmax,
167 [[tmin, 1], [tmin2, 2], [tmax2, 1], [tmax, 0]],
168 view_tmin, view_tmax, sx))
170 import time
171 import numpy as num
172 t0 = time.time()
173 exps = num.linspace(-4., 11., 100)
175 for exp in exps:
177 for line in time_axis(t0, t0+10**exp, sx):
178 print(line)
179 print()
181 from pyrocko import util
182 tmin = util.stt('2011-04-15 10:05:14')
183 tmax = util.stt('2012-09-20 14:41:00')
184 for line in time_axis(tmin, tmax, sx):
185 print(line)
186 print()
188 tmin = util.stt('2011-11-27 00:00:00')
189 tmax = util.stt('2011-11-28 00:00:00')
190 for line in time_axis(tmin, tmax, sx):
191 print(line)
192 print()