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