1 coding = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
2 ecoding = coding + '-.'
3 codeset = {
4 'simple': {
5 'coding': coding,
6 'max_value': 61,
7 'char': ',',
8 'dchar': '',
9 'none': '_',
10 'value': lambda x: coding[x]
11 },
12 'text': {
13 'coding': '',
14 'max_value': 100,
15 'none': '-1',
16 'char': '|',
17 'dchar': ',',
18 'value': lambda x: '%.1f' % float(x)
19 },
20 'extended': {
21 'coding': ecoding,
22 'max_value': 4095,
23 'none': '__',
24 'dchar': '',
25 'char': ',',
26 'value': lambda x: '%s%s' % \
27 (ecoding[int(float(x) / 64)], ecoding[int(x % 64)])
28 }
29 }
30
32 """Data encoder that handles simple,text, and extended encodings
33
34 Based on javascript encoding algorithm and pygooglecharts"""
35 - def __init__(self, encoding=None, scale=None, series=''):
44
46 return value
47 if self.encoding != 'text' and self.scale and \
48 isinstance(value, int) or isinstance(value, float):
49 if type(self.scale) == type(()):
50 lower,upper = self.scale
51 else:
52 lower,upper = 0,float(self.scale)
53 value = int(round(float(value - lower) * \
54 self.codeset['max_value'] / upper))
55 return min(value, self.codeset['max_value'])
56
57 - def encode(self, *args, **kwargs):
58 """Encode wrapper for a dataset with maximum value
59
60 Datasets can be one or two dimensional
61 Strings are ignored as ordinal encoding"""
62 if isinstance(args[0], str):
63 return self.encode([args[0]],**kwargs)
64 elif isinstance(args[0], int) or isinstance(args[0], float):
65 return self.encode([[args[0]]],**kwargs)
66 if len(args)>1:
67 dataset = args
68 else:
69 dataset = args[0]
70 typemap = list(map(type,dataset))
71 code = self.encoding[0]
72 if type('') in typemap:
73 data = ','.join(map(str,dataset))
74 elif type([]) in typemap or type(()) in typemap:
75 data = self.codeset['char'].join(map(self.encodedata, dataset))
76 elif len(dataset) == 1 and hasattr(dataset[0], '__iter__'):
77 data = self.encodedata(dataset[0])
78 else:
79 try:
80 data = self.encodedata(dataset)
81 except ValueError:
82 data = self.encodedata(','.join(map(unicode,dataset)))
83 if not '.' in data and code == 't':
84 code = 'e'
85 return '%s%s:%s'%(code,self.series,data)
86
88 sub_data = []
89 enc_size = len(self.codeset['coding'])
90 for value in data:
91 if value in (None,'None'):
92 sub_data.append(self.codeset['none'])
93 elif isinstance(value, str):
94 sub_data.append(value)
95 elif value >= -1:
96 try:
97 sub_data.append(self.codeset['value'](self.scalevalue(value)))
98 except:
99 raise ValueError('cannot encode value: %s'%value)
100 return self.codeset['dchar'].join(sub_data)
101
103 e = astr[0]
104 dec_data = []
105 for data in astr[2:].split(self.codeset['char']):
106 sub_data = []
107 if e == 't':
108 sub_data.extend(map(float, data.split(',')))
109 elif e == 'e':
110 flag = 0
111 index = self.codeset['coding'].index
112 for i in range(len(data)):
113 if not flag:
114 this,next = index(data[i]),index(data[i+1])
115 flag = 1
116 sub_data.append((64 * this) + next)
117 else: flag = 0
118 elif e == 's':
119 sub_data.extend(map(self.codeset['coding'].index, data))
120 dec_data.append(sub_data)
121 return dec_data
122