Skip to content

Commit ad08111

Browse files
committed
better handling of ansi ctr char
len() counts the ansi control characters which is not a desired behavior, specially for the info of a data point. Now we have a custom len function that removes those unwanted characters before computing the length resulting in a correct alignment.
1 parent cb11fc7 commit ad08111

File tree

3 files changed

+32
-14
lines changed

3 files changed

+32
-14
lines changed

ascii_graph/__init__.py

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
from __future__ import unicode_literals
55
import sys
6+
import re
67
import collections
78
import copy
89

@@ -68,9 +69,9 @@ def __init__(self, line_length=79,
6869
self.graphsymbol = self._u('█')
6970
else:
7071
self.graphsymbol = graphsymbol
71-
if len(self.graphsymbol) != 1:
72+
if self._len_noansi(self.graphsymbol) != 1:
7273
raise Exception('Bad graphsymbol length, must be 1',
73-
len(self.graphsymbol))
74+
self._len_noansi(self.graphsymbol))
7475
self.multivalue = multivalue
7576
self.hsymbols = [self._u(''), self._u('K'), self._u('M'),
7677
self._u('G'), self._u('T'), self._u('P'),
@@ -83,6 +84,11 @@ def __init__(self, line_length=79,
8384
else:
8485
self.divider = None
8586

87+
@staticmethod
88+
def _len_noansi(string):
89+
l = len(re.sub('\x1b[^m]*m', '', string))
90+
return l
91+
8692
def _trans_hr(self, value):
8793

8894
if self.divider is None:
@@ -168,8 +174,8 @@ def _get_thresholds(self, data):
168174
if maxvalue > all_thre['max_pos_value']:
169175
all_thre['max_pos_value'] = maxvalue
170176

171-
if len(info) > all_thre['info_max_length']:
172-
all_thre['info_max_length'] = len(info)
177+
if self._len_noansi(info) > all_thre['info_max_length']:
178+
all_thre['info_max_length'] = self._len_noansi(info)
173179

174180
if totalvalue_len > all_thre['value_max_length']:
175181
all_thre['value_max_length'] = totalvalue_len
@@ -265,7 +271,7 @@ def _gen_graph_string_part(
265271
def _gen_info_string(self, info, start_info_pos, line_length):
266272
"""Generate the info string + padding
267273
"""
268-
number_of_space = (line_length - start_info_pos - len(info))
274+
number_of_space = (line_length - start_info_pos - self._len_noansi(info))
269275
return info + Pyasciigraph._u(' ') * number_of_space
270276

271277
def _gen_value_string(self, value, min_neg_value, color, start_value_pos, start_info_pos):
@@ -390,7 +396,7 @@ def graph(self, label=None, data=[]):
390396

391397
if not label is None:
392398
san_label = self._sanitize_string(label)
393-
label_len = len(san_label)
399+
label_len = self._len_noansi(san_label)
394400
else:
395401
label_len = 0
396402

examples/color_multivalue_graphs.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,14 @@
2525
# Coloring data according to thresholds
2626
from ascii_graph.colordata import hcolor
2727

28-
test = [('testval0', 600),
29-
('testval1', 500),
30-
('testval2', -400),
31-
('testval3', 400),
32-
('testval4', 300),
33-
('testval5', 200),
34-
('testval6', 100),
35-
('testval7', 50 )]
28+
test = [('testval0 (\033[92m+\033[0m)', 600),
29+
('testval1 (\033[91m-\033[0m)', 500),
30+
('testval2 (\033[92m+\033[0m)', -400),
31+
('testval3 (\033[92m+\033[0m)', 400),
32+
('testval4 (\033[92m+\033[0m)', 300),
33+
('testval5 (\033[91m-\033[0m)', 200),
34+
('testval6 (\033[92m+\033[0m)', 100),
35+
('testval7 (\033[92m+\033[0m)', 50 )]
3636

3737
thresholds = {
3838
51: Gre,

tests/test_lib.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,18 @@ def test_unsorted_default_params(self):
4040
gprint(expected)
4141
assert res == expected
4242

43+
def test_noansi_info(self):
44+
test = [('long_labe☭ (\033[92m+\033[0m)', 423), ('sl (\033[91m-\033[0m)', 1234), ('line3 (\033[91m-\033[0m)', 531), ('line4', 200), ('line5', 834)]
45+
graph = Pyasciigraph()
46+
res = graph.graph('☭test print', test)
47+
expected = [u'\u262dtest print', u'###############################################################################', u'\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 423 long_labe\u262d (\x1b[92m+\x1b[0m)', u'\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 1234 sl (\x1b[91m-\x1b[0m) ', u'\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 531 line3 (\x1b[91m-\x1b[0m) ', u'\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 200 line4 ', u'\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 834 line5 ']
48+
gprint(res)
49+
gprint(expected)
50+
print res
51+
assert res == expected
52+
53+
54+
4355
def test_float_format(self):
4456
test = [('long_labe☭', 423.197), ('sl', 1234.12341), ('line3', 531.11), ('line4', 200), ('line5', 834)]
4557
graph = Pyasciigraph(float_format='{0:,.2f}')

0 commit comments

Comments
 (0)