1# http://pyrocko.org - GPLv3 

2# 

3# The Pyrocko Developers, 21st Century 

4# ---|P------/S----------~Lg---------- 

5 

6from __future__ import absolute_import, print_function 

7 

8from pyrocko import plot 

9 

10 

11ansi_reverse = u'\033[7m' 

12ansi_reverse_reset = u'\033[27m' 

13ansi_dim = u'\033[2m' 

14ansi_dim_reset = u'\033[22m' 

15 

16blocks = u'\u2588\u2589\u258a\u258b\u258c\u258d\u258e\u258f ' 

17bar_right = '\u2595' 

18bar_left = '\u258f' 

19 

20tri_left = '<' # '\u25c0' 

21tri_right = '>' # '\u25b6' 

22hmulti = 'X' 

23vmulti = '%s%%s%s' % (ansi_reverse, ansi_reverse_reset) 

24 

25 

26def time_axis(view_tmin, view_tmax, sx): 

27 

28 lines = [] 

29 for napprox in range(10, 0, -1): 

30 tinc, tunit = plot.nice_time_tick_inc( 

31 (view_tmax - view_tmin) / napprox) 

32 

33 times, labels = plot.time_tick_labels( 

34 view_tmin, view_tmax, tinc, tunit) 

35 

36 if not labels: 

37 # show only ticks? 

38 continue 

39 

40 delta = (view_tmax - view_tmin) / (sx-2) 

41 

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 

51 

52 if it > sx-1: 

53 break 

54 

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 + ' ' 

60 

61 if overfull: 

62 break 

63 

64 for iline in range(nlines): 

65 lines[iline] += ' ' * ((sx-1) - len(lines[iline])) + bar_left 

66 

67 if overfull: 

68 continue 

69 

70 break 

71 

72 return lines 

73 

74 

75def bar(view_tmin, view_tmax, changes, tmin, tmax, sx): 

76 

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 

82 

83 if 0 < ic and ic < len(changes): 

84 count = changes[ic-1][1] 

85 else: 

86 count = 0 

87 

88 out.append(bar_right if (ic == 0 and view_tmin <= tmin) else tri_left) 

89 

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 

100 

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')) 

109 

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]) 

129 

130 elif count == 1 and count == new_count: 

131 out.append(blocks[0]) 

132 else: 

133 out.apped('N') 

134 

135 count = new_count 

136 

137 elif nc_block > 1: 

138 _, count = changes[ic_start + nc_block - 1] 

139 out.append(hmulti) 

140 else: 

141 assert False 

142 

143 out.append( 

144 bar_left if (ic == len(changes) and tmax <= view_tmax) else tri_right) 

145 out.append(ansi_dim_reset) 

146 

147 return ''.join(out) 

148 

149 

150if __name__ == '__main__': 

151 from ..get_terminal_size import get_terminal_size 

152 sx, _ = get_terminal_size() 

153 

154 view_tmin = 0. 

155 view_tmax = 100. 

156 

157 import numpy as num 

158 

159 n = 20 

160 phis = num.linspace(-0.1, 1., n) 

161 

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)) 

171 

172 import time 

173 import numpy as num 

174 t0 = time.time() 

175 exps = num.linspace(-4., 11., 100) 

176 

177 for exp in exps: 

178 

179 for line in time_axis(t0, t0+10**exp, sx): 

180 print(line) 

181 print() 

182 

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() 

189 

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()