[RELEASE] OpenERP 5.0.12
[odoo/odoo.git] / bin / pychart / pychart_util.py
1 #
2 # Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com)
3
4 # Jockey is free software; you can redistribute it and/or modify it
5 # under the terms of the GNU General Public License as published by the
6 # Free Software Foundation; either version 2, or (at your option) any
7 # later version.
8 #
9 # Jockey is distributed in the hope that it will be useful, but WITHOUT
10 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 # FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 # for more details.
13 #
14 import sys
15 import math
16 import types
17 import traceback
18 from types import *
19
20 def inch_to_point(inch):
21     return inch * 72.0
22 def point_to_inch(pt):
23     return float(pt) / 72.0
24
25 def rotate(x, y, degree):
26     """Rotate a coordinate around point (0,0).
27     - x and y specify the coordinate.
28     - degree is a number from 0 to 360.
29     Returns a new coordinate.
30     """
31     radian = float(degree) * 2 * math.pi / 360.0
32     newx = math.cos(radian) * x - math.sin(radian) * y
33     newy = math.sin(radian) * x + math.cos(radian) * y
34     return (newx, newy)
35
36 debug_level = 1
37
38 def warn(*strs):
39     for s in strs:
40         sys.stderr.write(str(s))
41         sys.stderr.write(" ")
42     sys.stderr.write("\n")
43
44 def info(*strs):
45     if debug_level < 100:
46         return
47     for s in strs:
48         sys.stderr.write(str(s))
49     sys.stderr.write("\n")
50
51 def get_sample_val(l, col):
52     if len(l) <= col:
53         return None
54     return l[col]
55
56 def get_data_list(data, col):
57     # data = [ elem[col] for elem in data if elem[col] != None ]
58     r = []
59     for item in data:
60         val = get_sample_val(item, col)
61         if val != None:
62             r.append(val)
63     return r        
64     
65 def get_data_range(data, col):
66     data = get_data_list(data, col)
67     for item in data:
68         if type(item) not in (types.IntType, types.LongType, types.FloatType):
69             raise TypeError, "Non-number passed to data: %s" % (data)
70     return (min(data), max(data))
71
72 def round_down(val, bound):
73     return int(val/float(bound)) * bound
74
75 def round_up(val, bound):
76     return (int((val-1)/float(bound))+1) * bound
77
78     
79 #
80 # Attribute type checking stuff
81 #
82
83 def new_list():
84     return []
85
86 def union_dict(dict1, dict2):
87     dict = dict1.copy()
88     dict.update(dict2)
89     return dict
90
91 def TextVAlignType(val):
92     if val in ('T', 'B', 'M', None):
93         return None
94     return "Text vertical alignment must be one of T(op), B(ottom), or M(iddle).\n"
95
96 def TextAlignType(val):
97     if val in ('C', 'R', 'L', None):
98         return None
99     return "Text horizontal alignment must be one of C(enter), R(ight), or L(eft)."
100
101 def apply_format(format, val, defaultidx):
102     if format == None:
103         return None
104     elif type(format) == StringType:
105         return format % val[defaultidx]
106     else:
107         return apply(format, val)
108
109     
110 data_desc = "Specifies the data points. <<chart_data>>"
111 label_desc = "The label to be displayed in the legend. <<legend>>, <<font>>"
112 xcol_desc = """The column, within attribute "data", from which the X values of sample points are extracted. <<chart_data>>"""
113 ycol_desc = """The column, within attribute "data", from which the Y values of sample points are extracted. <<chart_data>>"""
114 tick_mark_desc = "Tick marks to be displayed at each sample point. <<tick_mark>>"
115 line_desc="The style of the line. "
116
117 def interval_desc(w):
118     return "When the value is a number, it specifies the interval at which %s are drawn. Otherwise, the value must be a function that takes no argument and returns the list of numbers. The return value specifies the X or Y points at which %s are drawn." % (w,w)
119
120 shadow_desc = """The value is either None or a tuple. When non-None,
121 a drop-shadow is drawn beneath the object. X-off, and y-off specifies the
122 offset of the shadow relative to the object, and fill specifies the
123 style of the shadow (@pxref{module-fill-style})."""
124
125 string_desc = """The appearance of the string produced here can be
126 controlled using escape sequences. <<font>>"""
127
128 #
129 #
130
131 class symbol_lookup_table:
132     def __init__(self, dict, objs):
133         self.names = {}
134         for name, val in dict.items():
135             for obj in objs.list():
136                 if val == obj:
137                     self.names[val] = name
138                     break
139     def lookup(self, obj):
140         if self.names.has_key(obj):
141             return self.names[obj]
142         return None